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 file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.toolbar; michael@0: michael@0: import android.graphics.Bitmap; michael@0: import android.graphics.Canvas; michael@0: import android.graphics.Paint; michael@0: import android.graphics.Path; michael@0: import android.graphics.PorterDuff.Mode; michael@0: import android.graphics.PorterDuffXfermode; michael@0: import android.graphics.Shader; michael@0: import android.os.Build; michael@0: michael@0: class CanvasDelegate { michael@0: Paint mPaint; michael@0: PorterDuffXfermode mMode; michael@0: DrawManager mDrawManager; michael@0: michael@0: // DrawManager would do a default draw of the background. michael@0: static interface DrawManager { michael@0: public void defaultDraw(Canvas cavas); michael@0: } michael@0: michael@0: CanvasDelegate(DrawManager drawManager, Mode mode) { michael@0: mDrawManager = drawManager; michael@0: michael@0: // DST_IN masks, DST_OUT clips. michael@0: mMode = new PorterDuffXfermode(mode); michael@0: michael@0: mPaint = new Paint(); michael@0: mPaint.setAntiAlias(true); michael@0: mPaint.setColor(0xFFFF0000); michael@0: mPaint.setStrokeWidth(0.0f); michael@0: } michael@0: michael@0: void draw(Canvas canvas, Path path, int width, int height) { michael@0: // Save the canvas. All PorterDuff operations should be done in a offscreen bitmap. michael@0: int count = canvas.saveLayer(0, 0, width, height, null, michael@0: Canvas.MATRIX_SAVE_FLAG | michael@0: Canvas.CLIP_SAVE_FLAG | michael@0: Canvas.HAS_ALPHA_LAYER_SAVE_FLAG | michael@0: Canvas.FULL_COLOR_LAYER_SAVE_FLAG | michael@0: Canvas.CLIP_TO_LAYER_SAVE_FLAG); michael@0: michael@0: // Do a default draw. michael@0: mDrawManager.defaultDraw(canvas); michael@0: michael@0: if (path != null && !path.isEmpty()) { michael@0: // ICS added double-buffering, which made it easier for drawing the Path directly over the DST. michael@0: // In pre-ICS, drawPath() doesn't seem to use ARGB_8888 mode for performance, hence transparency is not preserved. michael@0: if (Build.VERSION.SDK_INT >= 14) { michael@0: mPaint.setXfermode(mMode); michael@0: canvas.drawPath(path, mPaint); michael@0: } else { michael@0: // Allocate a bitmap and draw the masking/clipping path. michael@0: Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); michael@0: (new Canvas(bitmap)).drawPath(path, mPaint); michael@0: michael@0: mPaint.setXfermode(mMode); michael@0: canvas.drawBitmap(bitmap, 0, 0, mPaint); michael@0: bitmap.recycle(); michael@0: michael@0: mPaint.setXfermode(null); michael@0: } michael@0: } michael@0: michael@0: // Restore the canvas. michael@0: canvas.restoreToCount(count); michael@0: } michael@0: michael@0: void setShader(Shader shader) { michael@0: mPaint.setShader(shader); michael@0: } michael@0: }