Loading core/jni/android/graphics/Canvas.cpp +10 −20 Original line number Diff line number Diff line Loading @@ -758,21 +758,7 @@ public: jfloat x, jfloat y, int flags, SkPaint* paint) { jint count = end - start; sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count, end, flags); if (value == NULL) { LOGE("Cannot get TextLayoutCache value"); return ; } #else value = new TextLayoutCacheValue(); value->computeValues(paint, textArray, start, count, end, flags); #endif doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint); drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint); } static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray, Loading @@ -781,19 +767,23 @@ public: sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count, contextCount, flags); value = TextLayoutCache::getInstance().getValue(paint, textArray, contextCount, flags); if (value == NULL) { LOGE("Cannot get TextLayoutCache value"); return ; } #else value = new TextLayoutCacheValue(); value->computeValues(paint, textArray, start, count, contextCount, flags); value->computeValues(paint, textArray, contextCount, flags); #endif doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint); size_t startIndex = 0; size_t glyphsCount = 0; value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount); jchar* glyphs = new jchar[glyphsCount]; value->getGlyphs(startIndex, glyphsCount, glyphs); doDrawGlyphs(canvas, glyphs, 0, glyphsCount, x, y, flags, paint); delete[] glyphs; } static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count, Loading core/jni/android/graphics/Paint.cpp +7 −11 Original line number Diff line number Diff line Loading @@ -352,7 +352,7 @@ public: jfloat result = 0; #if RTL_USE_HARFBUZZ TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength, paint->getFlags(), NULL /* dont need all advances */, result); paint->getFlags(), NULL /* dont need all advances */, &result); #else // we double count, since measureText wants a byteLength SkScalar width = paint->measureText(textArray + index, count << 1); Loading Loading @@ -382,7 +382,7 @@ public: #if RTL_USE_HARFBUZZ TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength, paint->getFlags(), NULL /* dont need all advances */, width); paint->getFlags(), NULL /* dont need all advances */, &width); #else width = SkScalarToFloat(paint->measureText(textArray + start, count << 1)); Loading @@ -406,7 +406,7 @@ public: #if RTL_USE_HARFBUZZ TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength, paint->getFlags(), NULL /* dont need all advances */, width); paint->getFlags(), NULL /* dont need all advances */, &width); #else width = SkScalarToFloat(paint->measureText(textArray, textLength << 1)); #endif Loading Loading @@ -435,10 +435,8 @@ public: jfloat* widthsArray = autoWidths.ptr(); #if RTL_USE_HARFBUZZ jfloat totalAdvance; TextLayout::getTextRunAdvances(paint, text, 0, count, count, paint->getFlags(), widthsArray, totalAdvance); paint->getFlags(), widthsArray, NULL); #else SkScalar* scalarArray = (SkScalar*)widthsArray; Loading Loading @@ -489,7 +487,7 @@ public: HB_FontRec font; FontData fontData; TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text, start, count, contextCount, flags); contextCount, flags); int glyphCount = shaperItem.num_glyphs; for (int i = 0; i < glyphCount; i++) { Loading Loading @@ -533,7 +531,7 @@ public: jfloat totalAdvance = 0; TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags, advancesArray, totalAdvance); advancesArray, &totalAdvance); if (advances != NULL) { env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray); Loading Loading @@ -604,10 +602,8 @@ public: jint count, jint flags, jint offset, jint opt) { #if RTL_USE_HARFBUZZ jfloat scalarArray[count]; jfloat totalAdvance = 0; TextLayout::getTextRunAdvances(paint, text, start, count, count, flags, scalarArray, totalAdvance); scalarArray, NULL); #else SkScalar scalarArray[count]; jchar buffer[count]; Loading core/jni/android/graphics/TextLayout.cpp +80 −10 Original line number Diff line number Diff line Loading @@ -253,21 +253,22 @@ void TextLayout::drawTextRun(SkPaint* paint, const jchar* chars, void TextLayout::getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { jfloat* resultAdvances, jfloat* resultTotalAdvance) { sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE // Return advances from the cache. Compute them if needed value = TextLayoutCache::getInstance().getValue( paint, chars, start, count, contextCount, dirFlags); value = TextLayoutCache::getInstance().getValue(paint, chars, contextCount, dirFlags); #else value = new TextLayoutCacheValue(); value->computeValues(paint, chars, start, count, contextCount, dirFlags); value->computeValues(paint, chars, contextCount, dirFlags); #endif if (value != NULL) { if (resultAdvances != NULL) { memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat)); if (resultAdvances) { value->getAdvances(start, count, resultAdvances); } if (resultTotalAdvance) { *resultTotalAdvance = value->getTotalAdvance(start, count); } resultTotalAdvance = value->getTotalAdvance(); } } Loading @@ -275,18 +276,87 @@ void TextLayout::getTextRunAdvancesHB(SkPaint* paint, const jchar* chars, jint s jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { // Compute advances and return them TextLayoutCacheValue::computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, resultAdvances, &resultTotalAdvance, NULL, NULL); TextLayoutCacheValue::computeValuesWithHarfbuzz(paint, chars, contextCount, dirFlags, resultAdvances, &resultTotalAdvance, NULL, NULL, NULL); } void TextLayout::getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { // Compute advances and return them TextLayoutCacheValue::computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, resultAdvances, &resultTotalAdvance); } void TextLayout::computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, jfloat* outAdvances, jfloat* outTotalAdvance) { SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount); jchar* buffer = tempBuffer.get(); SkScalar* scalarArray = (SkScalar*)outAdvances; // this is where we'd call harfbuzz // for now we just use ushape.c size_t widths; const jchar* text; if (dirFlags & 0x1) { // rtl, call arabic shaping in case UErrorCode status = U_ZERO_ERROR; // Use fixed length since we need to keep start and count valid u_shapeArabic(chars, contextCount, buffer, contextCount, U_SHAPE_LENGTH_FIXED_SPACES_NEAR | U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE | U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status); // we shouldn't fail unless there's an out of memory condition, // in which case we're hosed anyway for (int i = start, e = i + count; i < e; ++i) { if (buffer[i] == UNICODE_NOT_A_CHAR) { buffer[i] = UNICODE_ZWSP; // zero-width-space for skia } } text = buffer + start; widths = paint->getTextWidths(text, count << 1, scalarArray); } else { text = chars + start; widths = paint->getTextWidths(text, count << 1, scalarArray); } jfloat totalAdvance = 0; if (widths < count) { #if DEBUG_ADVANCES LOGD("ICU -- count=%d", widths); #endif // Skia operates on code points, not code units, so surrogate pairs return only // one value. Expand the result so we have one value per UTF-16 code unit. // Note, skia's getTextWidth gets confused if it encounters a surrogate pair, // leaving the remaining widths zero. Not nice. for (size_t i = 0, p = 0; i < widths; ++i) { totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]); if (p < count && text[p] >= UNICODE_FIRST_LOW_SURROGATE && text[p] < UNICODE_FIRST_PRIVATE_USE && text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE && text[p-1] < UNICODE_FIRST_LOW_SURROGATE) { outAdvances[p++] = 0; } #if DEBUG_ADVANCES LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); #endif } } else { #if DEBUG_ADVANCES LOGD("ICU -- count=%d", count); #endif for (size_t i = 0; i < count; i++) { totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]); #if DEBUG_ADVANCES LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); #endif } } *outTotalAdvance = totalAdvance; } // Draws a paragraph of text on a single line, running bidi and shaping void TextLayout::drawText(SkPaint* paint, const jchar* text, jsize len, int bidiFlags, jfloat x, jfloat y, SkCanvas* canvas) { Loading core/jni/android/graphics/TextLayout.h +5 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public: static void getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance); jfloat* resultAdvances, jfloat* resultTotalAdvance); static void getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, Loading Loading @@ -106,5 +106,9 @@ private: UErrorCode &status); static void handleText(SkPaint* paint, const jchar* text, jsize len, int bidiFlags, jfloat x, jfloat y, SkCanvas* canvas, SkPath* path); static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, jfloat* outAdvances, jfloat* outTotalAdvance); }; } // namespace android core/jni/android/graphics/TextLayoutCache.cpp +152 −162 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/jni/android/graphics/Canvas.cpp +10 −20 Original line number Diff line number Diff line Loading @@ -758,21 +758,7 @@ public: jfloat x, jfloat y, int flags, SkPaint* paint) { jint count = end - start; sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count, end, flags); if (value == NULL) { LOGE("Cannot get TextLayoutCache value"); return ; } #else value = new TextLayoutCacheValue(); value->computeValues(paint, textArray, start, count, end, flags); #endif doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint); drawTextWithGlyphs(canvas, textArray + start, 0, count, count, x, y, flags, paint); } static void drawTextWithGlyphs(SkCanvas* canvas, const jchar* textArray, Loading @@ -781,19 +767,23 @@ public: sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count, contextCount, flags); value = TextLayoutCache::getInstance().getValue(paint, textArray, contextCount, flags); if (value == NULL) { LOGE("Cannot get TextLayoutCache value"); return ; } #else value = new TextLayoutCacheValue(); value->computeValues(paint, textArray, start, count, contextCount, flags); value->computeValues(paint, textArray, contextCount, flags); #endif doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint); size_t startIndex = 0; size_t glyphsCount = 0; value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount); jchar* glyphs = new jchar[glyphsCount]; value->getGlyphs(startIndex, glyphsCount, glyphs); doDrawGlyphs(canvas, glyphs, 0, glyphsCount, x, y, flags, paint); delete[] glyphs; } static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count, Loading
core/jni/android/graphics/Paint.cpp +7 −11 Original line number Diff line number Diff line Loading @@ -352,7 +352,7 @@ public: jfloat result = 0; #if RTL_USE_HARFBUZZ TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength, paint->getFlags(), NULL /* dont need all advances */, result); paint->getFlags(), NULL /* dont need all advances */, &result); #else // we double count, since measureText wants a byteLength SkScalar width = paint->measureText(textArray + index, count << 1); Loading Loading @@ -382,7 +382,7 @@ public: #if RTL_USE_HARFBUZZ TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength, paint->getFlags(), NULL /* dont need all advances */, width); paint->getFlags(), NULL /* dont need all advances */, &width); #else width = SkScalarToFloat(paint->measureText(textArray + start, count << 1)); Loading @@ -406,7 +406,7 @@ public: #if RTL_USE_HARFBUZZ TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength, paint->getFlags(), NULL /* dont need all advances */, width); paint->getFlags(), NULL /* dont need all advances */, &width); #else width = SkScalarToFloat(paint->measureText(textArray, textLength << 1)); #endif Loading Loading @@ -435,10 +435,8 @@ public: jfloat* widthsArray = autoWidths.ptr(); #if RTL_USE_HARFBUZZ jfloat totalAdvance; TextLayout::getTextRunAdvances(paint, text, 0, count, count, paint->getFlags(), widthsArray, totalAdvance); paint->getFlags(), widthsArray, NULL); #else SkScalar* scalarArray = (SkScalar*)widthsArray; Loading Loading @@ -489,7 +487,7 @@ public: HB_FontRec font; FontData fontData; TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text, start, count, contextCount, flags); contextCount, flags); int glyphCount = shaperItem.num_glyphs; for (int i = 0; i < glyphCount; i++) { Loading Loading @@ -533,7 +531,7 @@ public: jfloat totalAdvance = 0; TextLayout::getTextRunAdvances(paint, text, start, count, contextCount, flags, advancesArray, totalAdvance); advancesArray, &totalAdvance); if (advances != NULL) { env->SetFloatArrayRegion(advances, advancesIndex, count, advancesArray); Loading Loading @@ -604,10 +602,8 @@ public: jint count, jint flags, jint offset, jint opt) { #if RTL_USE_HARFBUZZ jfloat scalarArray[count]; jfloat totalAdvance = 0; TextLayout::getTextRunAdvances(paint, text, start, count, count, flags, scalarArray, totalAdvance); scalarArray, NULL); #else SkScalar scalarArray[count]; jchar buffer[count]; Loading
core/jni/android/graphics/TextLayout.cpp +80 −10 Original line number Diff line number Diff line Loading @@ -253,21 +253,22 @@ void TextLayout::drawTextRun(SkPaint* paint, const jchar* chars, void TextLayout::getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { jfloat* resultAdvances, jfloat* resultTotalAdvance) { sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE // Return advances from the cache. Compute them if needed value = TextLayoutCache::getInstance().getValue( paint, chars, start, count, contextCount, dirFlags); value = TextLayoutCache::getInstance().getValue(paint, chars, contextCount, dirFlags); #else value = new TextLayoutCacheValue(); value->computeValues(paint, chars, start, count, contextCount, dirFlags); value->computeValues(paint, chars, contextCount, dirFlags); #endif if (value != NULL) { if (resultAdvances != NULL) { memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat)); if (resultAdvances) { value->getAdvances(start, count, resultAdvances); } if (resultTotalAdvance) { *resultTotalAdvance = value->getTotalAdvance(start, count); } resultTotalAdvance = value->getTotalAdvance(); } } Loading @@ -275,18 +276,87 @@ void TextLayout::getTextRunAdvancesHB(SkPaint* paint, const jchar* chars, jint s jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { // Compute advances and return them TextLayoutCacheValue::computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, resultAdvances, &resultTotalAdvance, NULL, NULL); TextLayoutCacheValue::computeValuesWithHarfbuzz(paint, chars, contextCount, dirFlags, resultAdvances, &resultTotalAdvance, NULL, NULL, NULL); } void TextLayout::getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance) { // Compute advances and return them TextLayoutCacheValue::computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, resultAdvances, &resultTotalAdvance); } void TextLayout::computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, jfloat* outAdvances, jfloat* outTotalAdvance) { SkAutoSTMalloc<CHAR_BUFFER_SIZE, jchar> tempBuffer(contextCount); jchar* buffer = tempBuffer.get(); SkScalar* scalarArray = (SkScalar*)outAdvances; // this is where we'd call harfbuzz // for now we just use ushape.c size_t widths; const jchar* text; if (dirFlags & 0x1) { // rtl, call arabic shaping in case UErrorCode status = U_ZERO_ERROR; // Use fixed length since we need to keep start and count valid u_shapeArabic(chars, contextCount, buffer, contextCount, U_SHAPE_LENGTH_FIXED_SPACES_NEAR | U_SHAPE_TEXT_DIRECTION_LOGICAL | U_SHAPE_LETTERS_SHAPE | U_SHAPE_X_LAMALEF_SUB_ALTERNATE, &status); // we shouldn't fail unless there's an out of memory condition, // in which case we're hosed anyway for (int i = start, e = i + count; i < e; ++i) { if (buffer[i] == UNICODE_NOT_A_CHAR) { buffer[i] = UNICODE_ZWSP; // zero-width-space for skia } } text = buffer + start; widths = paint->getTextWidths(text, count << 1, scalarArray); } else { text = chars + start; widths = paint->getTextWidths(text, count << 1, scalarArray); } jfloat totalAdvance = 0; if (widths < count) { #if DEBUG_ADVANCES LOGD("ICU -- count=%d", widths); #endif // Skia operates on code points, not code units, so surrogate pairs return only // one value. Expand the result so we have one value per UTF-16 code unit. // Note, skia's getTextWidth gets confused if it encounters a surrogate pair, // leaving the remaining widths zero. Not nice. for (size_t i = 0, p = 0; i < widths; ++i) { totalAdvance += outAdvances[p++] = SkScalarToFloat(scalarArray[i]); if (p < count && text[p] >= UNICODE_FIRST_LOW_SURROGATE && text[p] < UNICODE_FIRST_PRIVATE_USE && text[p-1] >= UNICODE_FIRST_HIGH_SURROGATE && text[p-1] < UNICODE_FIRST_LOW_SURROGATE) { outAdvances[p++] = 0; } #if DEBUG_ADVANCES LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); #endif } } else { #if DEBUG_ADVANCES LOGD("ICU -- count=%d", count); #endif for (size_t i = 0; i < count; i++) { totalAdvance += outAdvances[i] = SkScalarToFloat(scalarArray[i]); #if DEBUG_ADVANCES LOGD("icu-adv = %f - total = %f", outAdvances[i], totalAdvance); #endif } } *outTotalAdvance = totalAdvance; } // Draws a paragraph of text on a single line, running bidi and shaping void TextLayout::drawText(SkPaint* paint, const jchar* text, jsize len, int bidiFlags, jfloat x, jfloat y, SkCanvas* canvas) { Loading
core/jni/android/graphics/TextLayout.h +5 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,7 @@ public: static void getTextRunAdvances(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, jfloat* resultAdvances, jfloat& resultTotalAdvance); jfloat* resultAdvances, jfloat* resultTotalAdvance); static void getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint start, jint count, jint contextCount, jint dirFlags, Loading Loading @@ -106,5 +106,9 @@ private: UErrorCode &status); static void handleText(SkPaint* paint, const jchar* text, jsize len, int bidiFlags, jfloat x, jfloat y, SkCanvas* canvas, SkPath* path); static void computeAdvancesWithICU(SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, int dirFlags, jfloat* outAdvances, jfloat* outTotalAdvance); }; } // namespace android
core/jni/android/graphics/TextLayoutCache.cpp +152 −162 File changed.Preview size limit exceeded, changes collapsed. Show changes