Title: [92150] trunk
Revision
92150
Author
z...@google.com
Date
2011-08-01 16:12:49 -0700 (Mon, 01 Aug 2011)

Log Message

Unreviewed, rolling out r92022.
http://trac.webkit.org/changeset/92022
https://bugs.webkit.org/show_bug.cgi?id=65203

try to see if this is causing a bunch of browser tests failues
on win bots - will recommit if not

Source/WebCore: 

* platform/graphics/chromium/FontChromiumWin.cpp:
(WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::TransparencyAwareFontPainter):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::init):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::initializeForGDI):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::~TransparencyAwareFontPainter):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::TransparencyAwareGlyphPainter):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::~TransparencyAwareGlyphPainter):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::drawGlyphs):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::hdc):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::TransparencyAwareUniscribePainter):
(WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::~TransparencyAwareUniscribePainter):
(WebCore::drawGlyphsWin):
(WebCore::Font::drawComplexText):
* platform/graphics/chromium/UniscribeHelper.cpp:
(WebCore::UniscribeHelper::draw):
* platform/graphics/skia/PlatformContextSkia.cpp:
(WebCore::PlatformContextSkia::isNativeFontRenderingAllowed):
* platform/graphics/skia/PlatformContextSkia.h:
* platform/graphics/skia/SkiaFontWin.cpp:
(WebCore::windowsCanHandleDrawTextShadow):
(WebCore::windowsCanHandleTextDrawing):
(WebCore::windowsCanHandleTextDrawingWithoutShadow):
* platform/graphics/skia/SkiaFontWin.h:

LayoutTests: 

* platform/chromium/test_expectations.txt:

Modified Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (92149 => 92150)


--- trunk/LayoutTests/ChangeLog	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/LayoutTests/ChangeLog	2011-08-01 23:12:49 UTC (rev 92150)
@@ -1,3 +1,14 @@
+2011-08-01  Zhenyao Mo  <z...@google.com>
+
+        Unreviewed, rolling out r92022.
+        http://trac.webkit.org/changeset/92022
+        https://bugs.webkit.org/show_bug.cgi?id=65203
+
+        try to see if this is causing a bunch of browser tests failues
+        on win bots - will recommit if not
+
+        * platform/chromium/test_expectations.txt:
+
 2011-08-01  Ryosuke Niwa  <rn...@webkit.org>
 
         Remove time out expectation since media/track has been added to the skipped list on Qt.

Modified: trunk/LayoutTests/platform/chromium/test_expectations.txt (92149 => 92150)


--- trunk/LayoutTests/platform/chromium/test_expectations.txt	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/LayoutTests/platform/chromium/test_expectations.txt	2011-08-01 23:12:49 UTC (rev 92150)
@@ -1834,83 +1834,6 @@
 
 BUGWK38705 : http/tests/security/sandbox-inherit-to-initial-document-2.html = TEXT
 
-// Switching windows over from GDI to Skia for all text rendering.
-// When that lands, we will rebaseline these images.
-BUGWK65203 WIN : fast/borders/border-antialiasing.html = IMAGE
-BUGWK65203 WIN : fast/reflections/reflection-overflow-hidden.html = IMAGE
-BUGWK65203 WIN : fast/repaint/reflection-redraw.html = IMAGE
-BUGWK65203 WIN : fast/text/atsui-spacing-features.html = IMAGE
-BUGWK65203 WIN : fast/text/cg-vs-atsui.html = IMAGE
-BUGWK65203 WIN : fast/text/complex-text-opacity.html = IMAGE
-BUGWK65203 WIN : fast/text/international/complex-character-based-fallback.html = IMAGE
-BUGWK65203 WIN : fast/text/international/danda-space.html = IMAGE
-BUGWK65203 WIN : fast/text/international/thai-baht-space.html = IMAGE
-BUGWK65203 WIN : fast/text/international/thai-line-breaks.html = IMAGE
-BUGWK65203 WIN : media/audio-repaint.html = IMAGE
-BUGWK65203 WIN : platform/win/fast/text/uniscribe-missing-glyph.html = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1-SE/text-intro-05-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-37-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-39-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-40-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-41-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-46-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-60-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-61-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-62-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-63-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-64-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-65-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-66-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-67-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-68-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-69-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-70-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-81-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-82-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/animate-elem-83-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/pservers-grad-07-b.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/struct-frag-02-t.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/text-align-04-b.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/text-align-05-b.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/text-align-06-b.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/text-path-01-b.svg = IMAGE
-BUGWK65203 WIN : svg/W3C-SVG-1.1/text-text-05-t.svg = IMAGE
-BUGWK65203 WIN : svg/as-background-image/animated-svg-as-background.html = IMAGE
-BUGWK65203 WIN : svg/as-image/animated-svg-as-image.html = IMAGE
-BUGWK65203 WIN : svg/batik/filters/feTile.svg = IMAGE
-BUGWK65203 WIN : svg/batik/filters/filterRegions.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/longTextOnPath.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/textAnchor.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/textFeatures.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/textLayout.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/textPCDATA.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/textProperties.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/textProperties2.svg = IMAGE
-BUGWK65203 WIN : svg/batik/text/textStyles.svg = IMAGE
-BUGWK65203 WIN : svg/carto.net/textbox.svg = IMAGE
-BUGWK65203 WIN : svg/carto.net/window.svg = IMAGE
-BUGWK65203 WIN : svg/custom/js-late-clipPath-and-object-creation.svg = IMAGE
-BUGWK65203 WIN : svg/custom/js-late-clipPath-creation.svg = IMAGE
-BUGWK65203 WIN : svg/custom/linking-a-03-b-viewBox.svg = IMAGE
-BUGWK65203 WIN : svg/custom/linking-uri-01-b.svg = IMAGE
-BUGWK65203 WIN : svg/custom/svg-fonts-fallback.xhtml = IMAGE
-BUGWK65203 WIN : svg/dynamic-updates/SVGTextElement-dom-lengthAdjust-attr.html = IMAGE
-BUGWK65203 WIN : svg/dynamic-updates/SVGTextElement-svgdom-lengthAdjust-prop.html = IMAGE
-BUGWK65203 WIN : svg/hixie/mixed/009.xml = IMAGE
-BUGWK65203 WIN : svg/text/foreignObject-text-clipping-bug.xml = IMAGE
-BUGWK65203 WIN : svg/text/scaling-font-with-geometric-precision.html = IMAGE
-BUGWK65203 WIN : svg/text/text-align-01-b.svg = IMAGE
-BUGWK65203 WIN : svg/text/text-align-05-b.svg = IMAGE
-BUGWK65203 WIN : svg/text/text-align-06-b.svg = IMAGE
-BUGWK65203 WIN : svg/text/text-intro-05-t.svg = IMAGE
-BUGWK65203 WIN : svg/text/text-path-01-b.svg = IMAGE
-BUGWK65203 WIN : svg/text/textPathBoundsBug.svg = IMAGE
-BUGWK65203 WIN : svg/zoom/page/zoom-coords-viewattr-01-b.svg = IMAGE
-BUGWK65203 WIN : svg/zoom/page/zoom-hixie-mixed-008.xml = IMAGE
-BUGWK65203 WIN : svg/zoom/page/zoom-hixie-mixed-009.xml = IMAGE
-BUGWK65203 WIN : svg/zoom/text/zoom-coords-viewattr-01-b.svg = IMAGE
-BUGWK65203 WIN : svg/zoom/text/zoom-hixie-mixed-009.xml = IMAGE
-
 // WebKit roll 58791:58807
 BUGCR43319 LINUX DEBUG : fast/forms/select-empty-option-height.html = PASS TIMEOUT
 

Modified: trunk/Source/WebCore/ChangeLog (92149 => 92150)


--- trunk/Source/WebCore/ChangeLog	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/Source/WebCore/ChangeLog	2011-08-01 23:12:49 UTC (rev 92150)
@@ -1,3 +1,36 @@
+2011-08-01  Zhenyao Mo  <z...@google.com>
+
+        Unreviewed, rolling out r92022.
+        http://trac.webkit.org/changeset/92022
+        https://bugs.webkit.org/show_bug.cgi?id=65203
+
+        try to see if this is causing a bunch of browser tests failues
+        on win bots - will recommit if not
+
+        * platform/graphics/chromium/FontChromiumWin.cpp:
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::TransparencyAwareFontPainter):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::init):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::initializeForGDI):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareFontPainter::~TransparencyAwareFontPainter):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::TransparencyAwareGlyphPainter):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::~TransparencyAwareGlyphPainter):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareGlyphPainter::drawGlyphs):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::hdc):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::TransparencyAwareUniscribePainter):
+        (WebCore::TransparencyAwareFontPainter::TransparencyAwareUniscribePainter::~TransparencyAwareUniscribePainter):
+        (WebCore::drawGlyphsWin):
+        (WebCore::Font::drawComplexText):
+        * platform/graphics/chromium/UniscribeHelper.cpp:
+        (WebCore::UniscribeHelper::draw):
+        * platform/graphics/skia/PlatformContextSkia.cpp:
+        (WebCore::PlatformContextSkia::isNativeFontRenderingAllowed):
+        * platform/graphics/skia/PlatformContextSkia.h:
+        * platform/graphics/skia/SkiaFontWin.cpp:
+        (WebCore::windowsCanHandleDrawTextShadow):
+        (WebCore::windowsCanHandleTextDrawing):
+        (WebCore::windowsCanHandleTextDrawingWithoutShadow):
+        * platform/graphics/skia/SkiaFontWin.h:
+
 2011-08-01  Scott Graham  <scot...@chromium.org>
 
         REGRESSION (r39725?): Resources removed from document can not be freed

Modified: trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp (92149 => 92150)


--- trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp	2011-08-01 23:12:49 UTC (rev 92150)
@@ -62,8 +62,14 @@
 class TransparencyAwareFontPainter {
 public:
     TransparencyAwareFontPainter(GraphicsContext*, const FloatPoint&);
+    ~TransparencyAwareFontPainter();
 
 protected:
+    // Called by our subclass' constructor to initialize GDI if necessary. This
+    // is a separate function so it can be called after the subclass finishes
+    // construction (it calls virtual functions).
+    void init();
+
     virtual IntRect estimateTextBounds() = 0;
 
     // Use the context from the transparency helper when drawing with GDI. It
@@ -72,6 +78,20 @@
     PlatformGraphicsContext* m_platformContext;
 
     FloatPoint m_point;
+
+    // Set when Windows can handle the type of drawing we're doing.
+    bool m_useGDI;
+
+    // These members are valid only when m_useGDI is set.
+    HDC m_hdc;
+    TransparencyWin m_transparency;
+
+private:
+    // Call when we're using GDI mode to initialize the TransparencyWin to help
+    // us draw GDI text.
+    void initializeForGDI();
+
+    bool m_createdTransparencyLayer;  // We created a layer to give the font some alpha.
 };
 
 TransparencyAwareFontPainter::TransparencyAwareFontPainter(GraphicsContext* context,
@@ -79,9 +99,90 @@
     : m_graphicsContext(context)
     , m_platformContext(context->platformContext())
     , m_point(point)
+    , m_useGDI(windowsCanHandleTextDrawing(context))
+    , m_hdc(0)
+    , m_createdTransparencyLayer(false)
 {
 }
 
+void TransparencyAwareFontPainter::init()
+{
+    if (m_useGDI)
+        initializeForGDI();
+}
+
+void TransparencyAwareFontPainter::initializeForGDI()
+{
+    m_graphicsContext->save();
+    SkColor color = m_platformContext->effectiveFillColor();
+    // Used only when m_createdTransparencyLayer is true.
+    float layerAlpha = 0.0f;
+    if (SkColorGetA(color) != 0xFF) {
+        // When the font has some transparency, apply it by creating a new
+        // transparency layer with that opacity applied. We'll actually create
+        // a new transparency layer after we calculate the bounding box.
+        m_createdTransparencyLayer = true;
+        layerAlpha = SkColorGetA(color) / 255.0f;
+        // The color should be opaque now.
+        color = SkColorSetRGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
+    }
+
+    TransparencyWin::LayerMode layerMode;
+    IntRect layerRect;
+    if (m_platformContext->isDrawingToImageBuffer()) {
+        // Assume if we're drawing to an image buffer that the background
+        // is not opaque and we have to undo ClearType. We may want to
+        // enhance this to actually check, since it will often be opaque
+        // and we could do ClearType in that case.
+        layerMode = TransparencyWin::TextComposite;
+        layerRect = estimateTextBounds();
+        m_graphicsContext->clip(layerRect);
+        if (m_createdTransparencyLayer)
+            m_graphicsContext->beginTransparencyLayer(layerAlpha);
+
+        // The transparency helper requires that we draw text in black in
+        // this mode and it will apply the color.
+        m_transparency.setTextCompositeColor(color);
+        color = SkColorSetRGB(0, 0, 0);
+    } else if (m_createdTransparencyLayer || canvasHasMultipleLayers(m_platformContext->canvas())) {
+        // When we're drawing a web page, we know the background is opaque,
+        // but if we're drawing to a layer, we still need extra work.
+        layerMode = TransparencyWin::OpaqueCompositeLayer;
+        layerRect = estimateTextBounds();
+        m_graphicsContext->clip(layerRect);
+        if (m_createdTransparencyLayer)
+            m_graphicsContext->beginTransparencyLayer(layerAlpha);
+    } else {
+        // Common case of drawing onto the bottom layer of a web page: we
+        // know everything is opaque so don't need to do anything special.
+        layerMode = TransparencyWin::NoLayer;
+    }
+
+    // Bug 26088 - init() might fail if layerRect is invalid. Given this, we
+    // need to be careful to check for null pointers everywhere after this call
+    m_transparency.init(m_graphicsContext, layerMode, 
+                        TransparencyWin::KeepTransform, layerRect);
+
+    // Set up the DC, using the one from the transparency helper.
+    if (m_transparency.platformContext()) {
+        m_hdc = skia::BeginPlatformPaint(m_transparency.platformContext()->canvas());
+        SetTextColor(m_hdc, skia::SkColorToCOLORREF(color));
+        SetBkMode(m_hdc, TRANSPARENT);
+    }
+}
+
+TransparencyAwareFontPainter::~TransparencyAwareFontPainter()
+{
+    if (!m_useGDI || !m_graphicsContext || !m_platformContext)
+        return;  // Nothing to do.
+    m_transparency.composite();
+    if (m_createdTransparencyLayer)
+        m_graphicsContext->endTransparencyLayer();
+    m_graphicsContext->restore();
+    if (m_transparency.platformContext())
+        skia::EndPlatformPaint(m_transparency.platformContext()->canvas());
+}
+
 // Specialization for simple GlyphBuffer painting.
 class TransparencyAwareGlyphPainter : public TransparencyAwareFontPainter {
  public:
@@ -90,10 +191,13 @@
                                   const GlyphBuffer&,
                                   int from, int numGlyphs,
                                   const FloatPoint&);
+    ~TransparencyAwareGlyphPainter();
 
     // Draws the partial string of glyphs, starting at |startAdvance| to the
-    // left of m_point.
-    void drawGlyphs(int numGlyphs, const WORD* glyphs, const int* advances, float startAdvance) const;
+    // left of m_point. We express it this way so that if we're using the Skia
+    // drawing path we can use floating-point positioning, even though we have
+    // to use integer positioning in the GDI path.
+    bool drawGlyphs(int numGlyphs, const WORD* glyphs, const int* advances, float startAdvance) const;
 
  private:
     virtual IntRect estimateTextBounds();
@@ -102,6 +206,10 @@
     const GlyphBuffer& m_glyphBuffer;
     int m_from;
     int m_numGlyphs;
+
+    // When m_useGdi is set, this stores the previous HFONT selected into the
+    // m_hdc so we can restore it.
+    HGDIOBJ m_oldFont;  // For restoring the DC to its original state.
 };
 
 TransparencyAwareGlyphPainter::TransparencyAwareGlyphPainter(
@@ -115,9 +223,21 @@
     , m_glyphBuffer(glyphBuffer)
     , m_from(from)
     , m_numGlyphs(numGlyphs)
+    , m_oldFont(0)
 {
+    init();
+
+    if (m_hdc)
+        m_oldFont = ::SelectObject(m_hdc, m_font->platformData().hfont());
 }
 
+TransparencyAwareGlyphPainter::~TransparencyAwareGlyphPainter()
+{
+    if (m_useGDI && m_hdc)
+        ::SelectObject(m_hdc, m_oldFont);
+}
+
+
 // Estimates the bounding box of the given text. This is copied from
 // FontCGWin.cpp, it is possible, but a lot more work, to get the precide
 // bounds.
@@ -134,15 +254,47 @@
                    fontMetrics.lineSpacing()); 
 }
 
-void TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
+bool TransparencyAwareGlyphPainter::drawGlyphs(int numGlyphs,
                                                const WORD* glyphs,
                                                const int* advances,
                                                float startAdvance) const
 {
-    SkPoint origin = m_point;
-    origin.fX += SkFloatToScalar(startAdvance);
-    paintSkiaText(m_graphicsContext, m_font->platformData().hfont(),
-                  numGlyphs, glyphs, advances, 0, &origin);
+    if (!m_useGDI) {
+        SkPoint origin = m_point;
+        origin.fX += SkFloatToScalar(startAdvance);
+        paintSkiaText(m_graphicsContext, m_font->platformData().hfont(),
+                      numGlyphs, glyphs, advances, 0, &origin);
+        return true;
+    }
+
+    if (!m_graphicsContext || !m_hdc)
+        return true;
+
+    // Windows' origin is the top-left of the bounding box, so we have
+    // to subtract off the font ascent to get it.
+    int x = lroundf(m_point.x() + startAdvance);
+    int y = lroundf(m_point.y() - m_font->fontMetrics().ascent());
+
+    // If there is a non-blur shadow and both the fill color and shadow color 
+    // are opaque, handle without skia. 
+    FloatSize shadowOffset;
+    float shadowBlur;
+    Color shadowColor;
+    ColorSpace shadowColorSpace;
+    if (m_graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace)) {
+        // If there is a shadow and this code is reached, windowsCanHandleDrawTextShadow()
+        // will have already returned true during the ctor initiatization of m_useGDI
+        ASSERT(shadowColor.alpha() == 255);
+        ASSERT(m_graphicsContext->fillColor().alpha() == 255);
+        ASSERT(shadowBlur == 0);
+        COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
+        COLORREF savedTextColor = GetTextColor(m_hdc);
+        SetTextColor(m_hdc, textColor);
+        ExtTextOut(m_hdc, x + shadowOffset.width(), y + shadowOffset.height(), ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), numGlyphs, &advances[0]);
+        SetTextColor(m_hdc, savedTextColor);
+    }
+    
+    return !!ExtTextOut(m_hdc, x, y, ETO_GLYPH_INDEX, 0, reinterpret_cast<const wchar_t*>(&glyphs[0]), numGlyphs, &advances[0]);
 }
 
 class TransparencyAwareUniscribePainter : public TransparencyAwareFontPainter {
@@ -152,7 +304,11 @@
                                       const TextRun&,
                                       int from, int to,
                                       const FloatPoint&);
+    ~TransparencyAwareUniscribePainter();
 
+    // Uniscibe will draw directly into our buffer, so we need to expose our DC.
+    HDC hdc() const { return m_hdc; }
+
  private:
     virtual IntRect estimateTextBounds();
 
@@ -174,8 +330,13 @@
     , m_from(from)
     , m_to(to)
 {
+    init();
 }
 
+TransparencyAwareUniscribePainter::~TransparencyAwareUniscribePainter()
+{
+}
+
 IntRect TransparencyAwareUniscribePainter::estimateTextBounds()
 {
     // This case really really sucks. There is no convenient way to estimate
@@ -264,7 +425,20 @@
                 advances[i] = 0;
         }
 
-        painter.drawGlyphs(curLen, &glyphs[0], &advances[0], horizontalOffset - point.x() - currentWidth);
+        // Actually draw the glyphs (with retry on failure).
+        bool success = false;
+        for (int executions = 0; executions < 2; ++executions) {
+            success = painter.drawGlyphs(curLen, &glyphs[0], &advances[0], horizontalOffset - point.x() - currentWidth);
+            if (!success && executions == 0) {
+                // Ask the browser to load the font for us and retry.
+                PlatformBridge::ensureFontLoaded(font->platformData().hfont());
+                continue;
+            }
+            break;
+        }
+
+        if (!success)
+            LOG_ERROR("Unable to draw the glyphs after second attempt");
     }
 }
 
@@ -318,9 +492,37 @@
     if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke)
         return;
 
+    TransparencyAwareUniscribePainter painter(graphicsContext, this, run, from, to, point);
+
+    HDC hdc = painter.hdc();
+    if (windowsCanHandleTextDrawing(graphicsContext) && !hdc)
+        return;
+
+    // TODO(maruel): http://b/700464 SetTextColor doesn't support transparency.
+    // Enforce non-transparent color.
+    color = SkColorSetRGB(SkColorGetR(color), SkColorGetG(color), SkColorGetB(color));
+    if (hdc) {
+        SetTextColor(hdc, skia::SkColorToCOLORREF(color));
+        SetBkMode(hdc, TRANSPARENT);
+    }
+
+    // If there is a non-blur shadow and both the fill color and shadow color 
+    // are opaque, handle without skia. 
+    FloatSize shadowOffset;
+    float shadowBlur;
+    Color shadowColor;
+    ColorSpace shadowColorSpace;
+    if (graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace) && windowsCanHandleDrawTextShadow(graphicsContext)) {
+        COLORREF textColor = skia::SkColorToCOLORREF(SkColorSetARGB(255, shadowColor.red(), shadowColor.green(), shadowColor.blue()));
+        COLORREF savedTextColor = GetTextColor(hdc);
+        SetTextColor(hdc, textColor);
+        state.draw(graphicsContext, hdc, static_cast<int>(point.x()) + shadowOffset.width(),
+                   static_cast<int>(point.y() - fontMetrics().ascent()) + shadowOffset.height(), from, to);
+        SetTextColor(hdc, savedTextColor); 
+    }
+
     // Uniscribe counts the coordinates from the upper left, while WebKit uses
     // the baseline, so we have to subtract off the ascent.
-    HDC hdc = 0;
     state.draw(graphicsContext, hdc, lroundf(point.x()), lroundf(point.y() - fontMetrics().ascent()), from, to);
 }
 

Modified: trunk/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp (92149 => 92150)


--- trunk/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp	2011-08-01 23:12:49 UTC (rev 92150)
@@ -269,6 +269,7 @@
     HGDIOBJ oldFont = 0;
     int curX = x;
     bool firstRun = true;
+    bool useWindowsDrawing = windowsCanHandleTextDrawing(graphicsContext);
 
     for (size_t screenIndex = 0; screenIndex < m_runs.size(); screenIndex++) {
         int itemIndex = m_screenOrder[screenIndex];
@@ -347,22 +348,43 @@
             // Pass 0 in when there is no justification.
             const int* justify = shaping.m_justify.size() == 0 ? 0 : &shaping.m_justify[fromGlyph];
 
+            if (useWindowsDrawing) {
+                if (firstRun) {
+                    oldFont = SelectObject(dc, shaping.m_hfont);
+                    firstRun = false;
+                } else
+                    SelectObject(dc, shaping.m_hfont);
+            }
+
             // Fonts with different ascents can be used to render different
             // runs.  'Across-runs' y-coordinate correction needs to be
             // adjusted for each font.
             bool textOutOk = false;
             for (int executions = 0; executions < 2; ++executions) {
-                SkPoint origin;
-                origin.fX = curX + + innerOffset;
-                origin.fY = y + m_ascent;
-                paintSkiaText(graphicsContext,
-                              shaping.m_hfont,
-                              glyphCount,
-                              &shaping.m_glyphs[fromGlyph],
-                              &shaping.m_advance[fromGlyph],
-                              &shaping.m_offsets[fromGlyph],
-                              &origin);
-                textOutOk = true;
+                if (useWindowsDrawing) {
+                    HRESULT hr = ScriptTextOut(dc, shaping.m_scriptCache,
+                                               curX + innerOffset,
+                                               y - shaping.m_ascentOffset,
+                                               0, 0, &item.a, 0, 0,
+                                               &shaping.m_glyphs[fromGlyph],
+                                               glyphCount,
+                                               &shaping.m_advance[fromGlyph],
+                                               justify,
+                                               &shaping.m_offsets[fromGlyph]);
+                    textOutOk = (hr == S_OK);
+                } else {
+                    SkPoint origin;
+                    origin.fX = curX + + innerOffset;
+                    origin.fY = y + m_ascent;
+                    paintSkiaText(graphicsContext,
+                                  shaping.m_hfont,
+                                  glyphCount,
+                                  &shaping.m_glyphs[fromGlyph],
+                                  &shaping.m_advance[fromGlyph],
+                                  &shaping.m_offsets[fromGlyph],
+                                  &origin);
+                    textOutOk = true;
+                }
 
                 if (!textOutOk && 0 == executions) {
                     // If TextOut is called from the renderer it might fail

Modified: trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp (92149 => 92150)


--- trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp	2011-08-01 23:12:49 UTC (rev 92150)
@@ -569,6 +569,17 @@
     return &m_canvas->getDevice()->accessBitmap(false);
 }
 
+bool PlatformContextSkia::isNativeFontRenderingAllowed()
+{
+#if ENABLE(SKIA_TEXT)
+    return false;
+#else
+    if (useSkiaGPU())
+        return false;
+    return skia::SupportsPlatformPaint(m_canvas);
+#endif
+}
+
 void PlatformContextSkia::getImageResamplingHint(IntSize* srcSize, FloatSize* dstSize) const
 {
     *srcSize = m_imageResamplingHintSrcSize;

Modified: trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h (92149 => 92150)


--- trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h	2011-08-01 23:12:49 UTC (rev 92150)
@@ -167,6 +167,11 @@
     bool printing() const { return m_printing; }
     void setPrinting(bool p) { m_printing = p; }
 
+    // Returns if the context allows rendering of fonts using native platform
+    // APIs. If false is returned font rendering is performed using the skia
+    // text drawing APIs.
+    bool isNativeFontRenderingAllowed();
+
     void getImageResamplingHint(IntSize* srcSize, FloatSize* dstSize) const;
     void setImageResamplingHint(const IntSize& srcSize, const FloatSize& dstSize);
     void clearImageResamplingHint();

Modified: trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp (92149 => 92150)


--- trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp	2011-08-01 23:12:49 UTC (rev 92150)
@@ -43,6 +43,58 @@
 
 namespace WebCore {
 
+bool windowsCanHandleDrawTextShadow(GraphicsContext *context)
+{
+    FloatSize shadowOffset;
+    float shadowBlur;
+    Color shadowColor;
+    ColorSpace shadowColorSpace;
+
+    bool hasShadow = context->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
+    return !hasShadow || (!shadowBlur && (shadowColor.alpha() == 255) && (context->fillColor().alpha() == 255));
+}
+
+bool windowsCanHandleTextDrawing(GraphicsContext* context)
+{
+    if (!windowsCanHandleTextDrawingWithoutShadow(context))
+        return false;
+
+    // Check for shadow effects.
+    if (!windowsCanHandleDrawTextShadow(context))
+        return false;
+
+    return true;
+}
+
+bool windowsCanHandleTextDrawingWithoutShadow(GraphicsContext* context)
+{
+    // Check for non-translation transforms. Sometimes zooms will look better in
+    // Skia, and sometimes better in Windows. The main problem is that zooming
+    // in using Skia will show you the hinted outlines for the smaller size,
+    // which look weird. All else being equal, it's better to use Windows' text
+    // drawing, so we don't check for zooms.
+    const AffineTransform& matrix = context->getCTM();
+    if (matrix.b() != 0 || matrix.c() != 0)  // Check for skew.
+        return false;
+
+    // Check for stroke effects.
+    if (context->platformContext()->getTextDrawingMode() != TextModeFill)
+        return false;
+
+    // Check for gradients.
+    if (context->fillGradient() || context->strokeGradient())
+        return false;
+
+    // Check for patterns.
+    if (context->fillPattern() || context->strokePattern())
+        return false;
+
+    if (!context->platformContext()->isNativeFontRenderingAllowed())
+        return false;
+
+    return true;
+}
+
 static void skiaDrawText(SkCanvas* canvas,
                          const SkPoint& point,
                          SkPaint* paint,

Modified: trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.h (92149 => 92150)


--- trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.h	2011-08-01 22:45:37 UTC (rev 92149)
+++ trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.h	2011-08-01 23:12:49 UTC (rev 92150)
@@ -39,7 +39,34 @@
 namespace WebCore {
 
 class GraphicsContext;
+class PlatformContextSkia;
 
+// The functions below are used for more complex font drawing (effects such as
+// stroking and more complex transforms) than Windows supports directly.  Since 
+// Windows drawing is faster you should use windowsCanHandleTextDrawing first to 
+// check if using Skia is required at all.
+// Note that the text will look different (no ClearType) so this should only be
+// used when necessary.
+//
+// When you call a Skia* text drawing function, various glyph outlines will be
+// cached. As a result, you should call SkiaWinOutlineCache::removePathsForFont
+// when the font is destroyed so that the cache does not outlive the font (since
+// the HFONTs are recycled).
+//
+// Remember that Skia's text drawing origin is the baseline, like WebKit, not
+// the top, like Windows.
+
+// Returns true if the fillColor and shadowColor are opaque and the text-shadow
+// is not blurred.
+bool windowsCanHandleDrawTextShadow(GraphicsContext*);
+
+// Returns true if advanced font rendering is recommended.
+bool windowsCanHandleTextDrawing(GraphicsContext*);
+
+// Returns true if advanced font rendering is recommended if shadows are
+// disregarded.
+bool windowsCanHandleTextDrawingWithoutShadow(GraphicsContext*);
+
 // Note that the offsets parameter is optional.  If not NULL it represents a
 // per glyph offset (such as returned by ScriptPlace Windows API function).
 void paintSkiaText(GraphicsContext*,
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to