// 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; }
//SAMSUNG_THAI_EDITING_FIX >> FloatRect Font::selectionRectForComplexText(const TextRun& run, const IntPoint& point, int h, int from, int to) const { SkPaint paint; SkPaint::FontMetrics metrics; float beforeWidth = 0.0f ; float afterWidth = 0.0f ; primaryFont()->platformData().setupPaint(&paint); size_t length = from ; if (length > 0) { beforeWidth = paint.measureText(run.characters(), length << 1); } length = to ; if (length > 0) { afterWidth = paint.measureText(run.characters(), length << 1); } return FloatRect(point.x() + floorf(beforeWidth), point.y(), roundf(afterWidth) - floorf(beforeWidth), roundf(SkScalarToFloat(h))); }
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); } }
void CommandSet::drawHelp(SkCanvas* canvas) { if (kNone_HelpMode == fHelpMode) { return; } // Sort commands for current mode: SkTQSort(fCommands.begin(), fCommands.end() - 1, kAlphabetical_HelpMode == fHelpMode ? compareCommandKey : compareCommandGroup); SkPaint bgPaint; bgPaint.setColor(0xC0000000); canvas->drawPaint(bgPaint); SkPaint paint; paint.setTextSize(16); paint.setAntiAlias(true); paint.setColor(0xFFFFFFFF); SkPaint groupPaint; groupPaint.setTextSize(18); groupPaint.setUnderlineText(true); groupPaint.setAntiAlias(true); groupPaint.setColor(0xFFFFFFFF); SkScalar x = SkIntToScalar(10); SkScalar y = SkIntToScalar(10); // Measure all key strings: SkScalar keyWidth = 0; for (Command& cmd : fCommands) { keyWidth = SkMaxScalar(keyWidth, paint.measureText(cmd.fKeyName.c_str(), cmd.fKeyName.size())); } keyWidth += paint.measureText(" ", 1); // If we're grouping by category, we'll be adding text height on every new group (including the // first), so no need to do that here. Otherwise, skip down so the first line is where we want. if (kGrouped_HelpMode != fHelpMode) { y += paint.getTextSize(); } // Print everything: SkString lastGroup; for (Command& cmd : fCommands) { if (kGrouped_HelpMode == fHelpMode && lastGroup != cmd.fGroup) { // Group change. Advance and print header: y += paint.getTextSize(); canvas->drawText(cmd.fGroup.c_str(), cmd.fGroup.size(), x, y, groupPaint); y += groupPaint.getTextSize() + 2; lastGroup = cmd.fGroup; } canvas->drawText(cmd.fKeyName.c_str(), cmd.fKeyName.size(), x, y, paint); SkString text = SkStringPrintf(": %s", cmd.fDescription.c_str()); canvas->drawText(text.c_str(), text.size(), x + keyWidth, y, paint); y += paint.getTextSize() + 2; } }
virtual void onDraw(SkCanvas* canvas) { SkPaint paint; SkScalar horizMargin = 10; SkScalar vertMargin = 10; SkBitmap src; src.allocN32Pixels(40, 40); SkCanvas canvasTmp(src); draw_checks(&canvasTmp, 40, 40); for (unsigned i = 0; i < NUM_CONFIGS; ++i) { src.copyTo(&fDst[i], gColorTypes[i]); } canvas->clear(0xFFDDDDDD); paint.setAntiAlias(true); sk_tool_utils::set_portable_typeface(&paint); SkScalar width = SkIntToScalar(40); SkScalar height = SkIntToScalar(40); if (paint.getFontSpacing() > height) { height = paint.getFontSpacing(); } for (unsigned i = 0; i < NUM_CONFIGS; i++) { const char* name = gColorTypeNames[src.colorType()]; SkScalar textWidth = paint.measureText(name, strlen(name)); if (textWidth > width) { width = textWidth; } } SkScalar horizOffset = width + horizMargin; SkScalar vertOffset = height + vertMargin; canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); for (unsigned i = 0; i < NUM_CONFIGS; i++) { canvas->save(); // Draw destination config name const char* name = gColorTypeNames[fDst[i].colorType()]; SkScalar textWidth = paint.measureText(name, strlen(name)); SkScalar x = (width - textWidth) / SkScalar(2); SkScalar y = paint.getFontSpacing() / SkScalar(2); canvas->drawText(name, strlen(name), x, y, paint); // Draw destination bitmap canvas->translate(0, vertOffset); x = (width - 40) / SkScalar(2); canvas->drawBitmap(fDst[i], x, 0, &paint); canvas->restore(); canvas->translate(horizOffset, 0); } }
virtual void onDraw(SkCanvas* canvas) { SkPaint paint; SkScalar horizMargin(SkIntToScalar(10)); SkScalar vertMargin(SkIntToScalar(10)); SkBitmapDevice devTmp(SkBitmap::kARGB_8888_Config, 40, 40, false); SkCanvas canvasTmp(&devTmp); draw_checks(&canvasTmp, 40, 40); SkBitmap src = canvasTmp.getTopDevice()->accessBitmap(false); for (unsigned i = 0; i < NUM_CONFIGS; ++i) { if (!src.deepCopyTo(&fDst[i], gConfigs[i])) { src.copyTo(&fDst[i], gConfigs[i]); } } canvas->clear(0xFFDDDDDD); paint.setAntiAlias(true); SkScalar width = SkIntToScalar(40); SkScalar height = SkIntToScalar(40); if (paint.getFontSpacing() > height) { height = paint.getFontSpacing(); } for (unsigned i = 0; i < NUM_CONFIGS; i++) { const char* name = gConfigNames[src.config()]; SkScalar textWidth = paint.measureText(name, strlen(name)); if (textWidth > width) { width = textWidth; } } SkScalar horizOffset = width + horizMargin; SkScalar vertOffset = height + vertMargin; canvas->translate(SkIntToScalar(20), SkIntToScalar(20)); for (unsigned i = 0; i < NUM_CONFIGS; i++) { canvas->save(); // Draw destination config name const char* name = gConfigNames[fDst[i].config()]; SkScalar textWidth = paint.measureText(name, strlen(name)); SkScalar x = (width - textWidth) / SkScalar(2); SkScalar y = paint.getFontSpacing() / SkScalar(2); canvas->drawText(name, strlen(name), x, y, paint); // Draw destination bitmap canvas->translate(0, vertOffset); x = (width - 40) / SkScalar(2); canvas->drawBitmap(fDst[i], x, 0, &paint); canvas->restore(); canvas->translate(horizOffset, 0); } }
static void test_text(SkCanvas* canvas) { SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(20); const char* str = "Hamburgefons"; size_t len = strlen(str); SkScalar x = 20; SkScalar y = 20; canvas->drawText(str, len, x, y, paint); y += 20; const SkPoint pts[] = { { x, y }, { x + paint.measureText(str, len), y } }; const SkColor colors[] = { SK_ColorBLACK, SK_ColorBLACK, 0 }; const SkScalar pos[] = { 0, 0.9f, 1 }; SkShader* s = SkGradientShader::CreateLinear(pts, colors, pos, SK_ARRAY_COUNT(colors), SkShader::kClamp_TileMode); paint.setShader(s)->unref(); canvas->drawText(str, len, x, y, paint); y += 20; paint.setShader(NULL); drawFadingText(canvas, str, len, x, y, paint); }
void recordCanvas(SkCanvas* canvas) override { SkPaint paint; paint.setTextSize(fTextSize); paint.setColor(SK_ColorBLACK); const char* text = "Hamburgefons"; size_t len = strlen(text); const SkScalar textWidth = paint.measureText(text, len); SkScalar* adv = new SkScalar[len]; paint.getTextWidths(text, len, adv); for (SkScalar x = 0; x < fPictureWidth; x += textWidth) { for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) { SkPoint* pos = new SkPoint[len]; SkScalar advX = 0; for (size_t i = 0; i < len; i++) { if (fDrawPosH) pos[i].set(x + advX, y); else pos[i].set(x + advX, y + i); advX += adv[i]; } canvas->drawPosText(text, len, pos, paint); delete[] pos; } } delete[] adv; }
void onDraw(SkCanvas* canvas) override { SkPaint paint; paint.setAntiAlias(true); paint.setLCDRenderText(true); paint.setSubpixelText(true); paint.setTypeface(fTypefaces[0]); paint.setTextSize(192); // Make sure the nul character does not cause problems. paint.measureText("\0", 1); SkScalar x = 20; SkScalar y = 128; SkString text("ABCDEFGHIJ"); draw_string(canvas, text, x, y, paint); y += 100; SkString text2("KLMNOPQRS"); draw_string(canvas, text2, x, y, paint); y += 100; SkString text3("TUVWXYZ012"); draw_string(canvas, text3, x, y, paint); y += 100; paint.setTypeface(fTypefaces[1]); draw_string(canvas, text, x, y, paint); y += 100; draw_string(canvas, text2, x, y, paint); y += 100; draw_string(canvas, text3, x, y, paint); y += 100; }
static void drawBaseline(SkCanvas* canvas, const SkPaint& paint, SkScalar x, SkScalar y) { SkScalar total = paint.measureText(gText, gLen); SkPaint p; p.setAntiAlias(true); p.setColor(0x80FF0000); canvas->drawLine(x, y, paint.isVerticalText() ? x : x + total, paint.isVerticalText() ? y + total : y, p); p.setColor(0xFF0000FF); SkScalar adv[gLen]; int numChars = paint.getTextWidths(gText, gLen, adv, nullptr); for (int i = 0; i < numChars; ++i) { canvas->drawCircle(x, y, SK_Scalar1 * 3 / 2, p); if (paint.isVerticalText()) { y += adv[i]; } else { x += adv[i]; } } canvas->drawCircle(x, y, SK_Scalar1 * 3 / 2, p); }
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; }
bool draw(SkCanvas* canvas, const SkString& newText, SkScalar x, SkScalar y, SkPaint& paint) { SkScalar scale; if (fInterp.timeToValues(SkTime::GetMSecs(), &scale) == SkInterpolator::kFreezeEnd_Result) { canvas->drawText(newText.c_str(), newText.size(), x, y, paint); return false; } else { U8 alpha = paint.getAlpha(); SkScalar above, below; (void)paint.measureText(nil, 0, &above, &below); SkScalar height = below - above; SkScalar dy = SkScalarMul(height, scale); if (scale < 0) height = -height; // draw the old paint.setAlpha((U8)SkScalarMul(alpha, SK_Scalar1 - SkScalarAbs(scale))); canvas->drawText(fOldText.c_str(), fOldText.size(), x, y - dy, paint); // draw the new paint.setAlpha((U8)SkScalarMul(alpha, SkScalarAbs(scale))); canvas->drawText(newText.c_str(), newText.size(), x, y + height - dy, paint); // restore the paint paint.setAlpha(alpha); return true; } }
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; }
static void test_breakText() { SkPaint paint; const char* text = "sdfkljAKLDFJKEWkldfjlk#$%&sdfs.dsj"; size_t length = strlen(text); SkScalar width = paint.measureText(text, length); SkScalar mm = 0; SkScalar nn = 0; for (SkScalar w = 0; w <= width; w += SK_Scalar1) { SkScalar m; size_t n = paint.breakText(text, length, w, &m, SkPaint::kBackward_TextBufferDirection); SkASSERT(n <= length); SkASSERT(m <= width); if (n == 0) { SkASSERT(m == 0); } else { // now assert that we're monotonic if (n == nn) { SkASSERT(m == mm); } else { SkASSERT(n > nn); SkASSERT(m > mm); } } nn = SkIntToScalar(n); mm = m; } SkDEBUGCODE(size_t length2 =) paint.breakText(text, length, width, &mm); SkASSERT(length2 == length); SkASSERT(mm == width); }
const SkAdvancedTypefaceMetrics* SkPDFFont::GetMetrics(SkTypeface* typeface, SkPDFCanon* canon) { SkASSERT(typeface); SkFontID id = typeface->uniqueID(); if (std::unique_ptr<SkAdvancedTypefaceMetrics>* ptr = canon->fTypefaceMetrics.find(id)) { return ptr->get(); // canon retains ownership. } int count = typeface->countGlyphs(); if (count <= 0 || count > 1 + SK_MaxU16) { // Cache nullptr to skip this check. Use SkSafeUnref(). canon->fTypefaceMetrics.set(id, nullptr); return nullptr; } std::unique_ptr<SkAdvancedTypefaceMetrics> metrics = typeface->getAdvancedMetrics(); if (!metrics) { metrics = skstd::make_unique<SkAdvancedTypefaceMetrics>(); } if (0 == metrics->fStemV || 0 == metrics->fCapHeight) { SkPaint tmpPaint; tmpPaint.setHinting(SkPaint::kNo_Hinting); tmpPaint.setTypeface(sk_ref_sp(typeface)); tmpPaint.setTextSize(1000); // glyph coordinate system if (0 == metrics->fStemV) { // Figure out a good guess for StemV - Min width of i, I, !, 1. // This probably isn't very good with an italic font. int16_t stemV = SHRT_MAX; for (char c : {'i', 'I', '!', '1'}) { SkRect bounds; tmpPaint.measureText(&c, 1, &bounds); stemV = SkTMin(stemV, SkToS16(SkScalarRoundToInt(bounds.width()))); } metrics->fStemV = stemV; } if (0 == metrics->fCapHeight) { // Figure out a good guess for CapHeight: average the height of M and X. SkScalar capHeight = 0; for (char c : {'M', 'X'}) { SkRect bounds; tmpPaint.measureText(&c, 1, &bounds); capHeight += bounds.height(); } metrics->fCapHeight = SkToS16(SkScalarRoundToInt(capHeight / 2)); } } return canon->fTypefaceMetrics.set(id, std::move(metrics))->get(); }
static void thread_main(void*) { SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); const char text[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; size_t len = strlen(text); SkPaint paint; for (int j = 0; j < 10; ++j) { for (int i = 9; i <= 48; ++i) { paint.setTextSize(SkIntToScalar(i)); paint.setAntiAlias(false); paint.measureText(text, len); paint.setAntiAlias(true); paint.measureText(text, len); } } }
static void draw_label(SkCanvas* canvas, const char* label, const SkPoint& offset) { SkPaint paint; size_t len = strlen(label); SkScalar width = paint.measureText(label, len); canvas->drawText(label, len, offset.x() - width / 2, offset.y(), paint); }
static void drawTestCase(SkCanvas* canvas, SkScalar textScale, SkScalar strokeWidth, SkPaint::Style strokeStyle) { SkPaint paint; paint.setColor(SK_ColorBLACK); paint.setAntiAlias(true); paint.setTextSize(kTextHeight * textScale); sk_tool_utils::set_portable_typeface(&paint); paint.setStrokeWidth(strokeWidth); paint.setStyle(strokeStyle); // This demonstrates that we can not measure the text if // there's a device transform. The canvas total matrix will // end up being a device transform. bool drawRef = !(canvas->getTotalMatrix().getType() & ~(SkMatrix::kIdentity_Mask | SkMatrix::kTranslate_Mask)); SkRect bounds; if (drawRef) { SkScalar advance = paint.measureText(kText, sizeof(kText) - 1, &bounds); paint.setStrokeWidth(0.0f); paint.setStyle(SkPaint::kStroke_Style); // Green box is the measured text bounds. paint.setColor(SK_ColorGREEN); canvas->drawRect(bounds, paint); // Red line is the measured advance from the 0,0 of the text position. paint.setColor(SK_ColorRED); canvas->drawLine(0.0f, 0.0f, advance, 0.0f, paint); } // Black text is the testcase, eg. the text. paint.setColor(SK_ColorBLACK); paint.setStrokeWidth(strokeWidth); paint.setStyle(strokeStyle); canvas->drawText(kText, sizeof(kText) - 1, 0.0f, 0.0f, paint); if (drawRef) { SkScalar widths[sizeof(kText) - 1]; paint.getTextWidths(kText, sizeof(kText) - 1, widths, nullptr); paint.setStrokeWidth(0.0f); paint.setStyle(SkPaint::kStroke_Style); // Magenta lines are the positions for the characters. paint.setColor(SK_ColorMAGENTA); SkScalar w = bounds.x(); for (size_t i = 0; i < sizeof(kText) - 1; ++i) { canvas->drawLine(w, 0.0f, w, 5.0f, paint); w += widths[i]; } } }
virtual void onDraw(SkCanvas* canvas) { canvas->drawColor(SK_ColorGRAY); SkPaint paint; paint.setTypeface(fTypeface); const char* text = "hamburgerfons"; // draw text at different point sizes const int textSize[] = { 10, 30, 50 }; const int textYOffset[] = { 10, 40, 100}; SkASSERT(sizeof(textSize) == sizeof(textYOffset)); for (size_t y = 0; y < sizeof(textSize) / sizeof(int); ++y) { paint.setTextSize(SkIntToScalar(textSize[y])); canvas->drawText(text, strlen(text), 10, SkIntToScalar(textYOffset[y]), paint); } // setup work needed to draw text with different clips canvas->translate(10, 160); paint.setTextSize(40); // compute the bounds of the text SkRect bounds; paint.measureText(text, strlen(text), &bounds); const SkScalar boundsHalfWidth = bounds.width() * SK_ScalarHalf; const SkScalar boundsHalfHeight = bounds.height() * SK_ScalarHalf; const SkScalar boundsQuarterWidth = boundsHalfWidth * SK_ScalarHalf; const SkScalar boundsQuarterHeight = boundsHalfHeight * SK_ScalarHalf; SkRect upperLeftClip = SkRect::MakeXYWH(bounds.left(), bounds.top(), boundsHalfWidth, boundsHalfHeight); SkRect lowerRightClip = SkRect::MakeXYWH(bounds.centerX(), bounds.centerY(), boundsHalfWidth, boundsHalfHeight); SkRect interiorClip = bounds; interiorClip.inset(boundsQuarterWidth, boundsQuarterHeight); const SkRect clipRects[] = { bounds, upperLeftClip, lowerRightClip, interiorClip }; SkPaint clipHairline; clipHairline.setColor(SK_ColorWHITE); clipHairline.setStyle(SkPaint::kStroke_Style); for (size_t x = 0; x < sizeof(clipRects) / sizeof(SkRect); ++x) { canvas->save(); canvas->drawRect(clipRects[x], clipHairline); paint.setAlpha(0x20); canvas->drawText(text, strlen(text), 0, 0, paint); canvas->clipRect(clipRects[x]); paint.setAlpha(0xFF); canvas->drawText(text, strlen(text), 0, 0, paint); canvas->restore(); canvas->translate(0, bounds.height() + SkIntToScalar(25)); } }
static void doTextBounds(JNIEnv* env, const jchar* text, int count, jobject bounds, const SkPaint& paint) { SkRect r; SkIRect ir; paint.measureText(text, count << 1, &r); r.roundOut(&ir); GraphicsJNI::irect_to_jrect(ir, env, bounds); }
float Font::floatWidthForComplexText(const TextRun& run, HashSet<const SimpleFontData*>*) const { SkPaint paint; primaryFont()->platformData().setupPaint(&paint); //printf("--------- complext measure %d chars\n", run.to() - run.from()); SkScalar width = paint.measureText(run.characters(), run.length() << 1); return SkScalarToFloat(width); }
int main (int argc, char * const argv[]) { SkAutoGraphics ag; SkString path("skhello.png"); SkString text("Hello"); for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--help")) { show_help(); return 0; } if (!strcmp(argv[i], "-o")) { if (i == argc-1) { SkDebugf("ERROR: -o needs a following filename\n"); return -1; } path.set(argv[i+1]); i += 1; // skip the out dir name } else if (!strcmp(argv[i], "-t")) { if (i == argc-1) { SkDebugf("ERROR: -t needs a following string\n"); return -1; } text.set(argv[i+1]); i += 1; // skip the text string } } SkPaint paint; paint.setAntiAlias(true); paint.setTextSize(SkIntToScalar(30)); SkScalar width = paint.measureText(text.c_str(), text.size()); SkScalar spacing = paint.getFontSpacing(); int w = SkScalarRound(width) + 30; int h = SkScalarRound(spacing) + 30; SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, w, h); bitmap.allocPixels(); SkCanvas canvas(bitmap); canvas.drawColor(SK_ColorWHITE); paint.setTextAlign(SkPaint::kCenter_Align); canvas.drawText(text.c_str(), text.size(), SkIntToScalar(w)/2, SkIntToScalar(h)*2/3, paint); bool success = SkImageEncoder::EncodeFile(path.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100); if (!success) { SkDebugf("--- failed to write %s\n", path.c_str()); } return !success; }
// found and fixed for android: not initializing rect for string's of length 0 static void regression_measureText(skiatest::Reporter* reporter) { SkPaint paint; paint.setTextSize(SkFloatToScalar(12.0f)); SkRect r; r.setLTRB(SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN, SK_ScalarNaN); // test that the rect was reset paint.measureText("", 0, &r, SkFloatToScalar(1.0f)); REPORTER_ASSERT(reporter, r.isEmpty()); }
SkRect draw(SkCanvas* canvas, const SkPaint& origPaint) override { SkPaint paint = origPaint; paint.setTextSize(30.f); this->setFont(&paint); const char* text = this->text(); static const SkVector offset = SkVector::Make(10, 10); canvas->drawText(text, strlen(text), offset.fX, offset.fY, paint); SkRect bounds; paint.measureText(text, strlen(text), &bounds); bounds.offset(offset); return bounds; }
static void show_k_text(SkCanvas* canvas, SkScalar x, SkScalar y, const SkScalar k[]) { SkPaint paint; paint.setTextSize(SkIntToScalar(24)); paint.setAntiAlias(true); for (int i = 0; i < 4; ++i) { SkString str; str.appendScalar(k[i]); SkScalar width = paint.measureText(str.c_str(), str.size()); canvas->drawText(str.c_str(), str.size(), x, y + paint.getTextSize(), paint); x += width + SkIntToScalar(10); } }
static jfloat measureText_String(JNIEnv* env, jobject jpaint, jstring text) { NPE_CHECK_RETURN_ZERO(env, jpaint); NPE_CHECK_RETURN_ZERO(env, text); SkPaint* paint = GraphicsJNI::getNativePaint(env, jpaint); const jchar* textArray = env->GetStringChars(text, NULL); size_t textLength = env->GetStringLength(text); jfloat width = SkScalarToFloat(paint->measureText(textArray, textLength << 1)); env->ReleaseStringChars(text, textArray); return width; }
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const { SkASSERT(sizeof(glyph) == 2); // compile-time assert SkPaint paint; m_font.setupPaint(&paint); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); SkScalar width = paint.measureText(&glyph, 2); return SkScalarToFloat(width); }
void recordCanvas(SkCanvas* canvas) override { SkPaint paint; paint.setTextSize(fTextSize); paint.setColor(SK_ColorBLACK); const char* text = "Hamburgefons"; size_t len = strlen(text); const SkScalar textWidth = paint.measureText(text, len); for (SkScalar x = 0; x < fPictureWidth; x += textWidth) { for (SkScalar y = 0; y < fPictureHeight; y += fTextSize) { canvas->drawText(text, len, x, y, paint); } } }
float SimpleFontData::platformWidthForGlyph(Glyph glyph) const { if (!m_platformData.size()) return 0; SkASSERT(sizeof(glyph) == 2); // compile-time assert SkPaint paint; m_platformData.setupPaint(&paint); paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); SkScalar width = paint.measureText(&glyph, 2); if (!paint.isSubpixelText()) width = SkScalarRoundToInt(width); return SkScalarToFloat(width); }
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); } }