Merge "Fix bug #5504346 Hung in native_getTextRunAdvances - DO NOT MERGE" into ics-mr1

This commit is contained in:
Fabrice Di Meglio
2011-11-01 13:30:24 -07:00
committed by Android (Google) Code Review

View File

@ -425,14 +425,10 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
// Initialize Harfbuzz Shaper // Initialize Harfbuzz Shaper
initShaperItem(shaperItem, &font, &fontData, paint, chars, contextCount); initShaperItem(shaperItem, &font, &fontData, paint, chars, contextCount);
bool useSingleRun = false;
bool isRTL = forceRTL;
if (forceLTR || forceRTL) { if (forceLTR || forceRTL) {
#if DEBUG_GLYPHS useSingleRun = true;
LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d",
forceLTR, forceRTL);
#endif
computeRunValuesWithHarfbuzz(shaperItem, paint,
start, count, forceRTL,
outAdvances, outTotalAdvance, outGlyphs);
} else { } else {
UBiDi* bidi = ubidi_open(); UBiDi* bidi = ubidi_open();
if (bidi) { if (bidi) {
@ -443,43 +439,50 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
ubidi_setPara(bidi, chars, contextCount, bidiReq, NULL, &status); ubidi_setPara(bidi, chars, contextCount, bidiReq, NULL, &status);
if (U_SUCCESS(status)) { if (U_SUCCESS(status)) {
int paraDir = ubidi_getParaLevel(bidi) & kDirection_Mask; // 0 if ltr, 1 if rtl int paraDir = ubidi_getParaLevel(bidi) & kDirection_Mask; // 0 if ltr, 1 if rtl
size_t rc = ubidi_countRuns(bidi, &status); ssize_t rc = ubidi_countRuns(bidi, &status);
#if DEBUG_GLYPHS #if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d",
dirFlags, rc, paraDir); dirFlags, rc, paraDir);
#endif #endif
if (rc == 1 || !U_SUCCESS(status)) { if (!U_SUCCESS(status) || rc <= 1) {
bool isRTL = (paraDir == 1); LOGW("computeValuesWithHarfbuzz -- need to force to single run");
#if DEBUG_GLYPHS isRTL = (paraDir == 1);
LOGD("computeValuesWithHarfbuzz -- processing SINGLE run " useSingleRun = true;
"-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
#endif
computeRunValuesWithHarfbuzz(shaperItem, paint,
start, count, isRTL,
outAdvances, outTotalAdvance, outGlyphs);
} else { } else {
int32_t end = start + count; int32_t end = start + count;
for (size_t i = 0; i < rc; ++i) { for (size_t i = 0; i < size_t(rc); ++i) {
int32_t startRun; int32_t startRun = -1;
int32_t lengthRun; int32_t lengthRun = -1;
UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &startRun, &lengthRun); UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &startRun, &lengthRun);
if (startRun == -1 || lengthRun == -1) {
// Something went wrong when getting the visual run, need to clear
// already computed data before doing a single run pass
LOGW("computeValuesWithHarfbuzz -- visual run is not valid");
outGlyphs->clear();
outAdvances->clear();
*outTotalAdvance = 0;
isRTL = (paraDir == 1);
useSingleRun = true;
break;
}
if (startRun >= end) { if (startRun >= end) {
continue; continue;
} }
int32_t endRun = startRun + lengthRun; int32_t endRun = startRun + lengthRun;
if (endRun <= start) { if (endRun <= int32_t(start)) {
continue; continue;
} }
if (startRun < start) { if (startRun < int32_t(start)) {
startRun = start; startRun = int32_t(start);
} }
if (endRun > end) { if (endRun > end) {
endRun = end; endRun = end;
} }
lengthRun = endRun - startRun; lengthRun = endRun - startRun;
bool isRTL = (runDir == UBIDI_RTL); isRTL = (runDir == UBIDI_RTL);
jfloat runTotalAdvance = 0; jfloat runTotalAdvance = 0;
#if DEBUG_GLYPHS #if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d", LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d",
@ -492,21 +495,30 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar
*outTotalAdvance += runTotalAdvance; *outTotalAdvance += runTotalAdvance;
} }
} }
} else {
LOGW("computeValuesWithHarfbuzz -- cannot set Para");
useSingleRun = true;
isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
} }
ubidi_close(bidi); ubidi_close(bidi);
} else { } else {
// Cannot run BiDi, just consider one Run LOGW("computeValuesWithHarfbuzz -- cannot ubidi_open()");
bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL); useSingleRun = true;
#if DEBUG_GLYPHS isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL);
LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run "
"-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
#endif
computeRunValuesWithHarfbuzz(shaperItem, paint,
start, count, isRTL,
outAdvances, outTotalAdvance, outGlyphs);
} }
} }
// Default single run case
if (useSingleRun){
#if DEBUG_GLYPHS
LOGD("computeValuesWithHarfbuzz -- Using a SINGLE Run "
"-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL);
#endif
computeRunValuesWithHarfbuzz(shaperItem, paint,
start, count, isRTL,
outAdvances, outTotalAdvance, outGlyphs);
}
// Cleaning // Cleaning
freeShaperItem(shaperItem); freeShaperItem(shaperItem);