sk_sp<SkFont> SkFont::Testing_CreateFromPaint(const SkPaint& paint) { uint32_t flags = 0; if (paint.isVerticalText()) { flags |= kVertical_Flag; } if (paint.isEmbeddedBitmapText()) { flags |= kEmbeddedBitmaps_Flag; } if (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) { flags |= kGenA8FromLCD_Flag; } if (paint.isFakeBoldText()) { flags |= kEmbolden_Flag; } if (SkPaint::kFull_Hinting == paint.getHinting()) { flags |= kEnableByteCodeHints_Flag; } if (paint.isAutohinted()) { flags |= kEnableAutoHints_Flag; } if (paint.isSubpixelText() || paint.isLinearText()) { // this is our default } else { flags |= kUseNonlinearMetrics_Flag; } MaskType maskType = SkFont::kBW_MaskType; if (paint.isAntiAlias()) { maskType = paint.isLCDRenderText() ? kLCD_MaskType : kA8_MaskType; } return Make(sk_ref_sp(paint.getTypeface()), paint.getTextSize(), paint.getTextScaleX(), paint.getTextSkewX(), maskType, flags); }
uint32_t GrTextUtils::FilterTextFlags(const SkSurfaceProps& surfaceProps, const SkPaint& paint) { uint32_t flags = paint.getFlags(); if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { return flags; } if (kUnknown_SkPixelGeometry == surfaceProps.pixelGeometry() || ShouldDisableLCD(paint)) { flags &= ~SkPaint::kLCDRenderText_Flag; flags |= SkPaint::kGenA8FromLCD_Flag; } return flags; }
uint32_t SkBaseDevice::filterTextFlags(const SkPaint& paint) const { uint32_t flags = paint.getFlags(); if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { return flags; } if (kUnknown_SkPixelGeometry == fSurfaceProps.pixelGeometry() || this->onShouldDisableLCD(paint)) { flags &= ~SkPaint::kLCDRenderText_Flag; flags |= SkPaint::kGenA8FromLCD_Flag; } return flags; }
bool SkBitmapDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { if (!paint.isLCDRenderText() || !paint.isAntiAlias()) { // we're cool with the paint as is return false; } if (kN32_SkColorType != fBitmap.colorType() || paint.getRasterizer() || paint.getPathEffect() || paint.isFakeBoldText() || paint.getStyle() != SkPaint::kFill_Style || !SkXfermode::IsMode(paint.getXfermode(), SkXfermode::kSrcOver_Mode)) { // turn off lcd flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag; flags->fHinting = paint.getHinting(); return true; } // we're cool with the paint as is return false; }
String LoggingCanvas::stringForSkPaintFlags(const SkPaint& paint) { if (!paint.getFlags()) return "none"; String flagsString = ""; appendFlagToString(&flagsString, paint.isAntiAlias(), "AntiAlias"); appendFlagToString(&flagsString, paint.isDither(), "Dither"); appendFlagToString(&flagsString, paint.isUnderlineText(), "UnderlinText"); appendFlagToString(&flagsString, paint.isStrikeThruText(), "StrikeThruText"); appendFlagToString(&flagsString, paint.isFakeBoldText(), "FakeBoldText"); appendFlagToString(&flagsString, paint.isLinearText(), "LinearText"); appendFlagToString(&flagsString, paint.isSubpixelText(), "SubpixelText"); appendFlagToString(&flagsString, paint.isDevKernText(), "DevKernText"); appendFlagToString(&flagsString, paint.isLCDRenderText(), "LCDRenderText"); appendFlagToString(&flagsString, paint.isEmbeddedBitmapText(), "EmbeddedBitmapText"); appendFlagToString(&flagsString, paint.isAutohinted(), "Autohinted"); appendFlagToString(&flagsString, paint.isVerticalText(), "VerticalText"); appendFlagToString(&flagsString, paint.getFlags() & SkPaint::kGenA8FromLCD_Flag, "GenA8FromLCD"); return flagsString; }
static void cgSetPaintForText(CGContextRef cg, const SkPaint& paint) { SkColor c = paint.getColor(); CGFloat rgba[] = { SkColorGetB(c) / 255.0f, SkColorGetG(c) / 255.0f, SkColorGetR(c) / 255.0f, SkColorGetA(c) / 255.0f, }; CGContextSetRGBFillColor(cg, rgba[0], rgba[1], rgba[2], rgba[3]); CGContextSetTextDrawingMode(cg, kCGTextFill); CGContextSetFont(cg, typefaceToCGFont(paint.getTypeface())); CGContextSetFontSize(cg, SkScalarToFloat(paint.getTextSize())); CGContextSetAllowsFontSubpixelPositioning(cg, paint.isSubpixelText()); CGContextSetShouldSubpixelPositionFonts(cg, paint.isSubpixelText()); CGContextSetShouldAntialias(cg, paint.isAntiAlias()); CGContextSetShouldSmoothFonts(cg, paint.isLCDRenderText()); }
bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) { if (!paint.isLCDRenderText()) { // we're cool with the paint as is return false; } if (SkBitmap::kARGB_8888_Config != fBitmap.config() || paint.getShader() || paint.getXfermode() || // unless its srcover paint.getMaskFilter() || paint.getRasterizer() || paint.getColorFilter() || paint.getPathEffect() || paint.isFakeBoldText() || paint.getStyle() != SkPaint::kFill_Style) { // turn off lcd flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag; flags->fHinting = paint.getHinting(); return true; } // we're cool with the paint as is return false; }
void GrTextUtils::DrawDFPosText(GrAtlasTextBlob* blob, int runIndex, GrBatchFontCache* fontCache, const SkSurfaceProps& props, const SkPaint& origPaint, GrColor color, const SkMatrix& viewMatrix, const char text[], size_t byteLength, const SkScalar pos[], int scalarsPerPosition, const SkPoint& offset) { SkASSERT(byteLength == 0 || text != nullptr); SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); // nothing to draw if (text == nullptr || byteLength == 0) { return; } SkTDArray<char> fallbackTxt; SkTDArray<SkScalar> fallbackPos; // Setup distance field paint and text ratio SkScalar textRatio; SkPaint dfPaint(origPaint); GrTextUtils::InitDistanceFieldPaint(blob, &dfPaint, &textRatio, viewMatrix); blob->setHasDistanceField(); blob->setSubRunHasDistanceFields(runIndex, origPaint.isLCDRenderText()); GrBatchTextStrike* currStrike = nullptr; SkGlyphCache* cache = blob->setupCache(runIndex, props, SkPaint::FakeGamma::Off, dfPaint, nullptr); SkPaint::GlyphCacheProc glyphCacheProc = dfPaint.getGlyphCacheProc(true); GrFontScaler* fontScaler = GrTextUtils::GetGrFontScaler(cache); const char* stop = text + byteLength; if (SkPaint::kLeft_Align == dfPaint.getTextAlign()) { while (text < stop) { const char* lastText = text; // the last 2 parameters are ignored const SkGlyph& glyph = glyphCacheProc(cache, &text); if (glyph.fWidth) { SkScalar x = offset.x() + pos[0]; SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0); if (!DfAppendGlyph(blob, runIndex, fontCache, &currStrike, glyph, x, y, color, fontScaler, textRatio, viewMatrix)) { // couldn't append, send to fallback fallbackTxt.append(SkToInt(text-lastText), lastText); *fallbackPos.append() = pos[0]; if (2 == scalarsPerPosition) { *fallbackPos.append() = pos[1]; } } } pos += scalarsPerPosition; } } else { SkScalar alignMul = SkPaint::kCenter_Align == dfPaint.getTextAlign() ? SK_ScalarHalf : SK_Scalar1; while (text < stop) { const char* lastText = text; // the last 2 parameters are ignored const SkGlyph& glyph = glyphCacheProc(cache, &text); if (glyph.fWidth) { SkScalar x = offset.x() + pos[0]; SkScalar y = offset.y() + (2 == scalarsPerPosition ? pos[1] : 0); SkScalar advanceX = SkFixedToScalar(glyph.fAdvanceX) * alignMul * textRatio; SkScalar advanceY = SkFixedToScalar(glyph.fAdvanceY) * alignMul * textRatio; if (!DfAppendGlyph(blob, runIndex, fontCache, &currStrike, glyph, x - advanceX, y - advanceY, color, fontScaler, textRatio, viewMatrix)) { // couldn't append, send to fallback fallbackTxt.append(SkToInt(text-lastText), lastText); *fallbackPos.append() = pos[0]; if (2 == scalarsPerPosition) { *fallbackPos.append() = pos[1]; } } } pos += scalarsPerPosition; } } SkGlyphCache::AttachCache(cache); if (fallbackTxt.count()) { blob->initOverride(runIndex); GrTextUtils::DrawBmpPosText(blob, runIndex, fontCache, props, origPaint, origPaint.getColor(), viewMatrix, fallbackTxt.begin(), fallbackTxt.count(), fallbackPos.begin(), scalarsPerPosition, offset); } }