Merge "Add implementation for drawBitmap()."
diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java
index 848e92e..0f895f0 100644
--- a/core/java/com/android/internal/widget/ActionBarContextView.java
+++ b/core/java/com/android/internal/widget/ActionBarContextView.java
@@ -28,6 +28,8 @@
 import android.view.MenuItem;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.View.MeasureSpec;
+import android.view.ViewGroup.LayoutParams;
 import android.widget.ImageButton;
 import android.widget.LinearLayout;
 import android.widget.TextView;
@@ -171,6 +173,13 @@
     }
 
     @Override
+    protected LayoutParams generateDefaultLayoutParams() {
+        // Used by custom views if they don't supply layout params. Everything else
+        // added to an ActionBarContextView should have them already.
+        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+    }
+
+    @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
         if (widthMode != MeasureSpec.EXACTLY) {
@@ -212,8 +221,17 @@
         }
 
         if (mCustomView != null) {
-            mCustomView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY),
-                    MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+            LayoutParams lp = mCustomView.getLayoutParams();
+            final int customWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
+                    MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
+            final int customWidth = lp.width >= 0 ?
+                    Math.min(lp.width, availableWidth) : availableWidth;
+            final int customHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
+                    MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
+            final int customHeight = lp.height >= 0 ?
+                    Math.min(lp.height, height) : height;
+            mCustomView.measure(MeasureSpec.makeMeasureSpec(customWidth, customWidthMode),
+                    MeasureSpec.makeMeasureSpec(customHeight, customHeightMode));
         }
 
         setMeasuredDimension(contentWidth, mContentHeight);
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index dcfdced..e919f1b 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -176,11 +176,11 @@
             };
         }
     }
-    
+
     public void setCallback(NavigationCallback callback) {
         mCallback = callback;
     }
-    
+
     public void setMenu(Menu menu) {
         MenuBuilder builder = (MenuBuilder) menu;
         mOptionsMenu = builder;
@@ -196,18 +196,18 @@
         addView(menuView);
         mMenuView = menuView;
     }
-    
+
     public void setCustomNavigationView(View view) {
         mCustomNavView = view;
         if (view != null) {
             setNavigationMode(ActionBar.NAVIGATION_MODE_CUSTOM);
         }
     }
-    
+
     public CharSequence getTitle() {
         return mTitle;
     }
-    
+
     public void setTitle(CharSequence title) {
         mTitle = title;
         if (mTitleView != null) {
@@ -217,18 +217,18 @@
             mLogoNavItem.setTitle(title);
         }
     }
-    
+
     public CharSequence getSubtitle() {
         return mSubtitle;
     }
-    
+
     public void setSubtitle(CharSequence subtitle) {
         mSubtitle = subtitle;
         if (mSubtitleView != null) {
             mSubtitleView.setText(subtitle);
         }
     }
-    
+
     public void setDisplayOptions(int options) {
         final int flagsChanged = options ^ mDisplayOptions;
         mDisplayOptions = options;
@@ -281,13 +281,9 @@
                 mSpinner = new Spinner(mContext, null,
                         com.android.internal.R.attr.dropDownSpinnerStyle);
                 mSpinner.setOnItemSelectedListener(mNavItemSelectedListener);
-                mSpinner.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                        LayoutParams.WRAP_CONTENT));
                 addView(mSpinner);
                 break;
             case ActionBar.NAVIGATION_MODE_CUSTOM:
-                mCustomNavView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
-                        LayoutParams.WRAP_CONTENT));
                 addView(mCustomNavView);
                 break;
             }
@@ -311,7 +307,14 @@
     public int getDisplayOptions() {
         return mDisplayOptions;
     }
-    
+
+    @Override
+    protected LayoutParams generateDefaultLayoutParams() {
+        // Used by custom nav views if they don't supply layout params. Everything else
+        // added to an ActionBarView should have them already.
+        return new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
+    }
+
     @Override
     protected void onFinishInflate() {
         super.onFinishInflate();
@@ -419,15 +422,24 @@
         case ActionBar.NAVIGATION_MODE_DROPDOWN_LIST:
             if (mSpinner != null) {
                 mSpinner.measure(
-                        MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY),
+                        MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST),
                         MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
             }
             break;
         case ActionBar.NAVIGATION_MODE_CUSTOM:
             if (mCustomNavView != null) {
+                LayoutParams lp = mCustomNavView.getLayoutParams();
+                final int customNavWidthMode = lp.width != LayoutParams.WRAP_CONTENT ?
+                        MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
+                final int customNavWidth = lp.width >= 0 ?
+                        Math.min(lp.width, availableWidth) : availableWidth;
+                final int customNavHeightMode = lp.height != LayoutParams.WRAP_CONTENT ?
+                        MeasureSpec.EXACTLY : MeasureSpec.AT_MOST;
+                final int customNavHeight = lp.height >= 0 ?
+                        Math.min(lp.height, height) : height;
                 mCustomNavView.measure(
-                        MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.EXACTLY),
-                        MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
+                        MeasureSpec.makeMeasureSpec(customNavWidth, customNavWidthMode),
+                        MeasureSpec.makeMeasureSpec(customNavHeight, customNavHeightMode));
             }
             break;
         }
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index 694ea16..2a47ca4 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -39,6 +39,7 @@
     mAllocLine = __LINE__;
     mInitialized = false;
     mHasKerning = false;
+    mFace = NULL;
 }
 
 bool Font::init(const char *name, uint32_t fontSize, uint32_t dpi)
@@ -63,8 +64,6 @@
     mFontSize = fontSize;
     mDpi = dpi;
 
-    //LOGE("Font initialized: %s", fullPath.string());
-
     error = FT_Set_Char_Size(mFace, fontSize * 64, 0, dpi, 0);
     if(error) {
         LOGE("Unable to set font size on %s", fullPath.string());
@@ -206,8 +205,6 @@
     newGlyph->mGlyphIndex = FT_Get_Char_Index(mFace, glyph);
     newGlyph->mIsValid = false;
 
-    //LOGE("Glyph = %c, face index: %u", (unsigned char)glyph, newGlyph->mGlyphIndex);
-
     updateGlyphCache(newGlyph);
 
     return newGlyph;
@@ -261,6 +258,7 @@
     mMaxNumberOfQuads = 1024;
     mCurrentQuadIndex = 0;
     mRSC = NULL;
+    mLibrary = NULL;
 }
 
 FontState::~FontState()
@@ -281,13 +279,12 @@
             return NULL;
         }
     }
+
     return mLibrary;
 }
 
 void FontState::init(Context *rsc)
 {
-    //getLib();
-
     mRSC = rsc;
 }
 
@@ -350,8 +347,6 @@
     uint32_t endX = startX + bitmap->width;
     uint32_t endY = startY + bitmap->rows;
 
-    //LOGE("Bitmap width, height = %i, %i", (int)bitmap->width, (int)bitmap->rows);
-
     uint32_t cacheWidth = getCacheTextureType()->getDimX();
 
     unsigned char *cacheBuffer = (unsigned char*)mTextTexture->getPtr();
@@ -508,13 +503,6 @@
 
     initVertexArrayBuffers();
 
-    /*mTextMeshRefs = new ObjectBaseRef<SimpleMesh>[mNumMeshes];
-
-    for(uint32_t i = 0; i < mNumMeshes; i ++){
-        SimpleMesh *textMesh = createTextMesh();
-        mTextMeshRefs[i].set(textMesh);
-    }*/
-
     mInitialized = true;
 }
 
@@ -626,6 +614,11 @@
         }
         currentFont = mDefault.get();
     }
+    if(!currentFont) {
+        LOGE("Unable to initialize any fonts");
+        return;
+    }
+
     currentFont->renderUTF(text, len, startIndex, numGlyphs, x, y);
 
     if(mCurrentQuadIndex != 0) {
@@ -681,8 +674,14 @@
 
     mDefault.clear();
 
+    Vector<Font*> fontsToDereference = mActiveFonts;
+    for(uint32_t i = 0; i < fontsToDereference.size(); i ++) {
+        fontsToDereference[i]->zeroUserRef();
+    }
+
     if(mLibrary) {
         FT_Done_FreeType( mLibrary );
+        mLibrary = NULL;
     }
 }
 
diff --git a/libs/rs/rsStream.cpp b/libs/rs/rsStream.cpp
index 39874a9..68241fa 100644
--- a/libs/rs/rsStream.cpp
+++ b/libs/rs/rsStream.cpp
@@ -55,7 +55,6 @@
 {
     uint32_t len = loadU32();
     s->setTo((const char *)&mData[mPos], len);
-    LOGE("loadString %s", s->string());
     mPos += len;
 }