| Index: src/core/SkPaint.cpp
|
| diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
|
| index 528b1d0404507fb484ab1da564bf716f7e2a8181..07c10d5a78cd4a0a9ee8b583ffe559f38ac44130 100644
|
| --- a/src/core/SkPaint.cpp
|
| +++ b/src/core/SkPaint.cpp
|
| @@ -27,12 +27,14 @@
|
| #include "SkShader.h"
|
| #include "SkStringUtils.h"
|
| #include "SkStroke.h"
|
| +#include "SkStrokeRec.h"
|
| +#include "SkSurfacePriv.h"
|
| +#include "SkTextBlob.h"
|
| +#include "SkTextBlobRunIterator.h"
|
| #include "SkTextFormatParams.h"
|
| #include "SkTextToPathIter.h"
|
| #include "SkTLazy.h"
|
| #include "SkTypeface.h"
|
| -#include "SkStrokeRec.h"
|
| -#include "SkSurfacePriv.h"
|
| #include "SkXfermode.h"
|
|
|
| static inline uint32_t set_clear_mask(uint32_t bits, bool cond, uint32_t mask) {
|
| @@ -1127,23 +1129,6 @@ void SkPaint::getTextPath(const void* textData, size_t length,
|
| }
|
| }
|
|
|
| -int SkPaint::getTextIntercepts(const void* textData, size_t length,
|
| - SkScalar x, SkScalar y, const SkScalar bounds[2],
|
| - SkScalar* array) const {
|
| - SkASSERT(length == 0 || textData != nullptr);
|
| - if (!length) {
|
| - return 0;
|
| - }
|
| -
|
| - const char* text = (const char*) textData;
|
| - SkTextInterceptsIter iter(text, length, *this, bounds, x, y,
|
| - SkTextInterceptsIter::TextType::kText);
|
| - int count = 0;
|
| - while (iter.next(array, &count)) {
|
| - }
|
| - return count;
|
| -}
|
| -
|
| void SkPaint::getPosTextPath(const void* textData, size_t length,
|
| const SkPoint pos[], SkPath* path) const {
|
| SkASSERT(length == 0 || textData != nullptr);
|
| @@ -1173,22 +1158,89 @@ void SkPaint::getPosTextPath(const void* textData, size_t length,
|
| }
|
| }
|
|
|
| -int SkPaint::getPosTextIntercepts(const void* textData, size_t length, const SkPoint pos[],
|
| - const SkScalar bounds[2], SkScalar* array) const {
|
| - SkASSERT(length == 0 || textData != nullptr);
|
| +template <SkTextInterceptsIter::TextType TextType, typename Func>
|
| +int GetTextIntercepts(const SkPaint& paint, const void* text, size_t length,
|
| + const SkScalar bounds[2], SkScalar* array, Func posMaker) {
|
| + SkASSERT(length == 0 || text != nullptr);
|
| if (!length) {
|
| return 0;
|
| }
|
|
|
| - const char* text = (const char*) textData;
|
| - SkTextInterceptsIter iter(text, length, *this, bounds, pos[0].fX, pos[0].fY,
|
| - SkTextInterceptsIter::TextType::kPosText);
|
| + const SkPoint pos0 = posMaker(0);
|
| + SkTextInterceptsIter iter(static_cast<const char*>(text), length, paint, bounds,
|
| + pos0.x(), pos0.y(), TextType);
|
| +
|
| int i = 0;
|
| int count = 0;
|
| while (iter.next(array, &count)) {
|
| - i++;
|
| - iter.setPosition(pos[i].fX, pos[i].fY);
|
| + if (TextType == SkTextInterceptsIter::TextType::kPosText) {
|
| + const SkPoint pos = posMaker(++i);
|
| + iter.setPosition(pos.x(), pos.y());
|
| + }
|
| + }
|
| +
|
| + return count;
|
| +}
|
| +
|
| +int SkPaint::getTextIntercepts(const void* textData, size_t length,
|
| + SkScalar x, SkScalar y, const SkScalar bounds[2],
|
| + SkScalar* array) const {
|
| +
|
| + return GetTextIntercepts<SkTextInterceptsIter::TextType::kText>(
|
| + *this, textData, length, bounds, array, [&x, &y] (int) -> SkPoint {
|
| + return SkPoint::Make(x, y);
|
| + });
|
| +}
|
| +
|
| +int SkPaint::getPosTextIntercepts(const void* textData, size_t length, const SkPoint pos[],
|
| + const SkScalar bounds[2], SkScalar* array) const {
|
| +
|
| + return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
|
| + *this, textData, length, bounds, array, [&pos] (int i) -> SkPoint {
|
| + return pos[i];
|
| + });
|
| +}
|
| +
|
| +int SkPaint::getPosTextHIntercepts(const void* textData, size_t length, const SkScalar xpos[],
|
| + SkScalar constY, const SkScalar bounds[2],
|
| + SkScalar* array) const {
|
| +
|
| + return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
|
| + *this, textData, length, bounds, array, [&xpos, &constY] (int i) -> SkPoint {
|
| + return SkPoint::Make(xpos[i], constY);
|
| + });
|
| +}
|
| +
|
| +int SkPaint::getTextBlobIntercepts(const SkTextBlob* blob, const SkScalar bounds[2],
|
| + SkScalar* intervals) const {
|
| + int count = 0;
|
| + SkPaint runPaint(*this);
|
| +
|
| + SkTextBlobRunIterator it(blob);
|
| + while (!it.done()) {
|
| + it.applyFontToPaint(&runPaint);
|
| + const size_t runByteCount = it.glyphCount() * sizeof(SkGlyphID);
|
| + SkScalar* runIntervals = intervals ? intervals + count : nullptr;
|
| +
|
| + switch (it.positioning()) {
|
| + case SkTextBlob::kDefault_Positioning:
|
| + count += runPaint.getTextIntercepts(it.glyphs(), runByteCount, it.offset().x(),
|
| + it.offset().y(), bounds, runIntervals);
|
| + break;
|
| + case SkTextBlob::kHorizontal_Positioning:
|
| + count += runPaint.getPosTextHIntercepts(it.glyphs(), runByteCount, it.pos(),
|
| + it.offset().y(), bounds, runIntervals);
|
| + break;
|
| + case SkTextBlob::kFull_Positioning:
|
| + count += runPaint.getPosTextIntercepts(it.glyphs(), runByteCount,
|
| + reinterpret_cast<const SkPoint*>(it.pos()),
|
| + bounds, runIntervals);
|
| + break;
|
| + }
|
| +
|
| + it.next();
|
| }
|
| +
|
| return count;
|
| }
|
|
|
|
|