Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(148)

Unified Diff: src/core/SkPaint.cpp

Issue 2186663004: SkPaint intercept API for SkTextBlob and horizontal text (Closed) Base URL: https://chromium.googlesource.com/skia.git@master
Patch Set: GM size, comments Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/core/SkPaint.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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;
}
« no previous file with comments | « include/core/SkPaint.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698