diff --git a/src/gui/text/freetype/qfontengine_ft.cpp b/src/gui/text/freetype/qfontengine_ft.cpp index d3791f1f6e7..50c52ef3705 100644 --- a/src/gui/text/freetype/qfontengine_ft.cpp +++ b/src/gui/text/freetype/qfontengine_ft.cpp @@ -1120,6 +1120,23 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, FT_Face face = freetype->face; FT_Matrix matrix = freetype->matrix; + bool transform = matrix.xx != 0x10000 + || matrix.yy != 0x10000 + || matrix.xy != 0 + || matrix.yx != 0; + if (obliquen && transform) { + // We have to apply the obliquen transformation before any + // other transforms. This means we need to duplicate Freetype's + // obliquen matrix here and this has to be kept in sync. + FT_Matrix slant; + slant.xx = 0x10000L; + slant.yx = 0; + slant.xy = 0x0366A; + slant.yy = 0x10000L; + + FT_Matrix_Multiply(&matrix, &slant); + matrix = slant; + } FT_Vector v; v.x = format == Format_Mono ? 0 : FT_Pos(subPixelPosition.x.value()); @@ -1130,11 +1147,6 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, int vfactor = 1; int load_flags = loadFlags(set, format, 0, hsubpixel, vfactor); - bool transform = matrix.xx != 0x10000 - || matrix.yy != 0x10000 - || matrix.xy != 0 - || matrix.yx != 0; - if (transform || obliquen || (format != Format_Mono && !isScalableBitmap())) load_flags |= FT_LOAD_NO_BITMAP; @@ -1166,7 +1178,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, if (embolden) FT_GlyphSlot_Embolden(slot); - if (obliquen) { + if (obliquen && !transform) { FT_GlyphSlot_Oblique(slot); // While Embolden alters the metrics of the slot, oblique does not, so we need diff --git a/tests/baseline/text/tst_baseline_text.cpp b/tests/baseline/text/tst_baseline_text.cpp index 45c709b92f5..fdb30cf7b6e 100644 --- a/tests/baseline/text/tst_baseline_text.cpp +++ b/tests/baseline/text/tst_baseline_text.cpp @@ -18,6 +18,7 @@ private slots: void tst_render_data(); void tst_render(); void tst_differentScriptsBackgrounds(); + void tst_synthesizedObliqueAndRotation(); private: QDir htmlDir; @@ -102,6 +103,29 @@ void tst_Text::tst_differentScriptsBackgrounds() QBASELINE_CHECK(image, "tst_differentScriptsBackgrounds"); } +void tst_Text::tst_synthesizedObliqueAndRotation() +{ + QFont font(QString::fromLatin1("Abyssinica SIL")); + font.setPixelSize(40); + font.setItalic(true); + + QImage image(800, 600, QImage::Format_ARGB32); + image.fill(Qt::white); + + { + QPainter painter(&image); + painter.setFont(font); + + painter.save(); + painter.translate(200, 450); + painter.rotate(270); + painter.drawText(0, 0, QString::fromLatin1("Foobar")); + painter.restore(); + } + + QBASELINE_CHECK(image, "tst_synthesizedObliqueAndRotation"); +} + QBASELINETEST_MAIN(tst_Text)