Author: matt
Date: 2011-10-02 15:34:05 -0700 (Sun, 02 Oct 2011)
New Revision: 9118
Log:
FLTK3/OSX (this should probably be applied to FLTK1.3 as well): move some code
around for the character width caching. Caching character widths in 128
character blocks was extremely expensive if most characters in that block need
substitute fonts. This was very visible when opening a pulldown menu with OS X
special charcters which would take up to two seconds on the Max! Now, if a
substitute font is needed, we defer width calculation until the character is
actually needed, speeding the code up by a factor of 127 in the best case.
Modified:
branches/branch-3.0/src/fltk3/cocoa_font.cxx
Modified: branches/branch-3.0/src/fltk3/cocoa_font.cxx
===================================================================
--- branches/branch-3.0/src/fltk3/cocoa_font.cxx 2011-10-02 19:56:19 UTC
(rev 9117)
+++ branches/branch-3.0/src/fltk3/cocoa_font.cxx 2011-10-02 22:34:05 UTC
(rev 9118)
@@ -296,52 +296,70 @@
static double fl_mac_width(const UniChar* txt, int n, Fl_Font_Descriptor
*fontsize) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-if (fl_mac_os_version >= 100500) {
- double retval = 0;
- UniChar uni;
- int i;
- for (i = 0; i < n; i++) { // loop over txt
- uni = txt[i];
- if (uni >= 0xD800 && uni <= 0xDBFF) { // handles the surrogate range
- retval += surrogate_width(&txt[i], fontsize);
- i++; // because a pair of UniChar's represent a single character
- continue;
- }
- const int block = 0x10000 / (sizeof(fontsize->width)/sizeof(float*)); //
block size
- // r: index of the character block containing uni
- unsigned int r = uni >> 7; // change 7 if sizeof(width) is changed
- if (!fontsize->width[r]) { // this character block has not been hit yet
-//fprintf(stderr,"r=%d size=%d name=%s\n",r,fltk3::fontsize->size,
fltk3::fontsize->q_name);
- // allocate memory to hold width of each character in the block
- fontsize->width[r] = (float*) malloc(sizeof(float) * block);
- UniChar ii = r * block;
- CGSize advance_size;
- CGGlyph glyph;
- for (int j = 0; j < block; j++) { // loop over the block
+ if (fl_mac_os_version >= 100500) {
+ static int nEx = 0;
+ double retval = 0;
+ UniChar uni;
+ int i;
+ for (i = 0; i < n; i++) { // loop over txt
+ uni = txt[i];
+ if (uni >= 0xD800 && uni <= 0xDBFF) { // handles the surrogate range
+ retval += surrogate_width(&txt[i], fontsize);
+ i++; // because a pair of UniChar's represent a single character
+ continue;
+ }
+ const int block = 0x10000 / (sizeof(fontsize->width)/sizeof(float*)); //
block size
+ //
r: index of the character block containing uni
+ unsigned int r = uni >> 7; // change 7 if sizeof(width) is changed
+ if (!fontsize->width[r]) { // this character block has not been hit yet
+ //fprintf(stderr,"r=%d size=%d
name=%s\n",r,fltk3::fontsize->size, fltk3::fontsize->q_name);
+ // allocate memory to hold width of each
character in the block
+ fontsize->width[r] = (float*) malloc(sizeof(float) * block);
+ UniChar ii = r * block;
+ CGSize advance_size;
+ CGGlyph glyph;
+ for (int j = 0; j < block; j++) { // loop over the block
+ CTFontRef font2 = fontsize->fontref;
+ bool must_release = false;
+ // ii spans all characters of this block
+ bool b = CTFontGetGlyphsForCharacters(font2, &ii, &glyph, 1);
+ if (b)
+ CTFontGetAdvancesForGlyphs(font2, kCTFontHorizontalOrientation,
&glyph, &advance_size, 1);
+ else
+ advance_size.width = -1e9; // calculate this later
+ // the width of one character of this block of characters
+ fontsize->width[r][j] = advance_size.width;
+ if (must_release) CFRelease(font2);
+ ii++;
+ }
+ }
+ // sum the widths of all characters of txt
+ double wdt = fontsize->width[r][uni & (block-1)];
+ if (wdt==-1e9) {
+ UniChar ii = uni;
+ CGSize advance_size;
+ CGGlyph glyph;
CTFontRef font2 = fontsize->fontref;
bool must_release = false;
// ii spans all characters of this block
bool b = CTFontGetGlyphsForCharacters(font2, &ii, &glyph, 1);
if (!b) { // the current font doesn't contain this char
- CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, &ii, 1,
kCFAllocatorNull);
- // find a font that contains it
- font2 = CTFontCreateForString(font2, str, CFRangeMake(0,1));
- must_release = true;
- CFRelease(str);
- b = CTFontGetGlyphsForCharacters(font2, &ii, &glyph, 1);
- }
+ CFStringRef str = CFStringCreateWithCharactersNoCopy(NULL, &ii, 1,
kCFAllocatorNull);
+ // find a font that contains it
+ font2 = CTFontCreateForString(font2, str, CFRangeMake(0,1));
+ must_release = true;
+ CFRelease(str);
+ b = CTFontGetGlyphsForCharacters(font2, &ii, &glyph, 1);
+ }
if (b) CTFontGetAdvancesForGlyphs(font2, kCTFontHorizontalOrientation,
&glyph, &advance_size, 1);
else advance_size.width = 0.;
// the width of one character of this block of characters
- fontsize->width[r][j] = advance_size.width;
+ wdt = fontsize->width[r][uni & (block-1)] = advance_size.width;
if (must_release) CFRelease(font2);
- ii++;
}
+ retval += wdt;
}
- // sum the widths of all characters of txt
- retval += fontsize->width[r][uni & (block-1)];
- }
- return retval;
+ return retval;
} else {
#endif
#if ! __LP64__
_______________________________________________
fltk-commit mailing list
[email protected]
http://lists.easysw.com/mailman/listinfo/fltk-commit