Bug 1416795 - Implement synthetic-oblique font rendering by applying a transform at gfxFont::Draw time, rather than setting it on the cairo font matrix. r=jrmuizel
authorJonathan Kew <jkew@mozilla.com>
Fri, 17 Nov 2017 10:54:21 +0000
changeset 436849 d0cdbb2cddf60e6e1b9c0f14fea388a3090427d6
parent 436848 d7d379420ed7bb512a2bad20aebaa924c5979a2e
child 436851 a9aa9965fecdbe86c2322434171ae45a4df96642
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewersjrmuizel
bugs1416795
milestone59.0a1
Bug 1416795 - Implement synthetic-oblique font rendering by applying a transform at gfxFont::Draw time, rather than setting it on the cairo font matrix. r=jrmuizel
gfx/thebes/gfxDWriteFonts.cpp
gfx/thebes/gfxFT2FontList.cpp
gfx/thebes/gfxFcPlatformFontList.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
@@ -509,29 +509,16 @@ gfxDWriteFont::InitCairoScaledFont()
     if (!mScaledFont) {
         cairo_matrix_t sizeMatrix;
         cairo_matrix_t identityMatrix;
 
         cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
         cairo_matrix_init_identity(&identityMatrix);
 
         cairo_font_options_t *fontOptions = cairo_font_options_create();
-        if (mNeedsOblique) {
-            double skewfactor = OBLIQUE_SKEW_FACTOR;
-
-            cairo_matrix_t style;
-            cairo_matrix_init(&style,
-                              1,                //xx
-                              0,                //yx
-                              -1 * skewfactor,  //xy
-                              1,                //yy
-                              0,                //x0
-                              0);               //y0
-            cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
-        }
 
         if (mAntialiasOption != kAntialiasDefault) {
             cairo_font_options_set_antialias(fontOptions,
                 GetCairoAntialiasOption(mAntialiasOption));
         }
 
         mScaledFont = cairo_scaled_font_create(CairoFontFace(),
                                                     &sizeMatrix,
--- a/gfx/thebes/gfxFT2FontList.cpp
+++ b/gfx/thebes/gfxFT2FontList.cpp
@@ -176,33 +176,16 @@ FT2FontEntry::CreateScaledFont(const gfx
 
     cairo_matrix_t sizeMatrix;
     cairo_matrix_t identityMatrix;
 
     // XXX deal with adjusted size
     cairo_matrix_init_scale(&sizeMatrix, aStyle->size, aStyle->size);
     cairo_matrix_init_identity(&identityMatrix);
 
-    // synthetic oblique by skewing via the font matrix
-    bool needsOblique = IsUpright() &&
-                        aStyle->style != NS_FONT_STYLE_NORMAL &&
-                        aStyle->allowSyntheticStyle;
-
-    if (needsOblique) {
-        cairo_matrix_t style;
-        cairo_matrix_init(&style,
-                          1,                //xx
-                          0,                //yx
-                          -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();
 
     if (gfxPlatform::GetPlatform()->RequiresLinearZoom()) {
         cairo_font_options_set_hint_metrics(fontOptions, CAIRO_HINT_METRICS_OFF);
     }
 
     scaledFont = cairo_scaled_font_create(cairoFace,
                                           &sizeMatrix,
--- a/gfx/thebes/gfxFcPlatformFontList.cpp
+++ b/gfx/thebes/gfxFcPlatformFontList.cpp
@@ -678,17 +678,17 @@ gfxFontconfigFontEntry::CreateScaledFont
                                          gfxFloat aAdjustedSize,
                                          const gfxFontStyle *aStyle,
                                          bool aNeedsBold)
 {
     if (aNeedsBold) {
         FcPatternAddBool(aRenderPattern, FC_EMBOLDEN, FcTrue);
     }
 
-    // synthetic oblique by skewing via the font matrix
+    // will synthetic oblique be applied using a transform?
     bool needsOblique = IsUpright() &&
                         aStyle->style != NS_FONT_STYLE_NORMAL &&
                         aStyle->allowSyntheticStyle;
 
     if (needsOblique) {
         // disable embedded bitmaps (mimics behavior in 90-synthetic.conf)
         FcPatternDel(aRenderPattern, FC_EMBEDDED_BITMAP);
         FcPatternAddBool(aRenderPattern, FC_EMBEDDED_BITMAP, FcFalse);
@@ -717,30 +717,16 @@ gfxFontconfigFontEntry::CreateScaledFont
     cairo_scaled_font_t *scaledFont = nullptr;
 
     cairo_matrix_t sizeMatrix;
     cairo_matrix_t identityMatrix;
 
     cairo_matrix_init_scale(&sizeMatrix, aAdjustedSize, aAdjustedSize);
     cairo_matrix_init_identity(&identityMatrix);
 
-    if (needsOblique) {
-        const double kSkewFactor = OBLIQUE_SKEW_FACTOR;
-
-        cairo_matrix_t style;
-        cairo_matrix_init(&style,
-                          1,                //xx
-                          0,                //yx
-                          -1 * kSkewFactor,  //xy
-                          1,                //yy
-                          0,                //x0
-                          0);               //y0
-        cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
-    }
-
     cairo_font_options_t *fontOptions = cairo_font_options_create();
     PrepareFontOptions(aRenderPattern, fontOptions);
 
     scaledFont = cairo_scaled_font_create(face, &sizeMatrix,
                                           &identityMatrix, fontOptions);
     cairo_font_options_destroy(fontOptions);
 
     NS_ASSERTION(cairo_scaled_font_status(scaledFont) == CAIRO_STATUS_SUCCESS,
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1595,17 +1595,17 @@ public:
         , mCapacity(0)
         , mNumGlyphs(0)
     {
     }
 
     ~GlyphBufferAzure()
     {
         if (mNumGlyphs > 0) {
-            Flush();
+            FlushGlyphs();
         }
 
         if (mBuffer != *mAutoBuffer.addr()) {
             free(mBuffer);
         }
     }
 
     // Ensure the buffer has enough space for aGlyphCount glyphs to be added.
@@ -1638,32 +1638,40 @@ public:
     }
 
     void OutputGlyph(uint32_t aGlyphID, const gfx::Point& aPt)
     {
         // Check that AddCapacity has been used appropriately!
         MOZ_ASSERT(mNumGlyphs < mCapacity);
         Glyph* glyph = mBuffer + mNumGlyphs++;
         glyph->mIndex = aGlyphID;
-        glyph->mPosition = mFontParams.matInv.TransformPoint(aPt);
+        glyph->mPosition = aPt;
+    }
+
+    void Flush()
+    {
+        if (mNumGlyphs > 0) {
+            FlushGlyphs();
+            mNumGlyphs = 0;
+        }
     }
 
     const TextRunDrawParams& mRunParams;
     const FontDrawParams& mFontParams;
 
 private:
     static DrawMode
     GetStrokeMode(DrawMode aMode)
     {
         return aMode & (DrawMode::GLYPH_STROKE |
                         DrawMode::GLYPH_STROKE_UNDERNEATH);
     }
 
     // Render the buffered glyphs to the draw target.
-    void Flush()
+    void FlushGlyphs()
     {
         if (mRunParams.isRTL) {
             std::reverse(mBuffer, mBuffer + mNumGlyphs);
         }
 
         gfx::GlyphBuffer buf;
         buf.mGlyphs = mBuffer;
         buf.mNumGlyphs = mNumGlyphs;
@@ -1692,46 +1700,18 @@ private:
                     } else {
                         pat = nullptr;
                     }
                 } else {
                     pat = fillPattern->GetPattern(mRunParams.dt);
                 }
 
                 if (pat) {
-                    Matrix saved;
-                    Matrix *mat = nullptr;
-                    if (mFontParams.passedInvMatrix) {
-                        // The brush matrix needs to be multiplied with the
-                        // inverted matrix as well, to move the brush into the
-                        // space of the glyphs.
-
-                        // This relies on the returned Pattern not to be reused
-                        // by others, but regenerated on GetPattern calls. This
-                        // is true!
-                        if (pat->GetType() == PatternType::LINEAR_GRADIENT) {
-                            mat = &static_cast<LinearGradientPattern*>(pat)->mMatrix;
-                        } else if (pat->GetType() == PatternType::RADIAL_GRADIENT) {
-                            mat = &static_cast<RadialGradientPattern*>(pat)->mMatrix;
-                        } else if (pat->GetType() == PatternType::SURFACE) {
-                            mat = &static_cast<SurfacePattern*>(pat)->mMatrix;
-                        }
-
-                        if (mat) {
-                            saved = *mat;
-                            *mat = (*mat) * (*mFontParams.passedInvMatrix);
-                        }
-                    }
-
                     mRunParams.dt->FillGlyphs(mFontParams.scaledFont, buf,
                                               *pat, mFontParams.drawOptions);
-
-                    if (mat) {
-                        *mat = saved;
-                    }
                 }
             } else if (state.sourceSurface) {
                 mRunParams.dt->FillGlyphs(mFontParams.scaledFont, buf,
                                           SurfacePattern(state.sourceSurface,
                                                          ExtendMode::CLAMP,
                                                          state.surfTransform),
                                           mFontParams.drawOptions);
             } else {
@@ -1745,44 +1725,17 @@ private:
             Pattern *pat;
             if (mRunParams.textStrokePattern) {
                 pat = mRunParams.textStrokePattern->GetPattern(
                   mRunParams.dt, state.patternTransformChanged
                                    ? &state.patternTransform
                                    : nullptr);
 
                 if (pat) {
-                    Matrix saved;
-                    Matrix *mat = nullptr;
-                    if (mFontParams.passedInvMatrix) {
-                        // The brush matrix needs to be multiplied with the
-                        // inverted matrix as well, to move the brush into the
-                        // space of the glyphs.
-
-                        // This relies on the returned Pattern not to be reused
-                        // by others, but regenerated on GetPattern calls. This
-                        // is true!
-                        if (pat->GetType() == PatternType::LINEAR_GRADIENT) {
-                            mat = &static_cast<LinearGradientPattern*>(pat)->mMatrix;
-                        } else if (pat->GetType() == PatternType::RADIAL_GRADIENT) {
-                            mat = &static_cast<RadialGradientPattern*>(pat)->mMatrix;
-                        } else if (pat->GetType() == PatternType::SURFACE) {
-                            mat = &static_cast<SurfacePattern*>(pat)->mMatrix;
-                        }
-
-                        if (mat) {
-                            saved = *mat;
-                            *mat = (*mat) * (*mFontParams.passedInvMatrix);
-                        }
-                    }
                     FlushStroke(buf, *pat);
-
-                    if (mat) {
-                        *mat = saved;
-                    }
                 }
             } else {
                 FlushStroke(buf,
                             ColorPattern(
                               Color::FromABGR(mRunParams.textStrokeColor)));
             }
         }
         if (mRunParams.drawMode & DrawMode::GLYPH_PATH) {
@@ -1964,18 +1917,36 @@ void
 gfxFont::DrawOneGlyph(uint32_t aGlyphID, const gfx::Point& aPt,
                       GlyphBufferAzure& aBuffer, bool *aEmittedGlyphs) const
 {
     const TextRunDrawParams& runParams(aBuffer.mRunParams);
 
     gfx::Point devPt(ToDeviceUnits(aPt.x, runParams.devPerApp),
                      ToDeviceUnits(aPt.y, runParams.devPerApp));
 
+    gfxContextMatrixAutoSaveRestore matrixRestore;
+
     if (FC == FontComplexityT::ComplexFont) {
         const FontDrawParams& fontParams(aBuffer.mFontParams);
+
+        if (fontParams.needsOblique && fontParams.isVerticalFont) {
+            // We have to flush each glyph individually when doing
+            // synthetic-oblique for vertical-upright text, because
+            // the skew transform needs to be applied to a separate
+            // origin for each glyph, not once for the whole run.
+            aBuffer.Flush();
+            matrixRestore.SetContext(runParams.context);
+            gfx::Matrix mat =
+                runParams.context->CurrentMatrix().
+                PreTranslate(devPt).
+                PreMultiply(gfx::Matrix(1, 0, -OBLIQUE_SKEW_FACTOR, 1, 0, 0)).
+                PreTranslate(-devPt);
+            runParams.context->SetMatrix(mat);
+        }
+
         if (fontParams.haveSVGGlyphs) {
             if (!runParams.paintSVGGlyphs) {
                 return;
             }
             NS_WARNING_ASSERTION(
               runParams.drawMode != DrawMode::GLYPH_PATH,
               "Rendering SVG glyph despite request for glyph path");
             if (RenderSVGGlyph(runParams.context, devPt,
@@ -1984,17 +1955,17 @@ gfxFont::DrawOneGlyph(uint32_t aGlyphID,
                 return;
             }
         }
 
         if (fontParams.haveColorGlyphs &&
             RenderColorGlyph(runParams.dt, runParams.context,
                              fontParams.scaledFont,
                              fontParams.drawOptions,
-                             fontParams.matInv.TransformPoint(devPt),
+                             devPt,
                              aGlyphID)) {
             return;
         }
     }
 
     aBuffer.OutputGlyph(aGlyphID, devPt);
 
     if (FC == FontComplexityT::ComplexFont) {
@@ -2003,16 +1974,20 @@ gfxFont::DrawOneGlyph(uint32_t aGlyphID,
         for (int32_t i = 0; i < fontParams.extraStrikes; ++i) {
             if (fontParams.isVerticalFont) {
                 devPt.y += fontParams.synBoldOnePixelOffset;
             } else {
                 devPt.x += fontParams.synBoldOnePixelOffset;
             }
             aBuffer.OutputGlyph(aGlyphID, devPt);
         }
+
+        if (fontParams.needsOblique && fontParams.isVerticalFont) {
+            aBuffer.Flush();
+        }
     }
 
     *aEmittedGlyphs = true;
 }
 
 bool
 gfxFont::DrawMissingGlyph(const TextRunDrawParams&            aRunParams,
                           const FontDrawParams&               aFontParams,
@@ -2035,35 +2010,33 @@ gfxFont::DrawMissingGlyph(const TextRunD
         Float height = GetMetrics(eHorizontal).maxAscent;
         Rect glyphRect = aFontParams.isVerticalFont ?
             Rect(pt.x - height / 2, pt.y,
                  height, advanceDevUnits) :
             Rect(pt.x, pt.y - height,
                  advanceDevUnits, height);
 
         // If there's a fake-italic skew in effect as part
-        // of the drawTarget's transform, we need to remove
+        // of the drawTarget's transform, we need to undo
         // this before drawing the hexbox. (Bug 983985)
-        Matrix oldMat;
-        if (aFontParams.passedInvMatrix) {
-            oldMat = aRunParams.dt->GetTransform();
-            aRunParams.dt->SetTransform(
-                *aFontParams.passedInvMatrix * oldMat);
+        gfxContextMatrixAutoSaveRestore matrixRestore;
+        if (aFontParams.needsOblique && !aFontParams.isVerticalFont) {
+            matrixRestore.SetContext(aRunParams.context);
+            gfx::Matrix mat =
+                aRunParams.context->CurrentMatrix().
+                PreTranslate(pt).
+                PreMultiply(gfx::Matrix(1, 0, OBLIQUE_SKEW_FACTOR, 1, 0, 0)).
+                PreTranslate(-pt);
+            aRunParams.context->SetMatrix(mat);
         }
 
         gfxFontMissingGlyphs::DrawMissingGlyph(
             aDetails->mGlyphID, glyphRect, *aRunParams.dt,
             PatternFromState(aRunParams.context),
             1.0 / aRunParams.devPerApp);
-
-        // Restore the matrix, if we modified it before
-        // drawing the hexbox.
-        if (aFontParams.passedInvMatrix) {
-            aRunParams.dt->SetTransform(oldMat);
-        }
     }
     return true;
 }
 
 // This method is mostly parallel to DrawGlyphs.
 void
 gfxFont::DrawEmphasisMarks(const gfxTextRun* aShapedText, gfx::Point* aPt,
                            uint32_t aOffset, uint32_t aCount,
@@ -2123,19 +2096,23 @@ gfxFont::Draw(const gfxTextRun *aTextRun
     }
 
     fontParams.scaledFont = GetScaledFont(aRunParams.dt);
     if (!fontParams.scaledFont) {
         return;
     }
 
     auto* textDrawer = aRunParams.context->GetTextDrawer();
+
+    fontParams.needsOblique = mFontEntry->IsUpright() &&
+                              mStyle.style != NS_FONT_STYLE_NORMAL &&
+                              mStyle.allowSyntheticStyle;
     fontParams.haveSVGGlyphs = GetFontEntry()->TryGetSVGData(this);
 
-    if (fontParams.haveSVGGlyphs && textDrawer) {
+    if ((fontParams.needsOblique || fontParams.haveSVGGlyphs) && textDrawer) {
         textDrawer->FoundUnsupportedFeature();
         return;
     }
 
     fontParams.haveColorGlyphs = GetFontEntry()->TryGetColorGlyphs();
     fontParams.contextPaint = aRunParams.runContextPaint;
     fontParams.isVerticalFont =
         aOrientation == gfx::ShapedTextFlags::TEXT_ORIENT_VERTICAL_UPRIGHT;
@@ -2180,16 +2157,33 @@ gfxFont::Draw(const gfxTextRun *aTextRun
         if (aTextRun->UseCenterBaseline()) {
             gfxPoint baseAdj(0, (metrics.emAscent - metrics.emDescent) / 2);
             mat.PreTranslate(baseAdj);
         }
 
         aRunParams.context->SetMatrixDouble(mat);
     }
 
+    if (fontParams.needsOblique && !fontParams.isVerticalFont) {
+        // Adjust matrix for synthetic-oblique, except if we're doing vertical-
+        // upright text, in which case this will be handled for each glyph
+        // individually in DrawOneGlyph.
+        if (!matrixRestore.HasMatrix()) {
+            matrixRestore.SetContext(aRunParams.context);
+        }
+        gfx::Point p(aPt->x * aRunParams.devPerApp,
+                     aPt->y * aRunParams.devPerApp);
+        gfx::Matrix mat =
+            aRunParams.context->CurrentMatrix().
+            PreTranslate(p).
+            PreMultiply(gfx::Matrix(1, 0, -OBLIQUE_SKEW_FACTOR, 1, 0, 0)).
+            PreTranslate(-p);
+        aRunParams.context->SetMatrix(mat);
+    }
+
     RefPtr<SVGContextPaint> contextPaint;
     if (fontParams.haveSVGGlyphs && !fontParams.contextPaint) {
         // If no pattern is specified for fill, use the current pattern
         NS_ASSERTION((int(aRunParams.drawMode) & int(DrawMode::GLYPH_STROKE)) == 0,
                      "no pattern supplied for stroking text");
         RefPtr<gfxPattern> fillPattern = aRunParams.context->GetPattern();
         contextPaint =
             new SimpleTextContextPaint(fillPattern, nullptr,
@@ -2220,71 +2214,35 @@ gfxFont::Draw(const gfxTextRun *aTextRun
     bool oldSubpixelAA = aRunParams.dt->GetPermitSubpixelAA();
     if (!AllowSubpixelAA()) {
         aRunParams.dt->SetPermitSubpixelAA(false);
     }
 
     Matrix mat;
     Matrix oldMat = aRunParams.dt->GetTransform();
 
-    // This is nullptr when we have inverse-transformed glyphs and we need
-    // to transform the Brush inside flush.
-    fontParams.passedInvMatrix = nullptr;
-
     fontParams.drawOptions.mAntialiasMode = Get2DAAMode(mAntialiasOption);
 
-    // The cairo DrawTarget backend uses the cairo_scaled_font directly
-    // and so has the font skew matrix applied already.
-    if (mScaledFont &&
-        aRunParams.dt->GetBackendType() != BackendType::CAIRO) {
-        cairo_matrix_t matrix;
-        cairo_scaled_font_get_font_matrix(mScaledFont, &matrix);
-        if (matrix.xy != 0) {
-            if (textDrawer) {
-                textDrawer->FoundUnsupportedFeature();
-            }
-
-            // If this matrix applies a skew, which can happen when drawing
-            // oblique fonts, we will set the DrawTarget matrix to apply the
-            // skew. We'll need to move the glyphs by the inverse of the skew to
-            // get the glyphs positioned correctly in the new device space
-            // though, since the font matrix should only be applied to drawing
-            // the glyphs, and not to their position.
-            mat = Matrix(matrix.xx, matrix.yx,
-                         matrix.xy, matrix.yy,
-                         matrix.x0, matrix.y0);
-
-            mat._11 = mat._22 = 1.0;
-            mat._21 /= GetAdjustedSize();
-
-            aRunParams.dt->SetTransform(mat * oldMat);
-
-            fontParams.matInv = mat;
-            fontParams.matInv.Invert();
-
-            fontParams.passedInvMatrix = &fontParams.matInv;
-        }
-    }
-
     float& baseline = fontParams.isVerticalFont ? aPt->x : aPt->y;
     float origBaseline = baseline;
     if (mStyle.baselineOffset != 0.0) {
         baseline +=
             mStyle.baselineOffset * aTextRun->GetAppUnitsPerDevUnit();
     }
 
     bool emittedGlyphs;
     {
         // Select appropriate version of the templated DrawGlyphs method
         // to output glyphs to the buffer, depending on complexity needed
         // for the type of font, and whether added inter-glyph spacing
         // is specified.
         GlyphBufferAzure buffer(aRunParams, fontParams);
         if (fontParams.haveSVGGlyphs || fontParams.haveColorGlyphs ||
-            fontParams.extraStrikes) {
+            fontParams.extraStrikes ||
+            (fontParams.needsOblique && fontParams.isVerticalFont)) {
             if (aRunParams.spacing) {
                 emittedGlyphs =
                     DrawGlyphs<FontComplexityT::ComplexFont,
                                SpacingT::HasSpacing>(aTextRun, aStart,
                                                      aEnd - aStart, aPt,
                                                      buffer);
             } else {
                 emittedGlyphs =
--- a/gfx/thebes/gfxFont.h
+++ b/gfx/thebes/gfxFont.h
@@ -56,21 +56,21 @@ class gfxMathTable;
 
 #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
+#define OBLIQUE_SKEW_FACTOR  0.3f
 #elif defined(MOZ_WIDGET_GTK)
-#define OBLIQUE_SKEW_FACTOR  0.2
+#define OBLIQUE_SKEW_FACTOR  0.2f
 #else
-#define OBLIQUE_SKEW_FACTOR  0.25
+#define OBLIQUE_SKEW_FACTOR  0.25f
 #endif
 
 struct gfxTextRunDrawCallbacks;
 
 namespace mozilla {
 class SVGContextPaint;
 } // namespace mozilla
 
@@ -2333,24 +2333,23 @@ struct MOZ_STACK_CLASS TextRunDrawParams
     bool                     isVerticalRun;
     bool                     isRTL;
     bool                     paintSVGGlyphs;
 };
 
 struct MOZ_STACK_CLASS FontDrawParams {
     RefPtr<mozilla::gfx::ScaledFont>            scaledFont;
     mozilla::SVGContextPaint *contextPaint;
-    mozilla::gfx::Matrix     *passedInvMatrix;
-    mozilla::gfx::Matrix      matInv;
     mozilla::gfx::Float       synBoldOnePixelOffset;
     int32_t                   extraStrikes;
     mozilla::gfx::DrawOptions drawOptions;
     bool                      isVerticalFont;
     bool                      haveSVGGlyphs;
     bool                      haveColorGlyphs;
+    bool                      needsOblique;
 };
 
 struct MOZ_STACK_CLASS EmphasisMarkDrawParams {
     gfxContext* context;
     gfxFont::Spacing* spacing;
     gfxTextRun* mark;
     gfxFloat advance;
     gfxFloat direction;
--- a/gfx/thebes/gfxGDIFont.cpp
+++ b/gfx/thebes/gfxGDIFont.cpp
@@ -416,31 +416,16 @@ gfxGDIFont::Initialize()
 
     mFontFace = cairo_win32_font_face_create_for_logfontw_hfont(&logFont,
                                                                 mFont);
 
     cairo_matrix_t sizeMatrix, ctm;
     cairo_matrix_init_identity(&ctm);
     cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
 
-    if (useCairoFakeItalic) {
-        // Skew the matrix to do fake italic if it wasn't already applied
-        // via the LOGFONT
-        double skewfactor = OBLIQUE_SKEW_FACTOR;
-        cairo_matrix_t style;
-        cairo_matrix_init(&style,
-                          1,                //xx
-                          0,                //yx
-                          -1 * skewfactor,  //xy
-                          1,                //yy
-                          0,                //x0
-                          0);               //y0
-        cairo_matrix_multiply(&sizeMatrix, &sizeMatrix, &style);
-    }
-
     cairo_font_options_t *fontOptions = cairo_font_options_create();
     if (mAntialiasOption != kAntialiasDefault) {
         cairo_font_options_set_antialias(fontOptions,
             GetCairoAntialiasOption(mAntialiasOption));
     }
     mScaledFont = cairo_scaled_font_create(mFontFace, &sizeMatrix,
                                            &ctm, fontOptions);
     cairo_font_options_destroy(fontOptions);
--- a/gfx/thebes/gfxMacFont.cpp
+++ b/gfx/thebes/gfxMacFont.cpp
@@ -80,34 +80,16 @@ gfxMacFont::gfxMacFont(const RefPtr<Unsc
 #endif
         return;
     }
 
     cairo_matrix_t sizeMatrix, ctm;
     cairo_matrix_init_identity(&ctm);
     cairo_matrix_init_scale(&sizeMatrix, mAdjustedSize, mAdjustedSize);
 
-    // synthetic oblique by skewing via the font matrix
-    bool needsOblique = mFontEntry != nullptr &&
-                        mFontEntry->IsUpright() &&
-                        mStyle.style != NS_FONT_STYLE_NORMAL &&
-                        mStyle.allowSyntheticStyle;
-
-    if (needsOblique) {
-        cairo_matrix_t style;
-        cairo_matrix_init(&style,
-                          1,                //xx
-                          0,                //yx
-                          -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();
 
     // turn off font anti-aliasing based on user pref setting
     if (mAdjustedSize <=
         (gfxFloat)gfxPlatformMac::GetPlatform()->GetAntiAliasingThreshold()) {
         cairo_font_options_set_antialias(fontOptions, CAIRO_ANTIALIAS_NONE);
         mAntialiasOption = kAntialiasNone;
     } else if (mStyle.useGrayscaleAntialiasing) {