diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2009-12-06 22:21:55 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2009-12-06 22:21:55 +0000 |
| commit | b2cffc688ea7abbddabc9ed23deea1921f59ac9d (patch) | |
| tree | 74a50bdb133fd6b5af7c785541bcc46e2e8e9c15 /src/fl_font_mac.cxx | |
| parent | 1ea4b4573538f2d53960dd8a4ef4f35480d2f5f7 (diff) | |
Moved OS X code base to the more moder Cocoa toolkit thanks to the awesome work of Manolo Gouy (STR #2221). This is a big one! I tested all test applications under 32-bit autoconf and Xcode, and a few apps under 64bit intel. No PPC testing was done. Please verify this patch if you have the machine!
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@6951 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/fl_font_mac.cxx')
| -rw-r--r-- | src/fl_font_mac.cxx | 199 |
1 files changed, 189 insertions, 10 deletions
diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx index 3e9db0763..552a579ad 100644 --- a/src/fl_font_mac.cxx +++ b/src/fl_font_mac.cxx @@ -33,6 +33,8 @@ extern unsigned fl_utf8toUtf16(const char* src, unsigned srclen, unsigned short* // if no font has been selected yet by the user, get one. #define check_default_font() {if (!fl_fontsize) fl_font(0, 12);} +static const CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 }; + Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) { next = 0; # if HAVE_GL @@ -43,13 +45,39 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) { // OpenGL needs those for its font handling q_name = strdup(name); size = Size; + minsize = maxsize = Size; +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(CTFontCreateWithName != NULL) { + CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8); + fontref = CTFontCreateWithName(str, size, NULL); + CGGlyph glyph[2]; + const UniChar A[2]={'W','.'}; + CTFontGetGlyphsForCharacters(fontref, A, glyph, 2); + CGSize advances[2]; + double w; + CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, advances, 2); + w = advances[0].width; + if( abs(advances[0].width - advances[1].width) < 1E-2 ) {//this is a fixed-width font + //slightly rescale fixed-width fonts so the character width has an integral value + CFRelease(fontref); + CGFloat fsize = size / ( w/floor(w + 0.5) ); + fontref = CTFontCreateWithName(str, fsize, NULL); + w = CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, NULL, 1); + } + CFRelease(str); + ascent = (short)(CTFontGetAscent(fontref) + 0.5); + descent = (short)(CTFontGetDescent(fontref) + 0.5); + q_width = w + 0.5; + } +else { +#endif +#if ! __LP64__ OSStatus err; // fill our structure with a few default values ascent = Size*3/4; descent = Size-ascent; q_width = Size*2/3; - minsize = maxsize = Size; - // now use ATS to get the actual Glyph size information + // now use ATS to get the actual Glyph size information // 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); @@ -112,6 +140,10 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) { // cause ATSU to find a suitable font to render any chars the current font can't do... ATSUSetTransientFontMatching (layout, true); # endif +#endif//__LP64__ +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif } Fl_Font_Descriptor* fl_fontsize = 0L; @@ -132,8 +164,12 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() { #endif */ if (this == fl_fontsize) fl_fontsize = 0; - ATSUDisposeTextLayout(layout); - ATSUDisposeStyle(style); +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + if(CTFontCreateWithName != NULL) CFRelease(fontref); +#else + /* ATSUDisposeTextLayout(layout); + ATSUDisposeStyle(style); */ +#endif } //////////////////////////////////////////////////////////////// @@ -235,7 +271,25 @@ double fl_width(const UniChar* txt, int n) { if (!fl_fontsize) return 8*n; // user must select a font first! } - OSStatus err; +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(CTFontCreateWithName != NULL) { + CTFontRef fontref = fl_fontsize->fontref; + CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n * sizeof(UniChar), kCFStringEncodingUTF16, false); + CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str, NULL); + CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr); + CFRelease(astr); + CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str)), kCTFontAttributeName, fontref); + CFRelease(str); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + double retval = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL); + CFRelease(ctline); + return retval; + } +else { +#endif +#if ! __LP64__ + OSStatus err; Fixed bBefore, bAfter, bAscent, bDescent; ATSUTextLayout layout; ByteCount iSize; @@ -256,6 +310,10 @@ double fl_width(const UniChar* txt, int n) { // If err is OK then return length, else return 0. Or something... int len = FixedToInt(bAfter); return len; +#endif +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif } double fl_width(const char* txt, int n) { @@ -281,6 +339,30 @@ void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h h = 8.0; return; } +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(CTFontCreateWithName != NULL) { + CTFontRef fontref = fl_fontsize->fontref; + CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n *sizeof(UniChar), kCFStringEncodingUTF16, false); + CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str16, NULL); + CFMutableAttributedStringRef mastr = CFAttributedStringCreateMutableCopy(NULL, 0, astr); + CFRelease(astr); + CFAttributedStringSetAttribute(mastr, CFRangeMake(0, CFStringGetLength(str16)), kCTFontAttributeName, fontref); + CFRelease(str16); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + CGContextSetTextPosition(fl_gc, 0, 0); + CGContextSetShouldAntialias(fl_gc, true); + CGRect rect = CTLineGetImageBounds(ctline, fl_gc); + CGContextSetShouldAntialias(fl_gc, false); + CFRelease(ctline); + dx = floor(rect.origin.x + 0.5); + dy = floor(- rect.origin.y - rect.size.height + 0.5); + w = rect.size.width + 0.5; + h = rect.size.height + 0.5; + } +else { +#endif +#if ! __LP64__ OSStatus err; ATSUTextLayout layout; ByteCount iSize; @@ -304,6 +386,10 @@ void fl_text_extents(const UniChar* txt, int n, int &dx, int &dy, int &w, int &h dx = bbox.left; dy = -bbox.bottom; //printf("r: %d l: %d t: %d b: %d w: %d h: %d\n", bbox.right, bbox.left, bbox.top, bbox.bottom, w, h); +#endif +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif return; } // fl_text_extents @@ -320,13 +406,76 @@ void fl_draw(const char* str, int n, int x, int y) { fl_draw(str, n, (float)x-0.0f, (float)y-0.5f); } + +#if defined(__APPLE_COCOA__) +static unsigned fl_cmap[256] = { +#include "fl_cmap.h" // this is a file produced by "cmap.cxx": +}; +CGColorRef flcolortocgcolor(Fl_Color i) +{ + int index; + uchar r, g, b; + if (i & 0xFFFFFF00) { + // translate rgb colors into color index + r = i>>24; + g = i>>16; + b = i>> 8; + } else { + // translate index into rgb: + index = i; + unsigned c = fl_cmap[i]; + r = c>>24; + g = c>>16; + b = c>> 8; + } + CGFloat components[4] = {r/255.0f, g/255.0f, b/255.0f, 1.}; +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4 + return CGColorCreate(CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB), components); +#else + return CGColorCreate(CGColorSpaceCreateWithName(kCGColorSpaceUserRGB), components); +#endif +} +#endif + void fl_draw(const char *str, int n, float x, float y) { - OSStatus err; - // convert to UTF-16 first - UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); // avoid a crash if no font has been selected by user yet ! check_default_font(); + // convert to UTF-16 first + UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(CTFontCreateWithName != NULL) { + CFStringRef keys[2]; + CFTypeRef values[2]; + CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)uniStr, n * sizeof(UniChar), kCFStringEncodingUTF16, false); + CGColorRef color = flcolortocgcolor(fl_color()); + keys[0] = kCTFontAttributeName; + keys[1] = kCTForegroundColorAttributeName; + values[0] = fl_fontsize->fontref; + values[1] = color; + CFDictionaryRef attributes = CFDictionaryCreate(kCFAllocatorDefault, + (const void**)&keys, + (const void**)&values, + 2, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes); + CFRelease(str16); + CFRelease(attributes); + CFRelease(color); + CTLineRef ctline = CTLineCreateWithAttributedString(mastr); + CFRelease(mastr); + CGContextSetTextMatrix(fl_gc, font_mx); + CGContextSetTextPosition(fl_gc, x, y); + CGContextSetShouldAntialias(fl_gc, true); + CTLineDraw(ctline, fl_gc); + CGContextSetShouldAntialias(fl_gc, false); + CFRelease(ctline); + } +else { +#endif +#if ! __LP64__ + OSStatus err; // now collect our ATSU resources ATSUTextLayout layout = fl_fontsize->layout; @@ -337,10 +486,25 @@ 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)); +#endif +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif } void fl_draw(int angle, const char *str, int n, int x, int y) { - OSStatus err; +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(CTFontCreateWithName != NULL) { + CGContextSaveGState(fl_gc); + CGContextTranslateCTM(fl_gc, x, y); + CGContextRotateCTM(fl_gc, - angle*(M_PI/180) ); + fl_draw(str, n, (float)0., (float)0.); + CGContextRestoreGState(fl_gc); + } +else { +#endif +#if ! __LP64__ + OSStatus err; // convert to UTF-16 first UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n); @@ -360,10 +524,21 @@ void fl_draw(int angle, const char *str, int n, int x, int y) { //restore layout baseline ang = IntToFixed(0); ATSUSetLayoutControls(layout, 2, iTag, iSize, aAttr); +#endif +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#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... +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 +if(CTFontCreateWithName != NULL) { + fl_draw(c, n, x - fl_width(c, n), y); //to check; + } +else { +#endif +#if ! __LP64__ + // 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 @@ -379,6 +554,10 @@ void fl_rtl_draw(const char* c, int n, int x, int y) { err = ATSUSetTextPointerLocation(layout, uniStr, kATSUFromTextBeginning, n, n); err = ATSUDrawText(layout, kATSUFromTextBeginning, n, FloatToFixed(x-offs), FloatToFixed(y)); +#endif +#if defined(__APPLE_COCOA__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5 + } +#endif } // |
