bool windowsCanHandleTextDrawing(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() != cTextFill) return false; // Check for gradients. if (context->fillGradient() || context->strokeGradient()) return false; // Check for patterns. if (context->fillPattern() || context->strokePattern()) return false; // Check for shadow effects. if (context->platformContext()->getDrawLooper() && (!windowsCanHandleDrawTextShadow(context))) return false; return true; }
void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { SkColor color = graphicsContext->platformContext()->effectiveFillColor(); unsigned char alpha = SkColorGetA(color); // Skip 100% transparent text; no need to draw anything. if (!alpha && graphicsContext->platformContext()->getStrokeStyle() == NoStroke && !graphicsContext->hasShadow()) return; if (!alpha || windowsCanHandleDrawTextShadow(graphicsContext) || !windowsCanHandleTextDrawingWithoutShadow(graphicsContext)) { drawGlyphsWin(graphicsContext, font, glyphBuffer, from, numGlyphs, point); return; } // Draw in two passes: skia for the shadow, GDI for foreground text // pass1: shadow (will use skia) graphicsContext->save(); graphicsContext->setFillColor(Color::transparent, graphicsContext->fillColorSpace()); drawGlyphsWin(graphicsContext, font, glyphBuffer, from, numGlyphs, point); graphicsContext->restore(); // pass2: foreground text (will use GDI) FloatSize shadowOffset; float shadowBlur; Color shadowColor; ColorSpace shadowColorSpace; graphicsContext->getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace); graphicsContext->setShadow(shadowOffset, shadowBlur, Color::transparent, shadowColorSpace); drawGlyphsWin(graphicsContext, font, glyphBuffer, from, numGlyphs, point); graphicsContext->setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace); }
bool windowsCanHandleTextDrawing(GraphicsContext* context) { if (!windowsCanHandleTextDrawingWithoutShadow(context)) return false; // Check for shadow effects. if (!windowsCanHandleDrawTextShadow(context)) return false; return true; }
void Font::drawComplexText(GraphicsContext* graphicsContext, const TextRun& run, const FloatPoint& point, int from, int to) const { PlatformGraphicsContext* context = graphicsContext->platformContext(); UniscribeHelperTextRun state(run, *this); SkColor color = graphicsContext->platformContext()->effectiveFillColor(); unsigned char alpha = SkColorGetA(color); // Skip 100% transparent text; no need to draw anything. 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. IntSize shadowSize; int shadowBlur; Color shadowColor; if (graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor) && 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()) + shadowSize.width(), static_cast<int>(point.y() - ascent()) + shadowSize.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. state.draw(graphicsContext, hdc, static_cast<int>(point.x()), static_cast<int>(point.y() - ascent()), from, to); context->canvas()->endPlatformPaint(); }