Bug 1211867 - Use the font's NBSP glyph (if present) rather than rendering NBSP using the standard <space> glyph. r=jdaggett
authorJonathan Kew <jkew@mozilla.com>
Wed, 14 Oct 2015 16:00:35 +0100
changeset 267699 5baceaa01feee58e5dee795f9ef3bd2a596c8448
parent 267698 67084d8fe8860db544eb9435f0600f88039c00fd
child 267700 efb3eb13c8bfa712edfb5548f3d1a30b70198924
push id66562
push userjkew@mozilla.com
push dateWed, 14 Oct 2015 19:06:04 +0000
treeherdermozilla-inbound@5baceaa01fee [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdaggett
bugs1211867
milestone44.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1211867 - Use the font's NBSP glyph (if present) rather than rendering NBSP using the standard <space> glyph. r=jdaggett
gfx/thebes/gfxFont.cpp
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2338,20 +2338,25 @@ gfxFont::NotifyGlyphsChanged()
 
     if (mGlyphChangeObservers) {
         for (auto it = mGlyphChangeObservers->Iter(); !it.Done(); it.Next()) {
             it.Get()->GetKey()->NotifyGlyphsChanged();
         }
     }
 }
 
-static bool
+// If aChar is a "word boundary" for shaped-word caching purposes, return it;
+// else return 0.
+static char16_t
 IsBoundarySpace(char16_t aChar, char16_t aNextChar)
 {
-    return (aChar == ' ' || aChar == 0x00A0) && !IsClusterExtender(aNextChar);
+    if ((aChar == ' ' || aChar == 0x00A0) && !IsClusterExtender(aNextChar)) {
+        return aChar;
+    }
+    return 0;
 }
 
 #ifdef __GNUC__
 #define GFX_MAYBE_UNUSED __attribute__((unused))
 #else
 #define GFX_MAYBE_UNUSED
 #endif
 
@@ -2760,17 +2765,17 @@ gfxFont::SplitAndInitTextRun(gfxContext 
     uint32_t hash = 0;
     bool wordIs8Bit = true;
     int32_t appUnitsPerDevUnit = aTextRun->GetAppUnitsPerDevUnit();
 
     T nextCh = aString[0];
     for (uint32_t i = 0; i <= aRunLength; ++i) {
         T ch = nextCh;
         nextCh = (i < aRunLength - 1) ? aString[i + 1] : '\n';
-        bool boundary = IsBoundarySpace(ch, nextCh);
+        T boundary = IsBoundarySpace(ch, nextCh);
         bool invalid = !boundary && gfxFontGroup::IsInvalidChar(ch);
         uint32_t length = i - wordStart;
 
         // break into separate ShapedWords when we hit an invalid char,
         // or a boundary space (always handled individually),
         // or the first non-space after a space
         if (!boundary && !invalid) {
             if (!IsChar8Bit(ch)) {
@@ -2822,26 +2827,31 @@ gfxFont::SplitAndInitTextRun(gfxContext 
         if (boundary) {
             // word was terminated by a space: add that to the textrun
             uint16_t orientation = flags & gfxTextRunFactory::TEXT_ORIENT_MASK;
             if (orientation == gfxTextRunFactory::TEXT_ORIENT_VERTICAL_MIXED) {
                 orientation = aVertical ?
                     gfxTextRunFactory::TEXT_ORIENT_VERTICAL_UPRIGHT :
                     gfxTextRunFactory::TEXT_ORIENT_VERTICAL_SIDEWAYS_RIGHT;
             }
-            if (!aTextRun->SetSpaceGlyphIfSimple(this, aContext,
+            if (boundary != ' ' ||
+                !aTextRun->SetSpaceGlyphIfSimple(this, aContext,
                                                  aRunStart + i, ch,
-                                                 orientation))
-            {
-                static const uint8_t space = ' ';
+                                                 orientation)) {
+                // Currently, the only "boundary" characters we recognize are
+                // space and no-break space, which are both 8-bit, so we force
+                // that flag (below). If we ever change IsBoundarySpace, we
+                // may need to revise this.
+                // Avoid tautological-constant-out-of-range-compare in 8-bit:
+                DebugOnly<char16_t> boundary16 = boundary;
+                NS_ASSERTION(boundary16 < 256, "unexpected boundary!");
                 gfxShapedWord *sw =
-                    GetShapedWord(aContext,
-                                  &space, 1,
-                                  gfxShapedWord::HashMix(0, ' '), aRunScript, aVertical,
-                                  appUnitsPerDevUnit,
+                    GetShapedWord(aContext, &boundary, 1,
+                                  gfxShapedWord::HashMix(0, boundary),
+                                  aRunScript, aVertical, appUnitsPerDevUnit,
                                   flags | gfxTextRunFactory::TEXT_IS_8BIT, tp);
                 if (sw) {
                     aTextRun->CopyGlyphDataFrom(sw, aRunStart + i);
                 } else {
                     return false;
                 }
             }
             hash = 0;