[haiku-commits] r40174 - haiku/trunk/src/servers/app

  • From: mmlr@xxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 9 Jan 2011 05:10:13 +0100 (CET)

Author: mmlr
Date: 2011-01-09 05:10:13 +0100 (Sun, 09 Jan 2011)
New Revision: 40174
Changeset: http://dev.haiku-os.org/changeset/40174
Ticket: http://dev.haiku-os.org/ticket/7077

Modified:
   haiku/trunk/src/servers/app/FontCacheEntry.cpp
Log:
Implement missing glyph handling, making the glyph retrieval the following:

1. If the glyph is cached, return it, as before.
2. Try to find a glyph in the fallback font, as before.
3. Check for ignorable characters as per Unicode and cache and return a zero
   width glyph (rendering as completely invisible).
4. Reset to the original font.
5. Check for whitespace as per Unicode and cache and return the normal space
   glyph.
6. If there still is no valid glyphIndex, continue with index 0 which caches
   and returns the usual "missing glyph box".

This implements the Unicode suggestions on how to handle missing glyphs and
closes #7077.


Modified: haiku/trunk/src/servers/app/FontCacheEntry.cpp
===================================================================
--- haiku/trunk/src/servers/app/FontCacheEntry.cpp      2011-01-08 23:37:54 UTC 
(rev 40173)
+++ haiku/trunk/src/servers/app/FontCacheEntry.cpp      2011-01-09 04:10:13 UTC 
(rev 40174)
@@ -187,6 +187,74 @@
 }
 
 
+inline bool
+render_as_space(uint32 glyphCode)
+{
+       // whitespace: render as space
+       // as per Unicode PropList.txt: White_Space
+       return (glyphCode >= 0x0009 && glyphCode <= 0x000d)
+                       // control characters
+               || (glyphCode == 0x0085)
+                       // another control
+               || (glyphCode == 0x00a0)
+                       // no-break space
+               || (glyphCode == 0x1680)
+                       // ogham space mark
+               || (glyphCode == 0x180e)
+                       // mongolian vowel separator
+               || (glyphCode >= 0x2000 && glyphCode <= 0x200a)
+                       // en quand, hair space
+               || (glyphCode >= 0x2028 && glyphCode <= 0x2029)
+                       // line and paragraph separators
+               || (glyphCode == 0x202f)
+                       // narrow no-break space
+               || (glyphCode == 0x205f)
+                       // medium math space
+               || (glyphCode == 0x3000)
+                       // ideographic space
+               ;
+}
+
+
+inline bool
+render_as_zero_width(uint32 glyphCode)
+{
+       // ignorable chars: render as invisible
+       // as per Unicode DerivedCoreProperties.txt: 
Default_Ignorable_Code_Point
+       return (glyphCode == 0x00ad)
+                       // soft hyphen
+               || (glyphCode == 0x034f)
+                       // combining grapheme joiner
+               || (glyphCode >= 0x115f && glyphCode <= 0x1160)
+                       // hangul fillers
+               || (glyphCode >= 0x17b4 && glyphCode <= 0x17b5)
+                       // ignorable khmer vowels
+               || (glyphCode >= 0x180b && glyphCode <= 0x180d)
+                       // variation selectors
+               || (glyphCode >= 0x200b && glyphCode <= 0x200f)
+                       // zero width space, cursive joiners, ltr marks
+               || (glyphCode >= 0x202a && glyphCode <= 0x202e)
+                       // left to right embed, override
+               || (glyphCode >= 0x2060 && glyphCode <= 0x206f)
+                       // word joiner, invisible math operators, reserved
+               || (glyphCode == 0x3164)
+                       // hangul filler
+               || (glyphCode >= 0xfe00 && glyphCode <= 0xfe0f)
+                       // variation selectors
+               || (glyphCode == 0xfeff)
+                       // zero width no-break space
+               || (glyphCode == 0xffa0)
+                       // halfwidth hangul filler
+               || (glyphCode >= 0xfff0 && glyphCode <= 0xfff8)
+                       // reserved
+               || (glyphCode >= 0x1d173 && glyphCode <= 0x1d17a)
+                       // musical symbols
+               || (glyphCode >= 0xe0000 && glyphCode <= 0xe01ef)
+                       // variation selectors, tag space, reserved
+               ;
+}
+
+
 const GlyphCache*
 FontCacheEntry::Glyph(uint32 glyphCode, FontCacheEntry* fallbackEntry)
 {
@@ -212,7 +280,24 @@
                glyphIndex = engine->GlyphIndexForGlyphCode(glyphCode);
        }
 
-       if (glyphIndex != 0 && engine->PrepareGlyph(glyphIndex)) {
+       if (glyphIndex == 0) {
+               if (render_as_zero_width(glyphCode)) {
+                       // cache and return a zero width glyph
+                       return fGlyphCache->CacheGlyph(glyphCode, 0, 
glyph_data_invalid,
+                               agg::rect_i(0, 0, -1, -1), 0, 0, 0, 0);
+               }
+
+               // reset to our engine
+               engine = &fEngine;
+               if (render_as_space(glyphCode)) {
+                       // get the normal space glyph
+                       glyphIndex = engine->GlyphIndexForGlyphCode(0x20 /* 
space */);
+               } else {
+                       // render the "missing glyph box" (by simply keeping 
glyphIndex 0)
+               }
+       }
+
+       if (engine->PrepareGlyph(glyphIndex)) {
                glyph = fGlyphCache->CacheGlyph(glyphCode,
                        engine->DataSize(), engine->DataType(), 
engine->Bounds(),
                        engine->AdvanceX(), engine->AdvanceY(),
@@ -220,8 +305,8 @@
 
                if (glyph != NULL)
                        engine->WriteGlyphTo(glyph->data);
+       }
 
-       }
        return glyph;
 }
 


Other related posts: