DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2530
Version: 1.3-current


Attached file "fast_mac_text2.patch"...


Link: http://www.fltk.org/str.php?L2530
Version: 1.3-current
Index: src/Fl_Font.H
===================================================================
--- src/Fl_Font.H       (revision 8287)
+++ src/Fl_Font.H       (working copy)
@@ -63,6 +63,8 @@
   ATSUTextLayout layout;
 #     if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
   CTFontRef fontref;
+  static const int glyph_count = 0x100;
+  int glyph_advances[glyph_count];
 #     endif
   ATSUStyle style;
   short ascent, descent, q_width;
Index: src/fl_font_mac.cxx
===================================================================
--- src/fl_font_mac.cxx (revision 8287)
+++ src/fl_font_mac.cxx (working copy)
@@ -69,7 +69,15 @@
   ascent = (short)(CTFontGetAscent(fontref) + 0.5);
   descent = (short)(CTFontGetDescent(fontref) + 0.5);
   q_width = w + 0.5;
-  }
+  // memorize in array glyph_advances the width of all characters with unicode 
<= 0xFF
+  CGSize advance_size;
+  for (int i = 0x20; i < glyph_count; i++) {
+    CTFontGetGlyphsForCharacters(fontref, (const UniChar*)&i, glyph, 1);
+    CTFontGetAdvancesForGlyphs(fontref, kCTFontHorizontalOrientation, glyph, 
&advance_size, 1);
+    glyph_advances[i] = (int)( advance_size.width + 0.5);
+    }
+  memset(glyph_advances, 0, 0x20 * sizeof(int));
+}
 else {
 #endif
 #if ! __LP64__
@@ -261,6 +269,8 @@
   else return -1;
 }
 
+static int use_glyphs(const UniChar *unis, int l);
+
 double fl_width(const UniChar* txt, int n) {
   check_default_font();
   if (!fl_fontsize) {
@@ -270,6 +280,12 @@
   }
 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
 if(fl_mac_os_version >= 0x1050) {
+  double retval = 0;
+  // if string is only made of characters with unicode <= 0xFF, its width can 
be computed fast
+  if (use_glyphs(txt, n)) {
+    for (int i = 0; i < n; i++) retval += fl_fontsize->glyph_advances[txt[i]];
+    return retval;
+  }
   CTFontRef fontref = fl_fontsize->fontref;
   CFStringRef str = CFStringCreateWithBytes(NULL, (const UInt8*)txt, n * 
sizeof(UniChar), kCFStringEncodingUTF16, false);
   CFAttributedStringRef astr = CFAttributedStringCreate(NULL, str, NULL);
@@ -279,7 +295,7 @@
   CFRelease(str);
   CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
   CFRelease(mastr);
-  double retval = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL);
+  retval = CTLineGetTypographicBounds(ctline, NULL, NULL, NULL);
   CFRelease(ctline);
   return retval;
   }
@@ -346,6 +362,14 @@
   CFMutableAttributedStringRef mastr = 
CFAttributedStringCreateMutableCopy(NULL, 0, astr);
   CFRelease(astr);
   CFAttributedStringSetAttribute(mastr, CFRangeMake(0, 
CFStringGetLength(str16)), kCTFontAttributeName, fontref);
+  if (use_glyphs(txt, n)) {
+    static CFNumberRef zero_ref = NULL;
+    if (!zero_ref) {
+      float zero = 0.;
+      zero_ref = CFNumberCreate(NULL, kCFNumberFloat32Type, &zero);
+      }
+    CFAttributedStringSetAttribute(mastr, CFRangeMake(0, 
CFStringGetLength(str16)), kCTKernAttributeName, zero_ref);
+    }
   CFRelease(str16);
   CTLineRef ctline = CTLineCreateWithAttributedString(mastr);
   CFRelease(mastr);
@@ -421,15 +445,22 @@
 #endif
 
 
+static void draw_as_glyphs(Fl_Font_Descriptor *font, UniChar *str16, int l, 
float x, float y);
+
 void fl_draw(const char *str, int n, float x, float y) {
   // 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 MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-  if(fl_mac_os_version >= 0x1050) {
+  if (fl_mac_os_version >= 0x1050) {
     CFStringRef keys[2];
     CFTypeRef values[2];  
+    // attempt to draw fast the string
+    if (use_glyphs(uniStr, n)) {
+      draw_as_glyphs(fl_fontsize, uniStr, n, x, y);
+      return;
+      }
     CFStringRef str16 = CFStringCreateWithBytes(NULL, (const UInt8*)uniStr, n 
* sizeof(UniChar), kCFStringEncodingUTF16, false);
     CGColorRef color = flcolortocgcolor(fl_color());
     keys[0] = kCTFontAttributeName;
@@ -489,6 +520,33 @@
   draw(c, n, int(x - fl_width(c, n)), y);
 }
 
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+
+static int use_glyphs(const UniChar *unis, int l)
+{
+  for (int i = 0; i < l; i++) {
+    if (unis[i] >= Fl_Font_Descriptor::glyph_count) return 0;
+  }
+  return 1;
+}
+       
+// draw fast a string if all its characters have unicode < 0x100
+static void draw_as_glyphs(Fl_Font_Descriptor *font, UniChar *unis, int l, 
float x, float y)
+{    
+  CGGlyph glyph;
+  CGContextSetTextMatrix(fl_gc, font_mx);
+  CGContextSetShouldAntialias(fl_gc, true);
+  CGContextSelectFont(fl_gc, font->q_name, CTFontGetSize(font->fontref), 
kCGEncodingMacRoman);
+  for (int i = 0; i < l; i++) {
+    CTFontGetGlyphsForCharacters(font->fontref, unis + i, &glyph, 1);
+    CGContextShowGlyphsAtPoint(fl_gc, x, y, &glyph, 1);
+    x += fl_fontsize->glyph_advances[unis[i]];
+    }
+  CGContextSetShouldAntialias(fl_gc, false);
+}
+
+#endif
+
 //
 // End of "$Id$".
 //
_______________________________________________
fltk-bugs mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-bugs

Reply via email to