virtual void onDrawContent(SkCanvas* canvas) { const char* str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; SkPaint paint; SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); paint.setFlags(0x105); paint.setARGB(fByte, 0xFF, 0xFF, 0xFF); paint.setMaskFilter(SkBlurMaskFilter::Create(SkIntToScalar(3), SkBlurMaskFilter::kNormal_BlurStyle)); paint.getMaskFilter()->unref(); SkRandom rand; for (int ps = 6; ps <= 35; ps++) { paint.setColor(rand.nextU() | (0xFF << 24)); paint.setTextSize(SkIntToScalar(ps)); paint.setTextSize(SkIntToScalar(24)); canvas->drawText(str, strlen(str), x, y, paint); y += paint.getFontMetrics(NULL); } if (false) { // avoid bit rot, suppress warning check_for_nonwhite(canvas->getDevice()->accessBitmap(false), fByte); SkDebugf("------ byte %x\n", fByte); } if (false) { fByte += 1; fByte &= 0xFF; this->inval(NULL); } }
SkRect FindCanvas::addMatchPos(int index, const SkPaint& paint, int count, const uint16_t* glyphs, const SkScalar xPos[], SkScalar /* y */) { SkRect r; r.setEmpty(); const SkPoint* temp = reinterpret_cast<const SkPoint*> (xPos); const SkPoint* points = &temp[index]; int countInBytes = count * sizeof(uint16_t); SkPaint::FontMetrics fontMetrics; paint.getFontMetrics(&fontMetrics); // Need to check each character individually, since the heights may be // different. for (int j = 0; j < count; j++) { SkRect bounds; bounds.fLeft = points[j].fX; bounds.fRight = bounds.fLeft + paint.measureText(&glyphs[j], sizeof(uint16_t), 0); SkScalar baseline = points[j].fY; bounds.fTop = baseline + fontMetrics.fAscent; bounds.fBottom = baseline + fontMetrics.fDescent; /* Accumulate and then add the resulting rect to mMatches */ r.join(bounds); } SkMatrix matrix = getTotalMatrix(); matrix.mapRect(&r); SkCanvas* canvas = getWorkingCanvas(); int saveCount = canvas->save(); canvas->concat(matrix); canvas->drawPosText(glyphs, countInBytes, points, paint); canvas->restoreToCount(saveCount); return r; }
void init() { fTypeface = chinese_typeface(); SkPaint paint; paint.setAntiAlias(true); paint.setColor(0xDE000000); paint.setTypeface(fTypeface); paint.setTextSize(11); paint.setTextEncoding(SkPaint::kUTF32_TextEncoding); paint.getFontMetrics(&fMetrics); SkUnichar glyphs[45]; for (int32_t i = 0; i < kNumBlobs; ++i) { SkTextBlobBuilder builder; auto paragraphLength = kParagraphLength; SkScalar y = 0; while (paragraphLength - 45 > 0) { auto currentLineLength = SkTMin(45, paragraphLength - 45); this->createRandomLine(glyphs, currentLineLength); sk_tool_utils::add_to_text_blob_w_len(&builder, (const char*) glyphs, currentLineLength*4, paint, 0, y); y += fMetrics.fDescent - fMetrics.fAscent + fMetrics.fLeading; paragraphLength -= 45; } fBlobs.emplace_back(builder.make()); } fIndex = 0; }
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int from, int to) const { SkPaint paint; SkScalar width, left; SkPaint::FontMetrics metrics; primaryFont()->platformData().setupPaint(&paint); SkScalar spacing = paint.getFontMetrics(&metrics); float beforeWidth = SkScalarToFloat(paint.measureText(run.characters(), from << 1)); float afterWidth = SkScalarToFloat(paint.measureText(run.characters(), to << 1)); if (run.rtl()) { float totalWidth = SkScalarToFloat(paint.measureText(run.characters(), run.length() << 1)); return FloatRect(point.x() + floorf(totalWidth - afterWidth), point.y(), roundf(totalWidth - beforeWidth) - floorf(totalWidth - afterWidth), //roundf(SkScalarToFloat(spacing))); // Don't compute rect height, but use h. h); } else { return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), //roundf(SkScalarToFloat(spacing))); // Don't compute rect height, but use h. h); } }
SkRect FindCanvas::addMatchPosH(int index, const SkPaint& paint, int count, const uint16_t* glyphs, const SkScalar position[], SkScalar constY) { SkRect r; // We only care about the positions starting at the index of our match const SkScalar* xPos = &position[index]; // This assumes that the position array is monotonic increasing // The left bounds will be the position of the left most character r.fLeft = xPos[0]; // The right bounds will be the position of the last character plus its // width int lastIndex = count - 1; r.fRight = paint.measureText(&glyphs[lastIndex], sizeof(uint16_t), 0) + xPos[lastIndex]; // Grab font metrics to determine the top and bottom of the bounds SkPaint::FontMetrics fontMetrics; paint.getFontMetrics(&fontMetrics); r.fTop = constY + fontMetrics.fAscent; r.fBottom = constY + fontMetrics.fDescent; const SkMatrix& matrix = getTotalMatrix(); matrix.mapRect(&r); SkCanvas* canvas = getWorkingCanvas(); int saveCount = canvas->save(); canvas->concat(matrix); canvas->drawPosTextH(glyphs, count * sizeof(uint16_t), xPos, constY, paint); canvas->restoreToCount(saveCount); return r; }
static void call_draw(SkCanvas* canvas) { SkPaint paint; uint16_t text[32]; SkRandom rand; paint.setAntiAlias(true); paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); for (int j = 0; j < SK_ARRAY_COUNT(text); j++) text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32); SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); canvas->drawColor(SK_ColorWHITE); for (int i = 9; i < 36; i++) { SkPaint::FontMetrics m; paint.setTextSize(SkIntToScalar(i)); paint.getFontMetrics(&m); canvas->drawText(text, sizeof(text), x, y, paint); y += m.fDescent - m.fAscent; } }
// Each version of addMatch returns a rectangle for a match. // Not all of the parameters are used by each version. SkRect FindCanvas::addMatchNormal(int index, const SkPaint& paint, int count, const uint16_t* glyphs, const SkScalar pos[], SkScalar y) { const uint16_t* lineStart = glyphs - index; /* Use the original paint, since "text" is in glyphs */ SkScalar before = paint.measureText(lineStart, index * sizeof(uint16_t), 0); SkRect rect; rect.fLeft = pos[0] + before; int countInBytes = count * sizeof(uint16_t); rect.fRight = paint.measureText(glyphs, countInBytes, 0) + rect.fLeft; SkPaint::FontMetrics fontMetrics; paint.getFontMetrics(&fontMetrics); SkScalar baseline = y; rect.fTop = baseline + fontMetrics.fAscent; rect.fBottom = baseline + fontMetrics.fDescent; const SkMatrix& matrix = getTotalMatrix(); matrix.mapRect(&rect); // Add the text to our picture. SkCanvas* canvas = getWorkingCanvas(); int saveCount = canvas->save(); canvas->concat(matrix); canvas->drawText(glyphs, countInBytes, pos[0] + before, y, paint); canvas->restoreToCount(saveCount); return rect; }
void onDraw(SkCanvas* canvas) override { SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(SkIntToScalar(30)); const char* text = fApplyKerning ? "Type AWAY" : "Hamburgefons"; const size_t textLen = strlen(text); SkScalar x = SkIntToScalar(10); SkScalar dy = paint.getFontMetrics(nullptr); SkScalar y = dy; if (fApplyKerning) { paint.setSubpixelText(true); } else { paint.setLinearText(true); } for (int i = 0; i < gFaceStylesCount; i++) { paint.setTypeface(fFaces[i]); canvas->drawText(text, textLen, x, y, paint); if (fApplyKerning) { drawKernText(canvas, text, textLen, x + 240, y, paint); } y += dy; } }
virtual void onDraw(SkCanvas* originalCanvas) { SkISize size = this->getISize(); SkBitmap bitmap; bitmap.allocN32Pixels(size.width(), size.height()); SkDeviceProperties properties = SkDeviceProperties::Make( SkDeviceProperties::Geometry::Make(SkDeviceProperties::Geometry::kVertical_Orientation, SkDeviceProperties::Geometry::kBGR_Layout), SK_Scalar1); SkBitmapDevice device(bitmap, properties); SkCanvas canvas(&device); canvas.drawColor(SK_ColorWHITE); SkPaint paint; paint.setAntiAlias(true); paint.setLCDRenderText(true); //With freetype the default (normal hinting) can be really ugly. //Most distros now set slight (vertical hinting only) in any event. paint.setHinting(SkPaint::kSlight_Hinting); sk_tool_utils::set_portable_typeface(&paint, "Times Roman", SkTypeface::kNormal); const char* text = "Hamburgefons ooo mmm"; const size_t textLen = strlen(text); for (int j = 0; j < 2; ++j) { for (int i = 0; i < 6; ++i) { SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); SkAutoCanvasRestore acr(&canvas, true); canvas.translate(SkIntToScalar(50 + i * 230), SkIntToScalar(20)); rotate_about(&canvas, SkIntToScalar(i * 5), x, y * 10); { SkPaint p; p.setAntiAlias(true); SkRect r; r.set(x - SkIntToScalar(3), SkIntToScalar(15), x - SkIntToScalar(1), SkIntToScalar(280)); canvas.drawRect(r, p); } int index = 0; for (int ps = 6; ps <= 22; ps++) { paint.setTextSize(SkIntToScalar(ps)); canvas.drawText(text, textLen, x, y, paint); y += paint.getFontMetrics(NULL); index += 1; } } canvas.translate(0, SkIntToScalar(360)); paint.setSubpixelText(true); } originalCanvas->drawBitmap(bitmap, 0, 0); }
void onDrawContent(SkCanvas* canvas) override { SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(SkIntToScalar(24)); SkAutoTUnref<SkBlurDrawLooper> looper( SkBlurDrawLooper::Create(SK_ColorBLUE, SkBlurMask::ConvertRadiusToSigma(SkIntToScalar(2)), 0, 0)); paint.setLooper(looper); SkScalar height = paint.getFontMetrics(nullptr); if (!fDecodeSucceeded) { SkString failure; if (fResPath.size() == 0) { failure.printf("resource path is required!"); } else { failure.printf("Failed to decode %s", fCurrFile.c_str()); } canvas->drawText(failure.c_str(), failure.size(), 0, height, paint); return; } // Name, size of the file, and whether or not it is premultiplied. SkString header(SkOSPath::Basename(fCurrFile.c_str())); header.appendf(" [%dx%d] %s", fBitmap.width(), fBitmap.height(), (fPremul ? "premultiplied" : "unpremultiplied")); canvas->drawText(header.c_str(), header.size(), 0, height, paint); canvas->translate(0, height); // Help messages header.printf("Press '%c' to move to the next image.'", fNextImageChar); canvas->drawText(header.c_str(), header.size(), 0, height, paint); canvas->translate(0, height); header.printf("Press '%c' to toggle premultiplied decode.", fTogglePremulChar); canvas->drawText(header.c_str(), header.size(), 0, height, paint); // Now draw the image itself. canvas->translate(height * 2, height * 2); if (!fPremul) { // A premultiplied bitmap cannot currently be drawn. SkAutoLockPixels alp(fBitmap); // Copy it to a bitmap which can be drawn, converting // to premultiplied: SkBitmap bm; bm.allocN32Pixels(fBitmap.width(), fBitmap.height()); for (int i = 0; i < fBitmap.width(); ++i) { for (int j = 0; j < fBitmap.height(); ++j) { *bm.getAddr32(i, j) = premultiply_unpmcolor(*fBitmap.getAddr32(i, j)); } } canvas->drawBitmap(bm, 0, 0); } else { canvas->drawBitmap(fBitmap, 0, 0); } }
// Return fontmetrics.fTop,fBottom in topbot[0,1], after they have been // tweaked by paint.computeFastBounds(). // static void computeFontMetricsTopBottom(const SkPaint& paint, SkScalar topbot[2]) { SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); SkRect bounds; // construct a rect so we can see any adjustments from the paint. // we use 0,1 for left,right, just so the rect isn't empty bounds.set(0, metrics.fTop, SK_Scalar1, metrics.fBottom); (void)paint.computeFastBounds(bounds, &bounds); topbot[0] = bounds.fTop; topbot[1] = bounds.fBottom; }
void SkPictureRecord::addFontMetricsTopBottom(const SkPaint& paint, SkScalar baselineY) { SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); SkRect bounds; // construct a rect so we can see any adjustments from the paint. // we use 0,1 for left,right, just so the rect isn't empty bounds.set(0, metrics.fTop + baselineY, SK_Scalar1, metrics.fBottom + baselineY); (void)paint.computeFastBounds(bounds, &bounds); // now record the top and bottom addScalar(bounds.fTop); addScalar(bounds.fBottom); }
void SimpleFontData::platformInit() { SkPaint paint; SkPaint::FontMetrics metrics; m_font.setupPaint(&paint); paint.getFontMetrics(&metrics); // Beware those who step here: This code is designed to match Win32 font // metrics *exactly*. if (metrics.fVDMXMetricsValid) { m_ascent = metrics.fVDMXAscent; m_descent = metrics.fVDMXDescent; } else { m_ascent = SkScalarRound(-metrics.fAscent); m_descent = SkScalarRound(metrics.fHeight) - m_ascent; } if (metrics.fXHeight) m_xHeight = metrics.fXHeight; else { // hack taken from the Windows port m_xHeight = static_cast<float>(m_ascent) * 0.56; } m_lineGap = SkScalarRound(metrics.fLeading); m_lineSpacing = m_ascent + m_descent + m_lineGap; // In WebKit/WebCore/platform/graphics/SimpleFontData.cpp, m_spaceWidth is // calculated for us, but we need to calculate m_maxCharWidth and // m_avgCharWidth in order for text entry widgets to be sized correctly. m_maxCharWidth = SkScalarRound(metrics.fXRange * SkScalarRound(m_font.size())); if (metrics.fAvgCharWidth) m_avgCharWidth = SkScalarRound(metrics.fAvgCharWidth); else { m_avgCharWidth = m_xHeight; GlyphPage* glyphPageZero = GlyphPageTreeNode::getRootChild(this, 0)->page(); if (glyphPageZero) { static const UChar32 x_char = 'x'; const Glyph xGlyph = glyphPageZero->glyphDataForCharacter(x_char).glyph; if (xGlyph) m_avgCharWidth = widthForGlyph(xGlyph); } } }
virtual void onDraw(SkCanvas* canvas) { this->drawBG(canvas); SkPaint paint; // test handling of obscene cubic values (currently broken) if (false) { SkPoint pts[4]; pts[0].set(1.61061274e+09, 6291456); pts[1].set(-7.18397061e+15, -1.53091184e+13); pts[2].set(-1.30077315e+16, -2.77196141e+13); pts[3].set(-1.30077315e+16, -2.77196162e+13); SkPath path; path.moveTo(pts[0]); path.cubicTo(pts[1], pts[2], pts[3]); canvas->drawPath(path, paint); } canvas->translate(200, 20); canvas->rotate(30); paint.setAntiAlias(true); paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal))->safeUnref(); // const char* text = "abcdefghijklmnopqrstuvwxyz"; const char* text = "HnHnHnHnHnHnHnHnH"; size_t textLen = strlen(text); SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); { SkPaint p; p.setColor(SK_ColorRED); SkRect r; r.set(0, 0, x, y*20); canvas->drawRect(r, p); } int index = 0; for (int ps = 9; ps <= 24; ps++) { textLen = strlen(text); paint.setTextSize(SkIntToScalar(ps)); canvas->drawText(text, textLen, x, y, paint); y += paint.getFontMetrics(NULL); index += 1; } }
static HB_Fixed getFontMetric(HB_Font hbFont, HB_FontMetric metric) { SkPaint* paint = static_cast<SkPaint*>(hbFont->userData); SkPaint::FontMetrics skiaMetrics; paint->getFontMetrics(&skiaMetrics); switch (metric) { case HB_FontAscent: return SkScalarToHBFixed(-skiaMetrics.fAscent); // We don't support getting the rest of the metrics and Harfbuzz doesn't seem to need them. default: return 0; } return 0; }
void SkBBoxRecord::onDrawText(const void* text, size_t byteLength, SkScalar x, SkScalar y, const SkPaint& paint) { SkRect bbox; paint.measureText(text, byteLength, &bbox); SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); // Vertical and aligned text need to be offset if (paint.isVerticalText()) { SkScalar h = bbox.fBottom - bbox.fTop; if (paint.getTextAlign() == SkPaint::kCenter_Align) { bbox.fTop -= h / 2; bbox.fBottom -= h / 2; } // Pad top and bottom with max extents from FontMetrics bbox.fBottom += metrics.fBottom; bbox.fTop += metrics.fTop; } else { SkScalar w = bbox.fRight - bbox.fLeft; if (paint.getTextAlign() == SkPaint::kCenter_Align) { bbox.fLeft -= w / 2; bbox.fRight -= w / 2; } else if (paint.getTextAlign() == SkPaint::kRight_Align) { bbox.fLeft -= w; bbox.fRight -= w; } // Set vertical bounds to max extents from font metrics bbox.fTop = metrics.fTop; bbox.fBottom = metrics.fBottom; } // Pad horizontal bounds on each side by half of max vertical extents (this is sort of // arbitrary, but seems to produce reasonable results, if there were a way of getting max // glyph X-extents to pad by, that may be better here, but FontMetrics fXMin and fXMax seem // incorrect on most platforms (too small in Linux, never even set in Windows). SkScalar pad = (metrics.fBottom - metrics.fTop) / 2; bbox.fLeft -= pad; bbox.fRight += pad; bbox.fLeft += x; bbox.fRight += x; bbox.fTop += y; bbox.fBottom += y; if (this->transformBounds(bbox, &paint)) { INHERITED::onDrawText(text, byteLength, x, y, paint); } }
void onDraw(SkCanvas* canvas) override { SkPaint paint; paint.setAntiAlias(true); paint.setLCDRenderText(true); SkAutoTUnref<SkFontMgr> fontMgr(SkFontMgr::RefDefault()); SkAutoTDelete<SkStreamAsset> distortable(GetResourceAsStream("/fonts/Distortable.ttf")); if (!distortable) { return; } const char* text = "abc"; const size_t textLen = strlen(text); for (int j = 0; j < 2; ++j) { for (int i = 0; i < 5; ++i) { SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); SkFourByteTag tag = SkSetFourByteTag('w','g','h','t'); SkScalar styleValue = SkDoubleToScalar(0.5 + (5*j + i) * ((2.0 - 0.5) / (2 * 5))); SkFontMgr::FontParameters::Axis axes[] = { { tag, styleValue } }; paint.setTypeface(sk_sp<SkTypeface>(fontMgr->createFromStream( distortable->duplicate(), SkFontMgr::FontParameters().setAxes(axes, 1)))); SkAutoCanvasRestore acr(canvas, true); canvas->translate(SkIntToScalar(30 + i * 100), SkIntToScalar(20)); rotate_about(canvas, SkIntToScalar(i * 5), x, y * 10); { SkPaint p; p.setAntiAlias(true); SkRect r; r.set(x - SkIntToScalar(3), SkIntToScalar(15), x - SkIntToScalar(1), SkIntToScalar(280)); canvas->drawRect(r, p); } for (int ps = 6; ps <= 22; ps++) { paint.setTextSize(SkIntToScalar(ps)); canvas->drawText(text, textLen, x, y, paint); y += paint.getFontMetrics(nullptr); } } canvas->translate(0, SkIntToScalar(360)); paint.setSubpixelText(true); } }
FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int, int) const { SkPaint paint; SkScalar width, left; SkPaint::FontMetrics metrics; primaryFont()->platformData().setupPaint(&paint); width = paint.measureText(run.characters(), run.length() << 1); SkScalar spacing = paint.getFontMetrics(&metrics); return FloatRect(point.x(), point.y() - floorf(SkScalarToFloat(-metrics.fAscent)), roundf(SkScalarToFloat(width)), roundf(SkScalarToFloat(spacing))); }
void SkBBoxRecord::onDrawTextOnPath(const void* text, size_t byteLength, const SkPath& path, const SkMatrix* matrix, const SkPaint& paint) { SkRect bbox = path.getBounds(); SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); // pad out all sides by the max glyph height above baseline SkScalar pad = metrics.fTop; bbox.fLeft += pad; bbox.fRight -= pad; bbox.fTop += pad; bbox.fBottom -= pad; if (this->transformBounds(bbox, &paint)) { INHERITED::onDrawTextOnPath(text, byteLength, path, matrix, paint); } }
static HB_Fixed getFontMetric(HB_Font hbFont, HB_FontMetric metric) { SkHarfBuzzFont* font = reinterpret_cast<SkHarfBuzzFont*>(hbFont->userData); SkPaint paint; SkPaint::FontMetrics skiaMetrics; font->setupPaint(&paint); paint.getFontMetrics(&skiaMetrics); switch (metric) { case HB_FontAscent: return SkScalarToHarfbuzzFixed(-skiaMetrics.fAscent); default: SkDebugf("--- unknown harfbuzz metric enum %d\n", metric); return 0; } }
static HB_Fixed getFontMetric(HB_Font hbFont, HB_FontMetric metric) { FontPlatformData* font = reinterpret_cast<FontPlatformData*>(hbFont->userData); SkPaint paint; font->setupPaint(&paint); SkPaint::FontMetrics skiaMetrics; paint.getFontMetrics(&skiaMetrics); switch (metric) { case HB_FontAscent: return SkiaScalarToHarfbuzzFixed(-skiaMetrics.fAscent); // We don't support getting the rest of the metrics and Harfbuzz doesn't seem to need them. default: return 0; } }
void onDraw(SkCanvas* canvas) override { SkPaint paint; paint.setAntiAlias(true); paint.setLCDRenderText(true); SkAutoTDelete<SkStreamAsset> distortable(GetResourceAsStream("/fonts/Distortable.ttf")); if (!distortable) { return; } const char* text = "abc"; const size_t textLen = strlen(text); for (int j = 0; j < 2; ++j) { for (int i = 0; i < 5; ++i) { SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); SkFixed axis = SkDoubleToFixed(0.5 + (5*j + i) * ((2.0 - 0.5) / (2 * 5))); SkAutoTUnref<SkTypeface> typeface(SkTypeface::CreateFromFontData( new SkFontData(distortable->duplicate(), 0, &axis, 1))); paint.setTypeface(typeface); SkAutoCanvasRestore acr(canvas, true); canvas->translate(SkIntToScalar(30 + i * 100), SkIntToScalar(20)); rotate_about(canvas, SkIntToScalar(i * 5), x, y * 10); { SkPaint p; p.setAntiAlias(true); SkRect r; r.set(x - SkIntToScalar(3), SkIntToScalar(15), x - SkIntToScalar(1), SkIntToScalar(280)); canvas->drawRect(r, p); } for (int ps = 6; ps <= 22; ps++) { paint.setTextSize(SkIntToScalar(ps)); canvas->drawText(text, textLen, x, y, paint); y += paint.getFontMetrics(nullptr); } } canvas->translate(0, SkIntToScalar(360)); paint.setSubpixelText(true); } }
virtual void onDraw(SkCanvas* canvas) { SkPaint paint; paint.setAntiAlias(true); paint.setLCDRenderText(true); //With freetype the default (normal hinting) can be really ugly. //Most distros now set slight (vertical hinting only) in any event. paint.setHinting(SkPaint::kSlight_Hinting); SkSafeUnref(paint.setTypeface(SkTypeface::CreateFromName("Times Roman", SkTypeface::kNormal))); const char* text = "Hamburgefons ooo mmm"; const size_t textLen = strlen(text); for (int j = 0; j < 2; ++j) { // This used to do 6 iterations but it causes the N4 to crash in the MSAA4 config. for (int i = 0; i < 5; ++i) { SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(20); SkAutoCanvasRestore acr(canvas, true); canvas->translate(SkIntToScalar(50 + i * 230), SkIntToScalar(20)); rotate_about(canvas, SkIntToScalar(i * 5), x, y * 10); { SkPaint p; p.setAntiAlias(true); SkRect r; r.set(x - SkIntToScalar(3), SkIntToScalar(15), x - SkIntToScalar(1), SkIntToScalar(280)); canvas->drawRect(r, p); } int index = 0; for (int ps = 6; ps <= 22; ps++) { paint.setTextSize(SkIntToScalar(ps)); canvas->drawText(text, textLen, x, y, paint); y += paint.getFontMetrics(NULL); index += 1; } } canvas->translate(0, SkIntToScalar(360)); paint.setSubpixelText(true); } }
void SkBBoxRecord::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { SkRect bbox; bbox.set(pos, paint.countText(text, byteLength)); SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); bbox.fTop += metrics.fTop; bbox.fBottom += metrics.fBottom; // pad on left and right by half of max vertical glyph extents SkScalar pad = (metrics.fTop - metrics.fBottom) / 2; bbox.fLeft += pad; bbox.fRight -= pad; if (this->transformBounds(bbox, &paint)) { INHERITED::drawPosText(text, byteLength, pos, paint); } }
static void call_measure() { SkPaint paint; uint16_t text[32]; SkRandom rand; paint.setAntiAlias(true); paint.setTextEncoding(SkPaint::kUTF16_TextEncoding); for (int j = 0; j < SK_ARRAY_COUNT(text); j++) text[j] = (uint16_t)((rand.nextU() & 0xFF) + 32); for (int i = 9; i < 36; i++) { SkPaint::FontMetrics m; paint.setTextSize(SkIntToScalar(i)); paint.getFontMetrics(&m); paint.measureText(text, sizeof(text)); } }
static void doMeasure(SkCanvas* canvas, const SkPaint& paint, const char text[]) { SkScalar dy = paint.getFontMetrics(NULL); size_t len = strlen(text); SkAutoTMalloc<SkScalar> autoWidths(len); SkScalar* widths = autoWidths.get(); SkAutoTMalloc<SkRect> autoRects(len); SkRect* rects = autoRects.get(); SkRect bounds; SkPaint p(paint); for (size_t i = 0; i < SK_ARRAY_COUNT(gSettings); i++) { p.setLinearText(gSettings[i].fLinearText); p.setDevKernText(gSettings[i].fDevKernText); SkScalar scale = gSettings[i].fScale; int n = p.getTextWidths(text, len, widths, rects); SkScalar w = p.measureText(text, len, &bounds, scale); p.setStyle(SkPaint::kFill_Style); p.setColor(0x8888FF88); canvas->drawRect(bounds, p); p.setColor(0xFF000000); canvas->drawText(text, len, 0, 0, p); p.setStyle(SkPaint::kStroke_Style); p.setStrokeWidth(0); p.setColor(0xFFFF0000); SkScalar x = 0; for (int j = 0; j < n; j++) { SkRect r = rects[j]; r.offset(x, 0); canvas->drawRect(r, p); x += widths[j]; } p.setColor(0xFF0000FF); canvas->drawLine(0, 0, w, 0, p); p.setStrokeWidth(SkIntToScalar(4)); canvas->drawPoint(x, 0, p); canvas->translate(0, dy); } }
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 init() { fTypeface = chinese_typeface(); SkPaint paint; make_paint(&paint, fTypeface); paint.getFontMetrics(&fMetrics); SkUnichar glyphs[kWordLength]; for (int32_t i = 0; i < kNumBlobs; ++i) { this->createRandomWord(glyphs); SkTextBlobBuilder builder; sk_tool_utils::add_to_text_blob_w_len(&builder, (const char*) glyphs, kWordLength*4, paint, 0, 0); fBlobs.emplace_back(builder.make()); } fIndex = 0; }
static void AdjustTextForFontMetrics(SkRect* rect, const SkPaint& paint) { #ifdef SK_DEBUG SkRect correct = *rect; #endif // crbug.com/373785 ~~> xPad = 4x yPad // crbug.com/424824 ~~> bump yPad from 2x text size to 2.5x const SkScalar yPad = 2.5f * paint.getTextSize(), xPad = 4.0f * yPad; rect->outset(xPad, yPad); #ifdef SK_DEBUG SkPaint::FontMetrics metrics; paint.getFontMetrics(&metrics); correct.fLeft += metrics.fXMin; correct.fTop += metrics.fTop; correct.fRight += metrics.fXMax; correct.fBottom += metrics.fBottom; // See skia:2862 for why we ignore small text sizes. SkASSERTF(paint.getTextSize() < 0.001f || rect->contains(correct), "%f %f %f %f vs. %f %f %f %f\n", -xPad, -yPad, +xPad, +yPad, metrics.fXMin, metrics.fTop, metrics.fXMax, metrics.fBottom); #endif }
static void drawFadingText(SkCanvas* canvas, const char* text, size_t len, SkScalar x, SkScalar y, const SkPaint& paint) { // Need a bounds for the text SkRect bounds; SkPaint::FontMetrics fm; paint.getFontMetrics(&fm); bounds.set(x, y + fm.fTop, x + paint.measureText(text, len), y + fm.fBottom); // may need to outset bounds a little, to account for hinting and/or // antialiasing bounds.inset(-SkIntToScalar(2), -SkIntToScalar(2)); canvas->saveLayer(&bounds, NULL); canvas->drawText(text, len, x, y, paint); const SkPoint pts[] = { { bounds.fLeft, y }, { bounds.fRight, y } }; const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 }; // pos[1] value is where we start to fade, relative to the width // of our pts[] array. const SkScalar pos[] = { 0, SkFloatToScalar(0.9f), SK_Scalar1 }; SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, 3, SkShader::kClamp_TileMode); SkPaint p; p.setShader(s)->unref(); p.setXfermodeMode(SkXfermode::kDstIn_Mode); canvas->drawRect(bounds, p); canvas->restore(); }