aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkPaint.cpp
diff options
context:
space:
mode:
authorGravatar fmalita <fmalita@chromium.org>2016-07-28 09:47:24 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-28 09:47:24 -0700
commiteae6a9127707b9391546012d11bcc7d9920dfa6d (patch)
tree911dfa97ca9220a4ee21904f10508c7e32894488 /src/core/SkPaint.cpp
parentfa84d94bb0b226f81b7eaa411aabbbaec3d180cb (diff)
SkPaint intercept API for SkTextBlob and horizontal text
Add getPosTextHIntercepts(), getTextBlobIntercepts(). Consolidate the implementation in GetTextIntercepts<> template. BUG=chormium:581456 R=caryclark@google.com,reed@google.com GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2186663004 Review-Url: https://codereview.chromium.org/2186663004
Diffstat (limited to 'src/core/SkPaint.cpp')
-rw-r--r--src/core/SkPaint.cpp106
1 files changed, 79 insertions, 27 deletions
diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp
index 528b1d0404..07c10d5a78 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;
}