[Freetype] Some text in Planet GNOME renders in the wrong place
authormrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Sep 2011 23:47:40 +0000 (23:47 +0000)
committermrobinson@webkit.org <mrobinson@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Sep 2011 23:47:40 +0000 (23:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=69099

Reviewed by Dirk Schulze.

Source/WebCore:

Test: platform/gtk/fonts/synthetic-oblique-positioning.html

Fold the oblique transform into the font matrix itself rather than transforming
the CTM of the context at render time. Not only does this fix the issue, it
prevents unnecessary work on every paint.

* platform/graphics/cairo/FontCairo.cpp:
No longer set the synthetic oblique transformation matrix on the context
when rendering the text. Instead it is now folded into the TM of the font
itself.
* platform/graphics/freetype/FontPlatformDataFreeType.cpp:
(WebCore::FontPlatformData::initializeWithFontFace): Fold the oblique transform into the scaled font.
* platform/graphics/win/FontPlatformDataCairoWin.cpp:
(WebCore::FontPlatformData::FontPlatformData): Ditto.

LayoutTests:

Add a test which exercises this issue. It seems the problem grows worse
as the y component of the text position increases, so position the text
about halfway down the page.

* platform/gtk/fonts/synthetic-oblique-positioning-expected.png: Added.
* platform/gtk/fonts/synthetic-oblique-positioning-expected.txt: Added.
* platform/gtk/fonts/synthetic-oblique-positioning.html: Added.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96378 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning-expected.png [new file with mode: 0644]
LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning-expected.txt [new file with mode: 0644]
LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/platform/graphics/cairo/FontCairo.cpp
Source/WebCore/platform/graphics/freetype/FontPlatformDataFreeType.cpp
Source/WebCore/platform/graphics/win/FontPlatformDataCairoWin.cpp

index 2030f6e..8c82e87 100644 (file)
@@ -1,3 +1,18 @@
+2011-09-29  Martin Robinson  <mrobinson@igalia.com>
+
+        [Freetype] Some text in Planet GNOME renders in the wrong place
+        https://bugs.webkit.org/show_bug.cgi?id=69099
+
+        Reviewed by Dirk Schulze.
+
+        Add a test which exercises this issue. It seems the problem grows worse
+        as the y component of the text position increases, so position the text
+        about halfway down the page.
+
+        * platform/gtk/fonts/synthetic-oblique-positioning-expected.png: Added.
+        * platform/gtk/fonts/synthetic-oblique-positioning-expected.txt: Added.
+        * platform/gtk/fonts/synthetic-oblique-positioning.html: Added.
+
 2011-09-29  Adam Barth  <abarth@webkit.org>
 
         Update image baselines after http://trac.webkit.org/changeset/96366.  These are progressions.
diff --git a/LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning-expected.png b/LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning-expected.png
new file mode 100644 (file)
index 0000000..eaf4509
Binary files /dev/null and b/LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning-expected.png differ
diff --git a/LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning-expected.txt b/LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning-expected.txt
new file mode 100644 (file)
index 0000000..2c1c1e3
--- /dev/null
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+layer at (8,200) size 200x40
+  RenderBlock (positioned) {DIV} at (8,200) size 200x40
+    RenderText {#text} at (0,0) size 80x40
+      text run at (0,0) width 80: "A "
+    RenderInline {CITE} at (0,0) size 40x40
+      RenderText {#text} at (80,0) size 40x40
+        text run at (80,0) width 40: "B"
+    RenderText {#text} at (120,0) size 80x40
+      text run at (120,0) width 80: " C"
diff --git a/LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning.html b/LayoutTests/platform/gtk/fonts/synthetic-oblique-positioning.html
new file mode 100644 (file)
index 0000000..d92ffde
--- /dev/null
@@ -0,0 +1,31 @@
+<html>
+<head>
+<style>
+    @font-face {
+        font-family: webkit-ahem;
+        font-style: normal;
+        src: url(resources/Ahem.ttf) format(truetype);
+    }
+</style>
+</head>
+
+<body>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.waitUntilDone();
+    document.onreadystatechange = function() {
+        if (document.readyState === 'complete')
+            setTimeout(function() {layoutTestController.notifyDone();}, 100);
+    };
+}
+</script>
+
+<!-- This test verifies that the CTM does not cause text that has a synthetic
+oblique to render in the wrong part of the page. You should be able to see
+three separate block characters with the middle rendered in italic.  -->
+
+<div style="position: absolute; top: 200px; font-family: webkit-ahem; font-size: 30pt;">
+A <cite>B</cite> C
+</div>
+</body>
+</html>
index 9ce8dd3..f651551 100644 (file)
@@ -1,3 +1,25 @@
+2011-09-29  Martin Robinson  <mrobinson@igalia.com>
+
+        [Freetype] Some text in Planet GNOME renders in the wrong place
+        https://bugs.webkit.org/show_bug.cgi?id=69099
+
+        Reviewed by Dirk Schulze.
+
+        Test: platform/gtk/fonts/synthetic-oblique-positioning.html
+
+        Fold the oblique transform into the font matrix itself rather than transforming
+        the CTM of the context at render time. Not only does this fix the issue, it
+        prevents unnecessary work on every paint.
+
+        * platform/graphics/cairo/FontCairo.cpp:
+        No longer set the synthetic oblique transformation matrix on the context
+        when rendering the text. Instead it is now folded into the TM of the font
+        itself.
+        * platform/graphics/freetype/FontPlatformDataFreeType.cpp:
+        (WebCore::FontPlatformData::initializeWithFontFace): Fold the oblique transform into the scaled font.
+        * platform/graphics/win/FontPlatformDataCairoWin.cpp:
+        (WebCore::FontPlatformData::FontPlatformData): Ditto.
+
 2011-09-29  Dan Bernstein  <mitz@apple.com>
 
         Follow-up fix for <rdar://problem/10191243> Glyph variants (line final swashes) appear where they should not
index 5b4d0be..35d1e5b 100644 (file)
 
 namespace WebCore {
 
-static const float gSyntheticObliqueSkew = -tanf(14 * acosf(0) / 90);
-
-static void prepareContextForGlyphDrawing(cairo_t* context, const SimpleFontData* font)
-{
-    cairo_set_scaled_font(context, font->platformData().scaledFont());
-
-    if (font->platformData().syntheticOblique()) {
-        cairo_matrix_t mat = {1, 0, gSyntheticObliqueSkew, 1, 0, 0};
-        cairo_transform(context, &mat);
-    }
-}
-
 static void drawGlyphsToContext(cairo_t* context, const SimpleFontData* font, GlyphBufferGlyph* glyphs, int numGlyphs)
 {
     cairo_matrix_t originalTransform;
     float syntheticBoldOffset = font->syntheticBoldOffset();
-    if (font->platformData().syntheticOblique() || syntheticBoldOffset)
+    if (syntheticBoldOffset)
         cairo_get_matrix(context, &originalTransform);
 
-    prepareContextForGlyphDrawing(context, font);
+    cairo_set_scaled_font(context, font->platformData().scaledFont());
     cairo_show_glyphs(context, glyphs, numGlyphs);
 
     if (syntheticBoldOffset) {
@@ -70,7 +58,7 @@ static void drawGlyphsToContext(cairo_t* context, const SimpleFontData* font, Gl
         cairo_show_glyphs(context, glyphs, numGlyphs);
     }
 
-    if (font->platformData().syntheticOblique() || syntheticBoldOffset)
+    if (syntheticBoldOffset)
         cairo_set_matrix(context, &originalTransform);
 }
 
@@ -139,7 +127,7 @@ void Font::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, cons
         cairo_set_line_width(cr, context->strokeThickness());
 
         // This may disturb the CTM, but we are going to call cairo_restore soon after.
-        prepareContextForGlyphDrawing(cr, font);
+        cairo_set_scaled_font(cr, font->platformData().scaledFont());
         cairo_glyph_path(cr, glyphs, numGlyphs);
         cairo_stroke(cr);
     }
index 1ca5c9e..47b2f7e 100644 (file)
@@ -270,6 +270,12 @@ void FontPlatformData::initializeWithFontFace(cairo_font_face_t* fontFace)
         cairo_matrix_scale(&fontMatrix, realSize, realSize);
     }
 
+    if (syntheticOblique()) {
+        static const float syntheticObliqueSkew = -tanf(14 * acosf(0) / 90);
+        cairo_matrix_t skew = {1, 0, syntheticObliqueSkew, 1, 0, 0};
+        cairo_matrix_multiply(&fontMatrix, &skew, &fontMatrix);
+    }
+
     m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
     cairo_font_options_destroy(options);
 }
index e60b69b..82d6b4f 100644 (file)
@@ -79,6 +79,12 @@ FontPlatformData::FontPlatformData(cairo_font_face_t* fontFace, float size, bool
    cairo_font_options_set_hint_style(options, CAIRO_HINT_STYLE_NONE);
    cairo_font_options_set_antialias(options, CAIRO_ANTIALIAS_GRAY);
 
+    if (syntheticOblique()) {
+        static const float syntheticObliqueSkew = -tanf(14 * acosf(0) / 90);
+        cairo_matrix_t skew = {1, 0, syntheticObliqueSkew, 1, 0, 0};
+        cairo_matrix_multiply(&fontMatrix, &skew, &fontMatrix);
+    }
+
    m_scaledFont = cairo_scaled_font_create(fontFace, &fontMatrix, &ctm, options);
    cairo_font_options_destroy(options);
 }