bug 3512 - fix computation of StyleDistance to account for font-stretch more accurately. r=jdaggett
authorJonathan Kew <jfkthame@gmail.com>
Mon, 05 Sep 2011 08:34:12 +0100
changeset 76546 36d230088375
parent 76545 b264ee97923a
child 76547 0d8e92d3138e
push id21118
push userkhuey@mozilla.com
push dateMon, 05 Sep 2011 11:57:30 +0000
treeherdermozilla-central@fc78ee766770 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdaggett
bugs3512
milestone9.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 3512 - fix computation of StyleDistance to account for font-stretch more accurately. r=jdaggett
gfx/thebes/gfxFont.cpp
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -576,22 +576,38 @@ gfxFontFamily::CheckForSimpleFamily()
 static inline PRUint32
 StyleDistance(gfxFontEntry *aFontEntry,
               PRBool anItalic, PRInt16 aStretch)
 {
     // Compute a measure of the "distance" between the requested style
     // and the given fontEntry,
     // considering italicness and font-stretch but not weight.
 
-    // TODO (refine CSS spec...): discuss priority of italic vs stretch;
-    // whether penalty for stretch mismatch should depend on actual difference in values;
-    // whether a sign mismatch in stretch should increase the effective distance
-
-    return (aFontEntry->IsItalic() != anItalic ? 1 : 0) +
-           (aFontEntry->mStretch != aStretch ? 10 : 0);
+    PRInt32 distance = 0;
+    if (aStretch != aFontEntry->mStretch) {
+        // stretch values are in the range -4 .. +4
+        // if aStretch is positive, we prefer more-positive values;
+        // if zero or negative, prefer more-negative
+        if (aStretch > 0) {
+            distance = (aFontEntry->mStretch - aStretch) * 2;
+        } else {
+            distance = (aStretch - aFontEntry->mStretch) * 2;
+        }
+        // if the computed "distance" here is negative, it means that
+        // aFontEntry lies in the "non-preferred" direction from aStretch,
+        // so we treat that as larger than any preferred-direction distance
+        // (max possible is 8) by adding an extra 10 to the absolute value
+        if (distance < 0) {
+            distance = -distance + 10;
+        }
+    }
+    if (aFontEntry->IsItalic() != anItalic) {
+        distance += 1;
+    }
+    return PRUint32(distance);
 }
 
 PRBool
 gfxFontFamily::FindWeightsForStyle(gfxFontEntry* aFontsForWeights[],
                                    PRBool anItalic, PRInt16 aStretch)
 {
     PRUint32 foundWeights = 0;
     PRUint32 bestMatchDistance = 0xffffffff;
@@ -604,19 +620,21 @@ gfxFontFamily::FindWeightsForStyle(gfxFo
         if (distance <= bestMatchDistance) {
             PRInt8 wt = fe->mWeight / 100;
             NS_ASSERTION(wt >= 1 && wt < 10, "invalid weight in fontEntry");
             if (!aFontsForWeights[wt]) {
                 // record this as a possible candidate for weight matching
                 aFontsForWeights[wt] = fe;
                 ++foundWeights;
             } else {
-                PRUint32 prevDistance = StyleDistance(aFontsForWeights[wt], anItalic, aStretch);
+                PRUint32 prevDistance =
+                    StyleDistance(aFontsForWeights[wt], anItalic, aStretch);
                 if (prevDistance >= distance) {
-                    // replacing a weight we already found, so don't increment foundWeights
+                    // replacing a weight we already found,
+                    // so don't increment foundWeights
                     aFontsForWeights[wt] = fe;
                 }
             }
             bestMatchDistance = distance;
         }
     }
 
     NS_ASSERTION(foundWeights > 0, "Font family containing no faces?");