Show
Ignore:
Timestamp:
03/26/08 21:02:07 (8 months ago)
Author:
mitz@apple.com
Message:

Reviewed by Dave Hyatt.

  • maintain subpixel-antialiasing when drawing text with a simple shadow
  • platform/graphics/mac/FontMac.mm: (WebCore::Font::drawComplexText): If the shadow has a zero blur radius, draw the shadow by drawing the text at an offset instead of relying on Core Graphics shadows. (WebCore::Font::drawGlyphs): Ditto.
  • platform/graphics/win/FontCGWin.cpp: (WebCore::Font::drawGlyphs): Ditto.
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/platform/graphics/mac/FontMac.mm

    r31322 r31356  
    528528    // ATSUI can't draw beyond -32768 to +32767 so we translate the CTM and tell ATSUI to draw at (0, 0). 
    529529    CGContextRef context = graphicsContext->platformContext(); 
    530  
    531530    CGContextTranslateCTM(context, point.x(), point.y()); 
     531 
     532    IntSize shadowSize; 
     533    int shadowBlur; 
     534    Color shadowColor; 
     535    graphicsContext->getShadow(shadowSize, shadowBlur, shadowColor); 
     536 
     537    bool hasSimpleShadow = graphicsContext->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur && !shadowSize.isEmpty(); 
     538    if (hasSimpleShadow) { 
     539        // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing. 
     540        graphicsContext->clearShadow(); 
     541        Color fillColor = graphicsContext->fillColor(); 
     542        Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); 
     543        graphicsContext->setFillColor(shadowFillColor); 
     544        CGContextTranslateCTM(context, shadowSize.width(), shadowSize.height()); 
     545        status = ATSUDrawText(params.m_layout, from, drawPortionLength, 0, 0); 
     546        if (status == noErr && params.m_hasSyntheticBold) { 
     547            // Force relayout for the bold pass 
     548            ATSUClearLayoutCache(params.m_layout, 0); 
     549            params.m_syntheticBoldPass = true; 
     550            status = ATSUDrawText(params.m_layout, from, drawPortionLength, 0, 0); 
     551            // Force relayout for the next pass 
     552            ATSUClearLayoutCache(params.m_layout, 0); 
     553            params.m_syntheticBoldPass = false; 
     554        } 
     555        CGContextTranslateCTM(context, -shadowSize.width(), -shadowSize.height()); 
     556        graphicsContext->setFillColor(fillColor); 
     557    } 
     558 
    532559    status = ATSUDrawText(params.m_layout, from, drawPortionLength, 0, 0); 
    533560    if (status == noErr && params.m_hasSyntheticBold) { 
     
    542569        // Nothing to do but report the error (dev build only). 
    543570        LOG_ERROR("ATSUDrawText() failed(%d)", status); 
     571 
     572    if (hasSimpleShadow) 
     573        graphicsContext->setShadow(shadowSize, shadowBlur, shadowColor); 
    544574 
    545575    disposeATSULayoutParameters(&params); 
     
    645675    } else 
    646676        CGContextSetFontSize(cgContext, platformData.m_size); 
    647      
     677 
     678    IntSize shadowSize; 
     679    int shadowBlur; 
     680    Color shadowColor; 
     681    context->getShadow(shadowSize, shadowBlur, shadowColor); 
     682 
     683    bool hasSimpleShadow = context->textDrawingMode() == cTextFill && shadowColor.isValid() && !shadowBlur && !shadowSize.isEmpty(); 
     684    if (hasSimpleShadow) { 
     685        // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing. 
     686        context->clearShadow(); 
     687        Color fillColor = context->fillColor(); 
     688        Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255); 
     689        context->setFillColor(shadowFillColor); 
     690        CGContextSetTextPosition(cgContext, point.x() + shadowSize.width(), point.y() + shadowSize.height()); 
     691        CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); 
     692        if (font->m_syntheticBoldOffset) { 
     693            CGContextSetTextPosition(cgContext, point.x() + shadowSize.width() + font->m_syntheticBoldOffset, point.y() + shadowSize.height()); 
     694            CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); 
     695        } 
     696        context->setFillColor(fillColor); 
     697    } 
     698 
    648699    CGContextSetTextPosition(cgContext, point.x(), point.y()); 
    649700    CGContextShowGlyphsWithAdvances(cgContext, glyphBuffer.glyphs(from), glyphBuffer.advances(from), numGlyphs); 
     
    653704    } 
    654705 
     706    if (hasSimpleShadow) 
     707        context->setShadow(shadowSize, shadowBlur, shadowColor); 
     708 
    655709    if (originalShouldUseFontSmoothing != newShouldUseFontSmoothing) 
    656710        CGContextSetShouldSmoothFonts(cgContext, originalShouldUseFontSmoothing);