diff options
-rw-r--r-- | core/java/android/app/backup/WallpaperBackupHelper.java | 2 | ||||
-rw-r--r-- | core/java/android/server/BluetoothHealthProfileHandler.java | 3 | ||||
-rw-r--r-- | core/java/android/webkit/FindActionModeCallback.java | 16 | ||||
-rw-r--r-- | core/java/android/webkit/WebView.java | 3 | ||||
-rw-r--r-- | core/java/android/widget/AbsListView.java | 102 | ||||
-rw-r--r-- | core/jni/android/graphics/Canvas.cpp | 11 | ||||
-rw-r--r-- | core/jni/android/graphics/Paint.cpp | 17 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayout.cpp | 11 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.cpp | 309 | ||||
-rw-r--r-- | core/jni/android/graphics/TextLayoutCache.h | 66 | ||||
-rw-r--r-- | core/jni/android_view_GLES20Canvas.cpp | 20 | ||||
-rw-r--r-- | graphics/java/android/renderscript/RenderScript.java | 8 | ||||
-rw-r--r-- | libs/hwui/FontRenderer.cpp | 14 | ||||
-rw-r--r-- | policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java | 17 | ||||
-rw-r--r-- | services/java/com/android/server/WallpaperManagerService.java | 2 |
15 files changed, 314 insertions, 287 deletions
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java index 0c034cf..170171e 100644 --- a/core/java/android/app/backup/WallpaperBackupHelper.java +++ b/core/java/android/app/backup/WallpaperBackupHelper.java @@ -35,7 +35,7 @@ import java.io.File; */ public class WallpaperBackupHelper extends FileBackupHelperBase implements BackupHelper { private static final String TAG = "WallpaperBackupHelper"; - private static final boolean DEBUG = true; + private static final boolean DEBUG = false; // This path must match what the WallpaperManagerService uses private static final String WALLPAPER_IMAGE = "/data/data/com.android.settings/files/wallpaper"; diff --git a/core/java/android/server/BluetoothHealthProfileHandler.java b/core/java/android/server/BluetoothHealthProfileHandler.java index 2961fd2..5e93b81 100644 --- a/core/java/android/server/BluetoothHealthProfileHandler.java +++ b/core/java/android/server/BluetoothHealthProfileHandler.java @@ -45,8 +45,7 @@ import java.util.concurrent.atomic.AtomicInteger; */ final class BluetoothHealthProfileHandler { private static final String TAG = "BluetoothHealthProfileHandler"; - /*STOPSHIP*/ - private static final boolean DBG = true; + private static final boolean DBG = false; private static BluetoothHealthProfileHandler sInstance; private BluetoothService mBluetoothService; diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java index 7398262..b85fd17 100644 --- a/core/java/android/webkit/FindActionModeCallback.java +++ b/core/java/android/webkit/FindActionModeCallback.java @@ -22,16 +22,14 @@ import android.text.Editable; import android.text.Selection; import android.text.Spannable; import android.text.TextWatcher; -import android.webkit.WebView; -import android.widget.EditText; -import android.widget.TextView; import android.view.ActionMode; import android.view.LayoutInflater; import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.TextView; class FindActionModeCallback implements ActionMode.Callback, TextWatcher, View.OnLongClickListener, View.OnClickListener { @@ -203,6 +201,7 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, @Override public void onDestroyActionMode(ActionMode mode) { + mActionMode = null; mWebView.notifyFindDialogDismissed(); mInput.hideSoftInputFromWindow(mWebView.getWindowToken(), 0); } @@ -255,4 +254,13 @@ class FindActionModeCallback implements ActionMode.Callback, TextWatcher, // Does nothing. Needed to implement TextWatcher. } + public int getActionModeHeight() { + if (mActionMode == null) { + return 0; + } + View parent = (View) mCustomView.getParent(); + return parent != null ? parent.getMeasuredHeight() + : mCustomView.getMeasuredHeight(); + } + } diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index d920f27..05d8da2 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -1483,7 +1483,8 @@ public class WebView extends AbsoluteLayout private int getVisibleTitleHeightImpl() { // need to restrict mScrollY due to over scroll - return Math.max(getTitleHeight() - Math.max(0, mScrollY), 0); + return Math.max(getTitleHeight() - Math.max(0, mScrollY), + mFindCallback != null ? mFindCallback.getActionModeHeight() : 0); } /* diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index c218f23..0d287cf 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -237,9 +237,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te SparseBooleanArray mCheckStates; /** - * Running state of which IDs are currently checked + * Running state of which IDs are currently checked. + * If there is a value for a given key, the checked state for that ID is true + * and the value holds the last known position in the adapter for that id. */ - LongSparseArray<Boolean> mCheckedIdStates; + LongSparseArray<Integer> mCheckedIdStates; /** * Controls how the next layout will happen @@ -472,6 +474,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te static final int OVERSCROLL_LIMIT_DIVISOR = 3; /** + * How many positions in either direction we will search to try to + * find a checked item with a stable ID that moved position across + * a data set change. If the item isn't found it will be unselected. + */ + private static final int CHECK_POSITION_SEARCH_DISTANCE = 20; + + /** * Used to request a layout when we changed touch mode */ private static final int TOUCH_MODE_UNKNOWN = -1; @@ -806,7 +815,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (adapter != null) { if (mChoiceMode != CHOICE_MODE_NONE && mAdapter.hasStableIds() && mCheckedIdStates == null) { - mCheckedIdStates = new LongSparseArray<Boolean>(); + mCheckedIdStates = new LongSparseArray<Integer>(); } } @@ -901,7 +910,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return new long[0]; } - final LongSparseArray<Boolean> idStates = mCheckedIdStates; + final LongSparseArray<Integer> idStates = mCheckedIdStates; final int count = idStates.size(); final long[] ids = new long[count]; @@ -948,7 +957,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mCheckStates.put(position, value); if (mCheckedIdStates != null && mAdapter.hasStableIds()) { if (value) { - mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE); + mCheckedIdStates.put(mAdapter.getItemId(position), position); } else { mCheckedIdStates.delete(mAdapter.getItemId(position)); } @@ -980,7 +989,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (value) { mCheckStates.put(position, true); if (updateIds) { - mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE); + mCheckedIdStates.put(mAdapter.getItemId(position), position); } mCheckedItemCount = 1; } else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) { @@ -1010,7 +1019,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mCheckStates.put(position, newValue); if (mCheckedIdStates != null && mAdapter.hasStableIds()) { if (newValue) { - mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE); + mCheckedIdStates.put(mAdapter.getItemId(position), position); } else { mCheckedIdStates.delete(mAdapter.getItemId(position)); } @@ -1032,7 +1041,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mCheckStates.put(position, true); if (mCheckedIdStates != null && mAdapter.hasStableIds()) { mCheckedIdStates.clear(); - mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE); + mCheckedIdStates.put(mAdapter.getItemId(position), position); } mCheckedItemCount = 1; } else if (mCheckStates.size() == 0 || !mCheckStates.valueAt(0)) { @@ -1081,7 +1090,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mCheckStates = new SparseBooleanArray(); } if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) { - mCheckedIdStates = new LongSparseArray<Boolean>(); + mCheckedIdStates = new LongSparseArray<Integer>(); } // Modal multi-choice mode only has choices when the mode is active. Clear them. if (mChoiceMode == CHOICE_MODE_MULTIPLE_MODAL) { @@ -1411,7 +1420,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te boolean inActionMode; int checkedItemCount; SparseBooleanArray checkState; - LongSparseArray<Boolean> checkIdState; + LongSparseArray<Integer> checkIdState; /** * Constructor called from {@link AbsListView#onSaveInstanceState()} @@ -1435,10 +1444,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te checkedItemCount = in.readInt(); checkState = in.readSparseBooleanArray(); long[] idState = in.createLongArray(); + int[] idPositions = in.createIntArray(); - if (idState.length > 0) { - checkIdState = new LongSparseArray<Boolean>(); - checkIdState.setValues(idState, Boolean.TRUE); + final int idLength = idState.length; + if (idLength > 0) { + checkIdState = new LongSparseArray<Integer>(); + for (int i = 0; i < idLength; i++) { + checkIdState.put(idState[i], idPositions[i]); + } } } @@ -1455,6 +1468,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te out.writeInt(checkedItemCount); out.writeSparseBooleanArray(checkState); out.writeLongArray(checkIdState != null ? checkIdState.getKeys() : new long[0]); + + int size = checkIdState != null ? checkIdState.size() : 0; + int[] idPositions = new int[size]; + if (size > 0) { + for (int i = 0; i < size; i++) { + idPositions[i] = checkIdState.valueAt(i); + } + out.writeIntArray(idPositions); + } } @Override @@ -1549,7 +1571,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te ss.checkState = mCheckStates.clone(); } if (mCheckedIdStates != null) { - final LongSparseArray<Boolean> idState = new LongSparseArray<Boolean>(); + final LongSparseArray<Integer> idState = new LongSparseArray<Integer>(); final int count = mCheckedIdStates.size(); for (int i = 0; i < count; i++) { idState.put(mCheckedIdStates.keyAt(i), mCheckedIdStates.valueAt(i)); @@ -4770,15 +4792,63 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te return selectedPos >= 0; } + void confirmCheckedPositionsById() { + // Clear out the positional check states, we'll rebuild it below from IDs. + mCheckStates.clear(); + + boolean checkedCountChanged = false; + for (int checkedIndex = 0; checkedIndex < mCheckedIdStates.size(); checkedIndex++) { + final long id = mCheckedIdStates.keyAt(checkedIndex); + final int lastPos = mCheckedIdStates.valueAt(checkedIndex); + + final long lastPosId = mAdapter.getItemId(lastPos); + if (id != lastPosId) { + // Look around to see if the ID is nearby. If not, uncheck it. + final int start = Math.max(0, lastPos - CHECK_POSITION_SEARCH_DISTANCE); + final int end = Math.min(lastPos + CHECK_POSITION_SEARCH_DISTANCE, mItemCount); + boolean found = false; + for (int searchPos = start; searchPos < end; searchPos++) { + final long searchId = mAdapter.getItemId(searchPos); + if (id == searchId) { + found = true; + mCheckStates.put(searchPos, true); + mCheckedIdStates.setValueAt(checkedIndex, searchPos); + break; + } + } + + if (!found) { + mCheckedIdStates.delete(id); + checkedIndex--; + mCheckedItemCount--; + checkedCountChanged = true; + if (mChoiceActionMode != null && mMultiChoiceModeCallback != null) { + mMultiChoiceModeCallback.onItemCheckedStateChanged(mChoiceActionMode, + lastPos, id, false); + } + } + } else { + mCheckStates.put(lastPos, true); + } + } + + if (checkedCountChanged && mChoiceActionMode != null) { + mChoiceActionMode.invalidate(); + } + } + @Override protected void handleDataChanged() { int count = mItemCount; int lastHandledItemCount = mLastHandledItemCount; mLastHandledItemCount = mItemCount; - if (count > 0) { - int newPos; + if (mChoiceMode != CHOICE_MODE_NONE && mAdapter != null && mAdapter.hasStableIds()) { + confirmCheckedPositionsById(); + } + if (count > 0) { + int newPos; int selectablePos; // Find the row we are supposed to sync to diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp index 02c5bb3..7724646 100644 --- a/core/jni/android/graphics/Canvas.cpp +++ b/core/jni/android/graphics/Canvas.cpp @@ -767,20 +767,17 @@ public: sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE - value = TextLayoutCache::getInstance().getValue(paint, textArray, contextCount, flags); + value = TextLayoutCache::getInstance().getValue(paint, textArray, start, count, + contextCount, flags); if (value == NULL) { LOGE("Cannot get TextLayoutCache value"); return ; } #else value = new TextLayoutCacheValue(); - value->computeValues(paint, textArray, contextCount, flags); + value->computeValues(paint, textArray, start, count, contextCount, flags); #endif - size_t startIndex = 0; - size_t glyphsCount = 0; - value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount); - const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount); - doDrawGlyphs(canvas, glyphs, 0, glyphsCount, x, y, flags, paint); + doDrawGlyphs(canvas, value->getGlyphs(), 0, value->getGlyphsCount(), x, y, flags, paint); } static void doDrawGlyphs(SkCanvas* canvas, const jchar* glyphArray, int index, int count, diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 3daf7d0..2ab7da9 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -483,18 +483,15 @@ public: } jchar* glyphsArray = env->GetCharArrayElements(glyphs, NULL); - HB_ShaperItem shaperItem; - HB_FontRec font; - FontData fontData; - TextLayoutCacheValue::shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, text, - start, count, contextCount, flags); - int glyphCount = shaperItem.num_glyphs; - for (int i = 0; i < glyphCount; i++) { - glyphsArray[i] = (jchar) shaperItem.glyphs[i]; - } + TextLayoutCacheValue value; + value.computeValues(paint, text, start, count, contextCount, flags); + const jchar* shapedGlyphs = value.getGlyphs(); + size_t glyphsCount = value.getGlyphsCount(); + memcpy(glyphsArray, shapedGlyphs, sizeof(jchar) * glyphsCount); + env->ReleaseCharArrayElements(glyphs, glyphsArray, JNI_ABORT); - return glyphCount; + return glyphsCount; } static int getTextGlyphs__StringIIIII_C(JNIEnv* env, jobject clazz, SkPaint* paint, diff --git a/core/jni/android/graphics/TextLayout.cpp b/core/jni/android/graphics/TextLayout.cpp index ae17aed..9b424f2 100644 --- a/core/jni/android/graphics/TextLayout.cpp +++ b/core/jni/android/graphics/TextLayout.cpp @@ -257,17 +257,18 @@ void TextLayout::getTextRunAdvances(SkPaint* paint, const jchar* chars, jint sta sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE // Return advances from the cache. Compute them if needed - value = TextLayoutCache::getInstance().getValue(paint, chars, contextCount, dirFlags); + value = TextLayoutCache::getInstance().getValue(paint, chars, start, count, + contextCount, dirFlags); #else value = new TextLayoutCacheValue(); - value->computeValues(paint, chars, contextCount, dirFlags); + value->computeValues(paint, chars, start, count, contextCount, dirFlags); #endif if (value != NULL) { - if (resultAdvances != NULL) { - value->getAdvances(start, count, resultAdvances); + if (resultAdvances) { + memcpy(resultAdvances, value->getAdvances(), value->getAdvancesCount() * sizeof(jfloat)); } if (resultTotalAdvance) { - *resultTotalAdvance = value->getTotalAdvance(start, count); + *resultTotalAdvance = value->getTotalAdvance(); } } } diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 9ba95bd..0b53850 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -106,7 +106,7 @@ void TextLayoutCache::clear() { * Caching */ sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint, - const jchar* text, jint count, jint dirFlags) { + const jchar* text, jint start, jint count, jint contextCount, jint dirFlags) { AutoMutex _l(mLock); nsecs_t startTime = 0; if (mDebugEnabled) { @@ -114,7 +114,7 @@ sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint, } // Create the key - TextLayoutCacheKey key(paint, text, count, dirFlags); + TextLayoutCacheKey key(paint, text, start, count, contextCount, dirFlags); // Get value from cache if possible sp<TextLayoutCacheValue> value = mCache.get(key); @@ -128,7 +128,7 @@ sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint, value = new TextLayoutCacheValue(); // Compute advances and store them - value->computeValues(paint, text, count, dirFlags); + value->computeValues(paint, text, start, count, contextCount, dirFlags); nsecs_t endTime = systemTime(SYSTEM_TIME_MONOTONIC); @@ -166,10 +166,10 @@ sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint, } else { if (mDebugEnabled) { LOGD("CACHE MISS: Calculated but not storing entry because it is too big " - "with count=%d, " + "with start=%d count=%d contextCount=%d, " "entry size %d bytes, remaining space %d bytes" " - Compute time in nanos: %lld - Text='%s'", - count, size, mMaxSize - mSize, endTime, + start, count, contextCount, size, mMaxSize - mSize, endTime, String8(text, count).string()); } value.clear(); @@ -184,10 +184,10 @@ sp<TextLayoutCacheValue> TextLayoutCache::getValue(SkPaint* paint, if (value->getElapsedTime() > 0) { float deltaPercent = 100 * ((value->getElapsedTime() - elapsedTimeThruCacheGet) / ((float)value->getElapsedTime())); - LOGD("CACHE HIT #%d with count=%d " + LOGD("CACHE HIT #%d with start=%d count=%d contextCount=%d" "- Compute time in nanos: %d - " "Cache get time in nanos: %lld - Gain in percent: %2.2f - Text='%s' ", - mCacheHitCount, count, + mCacheHitCount, start, count, contextCount, value->getElapsedTime(), elapsedTimeThruCacheGet, deltaPercent, String8(text, count).string()); } @@ -218,14 +218,14 @@ void TextLayoutCache::dumpCacheStats() { /** * TextLayoutCacheKey */ -TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), count(0), +TextLayoutCacheKey::TextLayoutCacheKey(): text(NULL), start(0), count(0), contextCount(0), dirFlags(0), typeface(NULL), textSize(0), textSkewX(0), textScaleX(0), flags(0), hinting(SkPaint::kNo_Hinting) { } -TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, - const UChar* text, size_t count, int dirFlags) : - text(text), count(count), +TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, const UChar* text, + size_t start, size_t count, size_t contextCount, int dirFlags) : + text(text), start(start), count(count), contextCount(contextCount), dirFlags(dirFlags) { typeface = paint->getTypeface(); textSize = paint->getTextSize(); @@ -238,7 +238,9 @@ TextLayoutCacheKey::TextLayoutCacheKey(const SkPaint* paint, TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) : text(NULL), textCopy(other.textCopy), + start(other.start), count(other.count), + contextCount(other.contextCount), dirFlags(other.dirFlags), typeface(other.typeface), textSize(other.textSize), @@ -252,7 +254,13 @@ TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) : } int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutCacheKey& rhs) { - int deltaInt = lhs.count - rhs.count; + int deltaInt = lhs.start - rhs.start; + if (deltaInt != 0) return (deltaInt); + + deltaInt = lhs.count - rhs.count; + if (deltaInt != 0) return (deltaInt); + + deltaInt = lhs.contextCount - rhs.contextCount; if (deltaInt != 0) return (deltaInt); if (lhs.typeface < rhs.typeface) return -1; @@ -276,16 +284,16 @@ int TextLayoutCacheKey::compare(const TextLayoutCacheKey& lhs, const TextLayoutC deltaInt = lhs.dirFlags - rhs.dirFlags; if (deltaInt) return (deltaInt); - return memcmp(lhs.getText(), rhs.getText(), lhs.count * sizeof(UChar)); + return memcmp(lhs.getText(), rhs.getText(), lhs.contextCount * sizeof(UChar)); } void TextLayoutCacheKey::internalTextCopy() { - textCopy.setTo(text, count); + textCopy.setTo(text, contextCount); text = NULL; } size_t TextLayoutCacheKey::getSize() { - return sizeof(TextLayoutCacheKey) + sizeof(UChar) * count; + return sizeof(TextLayoutCacheKey) + sizeof(UChar) * contextCount; } /** @@ -304,29 +312,32 @@ uint32_t TextLayoutCacheValue::getElapsedTime() { } void TextLayoutCacheValue::computeValues(SkPaint* paint, const UChar* chars, - size_t contextCount, int dirFlags) { + size_t start, size_t count, size_t contextCount, int dirFlags) { // Give a hint for advances, glyphs and log clusters vectors size mAdvances.setCapacity(contextCount); mGlyphs.setCapacity(contextCount); - mLogClusters.setCapacity(contextCount); - computeValuesWithHarfbuzz(paint, chars, contextCount, dirFlags, - &mAdvances, &mTotalAdvance, &mGlyphs, &mLogClusters); + computeValuesWithHarfbuzz(paint, chars, start, count, contextCount, dirFlags, + &mAdvances, &mTotalAdvance, &mGlyphs); #if DEBUG_ADVANCES - LOGD("Advances - countextCount=%d - totalAdvance=%f", contextCount, mTotalAdvance); + LOGD("Advances - start=%d, count=%d, countextCount=%d, totalAdvance=%f", start, count, + contextCount, mTotalAdvance); #endif } size_t TextLayoutCacheValue::getSize() { return sizeof(TextLayoutCacheValue) + sizeof(jfloat) * mAdvances.capacity() + - sizeof(jchar) * mGlyphs.capacity() + sizeof(unsigned short) * mLogClusters.capacity(); + sizeof(jchar) * mGlyphs.capacity(); } -void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, - FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, - size_t contextCount, bool isRTL) { +void TextLayoutCacheValue::initShaperItem(HB_ShaperItem& shaperItem, HB_FontRec* font, + FontData* fontData, SkPaint* paint, const UChar* chars, size_t contextCount) { + // Zero the Shaper struct + memset(&shaperItem, 0, sizeof(shaperItem)); + font->klass = &harfbuzzSkiaClass; font->userData = 0; + // The values which harfbuzzSkiaClass returns are already scaled to // pixel units, so we just set all these to one to disable further // scaling. @@ -335,11 +346,21 @@ void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec font->x_scale = 1; font->y_scale = 1; - memset(shaperItem, 0, sizeof(*shaperItem)); - shaperItem->font = font; - shaperItem->face = HB_NewFace(shaperItem->font, harfbuzzSkiaGetTable); + shaperItem.font = font; + shaperItem.face = HB_NewFace(shaperItem.font, harfbuzzSkiaGetTable); + + // Reset kerning + shaperItem.kerning_applied = false; + + // Define font data + fontData->typeFace = paint->getTypeface(); + fontData->textSize = paint->getTextSize(); + fontData->textSkewX = paint->getTextSkewX(); + fontData->textScaleX = paint->getTextScaleX(); + fontData->flags = paint->getFlags(); + fontData->hinting = paint->getHinting(); - shaperItem->kerning_applied = false; + shaperItem.font->userData = fontData; // We cannot know, ahead of time, how many glyphs a given script run // will produce. We take a guess that script runs will not produce more @@ -347,53 +368,42 @@ void TextLayoutCacheValue::setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec // padding and fallback if we find that we are wrong. createGlyphArrays(shaperItem, (contextCount + 2) * 2); - // Free memory for clusters if needed and recreate the clusters array - if (shaperItem->log_clusters) { - delete shaperItem->log_clusters; - } - shaperItem->log_clusters = new unsigned short[contextCount]; - - shaperItem->item.pos = start; - shaperItem->item.length = count; - shaperItem->item.bidiLevel = isRTL; - - shaperItem->item.script = isRTL ? HB_Script_Arabic : HB_Script_Common; - - shaperItem->string = chars; - shaperItem->stringLength = contextCount; + // Create log clusters array + shaperItem.log_clusters = new unsigned short[contextCount]; - fontData->typeFace = paint->getTypeface(); - fontData->textSize = paint->getTextSize(); - fontData->textSkewX = paint->getTextSkewX(); - fontData->textScaleX = paint->getTextScaleX(); - fontData->flags = paint->getFlags(); - fontData->hinting = paint->getHinting(); + // Set the string properties + shaperItem.string = chars; + shaperItem.stringLength = contextCount; +} - shaperItem->font->userData = fontData; +void TextLayoutCacheValue::freeShaperItem(HB_ShaperItem& shaperItem) { + deleteGlyphArrays(shaperItem); + delete[] shaperItem.log_clusters; + HB_FreeFace(shaperItem.face); } -void TextLayoutCacheValue::shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, - FontData* fontData, SkPaint* paint, const UChar* chars, size_t start, size_t count, - size_t contextCount, bool isRTL) { - // Setup Harfbuzz Shaper - setupShaperItem(shaperItem, font, fontData, paint, chars, start, count, - contextCount, isRTL); +void TextLayoutCacheValue::shapeRun(HB_ShaperItem& shaperItem, size_t start, size_t count, + bool isRTL) { + // Update Harfbuzz Shaper + shaperItem.item.pos = start; + shaperItem.item.length = count; + shaperItem.item.bidiLevel = isRTL; + + shaperItem.item.script = isRTL ? HB_Script_Arabic : HB_Script_Common; // Shape - resetGlyphArrays(shaperItem); - while (!HB_ShapeItem(shaperItem)) { + while (!HB_ShapeItem(&shaperItem)) { // We overflowed our arrays. Resize and retry. // HB_ShapeItem fills in shaperItem.num_glyphs with the needed size. deleteGlyphArrays(shaperItem); - createGlyphArrays(shaperItem, shaperItem->num_glyphs << 1); - resetGlyphArrays(shaperItem); + createGlyphArrays(shaperItem, shaperItem.num_glyphs << 1); } } void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, - size_t contextCount, int dirFlags, + size_t start, size_t count, size_t contextCount, int dirFlags, Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, - Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) { + Vector<jchar>* const outGlyphs) { UBiDiLevel bidiReq = 0; bool forceLTR = false; @@ -408,13 +418,21 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar case kBidi_Force_RTL: forceRTL = true; break; // every char is RTL } + HB_ShaperItem shaperItem; + HB_FontRec font; + FontData fontData; + + // Initialize Harfbuzz Shaper + initShaperItem(shaperItem, &font, &fontData, paint, chars, contextCount); + if (forceLTR || forceRTL) { #if DEBUG_GLYPHS LOGD("computeValuesWithHarfbuzz -- forcing run with LTR=%d RTL=%d", forceLTR, forceRTL); #endif - computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, forceRTL, - outAdvances, outTotalAdvance, outGlyphs, outLogClusters); + computeRunValuesWithHarfbuzz(shaperItem, paint, + start, count, forceRTL, + outAdvances, outTotalAdvance, outGlyphs); } else { UBiDi* bidi = ubidi_open(); if (bidi) { @@ -427,32 +445,49 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar int paraDir = ubidi_getParaLevel(bidi) & kDirection_Mask; // 0 if ltr, 1 if rtl size_t rc = ubidi_countRuns(bidi, &status); #if DEBUG_GLYPHS - LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", dirFlags, rc, paraDir); + LOGD("computeValuesWithHarfbuzz -- dirFlags=%d run-count=%d paraDir=%d", + dirFlags, rc, paraDir); #endif if (rc == 1 || !U_SUCCESS(status)) { bool isRTL = (paraDir == 1); #if DEBUG_GLYPHS LOGD("computeValuesWithHarfbuzz -- processing SINGLE run " - "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL); + "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL); #endif - computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, - isRTL, outAdvances, outTotalAdvance, outGlyphs, outLogClusters); + computeRunValuesWithHarfbuzz(shaperItem, paint, + start, count, isRTL, + outAdvances, outTotalAdvance, outGlyphs); } else { + int32_t end = start + count; for (size_t i = 0; i < rc; ++i) { int32_t startRun; int32_t lengthRun; UBiDiDirection runDir = ubidi_getVisualRun(bidi, i, &startRun, &lengthRun); + if (startRun >= end) { + continue; + } + int32_t endRun = startRun + lengthRun; + if (endRun <= start) { + continue; + } + if (startRun < start) { + startRun = start; + } + if (endRun > end) { + endRun = end; + } + + lengthRun = endRun - startRun; bool isRTL = (runDir == UBIDI_RTL); jfloat runTotalAdvance = 0; #if DEBUG_GLYPHS LOGD("computeValuesWithHarfbuzz -- run-start=%d run-len=%d isRTL=%d", startRun, lengthRun, isRTL); #endif - computeRunValuesWithHarfbuzz(paint, chars, startRun, - lengthRun, contextCount, isRTL, - outAdvances, &runTotalAdvance, - outGlyphs, outLogClusters); + computeRunValuesWithHarfbuzz(shaperItem, paint, + startRun, lengthRun, isRTL, + outAdvances, &runTotalAdvance, outGlyphs); *outTotalAdvance += runTotalAdvance; } @@ -464,12 +499,17 @@ void TextLayoutCacheValue::computeValuesWithHarfbuzz(SkPaint* paint, const UChar bool isRTL = (bidiReq = 1) || (bidiReq = UBIDI_DEFAULT_RTL); #if DEBUG_GLYPHS LOGD("computeValuesWithHarfbuzz -- cannot run BiDi, considering a SINGLE Run " - "-- run-start=%d run-len=%d isRTL=%d", 0, contextCount, isRTL); + "-- run-start=%d run-len=%d isRTL=%d", start, count, isRTL); #endif - computeRunValuesWithHarfbuzz(paint, chars, 0, contextCount, contextCount, isRTL, - outAdvances, outTotalAdvance, outGlyphs, outLogClusters); + computeRunValuesWithHarfbuzz(shaperItem, paint, + start, count, isRTL, + outAdvances, outTotalAdvance, outGlyphs); } } + + // Cleaning + freeShaperItem(shaperItem); + #if DEBUG_GLYPHS LOGD("computeValuesWithHarfbuzz -- total-glyphs-count=%d", outGlyphs->size()); #endif @@ -484,17 +524,12 @@ static void logGlyphs(HB_ShaperItem shaperItem) { } } -void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, - size_t start, size_t count, size_t contextCount, bool isRTL, +void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(HB_ShaperItem& shaperItem, SkPaint* paint, + size_t start, size_t count, bool isRTL, Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, - Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters) { - - HB_ShaperItem shaperItem; - HB_FontRec font; - FontData fontData; + Vector<jchar>* const outGlyphs) { - shapeWithHarfbuzz(&shaperItem, &font, &fontData, paint, chars, start, count, - contextCount, isRTL); + shapeRun(shaperItem, start, count, isRTL); #if DEBUG_GLYPHS LOGD("HARFBUZZ -- num_glypth=%d - kerning_applied=%d", shaperItem.num_glyphs, @@ -511,10 +546,6 @@ void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UC #endif outAdvances->insertAt(0, outAdvances->size(), count); *outTotalAdvance = 0; - - // Cleaning - deleteGlyphArrays(&shaperItem); - HB_FreeFace(shaperItem.face); return; } @@ -553,103 +584,21 @@ void TextLayoutCacheValue::computeRunValuesWithHarfbuzz(SkPaint* paint, const UC outGlyphs->add(glyph); } } - - // Get LogClusters - if (outLogClusters) { - size_t countLogClusters = outLogClusters->size(); - for (size_t i = 0; i < count; i++) { - // As there may be successive runs, we need to shift the log clusters - unsigned short logCluster = shaperItem.log_clusters[i] + countLogClusters; -#if DEBUG_GLYPHS - LOGD("HARFBUZZ -- logCluster[%d] relative=%d - absolute=%d", i, shaperItem.log_clusters[i], logCluster); -#endif - outLogClusters->add(logCluster); - } - } - - // Cleaning - deleteGlyphArrays(&shaperItem); - HB_FreeFace(shaperItem.face); -} - -void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem* shaperItem) { - delete[] shaperItem->glyphs; - delete[] shaperItem->attributes; - delete[] shaperItem->advances; - delete[] shaperItem->offsets; -} - -void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem* shaperItem, int size) { - shaperItem->glyphs = new HB_Glyph[size]; - shaperItem->attributes = new HB_GlyphAttributes[size]; - shaperItem->advances = new HB_Fixed[size]; - shaperItem->offsets = new HB_FixedPoint[size]; - shaperItem->num_glyphs = size; -} - -void TextLayoutCacheValue::resetGlyphArrays(HB_ShaperItem* shaperItem) { - int size = shaperItem->num_glyphs; - // All the types here don't have pointers. It is safe to reset to - // zero unless Harfbuzz breaks the compatibility in the future. - memset(shaperItem->glyphs, 0, size * sizeof(shaperItem->glyphs[0])); - memset(shaperItem->attributes, 0, size * sizeof(shaperItem->attributes[0])); - memset(shaperItem->advances, 0, size * sizeof(shaperItem->advances[0])); - memset(shaperItem->offsets, 0, size * sizeof(shaperItem->offsets[0])); -} - -void TextLayoutCacheValue::getAdvances(size_t start, size_t count, jfloat* outAdvances) const { - memcpy(outAdvances, mAdvances.array() + start, count * sizeof(jfloat)); -#if DEBUG_ADVANCES - LOGD("getAdvances - start=%d count=%d", start, count); - for (size_t i = 0; i < count; i++) { - LOGD(" adv[%d] = %f", i, outAdvances[i]); - } -#endif } -jfloat TextLayoutCacheValue::getTotalAdvance(size_t start, size_t count) const { - jfloat outTotalAdvance = 0; - for (size_t i = start; i < start + count; i++) { - outTotalAdvance += mAdvances[i]; - } -#if DEBUG_ADVANCES - LOGD("getTotalAdvance - start=%d count=%d - total=%f", start, count, outTotalAdvance); -#endif - return outTotalAdvance; +void TextLayoutCacheValue::deleteGlyphArrays(HB_ShaperItem& shaperItem) { + delete[] shaperItem.glyphs; + delete[] shaperItem.attributes; + delete[] shaperItem.advances; + delete[] shaperItem.offsets; } -void TextLayoutCacheValue::getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex, - size_t* outGlyphsCount) const { - *outStartIndex = 0; - if (count == 0) { - *outGlyphsCount = 0; - return; - } - *outStartIndex = mLogClusters[start]; - size_t endIndex = (start + count >= mAdvances.size()) ? - mGlyphs.size() : mLogClusters[start + count]; - *outGlyphsCount = endIndex - *outStartIndex; -#if DEBUG_GLYPHS - LOGD("getGlyphsIndexes - start=%d count=%d - startIndex=%d count=%d", start, count, - *outStartIndex, *outGlyphsCount); - for(size_t i = 0; i < mGlyphs.size(); i++) { - LOGD("getGlyphs - all - glyph[%d] = %d", i, mGlyphs[i]); - } - for(size_t i = 0; i < mAdvances.size(); i++) { - LOGD("getGlyphs - all - logcl[%d] = %d", i, mLogClusters[i]); - } -#endif -} - -const jchar* TextLayoutCacheValue::getGlyphs(size_t startIndex, size_t count) { - const jchar* glyphs = mGlyphs.array() + startIndex; -#if DEBUG_GLYPHS - LOGD("getGlyphs - with startIndex = %d count = %d", startIndex, count); - for (size_t i = 0; i < count; i++) { - LOGD("getGlyphs - result - glyph[%d] = %d", i, glyphs[i]); - } -#endif - return glyphs; +void TextLayoutCacheValue::createGlyphArrays(HB_ShaperItem& shaperItem, int size) { + shaperItem.glyphs = new HB_Glyph[size]; + shaperItem.attributes = new HB_GlyphAttributes[size]; + shaperItem.advances = new HB_Fixed[size]; + shaperItem.offsets = new HB_FixedPoint[size]; + shaperItem.num_glyphs = size; } } // namespace android diff --git a/core/jni/android/graphics/TextLayoutCache.h b/core/jni/android/graphics/TextLayoutCache.h index 6dda1e5..580079d 100644 --- a/core/jni/android/graphics/TextLayoutCache.h +++ b/core/jni/android/graphics/TextLayoutCache.h @@ -68,7 +68,8 @@ class TextLayoutCacheKey { public: TextLayoutCacheKey(); - TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t count, int dirFlags); + TextLayoutCacheKey(const SkPaint* paint, const UChar* text, size_t start, size_t count, + size_t contextCount, int dirFlags); TextLayoutCacheKey(const TextLayoutCacheKey& other); @@ -88,7 +89,9 @@ public: private: const UChar* text; // if text is NULL, use textCopy String16 textCopy; + size_t start; size_t count; + size_t contextCount; int dirFlags; SkTypeface* typeface; SkScalar textSize; @@ -119,32 +122,20 @@ public: void setElapsedTime(uint32_t time); uint32_t getElapsedTime(); - void computeValues(SkPaint* paint, const UChar* chars, size_t contextCount, int dirFlags); + void computeValues(SkPaint* paint, const UChar* chars, size_t start, size_t count, + size_t contextCount, int dirFlags); - void getAdvances(size_t start, size_t count, jfloat* outAdvances) const; - jfloat getTotalAdvance(size_t start, size_t count) const; - void getGlyphsIndexAndCount(size_t start, size_t count, size_t* outStartIndex, - size_t* outGlyphsCount) const; - const jchar* getGlyphs(size_t startIndex, size_t count); + inline const jfloat* getAdvances() const { return mAdvances.array(); } + inline size_t getAdvancesCount() const { return mAdvances.size(); } + inline jfloat getTotalAdvance() const { return mTotalAdvance; } + inline const jchar* getGlyphs() const { return mGlyphs.array(); } + inline size_t getGlyphsCount() const { return mGlyphs.size(); } /** * Get the size of the Cache entry */ size_t getSize(); - static void setupShaperItem(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, - SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, - bool isRTL); - - static void shapeWithHarfbuzz(HB_ShaperItem* shaperItem, HB_FontRec* font, FontData* fontData, - SkPaint* paint, const UChar* chars, size_t start, size_t count, size_t contextCount, - bool isRTL); - - static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, - size_t contextCount, int dirFlags, - Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, - Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters); - private: /** * Advances vector @@ -162,23 +153,31 @@ private: Vector<jchar> mGlyphs; /** - * Harfbuzz Log Clusters - */ - Vector<unsigned short> mLogClusters; - - /** * Time for computing the values (in milliseconds) */ uint32_t mElapsedTime; - static void deleteGlyphArrays(HB_ShaperItem* shaperItem); - static void createGlyphArrays(HB_ShaperItem* shaperItem, int size); - static void resetGlyphArrays(HB_ShaperItem* shaperItem); + static void computeValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, + size_t start, size_t count, size_t contextCount, int dirFlags, + Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, + Vector<jchar>* const outGlyphs); - static void computeRunValuesWithHarfbuzz(SkPaint* paint, const UChar* chars, size_t start, - size_t count, size_t contextCount, bool isRTL, + static void computeRunValuesWithHarfbuzz(HB_ShaperItem& shaperItem, SkPaint* paint, + size_t start, size_t count, bool isRTL, Vector<jfloat>* const outAdvances, jfloat* outTotalAdvance, - Vector<jchar>* const outGlyphs, Vector<unsigned short>* const outLogClusters); + Vector<jchar>* const outGlyphs); + + static void initShaperItem(HB_ShaperItem& shaperItem, HB_FontRec* font, FontData* fontData, + SkPaint* paint, const UChar* chars, size_t contextCount); + + static void freeShaperItem(HB_ShaperItem& shaperItem); + + static void shapeRun(HB_ShaperItem& shaperItem, size_t start, size_t count, bool isRTL); + + static void deleteGlyphArrays(HB_ShaperItem& shaperItem); + + static void createGlyphArrays(HB_ShaperItem& shaperItem, int size); + }; // TextLayoutCacheValue /** @@ -202,8 +201,8 @@ public: */ void operator()(TextLayoutCacheKey& text, sp<TextLayoutCacheValue>& desc); - sp<TextLayoutCacheValue> getValue(SkPaint* paint, const jchar* text, jint count, - jint dirFlags); + sp<TextLayoutCacheValue> getValue(SkPaint* paint, const jchar* text, jint start, jint count, + jint contextCount, jint dirFlags); /** * Clear the cache @@ -256,6 +255,7 @@ private: * Dump Cache statistics */ void dumpCacheStats(); + }; // TextLayoutCache } // namespace android diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index e542a47..e79de2d 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -477,19 +477,17 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count, #if RTL_USE_HARFBUZZ sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE - value = TextLayoutCache::getInstance().getValue(paint, text, count, flags); + value = TextLayoutCache::getInstance().getValue(paint, text, 0, count, count, flags); if (value == NULL) { LOGE("Cannot get TextLayoutCache value"); return ; } #else value = new TextLayoutCacheValue(); - value->computeValues(paint, text, count, flags); + value->computeValues(paint, text, 0, count, count, flags); #endif - size_t startIndex = 0; - size_t glyphsCount = 0; - value->getGlyphsIndexAndCount(0, count, &startIndex, &glyphsCount); - const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount); + const jchar* glyphs = value->getGlyphs(); + size_t glyphsCount = value->getGlyphsCount(); int bytesCount = glyphsCount * sizeof(jchar); renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); #else @@ -509,19 +507,17 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text, #if RTL_USE_HARFBUZZ sp<TextLayoutCacheValue> value; #if USE_TEXT_LAYOUT_CACHE - value = TextLayoutCache::getInstance().getValue(paint, text, contextCount, flags); + value = TextLayoutCache::getInstance().getValue(paint, text, start, count, contextCount, flags); if (value == NULL) { LOGE("Cannot get TextLayoutCache value"); return ; } #else value = new TextLayoutCacheValue(); - value->computeValues(paint, text, contextCount, flags); + value->computeValues(paint, text, start, count, contextCount, flags); #endif - size_t startIndex = 0; - size_t glyphsCount = 0; - value->getGlyphsIndexAndCount(start, count, &startIndex, &glyphsCount); - const jchar* glyphs = value->getGlyphs(startIndex, glyphsCount); + const jchar* glyphs = value->getGlyphs(); + size_t glyphsCount = value->getGlyphsCount(); int bytesCount = glyphsCount * sizeof(jchar); renderer->drawText((const char*) glyphs, bytesCount, glyphsCount, x, y, paint); #else diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java index e2950d5..d3d65a3 100644 --- a/graphics/java/android/renderscript/RenderScript.java +++ b/graphics/java/android/renderscript/RenderScript.java @@ -865,13 +865,7 @@ public class RenderScript { } static int getTargetSdkVersion(Context ctx) { - try { - PackageManager pm = ctx.getPackageManager(); - ApplicationInfo app = pm.getApplicationInfo(ctx.getPackageName(), 0); - return app.targetSdkVersion; - } catch (Exception e) { - throw new RSDriverException("Error calculating target SDK version for RS."); - } + return ctx.getApplicationInfo().targetSdkVersion; } /** diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp index dd05e61..a077cbc 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -185,7 +185,7 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len return; } - SkFixed penX = SkIntToFixed(x); + float penX = x; int penY = y; int glyphsLeft = 1; if (numGlyphs > 0) { @@ -193,7 +193,7 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len } SkFixed prevRsbDelta = 0; - penX += SK_Fixed1 / 2; + penX += 0.5f; text += start; @@ -206,25 +206,25 @@ void Font::render(SkPaint* paint, const char* text, uint32_t start, uint32_t len } CachedGlyphInfo* cachedGlyph = getCachedGlyph(paint, glyph); - penX += SkAutoKern_AdjustF(prevRsbDelta, cachedGlyph->mLsbDelta); + penX += SkFixedToFloat(SkAutoKern_AdjustF(prevRsbDelta, cachedGlyph->mLsbDelta)); prevRsbDelta = cachedGlyph->mRsbDelta; // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage if (cachedGlyph->mIsValid) { switch(mode) { case FRAMEBUFFER: - drawCachedGlyph(cachedGlyph, SkFixedFloor(penX), penY); + drawCachedGlyph(cachedGlyph, (int) floorf(penX), penY); break; case BITMAP: - drawCachedGlyph(cachedGlyph, SkFixedFloor(penX), penY, bitmap, bitmapW, bitmapH); + drawCachedGlyph(cachedGlyph, (int) floorf(penX), penY, bitmap, bitmapW, bitmapH); break; case MEASURE: - measureCachedGlyph(cachedGlyph, SkFixedFloor(penX), penY, bounds); + measureCachedGlyph(cachedGlyph, (int) floorf(penX), penY, bounds); break; } } - penX += cachedGlyph->mAdvanceX; + penX += SkFixedToFloat(cachedGlyph->mAdvanceX); // If we were given a specific number of glyphs, decrement if (numGlyphs > 0) { diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java index 4049c73..071044e 100644 --- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java +++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java @@ -526,11 +526,23 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler if (mUpdateMonitor.getPhoneState() == TelephonyManager.CALL_STATE_IDLE && transportInvisible) { bindToFaceLock(); + //Eliminate the black background so that the lockpattern will be visible + //If FaceUnlock is cancelled + mHandler.sendEmptyMessageDelayed(MSG_HIDE_FACELOCK_AREA_VIEW, 4000); } else { mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); } } + /** Unbind from facelock if something covers this window (such as an alarm) */ + @Override + public void onWindowFocusChanged (boolean hasWindowFocus) { + if(!hasWindowFocus) { + stopAndUnbindFromFaceLock(); + mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); + } + } + @Override public void show() { if (mMode == Mode.LockScreen) { @@ -607,7 +619,10 @@ public class LockPatternKeyguardView extends KeyguardViewBase implements Handler //We need to stop faceunlock when a phonecall comes in @Override public void onPhoneStateChanged(int phoneState) { - if(phoneState == TelephonyManager.CALL_STATE_RINGING) stopAndUnbindFromFaceLock(); + if(phoneState == TelephonyManager.CALL_STATE_RINGING) { + stopAndUnbindFromFaceLock(); + mHandler.sendEmptyMessage(MSG_HIDE_FACELOCK_AREA_VIEW); + } } @Override diff --git a/services/java/com/android/server/WallpaperManagerService.java b/services/java/com/android/server/WallpaperManagerService.java index 253e741..a0e28ed 100644 --- a/services/java/com/android/server/WallpaperManagerService.java +++ b/services/java/com/android/server/WallpaperManagerService.java @@ -834,7 +834,7 @@ class WallpaperManagerService extends IWallpaperManager.Stub { } if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success); if (success) { - bindWallpaperComponentLocked(null, false, false); + bindWallpaperComponentLocked(mNextWallpaperComponent, false, false); } } } |