use common impl for drawTextOnPath
BUG=skia:
Review URL: https://codereview.chromium.org/925343003
diff --git a/include/core/SkBitmapDevice.h b/include/core/SkBitmapDevice.h
index a801420..8ca6a52 100644
--- a/include/core/SkBitmapDevice.h
+++ b/include/core/SkBitmapDevice.h
@@ -93,9 +93,6 @@
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) SK_OVERRIDE;
- virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) SK_OVERRIDE;
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
const SkPoint verts[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,
diff --git a/include/core/SkDevice.h b/include/core/SkDevice.h
index 9f3ac58..777b7f8 100644
--- a/include/core/SkDevice.h
+++ b/include/core/SkDevice.h
@@ -218,9 +218,6 @@
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint& paint) = 0;
- virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) = 0;
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
const SkPoint verts[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,
@@ -238,6 +235,8 @@
virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
const SkPaint&) = 0;
+ virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
+ const SkMatrix*, const SkPaint&);
bool readPixels(const SkImageInfo&, void* dst, size_t rowBytes, int x, int y);
///////////////////////////////////////////////////////////////////////////
diff --git a/include/core/SkDraw.h b/include/core/SkDraw.h
index 2bb9c89..7b5514d 100644
--- a/include/core/SkDraw.h
+++ b/include/core/SkDraw.h
@@ -68,8 +68,6 @@
void drawPosText(const char text[], size_t byteLength,
const SkScalar pos[], int scalarsPerPosition,
const SkPoint& offset, const SkPaint& paint) const;
- void drawTextOnPath(const char text[], size_t byteLength,
- const SkPath&, const SkMatrix*, const SkPaint&) const;
void drawVertices(SkCanvas::VertexMode mode, int count,
const SkPoint vertices[], const SkPoint textures[],
const SkColor colors[], SkXfermode* xmode,
diff --git a/include/pdf/SkPDFDevice.h b/include/pdf/SkPDFDevice.h
index 66689f2..af65005 100644
--- a/include/pdf/SkPDFDevice.h
+++ b/include/pdf/SkPDFDevice.h
@@ -98,9 +98,6 @@
void drawPosText(const SkDraw&, const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint&) SK_OVERRIDE;
- void drawTextOnPath(const SkDraw&, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) SK_OVERRIDE;
void drawVertices(const SkDraw&, SkCanvas::VertexMode,
int vertexCount, const SkPoint verts[],
const SkPoint texs[], const SkColor colors[],
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index 1f17e6f..e545bae 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -329,13 +329,6 @@
draw.drawPosText((const char*)text, len, xpos, scalarsPerPos, offset, paint);
}
-void SkBitmapDevice::drawTextOnPath(const SkDraw& draw, const void* text,
- size_t len, const SkPath& path,
- const SkMatrix* matrix,
- const SkPaint& paint) {
- draw.drawTextOnPath((const char*)text, len, path, matrix, paint);
-}
-
void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
int vertexCount,
const SkPoint verts[], const SkPoint textures[],
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index bc6c892..2f51070 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -10,8 +10,11 @@
#include "SkDraw.h"
#include "SkMetaData.h"
#include "SkPatchUtils.h"
+#include "SkPathMeasure.h"
+#include "SkRasterClip.h"
#include "SkShader.h"
#include "SkTextBlob.h"
+#include "SkTextToPathIter.h"
SkBaseDevice::SkBaseDevice()
: fLeakyProperties(SkNEW_ARGS(SkDeviceProperties, (SkDeviceProperties::kLegacyLCD_InitType)))
@@ -212,6 +215,129 @@
//////////////////////////////////////////////////////////////////////////////////////////
+static void morphpoints(SkPoint dst[], const SkPoint src[], int count,
+ SkPathMeasure& meas, const SkMatrix& matrix) {
+ SkMatrix::MapXYProc proc = matrix.getMapXYProc();
+
+ for (int i = 0; i < count; i++) {
+ SkPoint pos;
+ SkVector tangent;
+
+ proc(matrix, src[i].fX, src[i].fY, &pos);
+ SkScalar sx = pos.fX;
+ SkScalar sy = pos.fY;
+
+ if (!meas.getPosTan(sx, &pos, &tangent)) {
+ // set to 0 if the measure failed, so that we just set dst == pos
+ tangent.set(0, 0);
+ }
+
+ /* This is the old way (that explains our approach but is way too slow
+ SkMatrix matrix;
+ SkPoint pt;
+
+ pt.set(sx, sy);
+ matrix.setSinCos(tangent.fY, tangent.fX);
+ matrix.preTranslate(-sx, 0);
+ matrix.postTranslate(pos.fX, pos.fY);
+ matrix.mapPoints(&dst[i], &pt, 1);
+ */
+ dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy),
+ pos.fY + SkScalarMul(tangent.fX, sy));
+ }
+}
+
+/* TODO
+
+ Need differentially more subdivisions when the follow-path is curvy. Not sure how to
+ determine that, but we need it. I guess a cheap answer is let the caller tell us,
+ but that seems like a cop-out. Another answer is to get Rob Johnson to figure it out.
+ */
+static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
+ const SkMatrix& matrix) {
+ SkPath::Iter iter(src, false);
+ SkPoint srcP[4], dstP[3];
+ SkPath::Verb verb;
+
+ while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ morphpoints(dstP, srcP, 1, meas, matrix);
+ dst->moveTo(dstP[0]);
+ break;
+ case SkPath::kLine_Verb:
+ // turn lines into quads to look bendy
+ srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX);
+ srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY);
+ morphpoints(dstP, srcP, 2, meas, matrix);
+ dst->quadTo(dstP[0], dstP[1]);
+ break;
+ case SkPath::kQuad_Verb:
+ morphpoints(dstP, &srcP[1], 2, meas, matrix);
+ dst->quadTo(dstP[0], dstP[1]);
+ break;
+ case SkPath::kCubic_Verb:
+ morphpoints(dstP, &srcP[1], 3, meas, matrix);
+ dst->cubicTo(dstP[0], dstP[1], dstP[2]);
+ break;
+ case SkPath::kClose_Verb:
+ dst->close();
+ break;
+ default:
+ SkDEBUGFAIL("unknown verb");
+ break;
+ }
+ }
+}
+
+void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t byteLength,
+ const SkPath& follow, const SkMatrix* matrix,
+ const SkPaint& paint) {
+ SkASSERT(byteLength == 0 || text != NULL);
+
+ // nothing to draw
+ if (text == NULL || byteLength == 0 || draw.fRC->isEmpty()) {
+ return;
+ }
+
+ SkTextToPathIter iter((const char*)text, byteLength, paint, true);
+ SkPathMeasure meas(follow, false);
+ SkScalar hOffset = 0;
+
+ // need to measure first
+ if (paint.getTextAlign() != SkPaint::kLeft_Align) {
+ SkScalar pathLen = meas.getLength();
+ if (paint.getTextAlign() == SkPaint::kCenter_Align) {
+ pathLen = SkScalarHalf(pathLen);
+ }
+ hOffset += pathLen;
+ }
+
+ const SkPath* iterPath;
+ SkScalar xpos;
+ SkMatrix scaledMatrix;
+ SkScalar scale = iter.getPathScale();
+
+ scaledMatrix.setScale(scale, scale);
+
+ while (iter.next(&iterPath, &xpos)) {
+ if (iterPath) {
+ SkPath tmp;
+ SkMatrix m(scaledMatrix);
+
+ tmp.setIsVolatile(true);
+ m.postTranslate(xpos + hOffset, 0);
+ if (matrix) {
+ m.postConcat(*matrix);
+ }
+ morphpath(&tmp, *iterPath, meas, m);
+ this->drawPath(draw, tmp, iter.getPaint(), NULL, true);
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+
uint32_t SkBaseDevice::filterTextFlags(const SkPaint& paint) const {
uint32_t flags = paint.getFlags();
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index 03b3311..f40c1bb 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -1866,135 +1866,6 @@
///////////////////////////////////////////////////////////////////////////////
-#include "SkPathMeasure.h"
-
-static void morphpoints(SkPoint dst[], const SkPoint src[], int count,
- SkPathMeasure& meas, const SkMatrix& matrix) {
- SkMatrix::MapXYProc proc = matrix.getMapXYProc();
-
- for (int i = 0; i < count; i++) {
- SkPoint pos;
- SkVector tangent;
-
- proc(matrix, src[i].fX, src[i].fY, &pos);
- SkScalar sx = pos.fX;
- SkScalar sy = pos.fY;
-
- if (!meas.getPosTan(sx, &pos, &tangent)) {
- // set to 0 if the measure failed, so that we just set dst == pos
- tangent.set(0, 0);
- }
-
- /* This is the old way (that explains our approach but is way too slow
- SkMatrix matrix;
- SkPoint pt;
-
- pt.set(sx, sy);
- matrix.setSinCos(tangent.fY, tangent.fX);
- matrix.preTranslate(-sx, 0);
- matrix.postTranslate(pos.fX, pos.fY);
- matrix.mapPoints(&dst[i], &pt, 1);
- */
- dst[i].set(pos.fX - SkScalarMul(tangent.fY, sy),
- pos.fY + SkScalarMul(tangent.fX, sy));
- }
-}
-
-/* TODO
-
- Need differentially more subdivisions when the follow-path is curvy. Not sure how to
- determine that, but we need it. I guess a cheap answer is let the caller tell us,
- but that seems like a cop-out. Another answer is to get Rob Johnson to figure it out.
-*/
-static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
- const SkMatrix& matrix) {
- SkPath::Iter iter(src, false);
- SkPoint srcP[4], dstP[3];
- SkPath::Verb verb;
-
- while ((verb = iter.next(srcP)) != SkPath::kDone_Verb) {
- switch (verb) {
- case SkPath::kMove_Verb:
- morphpoints(dstP, srcP, 1, meas, matrix);
- dst->moveTo(dstP[0]);
- break;
- case SkPath::kLine_Verb:
- // turn lines into quads to look bendy
- srcP[0].fX = SkScalarAve(srcP[0].fX, srcP[1].fX);
- srcP[0].fY = SkScalarAve(srcP[0].fY, srcP[1].fY);
- morphpoints(dstP, srcP, 2, meas, matrix);
- dst->quadTo(dstP[0], dstP[1]);
- break;
- case SkPath::kQuad_Verb:
- morphpoints(dstP, &srcP[1], 2, meas, matrix);
- dst->quadTo(dstP[0], dstP[1]);
- break;
- case SkPath::kCubic_Verb:
- morphpoints(dstP, &srcP[1], 3, meas, matrix);
- dst->cubicTo(dstP[0], dstP[1], dstP[2]);
- break;
- case SkPath::kClose_Verb:
- dst->close();
- break;
- default:
- SkDEBUGFAIL("unknown verb");
- break;
- }
- }
-}
-
-void SkDraw::drawTextOnPath(const char text[], size_t byteLength,
- const SkPath& follow, const SkMatrix* matrix,
- const SkPaint& paint) const {
- SkASSERT(byteLength == 0 || text != NULL);
-
- // nothing to draw
- if (text == NULL || byteLength == 0 || fRC->isEmpty()) {
- return;
- }
-
- SkTextToPathIter iter(text, byteLength, paint, true);
- SkPathMeasure meas(follow, false);
- SkScalar hOffset = 0;
-
- // need to measure first
- if (paint.getTextAlign() != SkPaint::kLeft_Align) {
- SkScalar pathLen = meas.getLength();
- if (paint.getTextAlign() == SkPaint::kCenter_Align) {
- pathLen = SkScalarHalf(pathLen);
- }
- hOffset += pathLen;
- }
-
- const SkPath* iterPath;
- SkScalar xpos;
- SkMatrix scaledMatrix;
- SkScalar scale = iter.getPathScale();
-
- scaledMatrix.setScale(scale, scale);
-
- while (iter.next(&iterPath, &xpos)) {
- if (iterPath) {
- SkPath tmp;
- SkMatrix m(scaledMatrix);
-
- tmp.setIsVolatile(true);
- m.postTranslate(xpos + hOffset, 0);
- if (matrix) {
- m.postConcat(*matrix);
- }
- morphpath(&tmp, *iterPath, meas, m);
- if (fDevice) {
- fDevice->drawPath(*this, tmp, iter.getPaint(), NULL, true);
- } else {
- this->drawPath(tmp, iter.getPaint(), NULL, true);
- }
- }
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
typedef void (*HairProc)(const SkPoint&, const SkPoint&, const SkRasterClip&,
SkBlitter*);
diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp
index b6cc69d..20dae68 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -1767,15 +1767,6 @@
}
}
-void SkGpuDevice::drawTextOnPath(const SkDraw& draw, const void* text,
- size_t len, const SkPath& path,
- const SkMatrix* m, const SkPaint& paint) {
- CHECK_SHOULD_DRAW(draw);
-
- SkASSERT(draw.fDevice == this);
- draw.drawTextOnPath((const char*)text, len, path, m, paint);
-}
-
///////////////////////////////////////////////////////////////////////////////
bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
diff --git a/src/gpu/SkGpuDevice.h b/src/gpu/SkGpuDevice.h
index 6cbf628..4830c02 100644
--- a/src/gpu/SkGpuDevice.h
+++ b/src/gpu/SkGpuDevice.h
@@ -97,9 +97,6 @@
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint&) SK_OVERRIDE;
- virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint&) SK_OVERRIDE;
virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
const SkPoint verts[], const SkPoint texs[],
const SkColor colors[], SkXfermode* xmode,
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index c3ee262..a15571a 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -1194,15 +1194,6 @@
content.entry()->fContent.writeText("ET\n");
}
-void SkPDFDevice::drawTextOnPath(const SkDraw& d, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) {
- if (d.fClip->isEmpty()) {
- return;
- }
- d.drawTextOnPath((const char*)text, len, path, matrix, paint);
-}
-
void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
int vertexCount, const SkPoint verts[],
const SkPoint texs[], const SkColor colors[],
diff --git a/src/pdf/SkPDFDeviceFlattener.cpp b/src/pdf/SkPDFDeviceFlattener.cpp
index 4774864..ab6ce09 100644
--- a/src/pdf/SkPDFDeviceFlattener.cpp
+++ b/src/pdf/SkPDFDeviceFlattener.cpp
@@ -132,16 +132,6 @@
INHERITED::drawPosText(d, text, len, pos, scalarsPerPos, offset, paint);
}
-void SkPDFDeviceFlattener::drawTextOnPath(const SkDraw& d, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) {
- if (mustPathText(d, paint) || (matrix && matrix->hasPerspective())) {
- d.drawTextOnPath((const char*)text, len, path, matrix, paint);
- return;
- }
- INHERITED::drawTextOnPath(d, text, len, path, matrix, paint);
-}
-
bool SkPDFDeviceFlattener::mustFlatten(const SkDraw& d) const {
// TODO(edisonn): testability, add flag to force return true.
return d.fMatrix->hasPerspective();
diff --git a/src/pdf/SkPDFDeviceFlattener.h b/src/pdf/SkPDFDeviceFlattener.h
index b2c3d7e..acf1447 100644
--- a/src/pdf/SkPDFDeviceFlattener.h
+++ b/src/pdf/SkPDFDeviceFlattener.h
@@ -39,9 +39,6 @@
virtual void drawPosText(const SkDraw&, const void* text, size_t len,
const SkScalar pos[], int scalarsPerPos,
const SkPoint& offset, const SkPaint&) SK_OVERRIDE;
- virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len,
- const SkPath& path, const SkMatrix* matrix,
- const SkPaint& paint) SK_OVERRIDE;
private:
bool mustFlatten(const SkDraw& d) const;