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
- trunk/LayoutTests/ChangeLog
- trunk/LayoutTests/platform/chromium/test_expectations.txt
- trunk/Source/WebCore/ChangeLog
- trunk/Source/WebCore/platform/graphics/chromium/FontChromiumWin.cpp
- trunk/Source/WebCore/platform/graphics/chromium/UniscribeHelper.cpp
- trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.cpp
- trunk/Source/WebCore/platform/graphics/skia/PlatformContextSkia.h
- trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.cpp
- trunk/Source/WebCore/platform/graphics/skia/SkiaFontWin.h
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