michael@0: /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko; michael@0: michael@0: import android.content.res.Resources; michael@0: import android.graphics.Bitmap; michael@0: import android.graphics.BitmapShader; michael@0: import android.graphics.Canvas; michael@0: import android.graphics.ColorFilter; michael@0: import android.graphics.ComposeShader; michael@0: import android.graphics.LinearGradient; michael@0: import android.graphics.Paint; michael@0: import android.graphics.PixelFormat; michael@0: import android.graphics.PorterDuff; michael@0: import android.graphics.PorterDuffColorFilter; michael@0: import android.graphics.Rect; michael@0: import android.graphics.Shader; michael@0: import android.graphics.drawable.Drawable; michael@0: michael@0: /** michael@0: * A special drawable used with lightweight themes. This draws a color michael@0: * (with an optional color-filter) and a bitmap (with a linear gradient michael@0: * to specify the alpha) in order. michael@0: */ michael@0: public class LightweightThemeDrawable extends Drawable { michael@0: private Paint mPaint; michael@0: private Paint mColorPaint; michael@0: michael@0: private Bitmap mBitmap; michael@0: private Resources mResources; michael@0: michael@0: private int mStartColor; michael@0: private int mEndColor; michael@0: michael@0: public LightweightThemeDrawable(Resources resources, Bitmap bitmap) { michael@0: mBitmap = bitmap; michael@0: mResources = resources; michael@0: michael@0: mPaint = new Paint(); michael@0: mPaint.setAntiAlias(true); michael@0: mPaint.setStrokeWidth(0.0f); michael@0: } michael@0: michael@0: @Override michael@0: protected void onBoundsChange(Rect bounds) { michael@0: super.onBoundsChange(bounds); michael@0: initializeBitmapShader(); michael@0: } michael@0: michael@0: @Override michael@0: public void draw(Canvas canvas) { michael@0: // Draw the colors, if available. michael@0: if (mColorPaint != null) michael@0: canvas.drawPaint(mColorPaint); michael@0: michael@0: // Draw the bitmap. michael@0: canvas.drawPaint(mPaint); michael@0: } michael@0: michael@0: @Override michael@0: public int getOpacity() { michael@0: return PixelFormat.TRANSLUCENT; michael@0: } michael@0: michael@0: @Override michael@0: public void setAlpha(int alpha) { michael@0: // A StateListDrawable will reset the alpha value with 255. michael@0: // We cannot use to be the bitmap alpha. michael@0: mPaint.setAlpha(alpha); michael@0: } michael@0: michael@0: @Override michael@0: public void setColorFilter(ColorFilter filter) { michael@0: mPaint.setColorFilter(filter); michael@0: } michael@0: michael@0: /** michael@0: * Creates a paint that paint a particular color. michael@0: * michael@0: * @param color The color to be painted. michael@0: */ michael@0: public void setColor(int color) { michael@0: mColorPaint = new Paint(mPaint); michael@0: mColorPaint.setColor(color); michael@0: } michael@0: michael@0: /** michael@0: * Creates a paint that paint a particular color, and a filter for the color. michael@0: * michael@0: * @param color The color to be painted. michael@0: * @param filter The filter color to be applied using SRC_OVER mode. michael@0: */ michael@0: public void setColorWithFilter(int color, int filter) { michael@0: mColorPaint = new Paint(mPaint); michael@0: mColorPaint.setColor(color); michael@0: mColorPaint.setColorFilter(new PorterDuffColorFilter(filter, PorterDuff.Mode.SRC_OVER)); michael@0: } michael@0: michael@0: /** michael@0: * Set the alpha for the linear gradient used with the bitmap's shader. michael@0: * michael@0: * @param startAlpha The starting alpha (0..255) value to be applied to the LinearGradient. michael@0: * @param startAlpha The ending alpha (0..255) value to be applied to the LinearGradient. michael@0: */ michael@0: public void setAlpha(int startAlpha, int endAlpha) { michael@0: mStartColor = startAlpha << 24; michael@0: mEndColor = endAlpha << 24; michael@0: initializeBitmapShader(); michael@0: } michael@0: michael@0: private void initializeBitmapShader() { michael@0: // A bitmap-shader to draw the bitmap. michael@0: // Clamp mode will repeat the last row of pixels. michael@0: // Hence its better to have an endAlpha of 0 for the linear-gradient. michael@0: BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); michael@0: michael@0: // A linear-gradient to specify the opacity of the bitmap. michael@0: LinearGradient gradient = new LinearGradient(0, 0, 0, mBitmap.getHeight(), mStartColor, mEndColor, Shader.TileMode.CLAMP); michael@0: michael@0: // Make a combined shader -- a performance win. michael@0: // The linear-gradient is the 'SRC' and the bitmap-shader is the 'DST'. michael@0: // Drawing the DST in the SRC will provide the opacity. michael@0: mPaint.setShader(new ComposeShader(bitmapShader, gradient, PorterDuff.Mode.DST_IN)); michael@0: } michael@0: }