From 4014ba6ec7a7825495ac0a6ed591c5dadd30751d Mon Sep 17 00:00:00 2001 From: Hal Canary Date: Tue, 24 Jul 2018 11:33:21 -0400 Subject: SkUtils: remove some versions of UTF routines. Change-Id: Ib1f776ae472117c23d2145253adf25fceb412b32 Reviewed-on: https://skia-review.googlesource.com/143111 Reviewed-by: Herb Derby Commit-Queue: Hal Canary --- gm/atlastext.cpp | 2 +- gm/coloremoji_blendmodes.cpp | 2 +- include/core/SkPaint.h | 2 +- modules/skshaper/src/SkShaper_harfbuzz.cpp | 20 ++++++----- src/core/SkDraw.cpp | 2 +- src/core/SkFindAndPlaceGlyph.h | 49 +++++++++++++++----------- src/core/SkOverdrawCanvas.cpp | 21 ++++++----- src/core/SkPaint.cpp | 56 ++++++++++++++++++------------ src/core/SkStringUtils.cpp | 5 +-- src/core/SkTextToPathIter.h | 2 +- src/gpu/text/GrTextContext.cpp | 6 ++-- src/gpu/text/GrTextUtils.cpp | 2 +- src/svg/SkSVGDevice.cpp | 5 +-- tests/UtilsTest.cpp | 11 +++--- tools/fonts/create_test_font.cpp | 2 +- 15 files changed, 106 insertions(+), 81 deletions(-) diff --git a/gm/atlastext.cpp b/gm/atlastext.cpp index c30a6754db..859b4c356f 100644 --- a/gm/atlastext.cpp +++ b/gm/atlastext.cpp @@ -30,7 +30,7 @@ static SkScalar draw_string(SkAtlasTextTarget* target, const SkString& text, SkS return x; } auto font = SkAtlasTextFont::Make(typeface, size); - int cnt = SkUTF8_CountUnichars(text.c_str()); + int cnt = SkUTF8_CountUnichars(text.c_str(), text.size()); std::unique_ptr glyphs(new SkGlyphID[cnt]); typeface->charsToGlyphs(text.c_str(), SkTypeface::Encoding::kUTF8_Encoding, glyphs.get(), cnt); diff --git a/gm/coloremoji_blendmodes.cpp b/gm/coloremoji_blendmodes.cpp index 1e1608d648..872527404c 100644 --- a/gm/coloremoji_blendmodes.cpp +++ b/gm/coloremoji_blendmodes.cpp @@ -148,7 +148,7 @@ protected: textP.setBlendMode(gModes[i]); textP.setTextEncoding(SkPaint::kUTF32_TextEncoding); const char* text = sk_tool_utils::emoji_sample_text(); - SkUnichar unichar = SkUTF8_ToUnichar(text); + SkUnichar unichar = SkUTF8_NextUnichar(&text, text + strlen(text)); canvas->drawText(&unichar, 4, x+ w/10.f, y + 7.f*h/8.f, textP); } #if 1 diff --git a/include/core/SkPaint.h b/include/core/SkPaint.h index 0664cdd360..d7ec9bbea8 100644 --- a/include/core/SkPaint.h +++ b/include/core/SkPaint.h @@ -1455,7 +1455,7 @@ public: Style style) const; private: - typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**); + typedef const SkGlyph& (*GlyphCacheProc)(SkGlyphCache*, const char**, const char*); sk_sp fTypeface; sk_sp fPathEffect; diff --git a/modules/skshaper/src/SkShaper_harfbuzz.cpp b/modules/skshaper/src/SkShaper_harfbuzz.cpp index 94c899d01e..2077dedadc 100644 --- a/modules/skshaper/src/SkShaper_harfbuzz.cpp +++ b/modules/skshaper/src/SkShaper_harfbuzz.cpp @@ -124,12 +124,13 @@ public: return ret; } - ret.init(utf8, std::move(bidi)); + ret.init(utf8, utf8 + utf8Bytes, std::move(bidi)); return ret; } - BiDiRunIterator(const char* utf8, ICUBiDi bidi) + BiDiRunIterator(const char* utf8, const char* end, ICUBiDi bidi) : fBidi(std::move(bidi)) , fEndOfCurrentRun(utf8) + , fEndOfAllRuns(end) , fUTF16LogicalPosition(0) , fLevel(UBIDI_DEFAULT_LTR) {} @@ -137,7 +138,7 @@ public: SkASSERT(fUTF16LogicalPosition < ubidi_getLength(fBidi.get())); int32_t endPosition = ubidi_getLength(fBidi.get()); fLevel = ubidi_getLevelAt(fBidi.get(), fUTF16LogicalPosition); - SkUnichar u = SkUTF8_NextUnichar(&fEndOfCurrentRun); + SkUnichar u = SkUTF8_NextUnichar(&fEndOfCurrentRun, fEndOfAllRuns); fUTF16LogicalPosition += SkUTF16_FromUnichar(u); UBiDiLevel level; while (fUTF16LogicalPosition < endPosition) { @@ -145,7 +146,7 @@ public: if (level != fLevel) { break; } - u = SkUTF8_NextUnichar(&fEndOfCurrentRun); + u = SkUTF8_NextUnichar(&fEndOfCurrentRun, fEndOfAllRuns); fUTF16LogicalPosition += SkUTF16_FromUnichar(u); } } @@ -162,6 +163,7 @@ public: private: ICUBiDi fBidi; const char* fEndOfCurrentRun; + const char* fEndOfAllRuns; int32_t fUTF16LogicalPosition; UBiDiLevel fLevel; }; @@ -182,11 +184,11 @@ public: {} void consume() override { SkASSERT(fCurrent < fEnd); - SkUnichar u = SkUTF8_NextUnichar(&fCurrent); + SkUnichar u = SkUTF8_NextUnichar(&fCurrent, fEnd); fCurrentScript = hb_unicode_script(fHBUnicode, u); while (fCurrent < fEnd) { const char* prev = fCurrent; - u = SkUTF8_NextUnichar(&fCurrent); + u = SkUTF8_NextUnichar(&fCurrent, fEnd); const hb_script_t script = hb_unicode_script(fHBUnicode, u); if (script != fCurrentScript) { if (fCurrentScript == HB_SCRIPT_INHERITED || fCurrentScript == HB_SCRIPT_COMMON) { @@ -241,7 +243,7 @@ public: {} void consume() override { SkASSERT(fCurrent < fEnd); - SkUnichar u = SkUTF8_NextUnichar(&fCurrent); + SkUnichar u = SkUTF8_NextUnichar(&fCurrent, fEnd); // If the starting typeface can handle this character, use it. if (fTypeface->charsToGlyphs(&u, SkTypeface::kUTF32_Encoding, nullptr, 1)) { fFallbackTypeface.reset(); @@ -263,7 +265,7 @@ public: while (fCurrent < fEnd) { const char* prev = fCurrent; - u = SkUTF8_NextUnichar(&fCurrent); + u = SkUTF8_NextUnichar(&fCurrent, fEnd); // If using a fallback and the initial typeface has this character, stop fallback. if (fFallbackTypeface && @@ -552,7 +554,7 @@ SkPoint SkShaper::shape(SkTextBlobBuilder* builder, const char* utf8Current = utf8Start; while (utf8Current < utf8End) { unsigned int cluster = utf8Current - utf8Start; - hb_codepoint_t u = SkUTF8_NextUnichar(&utf8Current); + hb_codepoint_t u = SkUTF8_NextUnichar(&utf8Current, utf8End); hb_buffer_add(buffer, u, cluster); } diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp index 4c9dddf1f5..8a49abfe3a 100644 --- a/src/core/SkDraw.cpp +++ b/src/core/SkDraw.cpp @@ -1551,7 +1551,7 @@ void SkDraw::drawPosText_asPaths(const char text[], size_t byteLength, const SkS paint.setPathEffect(origPaint.refPathEffect()); while (text < stop) { - const SkGlyph& glyph = glyphCacheProc(cache.get(), &text); + const SkGlyph& glyph = glyphCacheProc(cache.get(), &text, stop); if (glyph.fWidth) { const SkPath* path = cache->findPath(glyph); if (path) { diff --git a/src/core/SkFindAndPlaceGlyph.h b/src/core/SkFindAndPlaceGlyph.h index ae98faa1e5..f602e8d931 100644 --- a/src/core/SkFindAndPlaceGlyph.h +++ b/src/core/SkFindAndPlaceGlyph.h @@ -115,8 +115,9 @@ private: class GlyphFinderInterface { public: virtual ~GlyphFinderInterface() {} - virtual const SkGlyph& lookupGlyph(const char** text) = 0; - virtual const SkGlyph& lookupGlyphXY(const char** text, SkFixed x, SkFixed y) = 0; + virtual const SkGlyph& lookupGlyph(const char** text, const char* stop) = 0; + virtual const SkGlyph& lookupGlyphXY(const char** text, const char* stop, + SkFixed x, SkFixed y) = 0; }; class UtfNGlyphFinder : public GlyphFinderInterface { @@ -126,17 +127,17 @@ private: SkASSERT(cache != nullptr); } - const SkGlyph& lookupGlyph(const char** text) override { + const SkGlyph& lookupGlyph(const char** text, const char* stop) override { SkASSERT(text != nullptr); - return fCache->getUnicharMetrics(nextUnichar(text)); + return fCache->getUnicharMetrics(nextUnichar(text, stop)); } - const SkGlyph& lookupGlyphXY(const char** text, SkFixed x, SkFixed y) override { + const SkGlyph& lookupGlyphXY(const char** text, const char* stop, SkFixed x, SkFixed y) override { SkASSERT(text != nullptr); - return fCache->getUnicharMetrics(nextUnichar(text), x, y); + return fCache->getUnicharMetrics(nextUnichar(text, stop), x, y); } private: - virtual SkUnichar nextUnichar(const char** text) = 0; + virtual SkUnichar nextUnichar(const char** text, const char* stop) = 0; SkGlyphCache* fCache; }; @@ -145,7 +146,9 @@ private: explicit Utf8GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { } private: - SkUnichar nextUnichar(const char** text) override { return SkUTF8_NextUnichar(text); } + SkUnichar nextUnichar(const char** text, const char* stop) override { + return SkUTF8_NextUnichar(text, stop); + } }; class Utf16GlyphFinder final : public UtfNGlyphFinder { @@ -153,8 +156,8 @@ private: explicit Utf16GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { } private: - SkUnichar nextUnichar(const char** text) override { - return SkUTF16_NextUnichar((const uint16_t**)text); + SkUnichar nextUnichar(const char** text, const char* stop) override { + return SkUTF16_NextUnichar((const uint16_t**)text, (const uint16_t*)stop); } }; @@ -163,7 +166,7 @@ private: explicit Utf32GlyphFinder(SkGlyphCache* cache) : UtfNGlyphFinder(cache) { } private: - SkUnichar nextUnichar(const char** text) override { + SkUnichar nextUnichar(const char** text, const char* stop) override { const int32_t* ptr = *(const int32_t**)text; SkUnichar uni = *ptr++; *text = (const char*)ptr; @@ -178,10 +181,11 @@ private: SkASSERT(cache != nullptr); } - const SkGlyph& lookupGlyph(const char** text) override { + const SkGlyph& lookupGlyph(const char** text, const char*) override { return fCache->getGlyphIDMetrics(nextGlyphId(text)); } - const SkGlyph& lookupGlyphXY(const char** text, SkFixed x, SkFixed y) override { + const SkGlyph& lookupGlyphXY(const char** text, const char*, + SkFixed x, SkFixed y) override { return fCache->getGlyphIDMetrics(nextGlyphId(text), x, y); } @@ -319,7 +323,8 @@ private: // compile error. // See GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60277 virtual SkPoint findAndPositionGlyph( - const char** text, SkPoint position, ProcessOneGlyph&& processOneGlyph) { + const char** text, const char* stop, SkPoint position, + ProcessOneGlyph&& processOneGlyph) { SK_ABORT("Should never get here."); return {0.0f, 0.0f}; } @@ -335,12 +340,13 @@ private: : fGlyphFinder(glyphFinder) { } SkPoint findAndPositionGlyph( - const char** text, SkPoint position, ProcessOneGlyph&& processOneGlyph) override { + const char** text, const char* stop, SkPoint position, + ProcessOneGlyph&& processOneGlyph) override { // Find the glyph. SkIPoint lookupPosition = SubpixelAlignment(kAxisAlignment, position); const SkGlyph& renderGlyph = - fGlyphFinder->lookupGlyphXY(text, lookupPosition.fX, lookupPosition.fY); + fGlyphFinder->lookupGlyphXY(text, stop, lookupPosition.fX, lookupPosition.fY); // If the glyph has no width (no pixels) then don't bother processing it. if (renderGlyph.fWidth > 0) { @@ -365,9 +371,10 @@ private: } SkPoint findAndPositionGlyph( - const char** text, SkPoint position, ProcessOneGlyph&& processOneGlyph) override { + const char** text, const char* stop, SkPoint position, + ProcessOneGlyph&& processOneGlyph) override { SkPoint finalPosition = position; - const SkGlyph& glyph = fGlyphFinder->lookupGlyph(text); + const SkGlyph& glyph = fGlyphFinder->lookupGlyph(text, stop); if (glyph.fWidth > 0) { processOneGlyph(glyph, finalPosition, {SK_ScalarHalf, SK_ScalarHalf}); @@ -407,7 +414,7 @@ private: while (text < stop) { // don't need x, y here, since all subpixel variants will have the // same advance - const SkGlyph& glyph = glyphFinder->lookupGlyph(&text); + const SkGlyph& glyph = glyphFinder->lookupGlyph(&text, stop); x += SkFloatToScalar(glyph.fAdvanceX); y += SkFloatToScalar(glyph.fAdvanceY); @@ -451,7 +458,7 @@ inline void SkFindAndPlaceGlyph::ProcessPosText( while (cursor < stop) { SkPoint mappedPoint = mapper.TranslationMapper::map(positions->nextPoint()); positioner.Positioner::findAndPositionGlyph( - &cursor, mappedPoint, std::forward(processOneGlyph)); + &cursor, stop, mappedPoint, std::forward(processOneGlyph)); } return; } @@ -479,7 +486,7 @@ inline void SkFindAndPlaceGlyph::ProcessPosText( while (text < stop) { SkPoint mappedPoint = mapper->map(positionReader->nextPoint()); findAndPosition->findAndPositionGlyph( - &text, mappedPoint, std::forward(processOneGlyph)); + &text, stop, mappedPoint, std::forward(processOneGlyph)); } } diff --git a/src/core/SkOverdrawCanvas.cpp b/src/core/SkOverdrawCanvas.cpp index e8327e55cc..35656e0829 100644 --- a/src/core/SkOverdrawCanvas.cpp +++ b/src/core/SkOverdrawCanvas.cpp @@ -95,22 +95,26 @@ void SkOverdrawCanvas::onDrawTextOnPath(const void* text, size_t byteLength, con return; } -typedef int (*CountTextProc)(const char* text); -static int count_utf16(const char* text) { - const uint16_t* prev = (uint16_t*)text; - (void)SkUTF16_NextUnichar(&prev); +typedef int (*CountTextProc)(const char* text, const char* stop); +static int count_utf16(const char* text, const char* stop) { + const uint16_t* prev = (const uint16_t*)text; + (void)SkUTF16_NextUnichar(&prev, (const uint16_t*)stop); return SkToInt((const char*)prev - text); } -static int return_4(const char* text) { return 4; } -static int return_2(const char* text) { return 2; } +static int return_4(const char* text, const char* stop) { return 4; } +static int return_2(const char* text, const char* stop) { return 2; } +static int count_utf8(const char* text, const char* stop) { + return SkUTF8_LeadByteToCount(*(const uint8_t*)text); +} void SkOverdrawCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRSXform xform[], const SkRect*, const SkPaint& paint) { + const char* stop = (const char*)text + byteLength; CountTextProc proc = nullptr; switch (paint.getTextEncoding()) { case SkPaint::kUTF8_TextEncoding: - proc = SkUTF8_CountUTF8Bytes; + proc = count_utf8; break; case SkPaint::kUTF16_TextEncoding: proc = count_utf16; @@ -129,7 +133,8 @@ void SkOverdrawCanvas::onDrawTextRSXform(const void* text, size_t byteLength, while ((const char*)text < (const char*)stopText) { matrix.setRSXform(*xform++); matrix.setConcat(this->getTotalMatrix(), matrix); - int subLen = proc((const char*)text); + int subLen = proc((const char*)text, stop); + SkASSERT(subLen > 0); this->save(); this->concat(matrix); diff --git a/src/core/SkPaint.cpp b/src/core/SkPaint.cpp index 7643bab737..0fdf58b6e5 100644 --- a/src/core/SkPaint.cpp +++ b/src/core/SkPaint.cpp @@ -449,7 +449,7 @@ int SkPaint::textToGlyphs(const void* textData, size_t byteLength, uint16_t glyp const uint16_t* text16 = (const uint16_t*)text; const uint16_t* stop16 = (const uint16_t*)stop; while (text16 < stop16) { - *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16)); + *gptr++ = cache->unicharToGlyph(SkUTF16_NextUnichar(&text16, stop16)); } break; } @@ -493,7 +493,7 @@ bool SkPaint::containsText(const void* textData, size_t byteLength) const { const char* text = static_cast(textData); const char* stop = text + byteLength; while (text < stop) { - if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text))) { + if (0 == cache->unicharToGlyph(SkUTF8_NextUnichar(&text, stop))) { return false; } } @@ -503,7 +503,7 @@ bool SkPaint::containsText(const void* textData, size_t byteLength) const { const uint16_t* text = static_cast(textData); const uint16_t* stop = text + (byteLength >> 1); while (text < stop) { - if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text))) { + if (0 == cache->unicharToGlyph(SkUTF16_NextUnichar(&text, stop))) { return false; } } @@ -546,23 +546,27 @@ void SkPaint::glyphsToUnichars(const uint16_t glyphs[], int count, SkUnichar tex /////////////////////////////////////////////////////////////////////////////// static const SkGlyph& sk_getMetrics_utf8_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); - return cache->getUnicharMetrics(SkUTF8_NextUnichar(text)); + return cache->getUnicharMetrics(SkUTF8_NextUnichar(text, stop)); } static const SkGlyph& sk_getMetrics_utf16_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); - return cache->getUnicharMetrics(SkUTF16_NextUnichar((const uint16_t**)text)); + return cache->getUnicharMetrics( + SkUTF16_NextUnichar((const uint16_t**)text, (const uint16_t*)stop)); } static const SkGlyph& sk_getMetrics_utf32_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); @@ -573,7 +577,8 @@ static const SkGlyph& sk_getMetrics_utf32_next(SkGlyphCache* cache, } static const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); @@ -585,23 +590,27 @@ static const SkGlyph& sk_getMetrics_glyph_next(SkGlyphCache* cache, } static const SkGlyph& sk_getAdvance_utf8_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); - return cache->getUnicharAdvance(SkUTF8_NextUnichar(text)); + return cache->getUnicharAdvance(SkUTF8_NextUnichar(text, stop)); } static const SkGlyph& sk_getAdvance_utf16_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); - return cache->getUnicharAdvance(SkUTF16_NextUnichar((const uint16_t**)text)); + return cache->getUnicharAdvance( + SkUTF16_NextUnichar((const uint16_t**)text, (const uint16_t*)stop)); } static const SkGlyph& sk_getAdvance_utf32_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); @@ -612,7 +621,8 @@ static const SkGlyph& sk_getAdvance_utf32_next(SkGlyphCache* cache, } static const SkGlyph& sk_getAdvance_glyph_next(SkGlyphCache* cache, - const char** text) { + const char** text, + const char* stop) { SkASSERT(cache != nullptr); SkASSERT(text != nullptr); @@ -750,18 +760,18 @@ SkScalar SkPaint::measure_text(SkGlyphCache* cache, int n = 1; const char* stop = (const char*)text + byteLength; - const SkGlyph* g = &glyphCacheProc(cache, &text); + const SkGlyph* g = &glyphCacheProc(cache, &text, stop); SkScalar x = advance(*g, xyIndex); if (nullptr == bounds) { for (; text < stop; n++) { - x += advance(glyphCacheProc(cache, &text), xyIndex); + x += advance(glyphCacheProc(cache, &text, stop), xyIndex); } } else { set_bounds(*g, bounds); for (; text < stop; n++) { - g = &glyphCacheProc(cache, &text); + g = &glyphCacheProc(cache, &text, stop); joinBoundsProc(*g, bounds, x); x += advance(*g, xyIndex); } @@ -842,7 +852,7 @@ size_t SkPaint::breakText(const void* textD, size_t length, SkScalar maxWidth, while (text < stop) { const char* curr = text; - SkScalar x = advance(glyphCacheProc(cache.get(), &text), xyIndex); + SkScalar x = advance(glyphCacheProc(cache.get(), &text, stop), xyIndex); if ((width += x) > maxWidth) { width -= x; text = curr; @@ -933,7 +943,7 @@ int SkPaint::getTextWidths(const void* textData, size_t byteLength, if (scale) { while (text < stop) { - const SkGlyph& g = glyphCacheProc(cache.get(), &text); + const SkGlyph& g = glyphCacheProc(cache.get(), &text, stop); if (widths) { *widths++ = advance(g, xyIndex) * scale; } @@ -944,7 +954,7 @@ int SkPaint::getTextWidths(const void* textData, size_t byteLength, } } else { while (text < stop) { - const SkGlyph& g = glyphCacheProc(cache.get(), &text); + const SkGlyph& g = glyphCacheProc(cache.get(), &text, stop); if (widths) { *widths++ = advance(g, xyIndex); } @@ -1464,7 +1474,7 @@ SkTextBaseIter::SkTextBaseIter(const char text[], size_t length, bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { if (fText < fStop) { - const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText); + const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText, fStop); fXPos += fPrevAdvance * fScale; fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); @@ -1487,7 +1497,7 @@ bool SkTextToPathIter::next(const SkPath** path, SkScalar* xpos) { } bool SkTextInterceptsIter::next(SkScalar* array, int* count) { - const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText); + const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText, fStop); fXPos += fPrevAdvance * fScale; fPrevAdvance = advance(glyph, fXYIndex); // + fPaint.getTextTracking(); if (fCache->findPath(glyph)) { diff --git a/src/core/SkStringUtils.cpp b/src/core/SkStringUtils.cpp index c4c1739b19..500478585f 100644 --- a/src/core/SkStringUtils.cpp +++ b/src/core/SkStringUtils.cpp @@ -55,13 +55,14 @@ SkString SkTabString(const SkString& string, int tabCnt) { SkString SkStringFromUTF16(const uint16_t* src, size_t count) { SkString ret; + const uint16_t* stop = src + count; if (count > 0) { SkASSERT(src); size_t n = 0; const uint16_t* end = src + count; for (const uint16_t* ptr = src; ptr < end;) { const uint16_t* last = ptr; - SkUnichar u = SkUTF16_NextUnichar(&ptr); + SkUnichar u = SkUTF16_NextUnichar(&ptr, stop); size_t s = SkUTF8_FromUnichar(u); if (n > UINT32_MAX - s) { end = last; // truncate input string @@ -72,7 +73,7 @@ SkString SkStringFromUTF16(const uint16_t* src, size_t count) { ret = SkString(n); char* out = ret.writable_str(); for (const uint16_t* ptr = src; ptr < end;) { - out += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&ptr), out); + out += SkUTF8_FromUnichar(SkUTF16_NextUnichar(&ptr, stop), out); } SkASSERT(out == ret.writable_str() + n); } diff --git a/src/core/SkTextToPathIter.h b/src/core/SkTextToPathIter.h index c135de620b..875cf5a382 100644 --- a/src/core/SkTextToPathIter.h +++ b/src/core/SkTextToPathIter.h @@ -71,7 +71,7 @@ public: if (TextType::kPosText == fTextType && fPaint.getTextAlign() != SkPaint::kLeft_Align) { // need to measure first const char* text = fText; - const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &text); + const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &text, fStop); SkScalar width = (&glyph.fAdvanceX)[0] * fScale; if (fPaint.getTextAlign() == SkPaint::kCenter_Align) { width = SkScalarHalf(width); diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp index e68be09bfb..6a3489554b 100644 --- a/src/gpu/text/GrTextContext.cpp +++ b/src/gpu/text/GrTextContext.cpp @@ -339,7 +339,7 @@ void GrTextContext::DrawBmpPosTextAsPaths(GrTextBlob* blob, int runIndex, SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); while (text < stop) { - const SkGlyph& glyph = glyphCacheProc(cache.get(), &text); + const SkGlyph& glyph = glyphCacheProc(cache.get(), &text, stop); if (glyph.fWidth) { SkPoint loc; tmsProc(pos, &loc); @@ -554,7 +554,7 @@ void GrTextContext::drawDFPosText(GrTextBlob* blob, int runIndex, while (text < stop) { const char* lastText = text; // the last 2 parameters are ignored - const SkGlyph& glyph = glyphCacheProc(cache.get(), &text); + const SkGlyph& glyph = glyphCacheProc(cache.get(), &text, stop); if (glyph.fWidth) { SkPoint glyphPos(offset); @@ -664,7 +664,7 @@ void GrTextContext::FallbackTextHelper::drawText(GrTextBlob* blob, int runIndex, const char* stop = text + fFallbackTxt.count(); SkPoint* glyphPos = fFallbackPos.begin(); while (text < stop) { - const SkGlyph& glyph = glyphCacheProc(cache.get(), &text); + const SkGlyph& glyph = glyphCacheProc(cache.get(), &text, stop); if (!fUseTransformedFallback) { fViewMatrix.mapPoints(glyphPos, 1); glyphPos->fX = SkScalarFloorToScalar(glyphPos->fX); diff --git a/src/gpu/text/GrTextUtils.cpp b/src/gpu/text/GrTextUtils.cpp index 6f043e108f..ec5389c464 100644 --- a/src/gpu/text/GrTextUtils.cpp +++ b/src/gpu/text/GrTextUtils.cpp @@ -36,7 +36,7 @@ bool GrTextUtils::PathTextIter::next(const SkGlyph** skGlyph, const SkPath** pat SkASSERT(path); SkASSERT(xpos); if (fText < fStop) { - const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText); + const SkGlyph& glyph = fGlyphCacheProc(fCache.get(), &fText, fStop); fXPos += fPrevAdvance * fScale; SkASSERT(0 == fXYIndex || 1 == fXYIndex); diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp index c2a402f695..4a83a9c841 100644 --- a/src/svg/SkSVGDevice.cpp +++ b/src/svg/SkSVGDevice.cpp @@ -133,6 +133,7 @@ public: int count = paint.countText(text, byteLen); + const char* stop = (const char*)text + byteLen; switch(paint.getTextEncoding()) { case SkPaint::kGlyphID_TextEncoding: { SkASSERT(count * sizeof(uint16_t) == byteLen); @@ -145,14 +146,14 @@ public: case SkPaint::kUTF8_TextEncoding: { const char* c8 = reinterpret_cast(text); for (int i = 0; i < count; ++i) { - this->appendUnichar(SkUTF8_NextUnichar(&c8)); + this->appendUnichar(SkUTF8_NextUnichar(&c8, stop)); } SkASSERT(reinterpret_cast(text) + byteLen == c8); } break; case SkPaint::kUTF16_TextEncoding: { const uint16_t* c16 = reinterpret_cast(text); for (int i = 0; i < count; ++i) { - this->appendUnichar(SkUTF16_NextUnichar(&c16)); + this->appendUnichar(SkUTF16_NextUnichar(&c16, (const uint16_t*)stop)); } SkASSERT(SkIsAlign2(byteLen)); SkASSERT(reinterpret_cast(text) + (byteLen / 2) == c16); diff --git a/tests/UtilsTest.cpp b/tests/UtilsTest.cpp index 7e11f8478a..6f8ec914bc 100644 --- a/tests/UtilsTest.cpp +++ b/tests/UtilsTest.cpp @@ -177,7 +177,7 @@ static void test_utf16(skiatest::Reporter* reporter) { size_t count2 = SkUTF16_CountUnichars(buf, 2 * sizeof(uint16_t)); REPORTER_ASSERT(reporter, count2 == 1); const uint16_t* ptr = buf; - SkUnichar c = SkUTF16_NextUnichar(&ptr); + SkUnichar c = SkUTF16_NextUnichar(&ptr, buf + SK_ARRAY_COUNT(buf)); REPORTER_ASSERT(reporter, c == gUni[i]); REPORTER_ASSERT(reporter, ptr - buf == 2); } @@ -203,13 +203,12 @@ DEF_TEST(Utils, reporter) { for (size_t i = 0; i < SK_ARRAY_COUNT(gTest); i++) { const char* p = gTest[i].fUtf8; - int n = SkUTF8_CountUnichars(p); - SkUnichar u0 = SkUTF8_ToUnichar(gTest[i].fUtf8); - SkUnichar u1 = SkUTF8_NextUnichar(&p); + const char* stop = p + strlen(p); + int n = SkUTF8_CountUnichars(p, strlen(p)); + SkUnichar u1 = SkUTF8_NextUnichar(&p, stop); REPORTER_ASSERT(reporter, n == 1); - REPORTER_ASSERT(reporter, u0 == u1); - REPORTER_ASSERT(reporter, u0 == gTest[i].fUni); + REPORTER_ASSERT(reporter, u1 == gTest[i].fUni); REPORTER_ASSERT(reporter, p - gTest[i].fUtf8 == (int)strlen(gTest[i].fUtf8)); } diff --git a/tools/fonts/create_test_font.cpp b/tools/fonts/create_test_font.cpp index 6cbcf6e2f8..36ead3cb65 100644 --- a/tools/fonts/create_test_font.cpp +++ b/tools/fonts/create_test_font.cpp @@ -144,7 +144,7 @@ static void output_path_data(const SkPaint& paint, char str[1]; str[0] = ch; const char* used = str; - SkUnichar index = SkUTF8_NextUnichar(&used); + SkUnichar index = SkUTF8_NextUnichar(&used, str + 1); SkPath path; paint.getTextPath((const void*) &index, 2, 0, 0, &path); SkPath::RawIter iter(path); -- cgit v1.2.3