breakText on font
Bug: skia: Change-Id: Iebf65b158a0b08ed8e65b77d9d0aeef8c159d5db Reviewed-on: https://skia-review.googlesource.com/c/173770 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
parent
94cca60bfa
commit
da1b99f7f5
@ -295,6 +295,9 @@ public:
|
||||
*/
|
||||
bool containsText(const void* text, size_t byteLength, SkTextEncoding encoding) const;
|
||||
|
||||
size_t breakText(const void* text, size_t length, SkTextEncoding, SkScalar maxWidth,
|
||||
SkScalar* measuredWidth = nullptr) const;
|
||||
|
||||
/** Returns the advance width of text.
|
||||
The advance is the normal distance to move before drawing additional text.
|
||||
Returns the bounding box of text if bounds is not nullptr.
|
||||
|
@ -231,6 +231,55 @@ bool SkFont::containsText(const void* textData, size_t byteLength, SkTextEncodin
|
||||
return true;
|
||||
}
|
||||
|
||||
size_t SkFont::breakText(const void* textD, size_t length, SkTextEncoding encoding,
|
||||
SkScalar maxWidth, SkScalar* measuredWidth) const {
|
||||
if (0 == length || !(maxWidth > 0)) {
|
||||
if (measuredWidth) {
|
||||
*measuredWidth = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (0 == fSize) {
|
||||
if (measuredWidth) {
|
||||
*measuredWidth = 0;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
SkCanonicalizeFont canon(*this);
|
||||
const SkFont& font = canon.getFont();
|
||||
SkScalar scale = canon.getScale();
|
||||
|
||||
auto cache = SkStrikeCache::FindOrCreateStrikeWithNoDeviceExclusive(font);
|
||||
|
||||
const char* text = static_cast<const char*>(textD);
|
||||
const char* stop = text + length;
|
||||
auto glyphCacheProc = SkFontPriv::GetGlyphCacheProc(encoding, false);
|
||||
|
||||
if (scale) {
|
||||
maxWidth /= scale;
|
||||
}
|
||||
|
||||
SkScalar width = 0;
|
||||
while (text < stop) {
|
||||
const char* curr = text;
|
||||
SkScalar x = glyphCacheProc(cache.get(), &text, stop).fAdvanceX;
|
||||
if ((width += x) > maxWidth) {
|
||||
width -= x;
|
||||
text = curr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (measuredWidth) {
|
||||
if (scale) {
|
||||
width *= scale;
|
||||
}
|
||||
*measuredWidth = width;
|
||||
}
|
||||
return text - stop + length;
|
||||
}
|
||||
|
||||
static void set_bounds(const SkGlyph& g, SkRect* bounds) {
|
||||
bounds->set(SkIntToScalar(g.fLeft),
|
||||
SkIntToScalar(g.fTop),
|
||||
|
@ -6,9 +6,23 @@
|
||||
*/
|
||||
|
||||
#include "SkAutoMalloc.h"
|
||||
#include "SkFont.h"
|
||||
#include "SkPaint.h"
|
||||
#include "Test.h"
|
||||
|
||||
static size_t break_text(const SkPaint& paint, const void* text, size_t length, SkScalar maxw,
|
||||
SkScalar* measuredw, skiatest::Reporter* reporter) {
|
||||
size_t n = paint.breakText(text, length, maxw, measuredw);
|
||||
SkScalar measuredw2;
|
||||
size_t n2 = SkFont::LEGACY_ExtractFromPaint(paint).breakText(text, length,
|
||||
(SkTextEncoding)paint.getTextEncoding(), maxw, &measuredw2);
|
||||
REPORTER_ASSERT(reporter, n == n2);
|
||||
if (measuredw) {
|
||||
REPORTER_ASSERT(reporter, *measuredw == measuredw2);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static void test_monotonic(skiatest::Reporter* reporter,
|
||||
const SkPaint& paint,
|
||||
const char* msg) {
|
||||
@ -21,7 +35,7 @@ static void test_monotonic(skiatest::Reporter* reporter,
|
||||
const SkScalar step = SkMaxScalar(width / 10, SK_Scalar1);
|
||||
for (SkScalar w = 0; w <= width; w += step) {
|
||||
SkScalar m;
|
||||
const size_t n = paint.breakText(text, length, w, &m);
|
||||
const size_t n = break_text(paint, text, length, w, &m, reporter);
|
||||
|
||||
REPORTER_ASSERT(reporter, n <= length, msg);
|
||||
REPORTER_ASSERT(reporter, m <= width, msg);
|
||||
@ -51,7 +65,7 @@ static void test_eq_measure_text(skiatest::Reporter* reporter,
|
||||
const SkScalar width = paint.measureText(text, length);
|
||||
|
||||
SkScalar mm;
|
||||
const size_t length2 = paint.breakText(text, length, width, &mm);
|
||||
const size_t length2 = break_text(paint, text, length, width, &mm, reporter);
|
||||
REPORTER_ASSERT(reporter, length2 == length, msg);
|
||||
REPORTER_ASSERT(reporter, mm == width, msg);
|
||||
}
|
||||
@ -67,7 +81,7 @@ static void test_long_text(skiatest::Reporter* reporter,
|
||||
const SkScalar width = paint.measureText(text, kSize);
|
||||
|
||||
SkScalar mm;
|
||||
const size_t length = paint.breakText(text, kSize, width, &mm);
|
||||
const size_t length = break_text(paint, text, kSize, width, &mm, reporter);
|
||||
REPORTER_ASSERT(reporter, length == kSize, msg);
|
||||
REPORTER_ASSERT(reporter, mm == width, msg);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user