Title: [135888] trunk
Revision
135888
Author
[email protected]
Date
2012-11-27 11:25:54 -0800 (Tue, 27 Nov 2012)

Log Message

Canvas does not draw any text if the font is not fully loaded yet
https://bugs.webkit.org/show_bug.cgi?id=103392

Patch by Christophe Dumez <[email protected]> on 2012-11-27
Reviewed by Kenneth Rohde Christiansen.

Source/WebCore:

Update CanvasRenderingContext2D::drawTextInternal() so that the
text is being drawn, even if custom fonts are still being loaded.
Without this, WebKit was not drawing any text on the canvas if
the needed font is custom and is not fully loaded yet. This seems
broken.

The new behavior is according to specification:
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html

The specification says: "If a font is used before it is fully
loaded, or if the font style source object does not have that
font in scope at the time the font is to be used, then it must be
treated as if it was an unknown font, falling back to another as
described by the relevant CSS specifications."

Test: http/tests/canvas/canvas-slow-font-loading.html

* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::drawTextInternal):
* platform/graphics/Font.cpp:
(WebCore::Font::drawText): Add argument to specify the behavior
when custom fonts are not ready. By default, it will not draw
anything (same behavior as before). However, the Canvas code
can now request that a fallback font is used if the custom
font is not fully loaded yet.
* platform/graphics/Font.h: #undef Complex if defined to avoid
conflicting with Complex value in CodePath enum. X11/X.h is
defining Complex to 0.
* platform/graphics/GraphicsContext.cpp:
(WebCore::GraphicsContext::drawBidiText):
* platform/graphics/GraphicsContext.h:
(WebCore):
(GraphicsContext):

LayoutTests:

Add canvas test to check that text is drawn using a fallback font
if the primary font is not fully loaded yet.

* http/tests/canvas/canvas-slow-font-loading-expected.html: Added.
* http/tests/canvas/canvas-slow-font-loading.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (135887 => 135888)


--- trunk/LayoutTests/ChangeLog	2012-11-27 19:23:04 UTC (rev 135887)
+++ trunk/LayoutTests/ChangeLog	2012-11-27 19:25:54 UTC (rev 135888)
@@ -1,3 +1,16 @@
+2012-11-27  Christophe Dumez  <[email protected]>
+
+        Canvas does not draw any text if the font is not fully loaded yet
+        https://bugs.webkit.org/show_bug.cgi?id=103392
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Add canvas test to check that text is drawn using a fallback font
+        if the primary font is not fully loaded yet.
+
+        * http/tests/canvas/canvas-slow-font-loading-expected.html: Added.
+        * http/tests/canvas/canvas-slow-font-loading.html: Added.
+
 2012-11-27  Yael Aharon  <[email protected]>
 
         Unreviewed gardening. fast/loader/submit-form-while-parsing-2.html is still flaky

Added: trunk/LayoutTests/http/tests/canvas/canvas-slow-font-loading-expected.html (0 => 135888)


--- trunk/LayoutTests/http/tests/canvas/canvas-slow-font-loading-expected.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/canvas/canvas-slow-font-loading-expected.html	2012-11-27 19:25:54 UTC (rev 135888)
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<body>
+<canvas id="c" width="100" height="50"><p>FAIL (fallback content)</p></canvas>
+<script>
+var canvas = document.getElementById('c');
+var ctx = canvas.getContext('2d');
+
+ctx.font = '67px Arial';
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+ctx.fillStyle = '#0f0';
+ctx.fillText('XX', 0, 50);
+</script>
+

Added: trunk/LayoutTests/http/tests/canvas/canvas-slow-font-loading.html (0 => 135888)


--- trunk/LayoutTests/http/tests/canvas/canvas-slow-font-loading.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/canvas/canvas-slow-font-loading.html	2012-11-27 19:25:54 UTC (rev 135888)
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<head>
+<title>Canvas test: slow font loading</title>
+<style>
+@font-face {
+  font-family: Ahem;
+  src: url("../webfont/slow-ahem-loading.cgi");
+}
+</style>
+</head>
+<body>
+
+<canvas id="c" width="100" height="50"><p>FAIL (fallback content)</p></canvas>
+
+<script>
+var canvas = document.getElementById('c');
+var ctx = canvas.getContext('2d');
+
+// Ahem font loading is slow so it will not be ready
+// in time for drawing the text. As a consequence, the
+// fallback font should be used and the result should
+// be 2 green 'X' on a red background.
+ctx.font = '67px Ahem, Arial';
+ctx.fillStyle = '#f00';
+ctx.fillRect(0, 0, 100, 50);
+ctx.fillStyle = '#0f0';
+ctx.fillText('XX', 0, 50);
+</script>
+

Modified: trunk/Source/WebCore/ChangeLog (135887 => 135888)


--- trunk/Source/WebCore/ChangeLog	2012-11-27 19:23:04 UTC (rev 135887)
+++ trunk/Source/WebCore/ChangeLog	2012-11-27 19:25:54 UTC (rev 135888)
@@ -1,3 +1,44 @@
+2012-11-27  Christophe Dumez  <[email protected]>
+
+        Canvas does not draw any text if the font is not fully loaded yet
+        https://bugs.webkit.org/show_bug.cgi?id=103392
+
+        Reviewed by Kenneth Rohde Christiansen.
+
+        Update CanvasRenderingContext2D::drawTextInternal() so that the
+        text is being drawn, even if custom fonts are still being loaded.
+        Without this, WebKit was not drawing any text on the canvas if
+        the needed font is custom and is not fully loaded yet. This seems
+        broken.
+
+        The new behavior is according to specification:
+        http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html
+
+        The specification says: "If a font is used before it is fully
+        loaded, or if the font style source object does not have that
+        font in scope at the time the font is to be used, then it must be
+        treated as if it was an unknown font, falling back to another as
+        described by the relevant CSS specifications."
+
+        Test: http/tests/canvas/canvas-slow-font-loading.html
+
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::drawTextInternal):
+        * platform/graphics/Font.cpp:
+        (WebCore::Font::drawText): Add argument to specify the behavior
+        when custom fonts are not ready. By default, it will not draw
+        anything (same behavior as before). However, the Canvas code
+        can now request that a fallback font is used if the custom
+        font is not fully loaded yet.
+        * platform/graphics/Font.h: #undef Complex if defined to avoid
+        conflicting with Complex value in CodePath enum. X11/X.h is
+        defining Complex to 0.
+        * platform/graphics/GraphicsContext.cpp:
+        (WebCore::GraphicsContext::drawBidiText):
+        * platform/graphics/GraphicsContext.h:
+        (WebCore):
+        (GraphicsContext):
+
 2012-11-27  Dean Jackson  <[email protected]>
 
         No need for ExceptionCode in HTMLMediaElement::load

Modified: trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp (135887 => 135888)


--- trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2012-11-27 19:23:04 UTC (rev 135887)
+++ trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp	2012-11-27 19:25:54 UTC (rev 135888)
@@ -2306,10 +2306,10 @@
             maskImageContext->translate(location.x() - maskRect.x(), location.y() - maskRect.y());
             // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
             maskImageContext->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
-            maskImageContext->drawBidiText(font, textRun, FloatPoint(0, 0));
+            maskImageContext->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
         } else {
             maskImageContext->translate(-maskRect.x(), -maskRect.y());
-            maskImageContext->drawBidiText(font, textRun, location);
+            maskImageContext->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady);
         }
 
         GraphicsContextStateSaver stateSaver(*c);
@@ -2333,9 +2333,9 @@
         c->translate(location.x(), location.y());
         // We draw when fontWidth is 0 so compositing operations (eg, a "copy" op) still work.
         c->scale(FloatSize((fontWidth > 0 ? (width / fontWidth) : 0), 1));
-        c->drawBidiText(font, textRun, FloatPoint(0, 0));
+        c->drawBidiText(font, textRun, FloatPoint(0, 0), Font::UseFallbackIfFontNotReady);
     } else
-        c->drawBidiText(font, textRun, location);
+        c->drawBidiText(font, textRun, location, Font::UseFallbackIfFontNotReady);
 
     didDraw(textRect);
 

Modified: trunk/Source/WebCore/platform/graphics/Font.cpp (135887 => 135888)


--- trunk/Source/WebCore/platform/graphics/Font.cpp	2012-11-27 19:23:04 UTC (rev 135887)
+++ trunk/Source/WebCore/platform/graphics/Font.cpp	2012-11-27 19:25:54 UTC (rev 135888)
@@ -156,10 +156,12 @@
     m_typesettingFeatures = computeTypesettingFeatures();
 }
 
-void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to) const
+void Font::drawText(GraphicsContext* context, const TextRun& run, const FloatPoint& point, int from, int to, CustomFontNotReadyAction customFontNotReadyAction) const
 {
-    // Don't draw anything while we are using custom fonts that are in the process of loading.
-    if (loadingCustomFonts())
+    // Don't draw anything while we are using custom fonts that are in the process of loading,
+    // except if the 'force' argument is set to true (in which case it will use a fallback
+    // font).
+    if (loadingCustomFonts() && customFontNotReadyAction == DoNotPaintIfFontNotReady)
         return;
     
     to = (to == -1 ? run.length() : to);

Modified: trunk/Source/WebCore/platform/graphics/Font.h (135887 => 135888)


--- trunk/Source/WebCore/platform/graphics/Font.h	2012-11-27 19:23:04 UTC (rev 135887)
+++ trunk/Source/WebCore/platform/graphics/Font.h	2012-11-27 19:25:54 UTC (rev 135888)
@@ -42,6 +42,12 @@
 QT_END_NAMESPACE
 #endif
 
+// "X11/X.h" defines Complex to 0 and conflicts
+// with Complex value in CodePath enum.
+#ifdef Complex
+#undef Complex
+#endif
+
 namespace WebCore {
 
 class FloatPoint;
@@ -97,7 +103,8 @@
 
     void update(PassRefPtr<FontSelector>) const;
 
-    void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1) const;
+    enum CustomFontNotReadyAction { DoNotPaintIfFontNotReady, UseFallbackIfFontNotReady };
+    void drawText(GraphicsContext*, const TextRun&, const FloatPoint&, int from = 0, int to = -1, CustomFontNotReadyAction = DoNotPaintIfFontNotReady) const;
     void drawEmphasisMarks(GraphicsContext*, const TextRun&, const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1) const;
 
     float width(const TextRun&, HashSet<const SimpleFontData*>* fallbackFonts = 0, GlyphOverflow* = 0) const;

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp (135887 => 135888)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2012-11-27 19:23:04 UTC (rev 135887)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.cpp	2012-11-27 19:25:54 UTC (rev 135888)
@@ -28,7 +28,6 @@
 
 #include "BidiResolver.h"
 #include "BitmapImage.h"
-#include "Font.h"
 #include "Generator.h"
 #include "ImageBuffer.h"
 #include "IntRect.h"
@@ -404,7 +403,7 @@
     font.drawEmphasisMarks(this, run, mark, point, from, to);
 }
 
-void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const FloatPoint& point)
+void GraphicsContext::drawBidiText(const Font& font, const TextRun& run, const FloatPoint& point, Font::CustomFontNotReadyAction customFontNotReadyAction)
 {
     if (paintingDisabled())
         return;
@@ -428,7 +427,7 @@
         subrun.setDirection(isRTL ? RTL : LTR);
         subrun.setDirectionalOverride(bidiRun->dirOverride(false));
 
-        font.drawText(this, subrun, currPoint);
+        font.drawText(this, subrun, currPoint, 0, -1, customFontNotReadyAction);
 
         bidiRun = bidiRun->next();
         // FIXME: Have Font::drawText return the width of what it drew so that we don't have to re-measure here.

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext.h (135887 => 135888)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2012-11-27 19:23:04 UTC (rev 135887)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext.h	2012-11-27 19:25:54 UTC (rev 135888)
@@ -30,6 +30,7 @@
 #include "ColorSpace.h"
 #include "DashArray.h"
 #include "FloatRect.h"
+#include "Font.h"
 #include "Gradient.h"
 #include "Image.h"
 #include "ImageOrientation.h"
@@ -114,7 +115,6 @@
 
     class AffineTransform;
     class DrawingBuffer;
-    class Font;
     class Generator;
 #if !USE(SKIA)
     class GraphicsContextPlatformPrivate;
@@ -355,7 +355,7 @@
 
         void drawText(const Font&, const TextRun&, const FloatPoint&, int from = 0, int to = -1);
         void drawEmphasisMarks(const Font&, const TextRun& , const AtomicString& mark, const FloatPoint&, int from = 0, int to = -1);
-        void drawBidiText(const Font&, const TextRun&, const FloatPoint&);
+        void drawBidiText(const Font&, const TextRun&, const FloatPoint&, Font::CustomFontNotReadyAction = Font::DoNotPaintIfFontNotReady);
         void drawHighlightForText(const Font&, const TextRun&, const FloatPoint&, int h, const Color& backgroundColor, ColorSpace, int from = 0, int to = -1);
 
         enum RoundingMode {
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to