bool FontPlatformData::fontContainsCharacter(UChar32 character) { SkPaint paint; setupPaint(&paint); paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); uint16_t glyph; paint.textToGlyphs(&character, sizeof(character), &glyph); return glyph; }
bool SkDrawPaint::getProperty(int index, SkScriptValue* value) const { SkPaint::FontMetrics metrics; SkPaint paint; setupPaint(&paint); paint.getFontMetrics(&metrics); switch (index) { case SK_PROPERTY(ascent): value->fOperand.fScalar = metrics.fAscent; break; case SK_PROPERTY(descent): value->fOperand.fScalar = metrics.fDescent; break; // should consider returning fLeading as well (or roll it into ascent/descent somehow default: SkASSERT(0); return false; } value->fType = SkType_Float; return true; }
void SkDrawPaint::executeFunction(SkDisplayable* target, int index, SkTDArray<SkScriptValue>& parameters, SkDisplayTypes type, SkScriptValue* scriptValue) { if (scriptValue == NULL) return; SkASSERT(target == this); switch (index) { case SK_FUNCTION(measureText): { SkASSERT(parameters.count() == 1); SkASSERT(type == SkType_Float); SkPaint paint; setupPaint(&paint); scriptValue->fType = SkType_Float; SkASSERT(parameters[0].fType == SkType_String); scriptValue->fOperand.fScalar = paint.measureText(parameters[0].fOperand.fString->c_str(), parameters[0].fOperand.fString->size()); // SkDebugf("measureText: %s = %g\n", parameters[0].fOperand.fString->c_str(), // scriptValue->fOperand.fScalar / 65536.0f); } break; default: SkASSERT(0); } }
bool SkDrawPaint::draw(SkAnimateMaker& maker) { SkPaint* paint = maker.fPaint; setupPaint(paint); return false; }
// 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 void Font::drawGlyphs(GraphicsContext* gc, const SimpleFontData* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const { COMPILE_ASSERT(sizeof(GlyphBufferGlyph) == sizeof(uint16_t), GlyphBufferGlyphSize_equals_uint16_t); 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: // For the AutoSmooth case, don't do anything! Keep the default settings. break; } if (!shouldUseSmoothing() || PlatformSupport::layoutTestMode()) shouldSmoothFonts = false; const GlyphBufferGlyph* 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()); // 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. const GlyphBufferAdvance* adv = glyphBuffer.advances(from); SkAutoSTMalloc<32, SkPoint> storage(numGlyphs); SkPoint* pos = storage.get(); for (int i = 0; i < numGlyphs; i++) { pos[i].set(x, y); x += SkFloatToScalar(adv[i].width); y += SkFloatToScalar(adv[i].height); } SkCanvas* canvas = gc->platformContext()->canvas(); if (font->platformData().orientation() == Vertical) { canvas->save(); canvas->rotate(-90); SkMatrix rotator; rotator.reset(); rotator.setRotate(90); rotator.mapPoints(pos, numGlyphs); } TextDrawingModeFlags textMode = gc->platformContext()->getTextDrawingMode(); // We draw text up to two times (once for fill, once for stroke). if (textMode & TextModeFill) { SkPaint paint; gc->platformContext()->setupPaintForFilling(&paint); setupPaint(&paint, font, this, shouldAntialias, shouldSmoothFonts); gc->platformContext()->adjustTextRenderMode(&paint); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint); } if ((textMode & TextModeStroke) && gc->platformContext()->getStrokeStyle() != NoStroke && gc->platformContext()->getStrokeThickness() > 0) { SkPaint paint; gc->platformContext()->setupPaintForStroking(&paint, 0, 0); setupPaint(&paint, font, this, shouldAntialias, shouldSmoothFonts); gc->platformContext()->adjustTextRenderMode(&paint); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); if (textMode & TextModeFill) { // If we also filled, we don't want to draw shadows twice. // See comment in FontChromiumWin.cpp::paintSkiaText() for more details. paint.setLooper(0); } canvas->drawPosText(glyphs, numGlyphs * sizeof(uint16_t), pos, paint); } if (font->platformData().orientation() == Vertical) canvas->restore(); }