Changeset 126666 in webkit


Ignore:
Timestamp:
Aug 24, 2012 5:50:05 PM (12 years ago)
Author:
commit-queue@webkit.org
Message:

-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>

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):

Location:
trunk/Source/WebCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r126663 r126666  
     12012-08-24  Roger Fong  <roger_fong@apple.com>
     2
     3        -webkit-font-smoothing: antialiased should use CG font rendering code path, not GDI
     4        https://bugs.webkit.org/show_bug.cgi?id=54004
     5        <rdar://problem/8971429>
     6
     7        Reviewed by Dan Bernstein.
     8
     9        When specifying -webkit-font-smoothing: antialised; the code path ends up using GDI to draw the text.
     10        GDI ends up drawing subpixel antialiased text, not aliased text anyways.
     11        The CG code path also has the capability of drawing antialiased text. The reason that the GDI path was
     12        used in the first place is no longer a concern here so we can stop using the GDI code path.
     13
     14        * platform/graphics/win/FontCGWin.cpp: Removing GDI font drawing code path.
     15        (WebCore):
     16        (WebCore::Font::drawGlyphs):
     17
    1182012-08-24  Sami Kyostila  <skyostil@chromium.org>
    219
  • trunk/Source/WebCore/platform/graphics/win/FontCGWin.cpp

    r94897 r126666  
    128128}
    129129
    130 static void drawGDIGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
    131                       int from, int numGlyphs, const FloatPoint& point)
    132 {
    133     Color fillColor = graphicsContext->fillColor();
    134 
    135     bool drawIntoBitmap = false;
    136     TextDrawingModeFlags drawingMode = graphicsContext->textDrawingMode();
    137     if (drawingMode == TextModeFill) {
    138         if (!fillColor.alpha())
    139             return;
    140 
    141         drawIntoBitmap = fillColor.alpha() != 255 || graphicsContext->isInTransparencyLayer();
    142         if (!drawIntoBitmap) {
    143             FloatSize offset;
    144             float blur;
    145             Color color;
    146             ColorSpace shadowColorSpace;
    147 
    148             graphicsContext->getShadow(offset, blur, color, shadowColorSpace);
    149             drawIntoBitmap = offset.width() || offset.height() || blur;
    150         }
    151     }
    152 
    153     // We have to convert CG's two-dimensional floating point advances to just horizontal integer advances.
    154     Vector<int, 2048> gdiAdvances;
    155     int totalWidth = 0;
    156     for (int i = 0; i < numGlyphs; i++) {
    157         gdiAdvances.append(lroundf(glyphBuffer.advanceAt(from + i)));
    158         totalWidth += gdiAdvances[i];
    159     }
    160 
    161     HDC hdc = 0;
    162     OwnPtr<GraphicsContext::WindowsBitmap> bitmap;
    163     IntRect textRect;
    164     if (!drawIntoBitmap)
    165         hdc = graphicsContext->getWindowsContext(textRect, true, false);
    166     if (!hdc) {
    167         drawIntoBitmap = true;
    168         // We put slop into this rect, since glyphs can overflow the ascent/descent bounds and the left/right edges.
    169         // FIXME: Can get glyphs' optical bounds (even from CG) to get this right.
    170         const FontMetrics& fontMetrics = font->fontMetrics();
    171         int lineGap = fontMetrics.lineGap();
    172         textRect = IntRect(point.x() - (fontMetrics.ascent() + fontMetrics.descent()) / 2,
    173                            point.y() - fontMetrics.ascent() - lineGap,
    174                            totalWidth + fontMetrics.ascent() + fontMetrics.descent(),
    175                            fontMetrics.lineSpacing());
    176         bitmap = graphicsContext->createWindowsBitmap(textRect.size());
    177         memset(bitmap->buffer(), 255, bitmap->bufferLength());
    178         hdc = bitmap->hdc();
    179 
    180         XFORM xform;
    181         xform.eM11 = 1.0f;
    182         xform.eM12 = 0.0f;
    183         xform.eM21 = 0.0f;
    184         xform.eM22 = 1.0f;
    185         xform.eDx = -textRect.x();
    186         xform.eDy = -textRect.y();
    187         SetWorldTransform(hdc, &xform);
    188     }
    189 
    190     SelectObject(hdc, font->platformData().hfont());
    191 
    192     // Set the correct color.
    193     if (drawIntoBitmap)
    194         SetTextColor(hdc, RGB(0, 0, 0));
    195     else
    196         SetTextColor(hdc, RGB(fillColor.red(), fillColor.green(), fillColor.blue()));
    197 
    198     SetBkMode(hdc, TRANSPARENT);
    199     SetTextAlign(hdc, TA_LEFT | TA_BASELINE);
    200 
    201     // Uniscribe gives us offsets to help refine the positioning of combining glyphs.
    202     FloatSize translation = glyphBuffer.offsetAt(from);
    203     if (translation.width() || translation.height()) {
    204         XFORM xform;
    205         xform.eM11 = 1.0;
    206         xform.eM12 = 0;
    207         xform.eM21 = 0;
    208         xform.eM22 = 1.0;
    209         xform.eDx = translation.width();
    210         xform.eDy = translation.height();
    211         ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
    212     }
    213 
    214     if (drawingMode == TextModeFill) {
    215         XFORM xform;
    216         xform.eM11 = 1.0;
    217         xform.eM12 = 0;
    218         xform.eM21 = font->platformData().syntheticOblique() ? -tanf(syntheticObliqueAngle * piFloat / 180.0f) : 0;
    219         xform.eM22 = 1.0;
    220         xform.eDx = point.x();
    221         xform.eDy = point.y();
    222         ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
    223         ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
    224         if (font->syntheticBoldOffset()) {
    225             xform.eM21 = 0;
    226             xform.eDx = font->syntheticBoldOffset();
    227             xform.eDy = 0;
    228             ModifyWorldTransform(hdc, &xform, MWT_LEFTMULTIPLY);
    229             ExtTextOut(hdc, 0, 0, ETO_GLYPH_INDEX, 0, reinterpret_cast<const WCHAR*>(glyphBuffer.glyphs(from)), numGlyphs, gdiAdvances.data());
    230         }
    231     } else {
    232         XFORM xform;
    233         GetWorldTransform(hdc, &xform);
    234         AffineTransform hdcTransform(xform.eM11, xform.eM21, xform.eM12, xform.eM22, xform.eDx, xform.eDy);
    235         CGAffineTransform initialGlyphTransform = hdcTransform.isInvertible() ? hdcTransform.inverse() : CGAffineTransformIdentity;
    236         if (font->platformData().syntheticOblique())
    237             initialGlyphTransform = CGAffineTransformConcat(initialGlyphTransform, CGAffineTransformMake(1, 0, tanf(syntheticObliqueAngle * piFloat / 180.0f), 1, 0, 0));
    238         initialGlyphTransform.tx = 0;
    239         initialGlyphTransform.ty = 0;
    240         CGContextRef cgContext = graphicsContext->platformContext();
    241 
    242         CGContextSaveGState(cgContext);
    243 
    244         BOOL fontSmoothingEnabled = false;
    245         SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &fontSmoothingEnabled, 0);
    246         CGContextSetShouldAntialias(cgContext, fontSmoothingEnabled);
    247 
    248         CGContextScaleCTM(cgContext, 1.0, -1.0);
    249         CGContextTranslateCTM(cgContext, point.x() + glyphBuffer.offsetAt(from).width(), -(point.y() + glyphBuffer.offsetAt(from).height()));
    250 
    251         for (unsigned i = 0; i < numGlyphs; ++i) {
    252             RetainPtr<CGPathRef> glyphPath(AdoptCF, createPathForGlyph(hdc, glyphBuffer.glyphAt(from + i)));
    253             CGContextSaveGState(cgContext);
    254             CGContextConcatCTM(cgContext, initialGlyphTransform);
    255 
    256             if (drawingMode & TextModeFill) {
    257                 CGContextAddPath(cgContext, glyphPath.get());
    258                 CGContextFillPath(cgContext);
    259                 if (font->syntheticBoldOffset()) {
    260                     CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
    261                     CGContextAddPath(cgContext, glyphPath.get());
    262                     CGContextFillPath(cgContext);
    263                     CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
    264                 }
    265             }
    266             if (drawingMode & TextModeStroke) {
    267                 CGContextAddPath(cgContext, glyphPath.get());
    268                 CGContextStrokePath(cgContext);
    269                 if (font->syntheticBoldOffset()) {
    270                     CGContextTranslateCTM(cgContext, font->syntheticBoldOffset(), 0);
    271                     CGContextAddPath(cgContext, glyphPath.get());
    272                     CGContextStrokePath(cgContext);
    273                     CGContextTranslateCTM(cgContext, -font->syntheticBoldOffset(), 0);
    274                 }
    275             }
    276 
    277             CGContextRestoreGState(cgContext);
    278             CGContextTranslateCTM(cgContext, gdiAdvances[i], 0);
    279         }
    280 
    281         CGContextRestoreGState(cgContext);
    282     }
    283 
    284     if (drawIntoBitmap) {
    285         UInt8* buffer = bitmap->buffer();
    286         unsigned bufferLength = bitmap->bufferLength();
    287         for (unsigned i = 0; i < bufferLength; i += 4) {
    288             // Use green, which is always in the middle.
    289             UInt8 alpha = (255 - buffer[i + 1]) * fillColor.alpha() / 255;
    290             buffer[i] = fillColor.blue();
    291             buffer[i + 1] = fillColor.green();
    292             buffer[i + 2] = fillColor.red();
    293             buffer[i + 3] = alpha;
    294         }
    295         graphicsContext->drawWindowsBitmap(bitmap.get(), textRect.location());
    296     } else
    297         graphicsContext->releaseWindowsContext(hdc, textRect, true, false);
    298 }
    299 
    300130void Font::drawGlyphs(GraphicsContext* graphicsContext, const SimpleFontData* font, const GlyphBuffer& glyphBuffer,
    301131                      int from, int numGlyphs, const FloatPoint& point) const
     
    326156    default:
    327157        ASSERT_NOT_REACHED();
    328     }
    329 
    330     if (font->platformData().useGDI() && !shouldUseFontSmoothing) {
    331         drawGDIGlyphs(graphicsContext, font, glyphBuffer, from, numGlyphs, point);
    332         return;
    333158    }
    334159
Note: See TracChangeset for help on using the changeset viewer.