move intercepts impl into textblob

Bug: skia:
Change-Id: I1d2070546e08c050b7f340f1b447fec922cfb153
Reviewed-on: https://skia-review.googlesource.com/c/176589
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Herb Derby <herb@google.com>
This commit is contained in:
Mike Reed 2018-12-11 15:09:04 -05:00 committed by Skia Commit-Bot
parent 5beabfe918
commit cfb012032b
3 changed files with 64 additions and 87 deletions

View File

@ -1097,7 +1097,8 @@ public:
const SkPoint pos[], SkPath* path) const;
#endif
/** Returns the number of intervals that intersect bounds.
/** DEPRECATED -- call method on SkTextBlob
Returns the number of intervals that intersect bounds.
bounds describes a pair of lines parallel to the text advance.
The return count is zero or a multiple of two, and is at most twice the number of glyphs in
the string.
@ -1238,13 +1239,6 @@ private:
SkScalar measure_text(SkGlyphCache*, const char* text, size_t length,
int* count, SkRect* bounds) const;
int getTextIntercepts(const SkFont&, const SkGlyphID[], int count, SkScalar x, SkScalar y,
const SkScalar bounds[2], SkScalar* intervals) const;
int getPosTextIntercepts(const SkFont&, const SkGlyphID[], int count, const SkPoint pos[],
const SkScalar bounds[2], SkScalar* intervals) const;
int getPosTextHIntercepts(const SkFont&, const SkGlyphID[], int count, const SkScalar xpos[],
SkScalar constY, const SkScalar bounds[2], SkScalar* intervals) const;
/*
* The luminance color is used to determine which Gamma Canonical color to map to. This is
* really only used by backends which want to cache glyph masks, and need some way to know if

View File

@ -391,83 +391,9 @@ void SkPaint::getPosTextPath(const void* text, size_t length,
font.getPaths(gly.glyphs(), gly.count(), PathPosProc, &rec);
}
template <SkTextInterceptsIter::TextType TextType, typename Func>
int GetTextIntercepts(const SkFont& font, const SkPaint& paint, const SkGlyphID glyphs[],
int glyphCount, const SkScalar bounds[2], SkScalar* array, Func posMaker) {
SkASSERT(glyphCount == 0 || glyphs != nullptr);
const SkPoint pos0 = posMaker(0);
SkTextInterceptsIter iter(glyphs, glyphCount, font, paint, bounds, pos0.x(), pos0.y(), TextType);
int i = 0;
int count = 0;
while (iter.next(array, &count)) {
if (TextType == SkTextInterceptsIter::TextType::kPosText) {
const SkPoint pos = posMaker(++i);
iter.setPosition(pos.x(), pos.y());
}
}
return count;
}
int SkPaint::getTextIntercepts(const SkFont& font, const SkGlyphID glyphs[], int count,
SkScalar x, SkScalar y, const SkScalar bounds[2],
SkScalar* array) const {
return GetTextIntercepts<SkTextInterceptsIter::TextType::kText>(
font, *this, glyphs, count, bounds, array, [&x, &y] (int) -> SkPoint {
return SkPoint::Make(x, y);
});
}
int SkPaint::getPosTextIntercepts(const SkFont& font, const SkGlyphID glyphs[], int count,
const SkPoint pos[], const SkScalar bounds[2],
SkScalar* array) const {
return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
font, *this, glyphs, count, bounds, array, [&pos] (int i) -> SkPoint {
return pos[i];
});
}
int SkPaint::getPosTextHIntercepts(const SkFont& font, const SkGlyphID glyphs[], int count,
const SkScalar xpos[], SkScalar constY, const SkScalar bounds[2],
SkScalar* array) const {
return GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
font, *this, glyphs, count, 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;
SkTextBlobRunIterator it(blob);
while (!it.done()) {
SkScalar* runIntervals = intervals ? intervals + count : nullptr;
switch (it.positioning()) {
case SkTextBlobRunIterator::kDefault_Positioning:
count += this->getTextIntercepts(it.font(), it.glyphs(), it.glyphCount(), it.offset().x(),
it.offset().y(), bounds, runIntervals);
break;
case SkTextBlobRunIterator::kHorizontal_Positioning:
count += this->getPosTextHIntercepts(it.font(), it.glyphs(), it.glyphCount(), it.pos(),
it.offset().y(), bounds, runIntervals);
break;
case SkTextBlobRunIterator::kFull_Positioning:
count += this->getPosTextIntercepts(it.font(), it.glyphs(), it.glyphCount(),
reinterpret_cast<const SkPoint*>(it.pos()), bounds, runIntervals);
break;
}
it.next();
}
return count;
return blob->getIntercepts(bounds, intervals, this);
}
// return true if the paint is just a single color (i.e. not a shader). If its

View File

@ -586,16 +586,73 @@ sk_sp<SkTextBlob> SkTextBlobBuilder::make() {
}
///////////////////////////////////////////////////////////////////////////////////////////////////
#include "SkTextToPathIter.h"
template <SkTextInterceptsIter::TextType TextType, typename Func>
int GetTextIntercepts(const SkFont& font, const SkPaint& paint, const SkGlyphID glyphs[],
int glyphCount, const SkScalar bounds[2], SkScalar* array, Func posMaker) {
SkASSERT(glyphCount == 0 || glyphs != nullptr);
const SkPoint pos0 = posMaker(0);
SkTextInterceptsIter iter(glyphs, glyphCount, font, paint, bounds, pos0.x(), pos0.y(),
TextType);
int i = 0;
int count = 0;
while (iter.next(array, &count)) {
if (TextType == SkTextInterceptsIter::TextType::kPosText) {
const SkPoint pos = posMaker(++i);
iter.setPosition(pos.x(), pos.y());
}
}
return count;
}
int SkTextBlob::getIntercepts(const SkScalar bounds[2], SkScalar intervals[],
const SkPaint* paint) const {
SkPaint defaultPaint;
if (!paint) {
paint = &defaultPaint;
int count = 0;
SkTextBlobRunIterator it(this);
while (!it.done()) {
SkScalar* runIntervals = intervals ? intervals + count : nullptr;
const SkFont& font = it.font();
const SkGlyphID* glyphs = it.glyphs();
const int glyphCount = it.glyphCount();
switch (it.positioning()) {
case SkTextBlobRunIterator::kDefault_Positioning: {
SkPoint loc = it.offset();
count += GetTextIntercepts<SkTextInterceptsIter::TextType::kText>(
font, *paint, glyphs, glyphCount, bounds, runIntervals, [loc] (int) {
return loc;
});
} break;
case SkTextBlobRunIterator::kHorizontal_Positioning: {
const SkScalar* xpos = it.pos();
const SkScalar constY = it.offset().fY;
count += GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
font, *paint, glyphs, glyphCount, bounds, runIntervals, [xpos, constY] (int i) {
return SkPoint::Make(xpos[i], constY);
});
} break;
case SkTextBlobRunIterator::kFull_Positioning: {
const SkPoint* pos = reinterpret_cast<const SkPoint*>(it.pos());
count += GetTextIntercepts<SkTextInterceptsIter::TextType::kPosText>(
font, *paint, glyphs, glyphCount, bounds, runIntervals, [pos] (int i) {
return pos[i];
});
} break;
}
it.next();
}
return paint->getTextBlobIntercepts(this, bounds, intervals);
return count;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
void SkTextBlobPriv::Flatten(const SkTextBlob& blob, SkWriteBuffer& buffer) {
buffer.writeRect(blob.fBounds);