Skip to content

Commit

Permalink
-webkit-font-smoothing: antialiased should use CG font rendering code…
Browse files Browse the repository at this point in the history
… path, not GDI

https://bugs.webkit.org/show_bug.cgi?id=54004
<rdar://problem/8971429>

Patch by Roger Fong <roger_fong@apple.com> on 2012-08-24
Reviewed by Dan Bernstein.

When specifying -webkit-font-smoothing: antialised; the code path ends up using GDI to draw the text.
GDI ends up drawing subpixel antialiased text, not aliased text anyways.
The CG code path also has the capability of drawing antialiased text. The reason that the GDI path was
used in the first place is no longer a concern here so we can stop using the GDI code path.

* platform/graphics/win/FontCGWin.cpp: Removing GDI font drawing code path.
(WebCore):
(WebCore::Font::drawGlyphs):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@126666 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
webkit-commit-queue committed Aug 25, 2012
1 parent 2c6f924 commit f6f3744
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 175 deletions.
17 changes: 17 additions & 0 deletions Source/WebCore/ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
2012-08-24 Roger Fong <roger_fong@apple.com>

-webkit-font-smoothing: antialiased should use CG font rendering code path, not GDI
https://bugs.webkit.org/show_bug.cgi?id=54004
<rdar://problem/8971429>

Reviewed by Dan Bernstein.

When specifying -webkit-font-smoothing: antialised; the code path ends up using GDI to draw the text.
GDI ends up drawing subpixel antialiased text, not aliased text anyways.
The CG code path also has the capability of drawing antialiased text. The reason that the GDI path was
used in the first place is no longer a concern here so we can stop using the GDI code path.

* platform/graphics/win/FontCGWin.cpp: Removing GDI font drawing code path.
(WebCore):
(WebCore::Font::drawGlyphs):

2012-08-24 Sami Kyostila <skyostil@chromium.org>

Add support for compositing the contents of overflow:scroll areas
Expand Down
175 changes: 0 additions & 175 deletions Source/WebCore/platform/graphics/win/FontCGWin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,176 +127,6 @@ static CGPathRef createPathForGlyph(HDC hdc, Glyph glyph)
return path;
}

static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point)
{
Color fillColor = graphicsContext->fillColor();

bool drawIntoBitmap = false;
TextDrawingModeFlags drawingMode = graphicsContext->textDrawingMode();
if (drawingMode == TextModeFill) {
if (!fillColor.alpha())
return;

drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->isInTransparencyLayer();
if (!drawIntoBitmap) {
FloatSize offset;
float blur;
Color color;
ColorSpace shadowColorSpace;

graphicsContext->getShadow(offset, blur, color, shadowColorSpace);
drawIntoBitmap = offset.width() || offset.height() || blur;
}
}

// We have to convert CG's two-dimensional floating point advances to just horizontal integer advances.
Vector<int, 2048> gdiAdvances;
int totalWidth = 0;
for (int i = 0; i < numGlyphs; i++) {
gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i)));
totalWidth += gdiAdvances[i];
}

HDC hdc = 0;
OwnPtr<GraphicsContext::WindowsBitmap> bitmap;
IntRect textRect;
if (!drawIntoBitmap)
hdc = graphicsContext->getWindowsContext(textRect, true, false);
if (!hdc) {
drawIntoBitmap = true;
// We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
// FIXME: Can get glyphs' optical bounds (even from CG) to get this right.
const FontMetrics& fontMetrics = font->fontMetrics();
int lineGap = fontMetrics.lineGap();
textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
point.y() - fontMetrics.ascent() - lineGap,
totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
fontMetrics.lineSpacing());
bitmap = graphicsContext->createWindowsBitmap(textRect.size());
memset(bitmap->buffer(), 255, bitmap->bufferLength());
hdc = bitmap->hdc();

XFORM xform;
xform.eM11 = 1.0f;
xform.eM12 = 0.0f;
xform.eM21 = 0.0f;
xform.eM22 = 1.0f;
xform.eDx = -textRect.x();
xform.eDy = -textRect.y();
SetWorldTransform(hdc, &xform);
}

SelectObject(hdc, font->platformData().hfont());

// Set the correct color.
if (drawIntoBitmap)
SetTextColor(hdc, RGB(0, 0, 0));
else
SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));

SetBkMode(hdc, TRANSPARENT);
SetTextAlign(hdc, TA_LEFT | TA_BASELINE);

// Uniscribe gives us offsets to help refine the positioning of combining glyphs.
FloatSize translation = glyphBuffer.offsetAt(from);
if (translation.width() || translation.height()) {
XFORM xform;
xform.eM11 = 1.0;
xform.eM12 = 0;
xform.eM21 = 0;
xform.eM22 = 1.0;
xform.eDx = translation.width();
xform.eDy = translation.height();
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
}

if (drawingMode == TextModeFill) {
XFORM xform;
xform.eM11 = 1.0;
xform.eM12 = 0;
xform.eM21 = font->platformData().syntheticOblique() ? -tanf(syntheticObliqueAngle * piFloat / 180.0f) : 0;
xform.eM22 = 1.0;
xform.eDx = point.x();
xform.eDy = point.y();
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
if (font->syntheticBoldOffset()) {
xform.eM21 = 0;
xform.eDx = font->syntheticBoldOffset();
xform.eDy = 0;
ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
}
} else {
XFORM xform;
GetWorldTransform(hdc, &xform);
AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy);
CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity;
if (font->platformData().syntheticOblique())
initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0));
initialGlyphTransform.tx = 0;
initialGlyphTransform.ty = 0;
CGContextRef cgContext = graphicsContext->platformContext();

CGContextSaveGState(cgContext);

BOOL fontSmoothingEnabled = false;
SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0);
CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled);

CGContextScaleCTM(cgContext, 1.0, -1.0);
CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height()));

for (unsigned i = 0; i < numGlyphs; ++i) {
RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i)));
CGContextSaveGState(cgContext);
CGContextConcatCTM(cgContext, initialGlyphTransform);

if (drawingMode & TextModeFill) {
CGContextAddPath(cgContext, glyphPath.get());
CGContextFillPath(cgContext);
if (font->syntheticBoldOffset()) {
CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
CGContextAddPath(cgContext, glyphPath.get());
CGContextFillPath(cgContext);
CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
}
}
if (drawingMode & TextModeStroke) {
CGContextAddPath(cgContext, glyphPath.get());
CGContextStrokePath(cgContext);
if (font->syntheticBoldOffset()) {
CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
CGContextAddPath(cgContext, glyphPath.get());
CGContextStrokePath(cgContext);
CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
}
}

CGContextRestoreGState(cgContext);
CGContextTranslateCTM(cgContext, gdiAdvances[i], 0);
}

CGContextRestoreGState(cgContext);
}

if (drawIntoBitmap) {
UInt8* buffer = bitmap->buffer();
unsigned bufferLength = bitmap->bufferLength();
for (unsigned i = 0; i < bufferLength; i += 4) {
// Use green, which is always in the middle.
UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255;
buffer[i] = fillColor.blue();
buffer[i + 1] = fillColor.green();
buffer[i + 2] = fillColor.red();
buffer[i + 3] = alpha;
}
graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location());
} else
graphicsContext->releaseWindowsContext(hdc, textRect, true, false);
}

void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
int from, int numGlyphs, const FloatPoint& point) const
{
Expand Down Expand Up @@ -327,11 +157,6 @@ void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* fo
ASSERT_NOT_REACHED();
}

if (font->platformData().useGDI() && !shouldUseFontSmoothing) {
drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
return;
}

uint32_t oldFontSmoothingStyle = wkSetFontSmoothingStyle(cgContext, shouldUseFontSmoothing);

const FontPlatformData& platformData = font->platformData();
Expand Down

0 comments on commit f6f3744

Please sign in to comment.