Bug 1116480 - gfxTextRun::Measure needs to account for fake-italic transform when returning the bounding box. r=roc
authorJonathan Kew <jkew@mozilla.com>
Wed, 31 Dec 2014 22:35:40 +0000
changeset 221767 d39f67b09a5db237713438877dcc8b983c68b249
parent 221766 6294a0c2ce96441c7eb4928377b91d9a06d101bb
child 221768 f7dbc64435bcf9aecdd969230d5f48bb41f89dad
push id53420
push userjkew@mozilla.com
push dateWed, 31 Dec 2014 22:42:16 +0000
treeherdermozilla-inbound@f7dbc64435bc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs1116480
milestone37.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 1116480 - gfxTextRun::Measure needs to account for fake-italic transform when returning the bounding box. r=roc
gfx/thebes/gfxDWriteFonts.cpp
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxGDIFont.cpp
gfx/thebes/gfxMacFont.cpp
--- a/gfx/thebes/gfxDWriteFonts.cpp
+++ b/gfx/thebes/gfxDWriteFonts.cpp
@@ -10,19 +10,16 @@
 #include <algorithm>
 #include "gfxDWriteFontList.h"
 #include "gfxContext.h"
 #include "gfxTextRun.h"
 #include <dwrite.h>
 
 #include "harfbuzz/hb.h"
 
-// Chosen this as to resemble DWrite's own oblique face style.
-#define OBLIQUE_SKEW_FACTOR 0.3
-
 using namespace mozilla;
 using namespace mozilla::gfx;
 
 // This is also in gfxGDIFont.cpp. Would be nice to put it somewhere common,
 // but we can't declare it in the gfxFont.h or gfxFontUtils.h headers
 // because those are exported, and the cairo headers aren't.
 static inline cairo_antialias_t
 GetCairoAntialiasOption(gfxFont::AntialiasOption anAntialiasOption)
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -191,23 +191,21 @@ FT2FontEntry::CreateScaledFont(const gfx
     cairo_matrix_init_identity(&identityMatrix);
 
     // synthetic oblique by skewing via the font matrix
     bool needsOblique = !IsItalic() &&
             (aStyle->style & (NS_FONT_STYLE_ITALIC | NS_FONT_STYLE_OBLIQUE)) &&
             aStyle->allowSyntheticStyle;
 
     if (needsOblique) {
-        const double kSkewFactor = 0.25;
-
         cairo_matrix_t style;
         cairo_matrix_init(&style,
                           1,                //xx
                           0,                //yx
-                          -1 * kSkewFactor,  //xy
+                          -1 * OBLIQUE_SKEW_FACTOR, //xy
                           1,                //yy
                           0,                //x0
                           0);               //y0
         cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
     }
 
     cairo_font_options_t *fontOptions = cairo_font_options_create();
 
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2266,16 +2266,28 @@ gfxFont::Measure(gfxTextRun *aTextRun,
         gfxRect fontBox(advanceMin, -metrics.mAscent,
                         advanceMax - advanceMin, metrics.mAscent + metrics.mDescent);
         metrics.mBoundingBox = metrics.mBoundingBox.Union(fontBox);
     }
     if (isRTL) {
         metrics.mBoundingBox -= gfxPoint(x, 0);
     }
 
+    // If the font may be rendered with a fake-italic effect, we need to allow
+    // for the top-right of the glyphs being skewed to the right, and the
+    // bottom-left being skewed further left.
+    if (mStyle.style != NS_FONT_STYLE_NORMAL && !mFontEntry->IsItalic()) {
+        gfxFloat extendLeftEdge =
+            ceil(OBLIQUE_SKEW_FACTOR * metrics.mBoundingBox.YMost());
+        gfxFloat extendRightEdge =
+            ceil(OBLIQUE_SKEW_FACTOR * -metrics.mBoundingBox.y);
+        metrics.mBoundingBox.width += extendLeftEdge + extendRightEdge;
+        metrics.mBoundingBox.x -= extendLeftEdge;
+    }
+
     if (baselineOffset != 0) {
         metrics.mAscent -= baselineOffset;
         metrics.mDescent += baselineOffset;
         metrics.mBoundingBox.y += baselineOffset;
     }
 
     metrics.mAdvanceWidth = x*direction;
     return metrics;
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -45,16 +45,24 @@ class gfxSkipChars;
 class gfxTextContextPaint;
 
 #define FONT_MAX_SIZE                  2000.0
 
 #define NO_FONT_LANGUAGE_OVERRIDE      0
 
 #define SMALL_CAPS_SCALE_FACTOR        0.8
 
+// The skew factor used for synthetic-italic [oblique] fonts;
+// we use a platform-dependent value to harmonize with the platform's own APIs.
+#ifdef XP_WIN
+#define OBLIQUE_SKEW_FACTOR  0.3
+#else
+#define OBLIQUE_SKEW_FACTOR  0.25
+#endif
+
 struct gfxTextRunDrawCallbacks;
 
 namespace mozilla {
 namespace gfx {
 class GlyphRenderingOptions;
 }
 }
 
--- a/gfx/thebes/gfxGDIFont.cpp
+++ b/gfx/thebes/gfxGDIFont.cpp
@@ -163,18 +163,16 @@ gfxGDIFont::Measure(gfxTextRun *aTextRun
         metrics.mBoundingBox.width > 0) {
         metrics.mBoundingBox.x -= aTextRun->GetAppUnitsPerDevUnit();
         metrics.mBoundingBox.width += aTextRun->GetAppUnitsPerDevUnit() * 3;
     }
 
     return metrics;
 }
 
-#define OBLIQUE_SKEW_FACTOR 0.3
-
 void
 gfxGDIFont::Initialize()
 {
     NS_ASSERTION(!mMetrics, "re-creating metrics? this will leak");
 
     LOGFONTW logFont;
 
     // Figure out if we want to do synthetic oblique styling.
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -63,23 +63,21 @@ gfxMacFont::gfxMacFont(MacOSFontEntry *a
     // synthetic oblique by skewing via the font matrix
     bool needsOblique =
         (mFontEntry != nullptr) &&
         (!mFontEntry->IsItalic() &&
          (mStyle.style & (NS_FONT_STYLE_ITALIC | NS_FONT_STYLE_OBLIQUE))) &&
         mStyle.allowSyntheticStyle;
 
     if (needsOblique) {
-        double skewfactor = (needsOblique ? Fix2X(kATSItalicQDSkew) : 0);
-
         cairo_matrix_t style;
         cairo_matrix_init(&style,
                           1,                //xx
                           0,                //yx
-                          -1 * skewfactor,   //xy
+                          -1 * OBLIQUE_SKEW_FACTOR, //xy
                           1,                //yy
                           0,                //x0
                           0);               //y0
         cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
     }
 
     cairo_font_options_t *fontOptions = cairo_font_options_create();