Loading core/jni/android/graphics/TextLayout.cpp +70 −1 Original line number Diff line number Diff line Loading @@ -283,7 +283,7 @@ void TextLayout::getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint 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); } Loading Loading @@ -321,4 +321,73 @@ void TextLayout::drawTextOnPath(SkPaint* paint, const jchar* text, int count, } } 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; } } core/jni/android/graphics/TextLayout.h +4 −0 Original line number Diff line number Diff line 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 +1 −81 Original line number Diff line number Diff line Loading @@ -52,13 +52,7 @@ void TextLayoutCache::init() { mCacheStartTime = systemTime(SYSTEM_TIME_MONOTONIC); if (mDebugEnabled) { LOGD("Start time: %lld", mCacheStartTime); #if RTL_USE_HARFBUZZ LOGD("Using HARFBUZZ"); #else LOGD("Using ICU"); #endif LOGD("Initialization is done"); LOGD("Initialization is done - Start time: %lld", mCacheStartTime); } mInitialized = true; Loading Loading @@ -302,13 +296,8 @@ void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars, siz mAdvancesCount = count; mAdvances = new float[count]; #if RTL_USE_HARFBUZZ computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, mAdvances, &mTotalAdvance, &mGlyphs, &mGlyphsCount); #else computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, mAdvances, &mTotalAdvance); #endif #if DEBUG_ADVANCES LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - " "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, mTotalAdvance, Loading Loading @@ -632,75 +621,6 @@ void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UC HB_FreeFace(shaperItem.face); } void TextLayoutCacheValue::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; } void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) { delete[] shaperItem->glyphs; delete[] shaperItem->attributes; Loading Loading
core/jni/android/graphics/TextLayout.cpp +70 −1 Original line number Diff line number Diff line Loading @@ -283,7 +283,7 @@ void TextLayout::getTextRunAdvancesICU(SkPaint* paint, const jchar* chars, jint 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); } Loading Loading @@ -321,4 +321,73 @@ void TextLayout::drawTextOnPath(SkPaint* paint, const jchar* text, int count, } } 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; } }
core/jni/android/graphics/TextLayout.h +4 −0 Original line number Diff line number Diff line 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 +1 −81 Original line number Diff line number Diff line Loading @@ -52,13 +52,7 @@ void TextLayoutCache::init() { mCacheStartTime = systemTime(SYSTEM_TIME_MONOTONIC); if (mDebugEnabled) { LOGD("Start time: %lld", mCacheStartTime); #if RTL_USE_HARFBUZZ LOGD("Using HARFBUZZ"); #else LOGD("Using ICU"); #endif LOGD("Initialization is done"); LOGD("Initialization is done - Start time: %lld", mCacheStartTime); } mInitialized = true; Loading Loading @@ -302,13 +296,8 @@ void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars, siz mAdvancesCount = count; mAdvances = new float[count]; #if RTL_USE_HARFBUZZ computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, mAdvances, &mTotalAdvance, &mGlyphs, &mGlyphsCount); #else computeAdvancesWithICU(paint, chars, start, count, contextCount, dirFlags, mAdvances, &mTotalAdvance); #endif #if DEBUG_ADVANCES LOGD("Advances - count=%d - countextCount=%d - totalAdvance=%f - " "adv[0]=%f adv[1]=%f adv[2]=%f adv[3]=%f", count, contextCount, mTotalAdvance, Loading Loading @@ -632,75 +621,6 @@ void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UC HB_FreeFace(shaperItem.face); } void TextLayoutCacheValue::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; } void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) { delete[] shaperItem->glyphs; delete[] shaperItem->attributes; Loading