Bug 1273154 followup - Rework NNBSP handling in FindFontForChar to make word-initial NNBSP adopt the font that will be used for the following letter. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Wed, 25 May 2016 09:21:55 +0100
changeset 337912 f24ab718413961570a3c370396f7f297920229f7
parent 337911 8465a41d5bff393a45fc3ecae64b06c4f02ae236
child 337913 51b1f2343ad9544921e68859dfbe9d3c79b00951
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1273154
milestone49.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 1273154 followup - Rework NNBSP handling in FindFontForChar to make word-initial NNBSP adopt the font that will be used for the following letter. r=jrmuizel
gfx/thebes/gfxTextRun.cpp
--- a/gfx/thebes/gfxTextRun.cpp
+++ b/gfx/thebes/gfxTextRun.cpp
@@ -2632,27 +2632,47 @@ gfxFontGroup::GetUnderlineOffset()
     return mUnderlineOffset;
 }
 
 already_AddRefed<gfxFont>
 gfxFontGroup::FindFontForChar(uint32_t aCh, uint32_t aPrevCh, uint32_t aNextCh,
                               Script aRunScript, gfxFont *aPrevMatchedFont,
                               uint8_t *aMatchType)
 {
-    // If the char is a cluster extender or NNBSP, we want to use the same
-    // font as the preceding character if possible. This is preferable to using
-    // the font group because it avoids breaks in shaping within a cluster.
-    const uint32_t NARROW_NO_BREAK_SPACE = 0x202f;
-    if (aPrevMatchedFont &&
-        (IsClusterExtender(aCh) || aCh == NARROW_NO_BREAK_SPACE) &&
+    // If the char is a cluster extender, we want to use the same font as the
+    // preceding character if possible. This is preferable to using the font
+    // group because it avoids breaks in shaping within a cluster.
+    if (aPrevMatchedFont && IsClusterExtender(aCh) &&
         aPrevMatchedFont->HasCharacter(aCh)) {
         RefPtr<gfxFont> ret = aPrevMatchedFont;
         return ret.forget();
     }
 
+    // Special cases for NNBSP (as used in Mongolian):
+    const uint32_t NARROW_NO_BREAK_SPACE = 0x202f;
+    if (aCh == NARROW_NO_BREAK_SPACE) {
+        // If there is no preceding character, try the font that we'd use
+        // for the next char (unless it's just another NNBSP; we don't try
+        // to look ahead through a whole run of them).
+        if (!aPrevCh && aNextCh && aNextCh != NARROW_NO_BREAK_SPACE) {
+            RefPtr<gfxFont> nextFont =
+                FindFontForChar(aNextCh, 0, 0, aRunScript, aPrevMatchedFont,
+                                aMatchType);
+            if (nextFont->HasCharacter(aCh)) {
+                return nextFont.forget();
+            }
+        }
+        // Otherwise, treat NNBSP like a cluster extender (as above) and try
+        // to continue the preceding font run.
+        if (aPrevMatchedFont && aPrevMatchedFont->HasCharacter(aCh)) {
+            RefPtr<gfxFont> ret = aPrevMatchedFont;
+            return ret.forget();
+        }
+    }
+
     // To optimize common cases, try the first font in the font-group
     // before going into the more detailed checks below
     uint32_t nextIndex = 0;
     bool isJoinControl = gfxFontUtils::IsJoinControl(aCh);
     bool wasJoinCauser = gfxFontUtils::IsJoinCauser(aPrevCh);
     bool isVarSelector = gfxFontUtils::IsVarSelector(aCh);
 
     if (!isJoinControl && !wasJoinCauser && !isVarSelector) {