Chromium Code Reviews| Index: webkit/port/platform/graphics/chromium/FontChromiumWin.cpp |
| =================================================================== |
| --- webkit/port/platform/graphics/chromium/FontChromiumWin.cpp (revision 6975) |
| +++ webkit/port/platform/graphics/chromium/FontChromiumWin.cpp (working copy) |
| @@ -26,12 +26,14 @@ |
| #include "config.h" |
| #include <windows.h> |
| +#include "AffineTransform.h" |
| #include "ChromiumBridge.h" |
| #include "Font.h" |
| #include "FontFallbackList.h" |
| #include "GlyphBuffer.h" |
| #include "PlatformContextSkia.h" |
| #include "SimpleFontData.h" |
| +#include "SkiaFontWin.h" |
| #include "SkiaUtils.h" |
| #include "UniscribeHelperTextRun.h" |
| @@ -40,6 +42,76 @@ |
| namespace WebCore { |
| +static bool windowsCanHandleTextDrawing(GraphicsContext* context) |
| +{ |
| + // Check for non-translation transforms. |
| + const AffineTransform& xform = context->getCTM(); |
| + if (xform.b() != 0 || // Y skew |
| + xform.c() != 0 || // X skew |
| + xform.a() != 1.0 || // X scale |
| + xform.d() != 1.0) |
| + return false; |
| + |
| + // Check for stroke effects. |
| + if (context->platformContext()->getTextDrawingMode() != cTextFill) |
| + return false; |
| + |
| + // Check for shadow effects. |
| + if (context->platformContext()->getDrawLooper()) |
|
M-A Ruel
2008/12/15 19:54:51
shadow should be ignored when printing on Windows.
|
| + return false; |
| + |
| + return true; |
| +} |
| + |
| +static bool PaintSkiaText(PlatformContextSkia* platformContext, |
| + HFONT hfont, |
| + int numGlyphs, |
| + const WORD* glyphs, |
| + const int* advances, |
| + const SkPoint& origin) |
| +{ |
| + int textMode = platformContext->getTextDrawingMode(); |
| + |
| + // Filling (if necessary). This is the common case. |
| + SkPaint paint; |
| + platformContext->setupPaintForFilling(&paint); |
| + paint.setFlags(SkPaint::kAntiAlias_Flag); |
| + bool didFill = false; |
| + if ((textMode & cTextFill) && SkColorGetA(paint.getColor())) { |
| + if (!SkiaDrawText(hfont, platformContext->canvas(), origin, &paint, |
| + &glyphs[0], &advances[0], numGlyphs)) |
| + return false; |
| + didFill = true; |
| + } |
| + |
| + // Stroking on top (if necessary). |
| + if ((textMode & WebCore::cTextStroke) && |
| + platformContext->getStrokeStyle() != NoStroke && |
| + platformContext->getStrokeThickness() > 0) { |
| + |
| + paint.reset(); |
| + platformContext->setupPaintForStroking(&paint, NULL, 0); |
| + paint.setFlags(SkPaint::kAntiAlias_Flag); |
| + if (didFill) { |
| + // If there is a shadow and we filled above, there will already be |
| + // a shadow. We don't want to draw it again or it will be too dark |
| + // and it will go on top of the fill. |
| + // |
| + // Note that this isn't strictly correct, since the stroke could be |
| + // very thick and the shadow wouldn't account for this. The "right" |
| + // thing would be to draw to a new layer and then draw that layer |
| + // with a shadow. But this is a lot of extra work for something |
| + // that isn't normally an issue. |
| + paint.setLooper(NULL)->safeUnref(); |
| + } |
| + |
| + if (!SkiaDrawText(hfont, platformContext->canvas(), origin, |
| + &paint, &glyphs[0], &advances[0], numGlyphs)) |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| void Font::drawGlyphs(GraphicsContext* graphicsContext, |
| const SimpleFontData* font, |
| const GlyphBuffer& glyphBuffer, |
| @@ -82,6 +154,8 @@ |
| int x = static_cast<int>(point.x()); |
| int lineTop = static_cast<int>(point.y()) - font->ascent(); |
| + bool canUseGDI = windowsCanHandleTextDrawing(graphicsContext); |
|
M-A Ruel
2008/12/15 19:54:51
I wonder if canUseGDI should always be true when p
|
| + |
| // We draw the glyphs in chunks to avoid having to do a heap allocation for |
| // the arrays of characters and advances. Since ExtTextOut is the |
| // lowest-level text output function on Windows, there should be little |
| @@ -105,10 +179,19 @@ |
| bool success = false; |
| for (int executions = 0; executions < 2; ++executions) { |
| - success = !!ExtTextOut(hdc, x, lineTop, ETO_GLYPH_INDEX, NULL, |
| - reinterpret_cast<const wchar_t*>(&glyphs[0]), |
| - curLen, |
| - &advances[0]); |
| + if (canUseGDI) { |
| + success = !!ExtTextOut(hdc, x, lineTop, ETO_GLYPH_INDEX, NULL, |
| + reinterpret_cast<const wchar_t*>(&glyphs[0]), |
| + curLen, &advances[0]); |
| + } else { |
| + // Skia's text draing origin is the baseline, like WebKit, not |
|
M-A Ruel
2008/12/15 19:54:51
drawing
|
| + // the top, like Windows. |
| + SkPoint origin = { x, point.y() }; |
| + success = PaintSkiaText(context, |
| + font->platformData().hfont(), numGlyphs, |
| + reinterpret_cast<const WORD*>(&glyphs[0]), |
|
M-A Ruel
2008/12/15 19:54:51
80 cols, if you care.
|
| + &advances[0], origin); |
| + } |
| if (!success && executions == 0) { |
| // Ask the browser to load the font for us and retry. |