Index: src/core/SkTextToPathIter.h |
diff --git a/src/core/SkTextToPathIter.h b/src/core/SkTextToPathIter.h |
index e98d6d9370ed9fbc5a04dc48f82ef965157318cc..e299552327e44b72a4cc5e9f3029ae77babcc6bd 100644 |
--- a/src/core/SkTextToPathIter.h |
+++ b/src/core/SkTextToPathIter.h |
@@ -13,37 +13,91 @@ |
class SkGlyphCache; |
-class SkTextToPathIter { |
+class SkTextBaseIter { |
+protected: |
+ SkTextBaseIter(const char text[], size_t length, const SkPaint& paint, |
+ bool applyStrokeAndPathEffects); |
+ ~SkTextBaseIter(); |
+ |
+ SkGlyphCache* fCache; |
+ SkPaint fPaint; |
+ SkScalar fScale; |
+ SkFixed fPrevAdvance; |
+ const char* fText; |
+ const char* fStop; |
+ SkMeasureCacheProc fGlyphCacheProc; |
+ |
+ SkScalar fXPos; // accumulated xpos, returned in next |
+ SkAutoKern fAutoKern; |
+ int fXYIndex; // cache for horizontal -vs- vertical text |
+}; |
+ |
+class SkTextToPathIter : SkTextBaseIter { |
public: |
SkTextToPathIter(const char text[], size_t length, const SkPaint& paint, |
- bool applyStrokeAndPathEffects); |
- ~SkTextToPathIter(); |
+ bool applyStrokeAndPathEffects) |
+ : SkTextBaseIter(text, length, paint, applyStrokeAndPathEffects) { |
+ } |
const SkPaint& getPaint() const { return fPaint; } |
SkScalar getPathScale() const { return fScale; } |
- struct Rec { |
- const SkPath* fPath; // may be null for "whitespace" glyphs |
- SkScalar fXPos; |
+ /** |
+ * Returns false when all of the text has been consumed |
+ */ |
+ bool next(const SkPath** path, SkScalar* xpos); |
+}; |
+ |
+class SkTextInterceptsIter : SkTextBaseIter { |
+public: |
+ enum class TextType { |
+ kText, |
+ kPosText |
}; |
+ SkTextInterceptsIter(const char text[], size_t length, const SkPaint& paint, |
+ const SkScalar bounds[2], SkScalar x, SkScalar y, TextType textType) |
+ : SkTextBaseIter(text, length, paint, false) |
+ , fTextType(textType) { |
+ fBoundsBase[0] = bounds[0]; |
+ fBoundsBase[1] = bounds[1]; |
+ this->setPosition(x, y); |
+ } |
+ |
/** |
* Returns false when all of the text has been consumed |
*/ |
- bool next(const SkPath** path, SkScalar* xpos); |
+ bool next(SkScalar* array, int* count); |
-private: |
- SkGlyphCache* fCache; |
- SkPaint fPaint; |
- SkScalar fScale; |
- SkFixed fPrevAdvance; |
- const char* fText; |
- const char* fStop; |
- SkMeasureCacheProc fGlyphCacheProc; |
+ void setPosition(SkScalar x, SkScalar y) { |
+ SkScalar xOffset = TextType::kText == fTextType && fXYIndex ? fXPos : 0; |
+ if (TextType::kPosText == fTextType |
+ && fPaint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first |
+ const char* text = fText; |
+ const SkGlyph& glyph = fGlyphCacheProc(fCache, &text); |
+ SkScalar width = SkScalarMul(SkFixedToScalar((&glyph.fAdvanceX)[0]), fScale); |
+ if (fPaint.getTextAlign() == SkPaint::kCenter_Align) { |
+ width = SkScalarHalf(width); |
+ } |
+ xOffset = width; |
+ } |
- SkScalar fXPos; // accumulated xpos, returned in next |
- SkAutoKern fAutoKern; |
- int fXYIndex; // cache for horizontal -vs- vertical text |
+ for (int i = 0; i < (int) SK_ARRAY_COUNT(fBounds); ++i) { |
+ SkScalar bound = fBoundsBase[i] - (fXYIndex ? x : y); |
+ if (fXYIndex) { |
+ bound += xOffset; |
+ } |
+ fBounds[i] = bound / fScale; |
+ } |
+ |
+ fXPos = xOffset + (fXYIndex ? y : x); |
+ fPrevAdvance = 0; |
+ } |
+ |
+private: |
+ SkScalar fBounds[2]; |
+ SkScalar fBoundsBase[2]; |
+ TextType fTextType; |
}; |
#endif |