void SkPictureRecord::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { size_t points = paint.countText(text, byteLength); if (0 == points) return; bool fast = paint.canComputeFastBounds(); addDraw(fast ? DRAW_POS_TEXT_H_TOP_BOTTOM : DRAW_POS_TEXT_H); addPaint(paint); addText(text, byteLength); addInt(points); #ifdef SK_DEBUG_SIZE size_t start = fWriter.size(); #endif if (fast) { addFontMetricsTopBottom(paint, constY); } addScalar(constY); fWriter.writeMul4(xpos, points * sizeof(SkScalar)); #ifdef SK_DEBUG_SIZE fPointBytes += fWriter.size() - start; fPointWrites += points; #endif validate(); }
void SkRecorder::drawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { const unsigned points = paint.countText(text, byteLength); APPEND(DrawPosTextH, this->copy((const char*)text, byteLength), byteLength, this->copy(xpos, points), constY, delay_copy(paint)); }
void SkPipeCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], const SkRect* cull, const SkPaint& paint) { SkASSERT(byteLength); bool compact = fits_in(byteLength, 23); unsigned extra = compact ? (byteLength << 1) : 0; if (cull) { extra |= 1; } SkPipeWriter writer(this); writer.write32(pack_verb(SkPipeVerb::kDrawTextRSXform, extra)); if (!compact) { writer.write32(SkToU32(byteLength)); } write_pad(&writer, text, byteLength); int count = paint.countText(text, byteLength); writer.write32(count); // maybe we can/should store this in extra as well? writer.write(xform, count * sizeof(SkRSXform)); if (cull) { writer.writeRect(*cull); } write_paint(writer, paint, kText_PaintUsage); }
void operator()(const char text[], size_t length, SkScalar x, SkScalar y, const SkPaint& paint) override { SkPaint p(paint); p.setTextEncoding(SkPaint::kGlyphID_TextEncoding); const int count = paint.countText(text, length); paint.textToGlyphs(text, length, fBuilder.allocRun(p, count, x, y).glyphs); }
void SkRecorder::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], const SkRect* cull, const SkPaint& paint) { APPEND(DrawTextRSXform, paint, this->copy((const char*)text, byteLength), byteLength, this->copy(xform, paint.countText(text, byteLength)), this->copy(cull)); }
void SkRecorder::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { const int points = paint.countText(text, byteLength); APPEND(DrawPosText, paint, this->copy((const char*)text, byteLength), byteLength, this->copy(pos, points)); }
void SkRecorder::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { const int points = paint.countText(text, byteLength); APPEND(DrawPosTextH, paint, this->copy((const char*)text, byteLength), SkToUInt(byteLength), constY, this->copy(xpos, points)); }
void LoggingCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { AutoLogger logger(this); RefPtr<JSONObject> params = logger.logItemWithParams("drawPosText"); params->setString("text", stringForText(text, byteLength, paint)); size_t pointsCount = paint.countText(text, byteLength); params->setArray("pos", arrayForSkPoints(pointsCount, pos)); params->setObject("paint", objectForSkPaint(paint)); this->SkCanvas::onDrawPosText(text, byteLength, pos, paint); }
void SkPictureRecord::drawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { size_t points = paint.countText(text, byteLength); if (0 == points) return; bool canUseDrawH = true; // check if the caller really should have used drawPosTextH() { const SkScalar firstY = pos[0].fY; for (size_t index = 1; index < points; index++) { if (pos[index].fY != firstY) { canUseDrawH = false; break; } } } bool fast = canUseDrawH && paint.canComputeFastBounds(); if (fast) { addDraw(DRAW_POS_TEXT_H_TOP_BOTTOM); } else { addDraw(canUseDrawH ? DRAW_POS_TEXT_H : DRAW_POS_TEXT); } addPaint(paint); addText(text, byteLength); addInt(points); #ifdef SK_DEBUG_SIZE size_t start = fWriter.size(); #endif if (canUseDrawH) { if (fast) { addFontMetricsTopBottom(paint, pos[0].fY); } addScalar(pos[0].fY); SkScalar* xptr = (SkScalar*)fWriter.reserve(points * sizeof(SkScalar)); for (size_t index = 0; index < points; index++) *xptr++ = pos[index].fX; } else { fWriter.writeMul4(pos, points * sizeof(SkPoint)); } #ifdef SK_DEBUG_SIZE fPointBytes += fWriter.size() - start; fPointWrites += points; #endif validate(); }
void SkPipeCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { SkASSERT(byteLength); bool compact = fits_in(byteLength, 24); SkPipeWriter writer(this); writer.write32(pack_verb(SkPipeVerb::kDrawPosText, compact ? (unsigned)byteLength : 0)); if (!compact) { writer.write32(SkToU32(byteLength)); } write_pad(&writer, text, byteLength); writer.writePointArray(pos, paint.countText(text, byteLength)); write_paint(writer, paint, kText_PaintUsage); }
static void exercise_draw_pos_text_h(SkCanvas* canvas, const char* text, SkScalar x, SkScalar y, const SkPaint& paint) { size_t textLen = strlen(text); int count = paint.countText(text, textLen); SkAutoTArray<SkScalar> widths(count); paint.getTextWidths(text, textLen, &widths[0]); SkAutoTArray<SkScalar> pos(count); for (int i = 0; i < count; ++i) { pos[i] = x; x += widths[i]; } canvas->drawPosTextH(text, textLen, &pos[0], y, paint); }
void SkPictureRecord::onDrawPosText(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) { int points = paint.countText(text, byteLength); // op + paint index + length + 'length' worth of data + num points + x&y point data size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + kUInt32Size + points * sizeof(SkPoint); DrawType op = DRAW_POS_TEXT; size_t initialOffset = this->addDraw(op, &size); this->addPaint(paint); this->addText(text, byteLength); this->addInt(points); fWriter.writeMul4(pos, points * sizeof(SkPoint)); this->validate(initialOffset, size); }
void SkPictureRecord::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { int points = paint.countText(text, byteLength); // op + paint index + length + 'length' worth of data + num points size_t size = 3 * kUInt32Size + SkAlign4(byteLength) + 1 * kUInt32Size; // + y + the actual points size += 1 * kUInt32Size + points * sizeof(SkScalar); size_t initialOffset = this->addDraw(DRAW_POS_TEXT_H, &size); this->addPaint(paint); this->addText(text, byteLength); this->addInt(points); this->addScalar(constY); fWriter.writeMul4(xpos, points * sizeof(SkScalar)); this->validate(initialOffset, size); }
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); } }
SkDrawPosTextCommand::SkDrawPosTextCommand(const void* text, size_t byteLength, const SkPoint pos[], const SkPaint& paint) : INHERITED(DRAW_POS_TEXT) { size_t numPts = paint.countText(text, byteLength); fText = new char[byteLength]; memcpy(fText, text, byteLength); fByteLength = byteLength; fPos = new SkPoint[numPts]; memcpy(fPos, pos, numPts * sizeof(SkPoint)); fPaint = paint; fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding())); // TODO(chudy): Test that this works. fInfo.push(SkObjectParser::PointsToString(pos, 1)); fInfo.push(SkObjectParser::PaintToString(paint)); }
void SkBBoxRecord::onDrawPosTextH(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) { size_t numChars = paint.countText(text, byteLength); if (numChars == 0) { return; } const SkFlatData* flatPaintData = this->getFlatPaintData(paint); WriteTopBot(paint, *flatPaintData); SkScalar top = flatPaintData->topBot()[0]; SkScalar bottom = flatPaintData->topBot()[1]; SkScalar pad = top - bottom; SkRect bbox; bbox.fLeft = SK_ScalarMax; bbox.fRight = SK_ScalarMin; for (size_t i = 0; i < numChars; ++i) { if (xpos[i] < bbox.fLeft) { bbox.fLeft = xpos[i]; } if (xpos[i] > bbox.fRight) { bbox.fRight = xpos[i]; } } // pad horizontally by max glyph height pad = hack_373785_amend_pad(pad); bbox.fLeft += pad; bbox.fRight -= pad; bbox.fTop = top + constY; bbox.fBottom = bottom + constY; if (!this->transformBounds(bbox, &paint)) { return; } // This is the equivalent of calling: // INHERITED::drawPosTextH(text, byteLength, xpos, constY, paint); // but we filled our flat paint beforehand so that we could get font metrics. drawPosTextHImpl(text, byteLength, xpos, constY, paint, flatPaintData); }
SkDrawPosTextHCommand::SkDrawPosTextHCommand(const void* text, size_t byteLength, const SkScalar xpos[], SkScalar constY, const SkPaint& paint) : INHERITED(DRAW_POS_TEXT_H) { size_t numPts = paint.countText(text, byteLength); fText = new char[byteLength]; memcpy(fText, text, byteLength); fByteLength = byteLength; fXpos = new SkScalar[numPts]; memcpy(fXpos, xpos, numPts * sizeof(SkScalar)); fConstY = constY; fPaint = paint; fInfo.push(SkObjectParser::TextToString(text, byteLength, paint.getTextEncoding())); fInfo.push(SkObjectParser::ScalarToString(xpos[0], "XPOS: ")); fInfo.push(SkObjectParser::ScalarToString(constY, "SkScalar constY: ")); fInfo.push(SkObjectParser::PaintToString(paint)); }
void SkPictureRecord::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], const SkRect* cull, const SkPaint& paint) { const int count = paint.countText(text, byteLength); // [op + paint-index + count + flags + length] + [text] + [xform] + cull size_t size = 5 * kUInt32Size + SkAlign4(byteLength) + count * sizeof(SkRSXform); uint32_t flags = 0; if (cull) { flags |= DRAW_TEXT_RSXFORM_HAS_CULL; size += sizeof(SkRect); } size_t initialOffset = this->addDraw(DRAW_TEXT_RSXFORM, &size); this->addPaint(paint); this->addInt(count); this->addInt(flags); this->addText(text, byteLength); fWriter.write(xform, count * sizeof(SkRSXform)); if (cull) { fWriter.write(cull, sizeof(SkRect)); } this->validate(initialOffset, size); }
* Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "gm.h" // https://bugs.skia.org/5321 // two strings should draw the same. PDF did not. DEF_SIMPLE_GM(skbug_5321, canvas, 128, 128) { SkPaint paint; paint.setStyle(SkPaint::kFill_Style); paint.setTextSize(30); paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); const char text[] = "x\314\200y"; // utf8(u"x\u0300y") SkScalar x = 20, y = 45; size_t byteLength = strlen(text); canvas->drawText(text, byteLength, x, y, paint); int glyph_count = paint.countText(text, byteLength); SkAutoTMalloc<SkScalar> widths(glyph_count); (void)paint.getTextWidths(text, byteLength, &widths[0]); for (int i = 0; i < glyph_count; ++i) { SkScalar w = widths[i]; widths[i] = x; x += w; } y += paint.getFontMetrics(nullptr); canvas->drawPosTextH(text, byteLength, &widths[0], y, paint); }