summaryrefslogtreecommitdiff
path: root/src/fl_font_mac.cxx
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2008-09-10 23:56:49 +0000
committerMatthias Melcher <fltk@matthiasm.com>2008-09-10 23:56:49 +0000
commitb6bde2e4569aa617c8a6af64947c688c624ed7f8 (patch)
tree010d15843eb7d4faf7cd1b0cd44d5b9c00462a83 /src/fl_font_mac.cxx
parentdfb50e85292687561927610e689eb5ab30d0ba26 (diff)
Merging the UTF8 patch, consisting of O'ksi'd s original 1.1.6 patch and additions by Ian. PLEASE BE AWARE that the patch in its current incarnation is a regression in many aspects and further work is required before we can announce Unicode support.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6212 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/fl_font_mac.cxx')
-rw-r--r--src/fl_font_mac.cxx241
1 files changed, 83 insertions, 158 deletions
diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx
index 0914b1498..1b26b03d7 100644
--- a/src/fl_font_mac.cxx
+++ b/src/fl_font_mac.cxx
@@ -27,31 +27,15 @@
#include <config.h>
+/* from fl_utf.c */
+extern unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned short* dst, unsigned dstlen);
+
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
next = 0;
# if HAVE_GL
listbase = 0;
# endif
-#ifdef __APPLE_QD__
- knowMetrics = 0;
- switch (*name++) {
- case 'I': face = italic; break;
- case 'P': face = italic | bold; break;
- case 'B': face = bold; break;
- default: face = 0; break;
- }
- unsigned char fn[80];
- fn[0] = strlen(name); strcpy((char*)(fn+1), name);
- GetFNum(fn, &font);
- size = Size;
- FMInput fIn = { font, size, face, 0, 0, { 1, 1}, { 1, 1} };
- FMOutput *fOut = FMSwapFont(&fIn);
- ascent = fOut->ascent; //: the following three lines give only temporary aproimations
- descent = fOut->descent;
- for (int i=0; i<256; i++) width[i] = fOut->widMax;
- minsize = maxsize = size;
-#elif defined(__APPLE_QUARTZ__)
- knowWidths = 0;
+// knowWidths = 0;
// OpenGL needs those for its font handling
q_name = strdup(name);
size = Size;
@@ -62,7 +46,8 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
q_width = Size*2/3;
minsize = maxsize = Size;
// now use ATS to get the actual Glyph size information
- CFStringRef cfname = CFStringCreateWithCString(0L, name, kCFStringEncodingASCII);
+ // say that our passed-in name is encoded as UTF-8, since this works for plain ASCII names too...
+ CFStringRef cfname = CFStringCreateWithCString(0L, name, kCFStringEncodingUTF8);
ATSFontRef font = ATSFontFindFromName(cfname, kATSOptionFlagsDefault);
if (font) {
ATSFontMetrics m = { 0 };
@@ -80,18 +65,22 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
err = ATSUSetTextPointerLocation(layout, mTxt, kATSUFromTextBeginning, 1, 1);
err = ATSUCreateStyle(&style);
err = ATSUSetRunStyle(layout, style, kATSUFromTextBeginning, kATSUToTextEnd);
- // now set the actual font, size and attributes. We also set the font matrix to
+ // now set the actual font, size and attributes. We also set the font matrix to
// render our font up-side-down, so when rendered through our inverted CGContext,
// text will appear normal again.
- Fixed fsize = FloatToFixed(Size);
- ATSUFontID fontID = FMGetFontFromATSFontRef(font);
+ Fixed fsize = IntToFixed(Size);
+// ATSUFontID fontID = FMGetFontFromATSFontRef(font);
+ ATSUFontID fontID;
+ ATSUFindFontFromName(name, strlen(name), kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, &fontID);
+
+ // draw the font upside-down... Compensate for fltk/OSX origin differences
static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
ATSUAttributeTag sTag[] = { kATSUFontTag, kATSUSizeTag, kATSUFontMatrixTag };
ByteCount sBytes[] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(CGAffineTransform) };
ATSUAttributeValuePtr sAttr[] = { &fontID, &fsize, &font_mx };
err = ATSUSetAttributes(style, 3, sTag, sBytes, sAttr);
// next, make sure that Quartz will only render at integer coordinates
- ATSLineLayoutOptions llo = kATSLineUseDeviceMetrics|kATSLineDisableAllLayoutOperations;
+ ATSLineLayoutOptions llo = kATSLineUseDeviceMetrics | kATSLineDisableAllLayoutOperations;
ATSUAttributeTag aTag[] = { kATSULineLayoutOptionsTag };
ByteCount aBytes[] = { sizeof(ATSLineLayoutOptions) };
ATSUAttributeValuePtr aAttr[] = { &llo };
@@ -109,8 +98,15 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
descent = fd; //Size - ascent;
}
int w = FixedToInt(bAfter);
- if (w)
+ if (w)
q_width = FixedToInt(bAfter);
+
+#define ENABLE_TRANSIENT_FONTS 1
+
+#ifdef ENABLE_TRANSIENT_FONTS
+ // Now, by way of experiment, try enabling Transient Font Matching, this will
+ // cause ATSU to find a suitable font to render any chars the current font can't do...
+ ATSUSetTransientFontMatching (layout, true);
#endif
}
@@ -132,33 +128,13 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
#endif
*/
if (this == fl_fontsize) fl_fontsize = 0;
-#ifdef __APPLE_QUARTZ__
ATSUDisposeTextLayout(layout);
ATSUDisposeStyle(style);
-#endif
}
////////////////////////////////////////////////////////////////
static Fl_Fontdesc built_in_table[] = {
-#ifdef __APPLE_QD__
-{" Arial"},
-{"BArial"},
-{"IArial"},
-{"PArial"},
-{" Courier New"},
-{"BCourier New"},
-{"ICourier New"},
-{"PCourier New"},
-{" Times New Roman"},
-{"BTimes New Roman"},
-{"ITimes New Roman"},
-{"PTimes New Roman"},
-{" Symbol"},
-{" Chicago"},
-{"BChicago"},
-{" Webdings"},
-#elif defined(__APPLE_QUARTZ__)
{"Arial"},
{"Arial Bold"},
{"Arial Italic"},
@@ -175,74 +151,30 @@ static Fl_Fontdesc built_in_table[] = {
{"Monaco"},
{"Andale Mono"}, // there is no bold Monaco font on standard Mac
{"Webdings"},
-#endif
};
-#ifdef __APPLE_QUARTZ__
-static UniChar utf16lut[128] = {
- 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1,
- 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8,
- 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3,
- 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc,
- 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df,
- 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8,
- 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211,
- 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x03a9, 0x00e6, 0x00f8,
- 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab,
- 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153,
- 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca,
- 0x00ff, 0x0178, 0x2044, 0x20ac, 0x2039, 0x203a, 0xfb01, 0xfb02,
- 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1,
- 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4,
- 0xf8ff, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc,
- 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7,
-};
-static UniChar *utf16buf = 0;
-static int utf16len = 0;
-UniChar *fl_macToUtf16(const char *txt, int len)
+static UniChar *utfWbuf = 0;
+static unsigned utfWlen = 0;
+
+static UniChar *mac_Utf8_to_Utf16(const char *txt, int len, int *new_len)
{
- if ((len+1)>utf16len) {
- utf16len = len+100;
- free(utf16buf);
- utf16buf = (UniChar*)malloc((utf16len+1)*sizeof(UniChar));
- }
- int i;
- unsigned char c;
- const unsigned char *src = (unsigned char const*)txt;
- UniChar *dst = utf16buf;
- for (i=0; i<len; i++) {
- c = *src++;
- *dst++ =(c<128) ? c : utf16lut[c-128];
+ unsigned wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen);
+ if(wlen >= utfWlen)
+ {
+ utfWlen = wlen + 100;
+ if(utfWbuf) free(utfWbuf);
+ utfWbuf = (UniChar*)malloc((utfWlen)*sizeof(UniChar));
+ wlen = fl_utf8toUtf16(txt, len, (unsigned short*)utfWbuf, utfWlen);
}
- *dst = 0;
- return utf16buf;
-}
-#endif
+ *new_len = wlen;
+ return utfWbuf;
+} // mac_Utf8_to_Utf16
Fl_Fontdesc* fl_fonts = built_in_table;
void fl_font(Fl_Font_Descriptor* s) {
fl_fontsize = s;
-#ifdef __APPLE_QD__
- if (fl_window) SetPort( GetWindowPort(fl_window) );
- TextFont(fl_fontsize->font); //: select font into current QuickDraw GC
- TextFace(fl_fontsize->face);
- TextSize(fl_fontsize->size);
- if (!fl_fontsize->knowMetrics) { //: get the true metrics for the currnet GC
- //: (fails on multiple monitors with different dpi's!)
- FontInfo fi; GetFontInfo(&fi);
- fl_fontsize->ascent = fi.ascent;
- fl_fontsize->descent = fi.descent;
- FMetricRec mr; FontMetrics(&mr);
- short *f = (short*)*mr.wTabHandle; //: get the char size table
- for (int i=0; i<256; i++) fl_fontsize->width[i] = f[2*i];
- fl_fontsize->knowMetrics = 1;
- }
-#elif defined(__APPLE_QUARTZ__)
// we will use fl_fontsize later to access the required style and layout
-#else
-# error : need to defined either Quartz or Quickdraw
-#endif
}
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
@@ -284,81 +216,59 @@ int fl_descent() {
else return -1;
}
-double fl_width(const char* txt, int n) {
-#ifdef __APPLE_QD__
- return (double)TextWidth( txt, 0, n );
-#else
+double fl_width(const UniChar* txt, int n) {
if (!fl_fontsize) {
fl_font(0, 12); // avoid a crash!
if (!fl_fontsize)
return 8*n; // user must select a font first!
}
- if (!fl_fontsize->knowWidths) {
- if (!fl_gc) {
- Fl_Window *w = Fl::first_window();
- if (w) w->make_current();
- if (!fl_gc) {
- if (fl_fontsize) return fl_fontsize->q_width*n;
- return 8*n;
- // We fall back to some internal QuickDraw port.
- // The result should be the same.
- }
- }
- char buf[2];
- for (int i=0; i<256; i++) {
OSStatus err;
- buf[0] = (char)i;
- // convert to UTF-16 first
- UniChar *uniStr = fl_macToUtf16(buf, 1);
- // now collect our ATSU resources
- ATSUTextLayout layout = fl_fontsize->layout;
+ Fixed bBefore, bAfter, bAscent, bDescent;
+ ATSUTextLayout layout;
+ ByteCount iSize;
+ ATSUAttributeTag iTag;
+ ATSUAttributeValuePtr iValuePtr;
+
+// Here's my ATSU text measuring attempt... This seems to do the Right Thing
+ // now collect our ATSU resources and measure our text string
+ layout = fl_fontsize->layout;
// activate the current GC
- ByteCount iSize = sizeof(CGContextRef);
- ATSUAttributeTag iTag = kATSUCGContextTag;
- ATSUAttributeValuePtr iValuePtr=&fl_gc;
+ iSize = sizeof(CGContextRef);
+ iTag = kATSUCGContextTag;
+ iValuePtr = &fl_gc;
ATSUSetLayoutControls(layout, 1, &iTag, &iSize, &iValuePtr);
// now measure the bounding box
- err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, 1, 1);
- Fixed bBefore, bAfter, bAscent, bDescent;
- err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, 1, &bBefore, &bAfter, &bAscent, &bDescent);
- fl_fontsize->width[i] = FixedToInt(bAfter);
- }
- fl_fontsize->knowWidths = 1;
- }
- int len = 0;
- const char *src = txt;
- for (int j=0; j<n; j++) {
- unsigned char c = *src++;
- len += fl_fontsize->width[c];
- }
+ err = ATSUSetTextPointerLocation(layout, txt, kATSUFromTextBeginning, n, n);
+ err = ATSUGetUnjustifiedBounds(layout, kATSUFromTextBeginning, n, &bBefore, &bAfter, &bAscent, &bDescent);
+ // If err is OK then return length, else return 0. Or something...
+ int len = FixedToInt(bAfter);
return len;
-#endif
+}
+
+double fl_width(const char* txt, int n) {
+ int wc_len = n;
+ UniChar *uniStr = mac_Utf8_to_Utf16(txt, n, &wc_len);
+ return fl_width(uniStr, wc_len);
}
double fl_width(uchar c) {
return fl_width((const char*)(&c), 1);
}
+double fl_width(unsigned int wc) {
+ return fl_width((const UniChar*)(&wc), 1);
+}
+
void fl_draw(const char *str, int n, float x, float y);
void fl_draw(const char* str, int n, int x, int y) {
-#ifdef __APPLE_QD__
- MoveTo(x, y);
- DrawText((const char *)str, 0, n);
-#elif defined(__APPLE_QUARTZ__)
fl_draw(str, n, (float)x-0.0f, (float)y-0.5f);
-#else
-# error : neither Quartz no Quickdraw chosen
-#endif
}
void fl_draw(const char *str, int n, float x, float y) {
-#ifdef __APPLE_QD__
- fl_draw(str, n, (int)x, (int)y);
-#elif defined(__APPLE_QUARTZ__)
OSStatus err;
- // convert to UTF-16 first
- UniChar *uniStr = fl_macToUtf16(str, n);
+ // convert to UTF-16 first
+ UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
// now collect our ATSU resources
ATSUTextLayout layout = fl_fontsize->layout;
@@ -369,11 +279,26 @@ void fl_draw(const char *str, int n, float x, float y) {
err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n);
err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x), FloatToFixed(y));
-#else
-# error : neither Quartz no Quickdraw chosen
-#endif
}
+void fl_rtl_draw(const char* c, int n, int x, int y) {
+// I guess with ATSU the thing to do is force the layout mode to RTL and let ATSU draw the text...
+ double offs = fl_width(c, n);
+ OSStatus err;
+ // convert to UTF-16 first
+ UniChar *uniStr = mac_Utf8_to_Utf16(c, n, &n);
+ // now collect our ATSU resources
+ ATSUTextLayout layout = fl_fontsize->layout;
+ // reverse the layout direction
+ ATSUAttributeTag llo = kATSURightToLeftBaseDirection; // layout option
+ ByteCount iSize[] = {sizeof(ATSUAttributeTag), sizeof(CGContextRef)};
+ ATSUAttributeTag iTag[] = {kATSULineDirectionTag, kATSUCGContextTag};
+ ATSUAttributeValuePtr aAttr[] = { &llo, &fl_gc};
+ ATSUSetLayoutControls (layout, 2, iTag, iSize, aAttr );
+
+ err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n);
+ err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x-offs), FloatToFixed(y));
+}
//
// End of "$Id$".
//