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; }
void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len, SkScalar x, SkScalar y, const SkPaint& paint) { SkPaint textPaint = calculateTextPaint(paint); updateGSFromPaint(textPaint, true); // We want the text in glyph id encoding and a writable buffer, so we end // up making a copy either way. size_t numGlyphs = paint.textToGlyphs(text, len, NULL); uint16_t* glyphIDs = (uint16_t*)sk_malloc_flags(numGlyphs * 2, SK_MALLOC_TEMP | SK_MALLOC_THROW); SkAutoFree autoFreeGlyphIDs(glyphIDs); if (paint.getTextEncoding() != SkPaint::kGlyphID_TextEncoding) { paint.textToGlyphs(text, len, glyphIDs); textPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); } else { SkASSERT((len & 1) == 0); SkASSERT(len / 2 == numGlyphs); memcpy(glyphIDs, text, len); } SkScalar width; SkScalar* widthPtr = NULL; if (textPaint.isUnderlineText() || textPaint.isStrikeThruText()) widthPtr = &width; SkDrawCacheProc glyphCacheProc = textPaint.getDrawCacheProc(); alignText(glyphCacheProc, textPaint, glyphIDs, numGlyphs, &x, &y, widthPtr); fContent.writeText("BT\n"); setTextTransform(x, y, textPaint.getTextSkewX()); size_t consumedGlyphCount = 0; while (numGlyphs > consumedGlyphCount) { updateFont(textPaint, glyphIDs[consumedGlyphCount]); SkPDFFont* font = fGraphicStack[fGraphicStackIndex].fFont; size_t availableGlyphs = font->glyphsToPDFFontEncoding(glyphIDs + consumedGlyphCount, numGlyphs - consumedGlyphCount); SkString encodedString = SkPDFString::formatString(glyphIDs + consumedGlyphCount, availableGlyphs, font->multiByteGlyphs()); fContent.writeText(encodedString.c_str()); consumedGlyphCount += availableGlyphs; fContent.writeText(" Tj\n"); } fContent.writeText("ET\n"); // Draw underline and/or strikethrough if the paint has them. // drawPosText() and drawTextOnPath() don't draw underline or strikethrough // because the raster versions don't. Use paint instead of textPaint // because we may have changed strokeWidth to do fakeBold text. if (paint.isUnderlineText() || paint.isStrikeThruText()) { SkScalar textSize = paint.getTextSize(); SkScalar height = SkScalarMul(textSize, kStdUnderline_Thickness); if (paint.isUnderlineText()) { SkScalar top = SkScalarMulAdd(textSize, kStdUnderline_Offset, y); SkRect r = SkRect::MakeXYWH(x, top - height, width, height); drawRect(d, r, paint); } if (paint.isStrikeThruText()) { SkScalar top = SkScalarMulAdd(textSize, kStdStrikeThru_Offset, y); SkRect r = SkRect::MakeXYWH(x, top - height, width, height); drawRect(d, r, paint); } } }