Bug 1273154 - Re-land followup to handle word-initial NNBSP shaping in Mongolian, with its reftest. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Wed, 25 May 2016 10:51:13 +0100
changeset 298877 2dc65c74bfa6c40479deb070b912b7bd2d151550
parent 298876 8a1948d999aa496869bac91196b19feb26c5236e
child 298878 b8dbe70e2500cbd910c21c1b3626346121c71004
push id77355
push userjkew@mozilla.com
push dateWed, 25 May 2016 09:54:16 +0000
treeherdermozilla-inbound@2dc65c74bfa6 [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 - Re-land followup to handle word-initial NNBSP shaping in Mongolian, with its reftest. r=jrmuizel
gfx/thebes/gfxTextRun.cpp
layout/reftests/bugs/1273154-2-ref.html
layout/reftests/bugs/1273154-2.html
layout/reftests/bugs/reftest.list
--- 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 && 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) {
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1273154-2-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      body {
+        /* Force a large line-height so that we don't get a positioning
+           discrepancy on the test span depending on which font's metrics
+           are used in line-height computation. */
+        font: 64px/2 serif;
+      }
+      span {
+        font-family: "Mongolian Baiti", "Times New Roman", serif;
+        font-size: 32px;
+      }
+    </style>
+  </head>
+  <body>
+    <span>&#x202F;&#x1824;&#x1828;</span>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/1273154-2.html
@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style>
+      body {
+        /* Force a large line-height so that we don't get a positioning
+           discrepancy on the test span depending on which font's metrics
+           are used in line-height computation. */
+        font: 64px/2 serif;
+      }
+      span {
+        /* Times does NOT support Mongolian characters, so the entire text
+           should be rendered as a single Mongolian Baiti run, including
+           the initial U+202F, even though it _is_ available in Times. */
+        font-family: "Times New Roman", "Mongolian Baiti", serif;
+        font-size: 32px;
+      }
+    </style>
+  </head>
+  <body>
+    <span>&#x202F;&#x1824;&#x1828;</span>
+  </body>
+</html>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1949,9 +1949,10 @@ random-if(OSX==1006) == 1238243-2.html 1
 fuzzy(100,2000) == 1239564.html 1239564-ref.html
 == 1242172-1.html 1242172-1-ref.html
 == 1242172-2.html 1242172-2-ref.html
 == 1242781.html 1242781-ref.html
 == 1263845.html 1263845-ref.html
 == 1260543-1.html 1260543-1-ref.html
 == 1272997-1.html 1272997-1-ref.html
 random-if(!winWidget) == 1273154-1.html 1273154-1-ref.html # depends on Windows font
+random-if(!winWidget) == 1273154-2.html 1273154-2-ref.html # depends on Windows font
 == 1274368-1.html 1274368-1-ref.html