Index: gm/drawatlas.cpp |
diff --git a/gm/drawatlas.cpp b/gm/drawatlas.cpp |
index ca0e9b91ba387666d956695c4e998e14b93a425a..a98b176a376674f04d787062635931d2a20d26ed 100644 |
--- a/gm/drawatlas.cpp |
+++ b/gm/drawatlas.cpp |
@@ -110,56 +110,62 @@ static void draw_text_on_path_rigid(SkCanvas* canvas, const void* text, size_t l |
SkPathMeasure meas(path, false); |
int count = paint.countText(text, length); |
- SkAutoSTArray<100, SkRSXform> xform(count); |
+ size_t size = count * (sizeof(SkRSXform) + sizeof(SkScalar)); |
+ SkAutoSMalloc<512> storage(size); |
+ SkRSXform* xform = (SkRSXform*)storage.get(); |
+ SkScalar* widths = (SkScalar*)(xform + count); |
+ |
+ paint.getTextWidths(text, length, widths); |
for (int i = 0; i < count; ++i) { |
+ // we want to position each character on the center of its advance |
+ const SkScalar offset = SkScalarHalf(widths[i]); |
SkPoint pos; |
SkVector tan; |
- if (!meas.getPosTan(xy[i].x(), &pos, &tan)) { |
+ if (!meas.getPosTan(xy[i].x() + offset, &pos, &tan)) { |
pos = xy[i]; |
tan.set(1, 0); |
} |
xform[i].fSCos = tan.x(); |
xform[i].fSSin = tan.y(); |
- xform[i].fTx = pos.x() - tan.y() * xy[i].y(); |
- xform[i].fTy = pos.y() + tan.x() * xy[i].y(); |
+ xform[i].fTx = pos.x() - tan.y() * xy[i].y() - tan.x() * offset; |
+ xform[i].fTy = pos.y() + tan.x() * xy[i].y() - tan.y() * offset; |
} |
- canvas->drawTextRSXform(text, length, &xform[0], nullptr, paint); |
+ // Compute a conservative bounds so we can cull the draw |
+ const SkRect font = paint.getFontBounds(); |
+ const SkScalar max = SkTMax(SkTMax(SkScalarAbs(font.fLeft), SkScalarAbs(font.fRight)), |
+ SkTMax(SkScalarAbs(font.fTop), SkScalarAbs(font.fBottom))); |
+ const SkRect bounds = path.getBounds().makeOutset(max, max); |
+ |
+ canvas->drawTextRSXform(text, length, &xform[0], &bounds, paint); |
+ |
+ if (true) { |
+ SkPaint p; |
+ p.setStyle(SkPaint::kStroke_Style); |
+ canvas->drawRect(bounds, p); |
+ } |
} |
-DEF_SIMPLE_GM(drawTextRSXform, canvas, 510, 370) { |
+DEF_SIMPLE_GM(drawTextRSXform, canvas, 860, 860) { |
const char text0[] = "ABCDFGHJKLMNOPQRSTUVWXYZ"; |
- const char text1[] = "AAAAAAAAAAAAAAAAAAAAAAAAAA"; |
const int N = sizeof(text0) - 1; |
SkPoint pos[N]; |
- SkRSXform xform[N]; |
- canvas->translate(0, 30); |
+ SkPaint paint; |
+ paint.setAntiAlias(true); |
+ paint.setTextSize(100); |
- SkScalar x = 20; |
- SkScalar dx = 20; |
- SkScalar rad = 0; |
- SkScalar drad = 2 * SK_ScalarPI / (N - 1); |
+ SkScalar x = 0; |
for (int i = 0; i < N; ++i) { |
- xform[i].fSCos = SkScalarCos(rad); |
- xform[i].fSSin = SkScalarSin(rad); |
- xform[i].fTx = x; |
- xform[i].fTy = 0; |
- pos[i].set(x, -10); |
- x += dx; |
- rad += drad; |
+ pos[i].set(x, 0); |
+ x += paint.measureText(&text0[i], 1); |
} |
- SkPaint paint; |
- paint.setAntiAlias(true); |
- paint.setTextSize(20); |
- canvas->drawTextRSXform(text0, N, xform, nullptr, paint); |
- |
SkPath path; |
- path.addOval(SkRect::MakeXYWH(150, 100, 200, 200)); |
+ path.addOval(SkRect::MakeXYWH(160, 160, 540, 540)); |
- draw_text_on_path_rigid(canvas, text1, N, pos, path, paint); |
+ draw_text_on_path_rigid(canvas, text0, N, pos, path, paint); |
paint.setStyle(SkPaint::kStroke_Style); |
canvas->drawPath(path, paint); |