diff options
author | fmalita <fmalita@chromium.org> | 2016-07-28 09:47:24 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-28 09:47:24 -0700 |
commit | eae6a9127707b9391546012d11bcc7d9920dfa6d (patch) | |
tree | 911dfa97ca9220a4ee21904f10508c7e32894488 /src/core | |
parent | fa84d94bb0b226f81b7eaa411aabbbaec3d180cb (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')
-rw-r--r-- | src/core/SkPaint.cpp | 106 |
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; } |