Source/platform/fonts/mac/FontMac.cpp
// TODO: This needs to be split into helper functions to better scope the
// inputs/outputs, and reduce duplicate code.
// This issue is tracked in https://bugs.webkit.org/show_bug.cgi?id=62989
This needs to be split into helper functions to better scope the
inputs/outputs, and reduce duplicate code.
This needs to be split into helper functions to better scope the inputs / outputs and reduce duplicate code .
void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font,
    const GlyphBuffer& glyphBuffer, unsigned from, unsigned numGlyphs,
    const FloatPoint& point, const FloatRect& textRect) const
{
    bool shouldSmoothFonts = true;
    bool shouldAntialias = true;
    switch (fontDescription().fontSmoothing()) {
    case Antialiased:
        shouldSmoothFonts = false;
        break;
    case SubpixelAntialiased:
        break;
    case NoSmoothing:
        shouldAntialias = false;
        shouldSmoothFonts = false;
        break;
    case AutoSmoothing:
        break;
    }
    if (isRunningLayoutTest()) {
        shouldSmoothFonts = false;
        shouldAntialias = shouldAntialias && isFontAntialiasingEnabledForTest();
    }
    const Glyph* glyphs = glyphBuffer.glyphs(from);
    SkScalar x = SkFloatToScalar(point.x());
    SkScalar y = SkFloatToScalar(point.y());
    if (font->platformData().orientation() == Vertical)
        y += SkFloatToScalar(font->fontMetrics().floatAscent(IdeographicBaseline) - font->fontMetrics().floatAscent());
    const FloatSize* adv = glyphBuffer.advances(from);
    SkAutoSTMalloc<32, SkPoint> storage(numGlyphs);
    SkPoint* pos = storage.get();
    for (unsigned i = 0; i < numGlyphs; i++) {
        pos[i].set(x, y);
        x += SkFloatToScalar(adv[i].width());
        y += SkFloatToScalar(adv[i].height());
    }
    if (font->platformData().orientation() == Vertical) {
        gc->save();
        gc->rotate(-0.5 * SK_ScalarPI);
        SkMatrix rotator;
        rotator.reset();
        rotator.setRotate(90);
        rotator.mapPoints(pos, numGlyphs);
    }
    TextDrawingModeFlags textMode = gc->textDrawingMode();
    if (textMode & TextModeFill) {
        SkPaint paint = gc->fillPaint();
        setupPaint(&paint, font, this, shouldAntialias, shouldSmoothFonts);
        gc->adjustTextRenderMode(&paint);
        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
        gc->drawPosText(glyphs, numGlyphs * sizeof(Glyph), pos, textRect, paint);
    }
    if ((textMode & TextModeStroke)
        && gc->strokeStyle() != NoStroke
        && gc->strokeThickness() > 0) {
        SkPaint paint = gc->strokePaint();
        setupPaint(&paint, font, this, shouldAntialias, shouldSmoothFonts);
        gc->adjustTextRenderMode(&paint);
        paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
        if (textMode & TextModeFill) {
            paint.setLooper(0);
        }
        gc->drawPosText(glyphs, numGlyphs * sizeof(Glyph), pos, textRect, paint);
    }
    if (font->platformData().orientation() == Vertical)
        gc->restore();
}
void Font :: drawGlyphs ( GraphicsContext * gc , const SimpleFontData * font , const GlyphBuffer & glyphBuffer , unsigned from , unsigned numGlyphs , const FloatPoint & point , const FloatRect & textRect ) const { bool shouldSmoothFonts = true ; bool shouldAntialias = true ; switch ( fontDescription ( ) . fontSmoothing ( ) ) { case Antialiased : shouldSmoothFonts = false ; break ; case SubpixelAntialiased : break ; case NoSmoothing : shouldAntialias = false ; shouldSmoothFonts = false ; break ; case AutoSmoothing : break ; } if ( isRunningLayoutTest ( ) ) { shouldSmoothFonts = false ; shouldAntialias = shouldAntialias && isFontAntialiasingEnabledForTest ( ) ; } const Glyph * glyphs = glyphBuffer . glyphs ( from ) ; SkScalar x = SkFloatToScalar ( point . x ( ) ) ; SkScalar y = SkFloatToScalar ( point . y ( ) ) ; if ( font -> platformData ( ) . orientation ( ) == Vertical ) y += SkFloatToScalar ( font -> fontMetrics ( ) . floatAscent ( IdeographicBaseline ) - font -> fontMetrics ( ) . floatAscent ( ) ) ; const FloatSize * adv = glyphBuffer . advances ( from ) ; SkAutoSTMalloc < 32 , SkPoint > storage ( numGlyphs ) ; SkPoint * pos = storage . get ( ) ; for ( unsigned i = 0 ; i < numGlyphs ; i ++ ) { pos [ i ] . set ( x , y ) ; x += SkFloatToScalar ( adv [ i ] . width ( ) ) ; y += SkFloatToScalar ( adv [ i ] . height ( ) ) ; } if ( font -> platformData ( ) . orientation ( ) == Vertical ) { gc -> save ( ) ; gc -> rotate ( -0.5 * SK_ScalarPI ) ; SkMatrix rotator ; rotator . reset ( ) ; rotator . setRotate ( 90 ) ; rotator . mapPoints ( pos , numGlyphs ) ; } TextDrawingModeFlags textMode = gc -> textDrawingMode ( ) ; if ( textMode & TextModeFill ) { SkPaint paint = gc -> fillPaint ( ) ; setupPaint ( & paint , font , this , shouldAntialias , shouldSmoothFonts ) ; gc -> adjustTextRenderMode ( & paint ) ; paint . setTextEncoding ( SkPaint :: kGlyphID_TextEncoding ) ; gc -> drawPosText ( glyphs , numGlyphs * sizeof ( Glyph ) , pos , textRect , paint ) ; } if ( ( textMode & TextModeStroke ) && gc -> strokeStyle ( ) != NoStroke && gc -> strokeThickness ( ) > 0 ) { SkPaint paint = gc -> strokePaint ( ) ; setupPaint ( & paint , font , this , shouldAntialias , shouldSmoothFonts ) ; gc -> adjustTextRenderMode ( & paint ) ; paint . setTextEncoding ( SkPaint :: kGlyphID_TextEncoding ) ; if ( textMode & TextModeFill ) { paint . setLooper ( 0 ) ; } gc -> drawPosText ( glyphs , numGlyphs * sizeof ( Glyph ) , pos , textRect , paint ) ; } if ( font -> platformData ( ) . orientation ( ) == Vertical ) gc -> restore ( ) ; }
TODO: This needs to be split into helper functions to better scope the
inputs/outputs, and reduce duplicate code.
TODO : This needs to be split into helper functions to better scope the inputs / outputs and reduce duplicate code .
// For the AutoSmooth case, don't do anything! Keep the default settings. // FIXME: text rendering speed: // Android has code in their WebCore fork to special case when the // GlyphBuffer has no advances other than the defaults. In that case the // text drawing can proceed faster. However, it's unclear when those // patches may be upstreamed to WebKit so we always use the slower path // here. // We draw text up to two times (once for fill, once for stroke). // If we also filled, we don't want to draw shadows twice. // See comment in FontHarfBuzz.cpp::paintGlyphs() for more details.