Canvas_Delegate.java revision f587825e94af5200aadc77a86e9f5084ac1a4e94
1ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/*
2ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Copyright (C) 2010 The Android Open Source Project
3ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
4ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License");
5ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * you may not use this file except in compliance with the License.
6ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * You may obtain a copy of the License at
7ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
8ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *      http://www.apache.org/licenses/LICENSE-2.0
9ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
10ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Unless required by applicable law or agreed to in writing, software
11ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS,
12ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * See the License for the specific language governing permissions and
14ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * limitations under the License.
15ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */
16ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
17ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipackage android.graphics;
18ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
19ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.ide.common.rendering.api.LayoutLog;
20ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.Bridge;
21ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.impl.DelegateManager;
22ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.layoutlib.bridge.impl.GcSnapshot;
23ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport com.android.tools.layoutlib.annotations.LayoutlibDelegate;
24ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
25ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.graphics.Bitmap.Config;
26ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport android.text.TextUtils;
27ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
28ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.Color;
29ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.Composite;
30ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.Graphics2D;
31ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.Rectangle;
32ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.RenderingHints;
33ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.Shape;
34ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.geom.AffineTransform;
35ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.geom.Arc2D;
36ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskiimport java.awt.image.BufferedImage;
37ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
38ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
39ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski/**
40ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Delegate implementing the native methods of android.graphics.Canvas
41ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
42ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * Through the layoutlib_create tool, the original native methods of Canvas have been replaced
43ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * by calls to methods of the same name in this delegate class.
44ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
45ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * This class behaves like the original native implementation, but in Java, keeping previously
46ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * native data into its own objects and mapping them to int that are sent back and forth between
47ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * it and the original Canvas class.
48ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
49ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski * @see DelegateManager
50ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski *
51ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski */
52ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinskipublic final class Canvas_Delegate {
53ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
54ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- delegate manager ----
55ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private static final DelegateManager<Canvas_Delegate> sManager =
56ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            new DelegateManager<Canvas_Delegate>(Canvas_Delegate.class);
57ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
58ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- delegate helper data ----
59ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
60ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private final static boolean[] sBoolOut = new boolean[1];
61ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
62ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- delegate data ----
63ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private Bitmap_Delegate mBitmap;
64ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private GcSnapshot mSnapshot;
65ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
66ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private DrawFilter_Delegate mDrawFilter = null;
67ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
68ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- Public Helper methods ----
69ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
70ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
71ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the native delegate associated to a given {@link Canvas} object.
72ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
73ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public static Canvas_Delegate getDelegate(Canvas canvas) {
747aca43390f64ee5bd82c17552c03accb0745b5b2Florin Malita        return sManager.getDelegate(canvas.getNativeCanvasWrapper());
75ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
76ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
77ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
78ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the native delegate associated to a given an int referencing a {@link Canvas} object.
79ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
80ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    public static Canvas_Delegate getDelegate(long native_canvas) {
81ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return sManager.getDelegate(native_canvas);
82ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
83ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
84ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
85ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the current {@link Graphics2D} used to draw.
86ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
87ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public GcSnapshot getSnapshot() {
88ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return mSnapshot;
89ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
90ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
91ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
92ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns the {@link DrawFilter} delegate or null if none have been set.
93ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
94ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @return the delegate or null.
95ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
96ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    public DrawFilter_Delegate getDrawFilter() {
97ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return mDrawFilter;
98ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
99ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
100ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- native methods ----
101ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
102ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
103f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static boolean native_isOpaque(long nativeCanvas) {
104ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
105f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
106ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
107ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return false;
108ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
109ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
110ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.mBitmap.getConfig() == Config.RGB_565;
111ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
112ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
113ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
114f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static int native_getWidth(long nativeCanvas) {
115ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
116f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
117ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
118ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
119ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
120ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
121ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.mBitmap.getImage().getWidth();
122ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
123ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
124ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
125f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static int native_getHeight(long nativeCanvas) {
126ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
127f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
128ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
129ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
130ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
131ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
132ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.mBitmap.getImage().getHeight();
133ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
134ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
135ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
136f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta   /*package*/ static void native_translate(long nativeCanvas, float dx, float dy) {
137ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
138f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
139ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
140ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
141ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
142ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
143ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.getSnapshot().translate(dx, dy);
144ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
145ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
146ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
147f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static void native_rotate(long nativeCanvas, float degrees) {
148ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
149f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
150ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
151ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
152ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
153ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
154ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.getSnapshot().rotate(Math.toRadians(degrees));
155ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
156ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
157ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
158f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta   /*package*/ static void native_scale(long nativeCanvas, float sx, float sy) {
159ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
160f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
161ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
162ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
163ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
164ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
165ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.getSnapshot().scale(sx, sy);
166ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
167ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
168ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
169f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta   /*package*/ static void native_skew(long nativeCanvas, float kx, float ky) {
170ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
171f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
172ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
173ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
174ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
175ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
176ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the current top graphics2D object.
177ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        GcSnapshot g = canvasDelegate.getSnapshot();
178ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
179ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get its current matrix
180ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        AffineTransform currentTx = g.getTransform();
181ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the AffineTransform for the given skew.
182ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        float[] mtx = Matrix_Delegate.getSkew(kx, ky);
183ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        AffineTransform matrixTx = Matrix_Delegate.getAffineTransform(mtx);
184ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
185ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // combine them so that the given matrix is applied after.
186ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        currentTx.preConcatenate(matrixTx);
187ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
188ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // give it to the graphics2D as a new matrix replacing all previous transform
189ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        g.setTransform(currentTx);
190ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
191ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
192ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
193f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static int native_save(long nativeCanvas, int saveFlags) {
194ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
195f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
196ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
197ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
198ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
199ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
200ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.save(saveFlags);
201ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
202ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
203ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
204f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static void native_restore(long nativeCanvas) {
205ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
206f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
207ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
208ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
209ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
210ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
211ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.restore();
212ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
213ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
214ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
215f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static int native_getSaveCount(long nativeCanvas) {
216ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
217f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
218ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
219ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
220ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
221ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
222ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.getSnapshot().size();
223ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
224ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
225ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
226f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static void native_restoreToCount(long nativeCanvas, int saveCount) {
227ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
228f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
229ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
230ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
231ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
232ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
233ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.restoreTo(saveCount);
234ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
235ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
236ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
237f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static void native_drawPoints(long nativeCanvas, float[] pts, int offset, int count,
238f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            long nativePaint) {
239ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME
240ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
241ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Canvas.drawPoint is not supported.", null, null /*data*/);
242ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
243ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
244ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
245f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static void native_drawPoint(long nativeCanvas, float x, float y,
246f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            long nativePaint) {
247ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME
248ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
249ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Canvas.drawPoint is not supported.", null, null /*data*/);
250ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
251ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
252ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
253f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static void native_drawLines(long nativeCanvas,
254ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            final float[] pts, final int offset, final int count,
255f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            long nativePaint) {
256f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta
257f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        draw(nativeCanvas, nativePaint, false /*compositeOnly*/,
258ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                false /*forceSrcMode*/, new GcSnapshot.Drawable() {
259ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    @Override
260ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
261f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                        for (int i = 0; i < count; i += 4) {
262f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                            graphics.drawLine((int) pts[i + offset], (int) pts[i + offset + 1],
263f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                                    (int) pts[i + offset + 2], (int) pts[i + offset + 3]);
264ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
265ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
266ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                });
267ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
268ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
269ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
270ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /*package*/ static void freeCaches() {
271ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // nothing to be done here.
272ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
273ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
274ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
275ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /*package*/ static void freeTextLayoutCaches() {
276ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // nothing to be done here yet.
277ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
278ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
279ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
280ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static long initRaster(long nativeBitmapOrZero) {
281ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (nativeBitmapOrZero > 0) {
282ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // get the Bitmap from the int
283ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
284ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
285ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // create a new Canvas_Delegate with the given bitmap and return its new native int.
286ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate);
287ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
288ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return sManager.addNewDelegate(newDelegate);
289ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
290ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
291ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create a new Canvas_Delegate and return its new native int.
292ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate newDelegate = new Canvas_Delegate();
293ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
294ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return sManager.addNewDelegate(newDelegate);
295ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
296ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
297ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
298f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static long initCanvas(long nativeCanvas) {
299ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
300f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate nativeCanvasDelegate = sManager.getDelegate(nativeCanvas);
301f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        if (nativeCanvasDelegate == null) {
302f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            return 0;
303ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
304ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
305f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate newDelegate = new Canvas_Delegate();
306f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta
307ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // TODO: actually copy the canvas state.
308f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        return sManager.addNewDelegate(newDelegate);
309ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
310ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
311ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
312f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/
313f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    static void native_setBitmap(long canvas, long bitmap, boolean copyState) {
314f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
315f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
316f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        if (canvasDelegate == null || bitmapDelegate==null) {
317f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            return;
318ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
319f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        canvasDelegate.mBitmap = bitmapDelegate;
320f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        canvasDelegate.mSnapshot = GcSnapshot.createDefaultSnapshot(bitmapDelegate);
321ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
322ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
323ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
324f9a823540ce0e23e3bbdd7c1fb8bf2639e20a8bcDeepanshu Gupta    /*package*/ static int native_saveLayer(long nativeCanvas, float l,
325ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                               float t, float r, float b,
326ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                               long paint, int layerFlags) {
327ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
328ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
329ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
330ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
331ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
332ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
333ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
334ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (paintDelegate == null) {
335ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
336ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
337ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
338ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.saveLayer(new RectF(l, t, r, b),
339ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                paintDelegate, layerFlags);
340ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
341ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
342ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
343f9a823540ce0e23e3bbdd7c1fb8bf2639e20a8bcDeepanshu Gupta    /*package*/ static int native_saveLayerAlpha(long nativeCanvas, float l,
344ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                    float t, float r, float b,
345ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                    int alpha, int layerFlags) {
346ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
347ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
348ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
349ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return 0;
350ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
351ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
352ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.saveLayerAlpha(new RectF(l, t, r, b), alpha, layerFlags);
353ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
354ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
355ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
356ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
357ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_concat(long nCanvas, long nMatrix) {
358ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
359ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
360ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
361ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
362ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
363ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
364ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
365ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (matrixDelegate == null) {
366ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
367ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
368ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
369ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the current top graphics2D object.
370ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        GcSnapshot snapshot = canvasDelegate.getSnapshot();
371ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
372ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get its current matrix
373ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        AffineTransform currentTx = snapshot.getTransform();
374ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the AffineTransform of the given matrix
375ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
376ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
377ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // combine them so that the given matrix is applied after.
378ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        currentTx.concatenate(matrixTx);
379ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
380ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // give it to the graphics2D as a new matrix replacing all previous transform
381ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        snapshot.setTransform(currentTx);
382ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
383ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
384ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
385ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_setMatrix(long nCanvas, long nMatrix) {
386ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
387ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
388ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
389ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
390ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
391ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
392ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
393ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (matrixDelegate == null) {
394ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
395ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
396ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
397ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the current top graphics2D object.
398ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        GcSnapshot snapshot = canvasDelegate.getSnapshot();
399ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
400ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the AffineTransform of the given matrix
401ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        AffineTransform matrixTx = matrixDelegate.getAffineTransform();
402ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
403ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // give it to the graphics2D as a new matrix replacing all previous transform
404ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        snapshot.setTransform(matrixTx);
405ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
406ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (matrixDelegate.hasPerspective()) {
407ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            assert false;
408ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            Bridge.getLog().fidelityWarning(LayoutLog.TAG_MATRIX_AFFINE,
409ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
410ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    "supports affine transformations.", null, null /*data*/);
411ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
412ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
413ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
414ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
415ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean native_clipRect(long nCanvas,
416ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                  float left, float top,
417ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                  float right, float bottom,
418ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                  int regionOp) {
419ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
420ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
421ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
422ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
423ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return false;
424ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
425ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
426ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.clipRect(left, top, right, bottom, regionOp);
427ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
428ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
429ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
430ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean native_clipPath(long nativeCanvas,
431ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                  long nativePath,
432ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                  int regionOp) {
433ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
434ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
435ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
436ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
437ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
438ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Path_Delegate pathDelegate = Path_Delegate.getDelegate(nativePath);
439ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (pathDelegate == null) {
440ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
441ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
442ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
443ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.mSnapshot.clip(pathDelegate.getJavaShape(), regionOp);
444ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
445ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
446ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
447ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean native_clipRegion(long nativeCanvas,
448ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                    long nativeRegion,
449ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                    int regionOp) {
450ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
451ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
452ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
453ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
454ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
455ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Region_Delegate region = Region_Delegate.getDelegate(nativeRegion);
456ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (region == null) {
457ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
458ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
459ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
460ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return canvasDelegate.mSnapshot.clip(region.getJavaArea(), regionOp);
461ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
462ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
463ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
464ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeSetDrawFilter(long nativeCanvas, long nativeFilter) {
465ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
466ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
467ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
468ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
469ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
470ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.mDrawFilter = DrawFilter_Delegate.getDelegate(nativeFilter);
471ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
472ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate.mDrawFilter != null &&
473ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                canvasDelegate.mDrawFilter.isSupported() == false) {
474ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            Bridge.getLog().fidelityWarning(LayoutLog.TAG_DRAWFILTER,
475ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    canvasDelegate.mDrawFilter.getSupportMessage(), null, null /*data*/);
476ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
477ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
478ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
479ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
480ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean native_getClipBounds(long nativeCanvas,
481ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                       Rect bounds) {
482ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
483ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
484ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
485ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return false;
486ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
487ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
488ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Rectangle rect = canvasDelegate.getSnapshot().getClip().getBounds();
489ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (rect != null && rect.isEmpty() == false) {
490ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            bounds.left = rect.x;
491ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            bounds.top = rect.y;
492ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            bounds.right = rect.x + rect.width;
493ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            bounds.bottom = rect.y + rect.height;
494ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return true;
495ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
496ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
497ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return false;
498ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
499ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
500ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
501ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_getCTM(long canvas, long matrix) {
502ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
503ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(canvas);
504ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
505ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
506ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
507ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
508ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(matrix);
509ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (matrixDelegate == null) {
510ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
511ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
512ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
513ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        AffineTransform transform = canvasDelegate.getSnapshot().getTransform();
514ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        matrixDelegate.set(Matrix_Delegate.makeValues(transform));
515ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
516ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
517ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
518ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean native_quickReject(long nativeCanvas,
519ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                     long path) {
520ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME properly implement quickReject
521ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return false;
522ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
523ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
524ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
525ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static boolean native_quickReject(long nativeCanvas,
526ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                     float left, float top,
527ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                     float right, float bottom) {
528ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME properly implement quickReject
529ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return false;
530ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
531ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
532ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
533ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawRGB(long nativeCanvas, int r, int g, int b) {
534ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        native_drawColor(nativeCanvas, 0xFF000000 | r << 16 | (g&0xFF) << 8 | (b&0xFF),
535ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                PorterDuff.Mode.SRC_OVER.nativeInt);
536ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
537ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
538ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
539ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
540ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawARGB(long nativeCanvas, int a, int r, int g, int b) {
541ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        native_drawColor(nativeCanvas, a << 24 | (r&0xFF) << 16 | (g&0xFF) << 8 | (b&0xFF),
542ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                PorterDuff.Mode.SRC_OVER.nativeInt);
543ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
544ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
545ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
546ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawColor(long nativeCanvas, int color) {
547ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        native_drawColor(nativeCanvas, color, PorterDuff.Mode.SRC_OVER.nativeInt);
548ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
549ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
550ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
551ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawColor(long nativeCanvas, final int color, final int mode) {
552ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
553ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
554ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
555ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
556ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
557ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
558ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final int w = canvasDelegate.mBitmap.getImage().getWidth();
559ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final int h = canvasDelegate.mBitmap.getImage().getHeight();
560ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, new GcSnapshot.Drawable() {
561ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
562ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            @Override
563ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            public void draw(Graphics2D graphics, Paint_Delegate paint) {
564ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                // reset its transform just in case
565ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                graphics.setTransform(new AffineTransform());
566ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
567ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                // set the color
568ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                graphics.setColor(new Color(color, true /*alpha*/));
569ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
5701128e789ab65efbc69405b2fd3455f4cd2fc45ecDeepanshu Gupta                Composite composite = PorterDuffXfermode_Delegate.getComposite(mode, 0xFF);
571ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                if (composite != null) {
572ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    graphics.setComposite(composite);
573ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                }
574ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
575ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                graphics.fillRect(0, 0, w, h);
576ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            }
577ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
578ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
579ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
580ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
581ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawPaint(long nativeCanvas, long paint) {
582ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME
583ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
584ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Canvas.drawPaint is not supported.", null, null /*data*/);
585ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
586ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
587ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
588ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawLine(long nativeCanvas,
589ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            final float startX, final float startY, final float stopX, final float stopY,
590ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            long paint) {
591ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
592ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
593ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                new GcSnapshot.Drawable() {
594ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    @Override
595ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
596ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        graphics.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
597ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
598ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
599ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
600ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
601ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
602ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawRect(long nativeCanvas,
603ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            final float left, final float top, final float right, final float bottom, long paint) {
604ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
605ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
606ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                new GcSnapshot.Drawable() {
607ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    @Override
608ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
609ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        int style = paintDelegate.getStyle();
610ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
611ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        // draw
612ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (style == Paint.Style.FILL.nativeInt ||
613ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
614ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.fillRect((int)left, (int)top,
615ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    (int)(right-left), (int)(bottom-top));
616ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
617ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
618ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (style == Paint.Style.STROKE.nativeInt ||
619ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
620ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.drawRect((int)left, (int)top,
621ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    (int)(right-left), (int)(bottom-top));
622ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
623ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
624ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
625ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
626ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
627ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
628f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta    /*package*/ static void native_drawOval(long nativeCanvas, final float left,
629f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            final float top, final float right, final float bottom, long paint) {
630f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        if (right > left && bottom > top) {
631ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
632ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    new GcSnapshot.Drawable() {
633ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        @Override
634ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
635ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            int style = paintDelegate.getStyle();
636ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
637ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            // draw
638ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            if (style == Paint.Style.FILL.nativeInt ||
639ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
640f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                                graphics.fillOval((int)left, (int)top,
641f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                                        (int)(right - left), (int)(bottom - top));
642ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            }
643ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
644ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            if (style == Paint.Style.STROKE.nativeInt ||
645ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
646f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                                graphics.drawOval((int)left, (int)top,
647f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                                        (int)(right - left), (int)(bottom - top));
648ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            }
649ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
650ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            });
651ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
652ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
653ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
654ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
655ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawCircle(long nativeCanvas,
656ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            float cx, float cy, float radius, long paint) {
657ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        native_drawOval(nativeCanvas,
658f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                cx - radius, cy - radius, cx + radius, cy + radius,
659ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                paint);
660ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
661ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
662ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
663ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawArc(long nativeCanvas,
664f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            final float left, final float top, final float right, final float bottom,
665f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta            final float startAngle, final float sweep,
666ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            final boolean useCenter, long paint) {
667f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta        if (right > left && bottom > top) {
668ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
669ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    new GcSnapshot.Drawable() {
670ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        @Override
671ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
672ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            int style = paintDelegate.getStyle();
673ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
674ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            Arc2D.Float arc = new Arc2D.Float(
675f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                                    left, top, right - left, bottom - top,
676ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    -startAngle, -sweep,
677ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    useCenter ? Arc2D.PIE : Arc2D.OPEN);
678ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
679ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            // draw
680ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            if (style == Paint.Style.FILL.nativeInt ||
681ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
682ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                graphics.fill(arc);
683ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            }
684ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
685ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            if (style == Paint.Style.STROKE.nativeInt ||
686ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    style == Paint.Style.FILL_AND_STROKE.nativeInt) {
687ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                graphics.draw(arc);
688ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            }
689ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
690ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            });
691ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
692ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
693ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
694ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
695ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawRoundRect(long nativeCanvas,
6960bec685a9bde5e23ee2e9ce598e948e2aec8bcf0Deepanshu Gupta            final float left, final float top, final float right, final float bottom,
6970bec685a9bde5e23ee2e9ce598e948e2aec8bcf0Deepanshu Gupta            final float rx, final float ry, long paint) {
698ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
699ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
700ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                new GcSnapshot.Drawable() {
701ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    @Override
702ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
703ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        int style = paintDelegate.getStyle();
704ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
705ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        // draw
706ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (style == Paint.Style.FILL.nativeInt ||
707ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
708ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.fillRoundRect(
7090bec685a9bde5e23ee2e9ce598e948e2aec8bcf0Deepanshu Gupta                                    (int)left, (int)top,
7100bec685a9bde5e23ee2e9ce598e948e2aec8bcf0Deepanshu Gupta                                    (int)(right - left), (int)(bottom - top),
711ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    (int)rx, (int)ry);
712ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
713ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
714ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (style == Paint.Style.STROKE.nativeInt ||
715ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
716ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.drawRoundRect(
7170bec685a9bde5e23ee2e9ce598e948e2aec8bcf0Deepanshu Gupta                                    (int)left, (int)top,
7180bec685a9bde5e23ee2e9ce598e948e2aec8bcf0Deepanshu Gupta                                    (int)(right - left), (int)(bottom - top),
719ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    (int)rx, (int)ry);
720ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
721ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
722ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
723ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
724ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
725ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
726cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta    /*package*/ static void native_drawPath(long nativeCanvas, long path, long paint) {
727ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final Path_Delegate pathDelegate = Path_Delegate.getDelegate(path);
728ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (pathDelegate == null) {
729ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
730ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
731ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
732ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
733ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                new GcSnapshot.Drawable() {
734ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    @Override
735ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
736ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        Shape shape = pathDelegate.getJavaShape();
737ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        int style = paintDelegate.getStyle();
738ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
739ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (style == Paint.Style.FILL.nativeInt ||
740ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
741ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.fill(shape);
742ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
743ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
744ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (style == Paint.Style.STROKE.nativeInt ||
745ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                style == Paint.Style.FILL_AND_STROKE.nativeInt) {
746ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.draw(shape);
747ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
748ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
749ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
750ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
751ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
752ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
753ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap,
754ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 float left, float top,
755ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                 long nativePaintOrZero,
756ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 int canvasDensity,
757ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 int screenDensity,
758ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 int bitmapDensity) {
759ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
760ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
761ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (bitmapDelegate == null) {
762ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
763ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
764ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
765ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = bitmapDelegate.getImage();
766ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        float right = left + image.getWidth();
767ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        float bottom = top + image.getHeight();
768ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
769ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
770ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                0, 0, image.getWidth(), image.getHeight(),
771ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                (int)left, (int)top, (int)right, (int)bottom);
772ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
773ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
774ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
775ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawBitmap(Canvas thisCanvas, long nativeCanvas, long bitmap,
776ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 Rect src, RectF dst,
777ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                 long nativePaintOrZero,
778ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 int screenDensity,
779ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 int bitmapDensity) {
780ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
781ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
782ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (bitmapDelegate == null) {
783ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
784ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
785ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
786ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = bitmapDelegate.getImage();
787ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
788ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (src == null) {
789ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
790ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    0, 0, image.getWidth(), image.getHeight(),
791ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
792ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        } else {
793ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
794ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    src.left, src.top, src.width(), src.height(),
795ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
796ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
797ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
798ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
799ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
800ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawBitmap(long nativeCanvas, long bitmap,
801ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 Rect src, Rect dst,
802ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                 long nativePaintOrZero,
803ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 int screenDensity,
804ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 int bitmapDensity) {
805ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
806ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
807ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (bitmapDelegate == null) {
808ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
809ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
810ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
811ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = bitmapDelegate.getImage();
812ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
813ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (src == null) {
814ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
815ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    0, 0, image.getWidth(), image.getHeight(),
816ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    dst.left, dst.top, dst.right, dst.bottom);
817ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        } else {
818ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            drawBitmap(nativeCanvas, bitmapDelegate, nativePaintOrZero,
819ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    src.left, src.top, src.width(), src.height(),
820ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    dst.left, dst.top, dst.right, dst.bottom);
821ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
822ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
823ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
824ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
825ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawBitmap(long nativeCanvas, int[] colors,
826ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                int offset, int stride, final float x,
827ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 final float y, int width, int height,
828ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                 boolean hasAlpha,
829ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                 long nativePaintOrZero) {
830ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
831ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // create a temp BufferedImage containing the content.
832ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final BufferedImage image = new BufferedImage(width, height,
833ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                hasAlpha ? BufferedImage.TYPE_INT_ARGB : BufferedImage.TYPE_INT_RGB);
834ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        image.setRGB(0, 0, width, height, colors, offset, stride);
835ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
836ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, false /*forceSrcMode*/,
837ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                new GcSnapshot.Drawable() {
838ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    @Override
839ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
840ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (paint != null && paint.isFilterBitmap()) {
841ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
842ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
843ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
844ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
845ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        graphics.drawImage(image, (int) x, (int) y, null);
846ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
847ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
848ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
849ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
850ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
851ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeDrawBitmapMatrix(long nCanvas, long nBitmap,
852ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                      long nMatrix, long nPaint) {
853ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
854ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
855ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
856ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
857ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
858ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
859ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int, which can be null
860ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
861ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
862ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
863ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nBitmap);
864ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (bitmapDelegate == null) {
865ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
866ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
867ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
868ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final BufferedImage image = getImageToDraw(bitmapDelegate, paintDelegate, sBoolOut);
869ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
870ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
871ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (matrixDelegate == null) {
872ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
873ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
874ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
875ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final AffineTransform mtx = matrixDelegate.getAffineTransform();
876ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
877ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.getSnapshot().draw(new GcSnapshot.Drawable() {
878ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                @Override
879ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                public void draw(Graphics2D graphics, Paint_Delegate paint) {
880ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    if (paint != null && paint.isFilterBitmap()) {
881ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
882ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
883ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
884ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
885ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    //FIXME add support for canvas, screen and bitmap densities.
886ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    graphics.drawImage(image, mtx, null);
887ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                }
888ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }, paintDelegate, true /*compositeOnly*/, false /*forceSrcMode*/);
889ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
890ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
891ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
892ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeDrawBitmapMesh(long nCanvas, long nBitmap,
893ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors,
894ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            int colorOffset, long nPaint) {
895ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME
896ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
897ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Canvas.drawBitmapMesh is not supported.", null, null /*data*/);
898ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
899ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
900ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
901ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void nativeDrawVertices(long nCanvas, int mode, int n,
902ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            float[] verts, int vertOffset,
903ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            float[] texs, int texOffset,
904ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int[] colors, int colorOffset,
905ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            short[] indices, int indexOffset,
906ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            int indexCount, long nPaint) {
907ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME
908ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
909ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Canvas.drawVertices is not supported.", null, null /*data*/);
910ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
911ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
912ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
913ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawText(long nativeCanvas,
914ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            final char[] text, final int index, final int count,
915cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta            final float startX, final float startY, final int flags, long paint,
916b1ce7c1c2d22e1455f1a2f741d38424988aa6be6Deepanshu Gupta            final long typeface) {
91797ba95f72ef9e5fa3e37ec0ad5c6a2da698e0a1fDeepanshu Gupta
918ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, paint, false /*compositeOnly*/, false /*forceSrcMode*/,
919ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                new GcSnapshot.Drawable() {
920ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            @Override
921ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            public void draw(Graphics2D graphics, Paint_Delegate paintDelegate) {
922ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                // WARNING: the logic in this method is similar to Paint_Delegate.measureText.
923ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                // Any change to this method should be reflected in Paint.measureText
924b1ce7c1c2d22e1455f1a2f741d38424988aa6be6Deepanshu Gupta
925b1ce7c1c2d22e1455f1a2f741d38424988aa6be6Deepanshu Gupta                // assert that the typeface passed is actually the one stored in paint.
926b1ce7c1c2d22e1455f1a2f741d38424988aa6be6Deepanshu Gupta                assert (typeface == paintDelegate.mNativeTypeface);
927b1ce7c1c2d22e1455f1a2f741d38424988aa6be6Deepanshu Gupta
928b1ce7c1c2d22e1455f1a2f741d38424988aa6be6Deepanshu Gupta
929ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                // Paint.TextAlign indicates how the text is positioned relative to X.
930ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                // LEFT is the default and there's nothing to do.
931ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                float x = startX;
93297ba95f72ef9e5fa3e37ec0ad5c6a2da698e0a1fDeepanshu Gupta                int limit = index + count;
93397ba95f72ef9e5fa3e37ec0ad5c6a2da698e0a1fDeepanshu Gupta                boolean isRtl = flags == Canvas.DIRECTION_RTL;
934ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                if (paintDelegate.getTextAlign() != Paint.Align.LEFT.nativeInt) {
935eb998d3d38dfb2cab9759ce6b85d0af34f16f77cDeepanshu Gupta                    RectF bounds = paintDelegate.measureText(text, index, count, isRtl);
936eb998d3d38dfb2cab9759ce6b85d0af34f16f77cDeepanshu Gupta                    float m = bounds.right - bounds.left;
937ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    if (paintDelegate.getTextAlign() == Paint.Align.CENTER.nativeInt) {
938ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        x -= m / 2;
939ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    } else if (paintDelegate.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
940ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        x -= m;
941ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
942ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                }
943ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
94497ba95f72ef9e5fa3e37ec0ad5c6a2da698e0a1fDeepanshu Gupta                new BidiRenderer(graphics, paintDelegate, text).renderText(
94597ba95f72ef9e5fa3e37ec0ad5c6a2da698e0a1fDeepanshu Gupta                        index, limit, isRtl, null, 0, true, x, startY);
946ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            }
947ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
948ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
949ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
950ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
951ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawText(long nativeCanvas, String text,
952cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta            int start, int end, float x, float y, final int flags, long paint,
953cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta            long typeface) {
954ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int count = end - start;
955ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        char[] buffer = TemporaryBuffer.obtain(count);
956ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        TextUtils.getChars(text, start, end, buffer, 0);
957ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
958cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
959ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
960ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
961ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
962ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawTextRun(long nativeCanvas, String text,
963ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int start, int end, int contextStart, int contextEnd,
964cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta            float x, float y, int flags, long paint, long typeface) {
965ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int count = end - start;
966ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        char[] buffer = TemporaryBuffer.obtain(count);
967ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        TextUtils.getChars(text, start, end, buffer, 0);
968ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
969cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta        native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint, typeface);
970ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
971ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
972ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
973ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawTextRun(long nativeCanvas, char[] text,
974ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            int start, int count, int contextStart, int contextCount,
975cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta            float x, float y, int flags, long paint, long typeface) {
976cd0ed56f8a5f7788bcff050ab8aa42b0504e8535Deepanshu Gupta        native_drawText(nativeCanvas, text, start, count, x, y, flags, paint, typeface);
977ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
978ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
979ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
980ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawTextOnPath(long nativeCanvas,
981ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                     char[] text, int index,
982ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                     int count, long path,
983ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                     float hOffset,
984ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                     float vOffset, int bidiFlags,
985ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                     long paint) {
986ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME
987ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
988ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
989ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
990ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
991ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
992ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void native_drawTextOnPath(long nativeCanvas,
993ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath                                                     String text, long path,
994ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                     float hOffset,
995ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                                     float vOffset,
996f587825e94af5200aadc77a86e9f5084ac1a4e94Deepanshu Gupta                                                     int bidiFlags, long paint, long typeface) {
997ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // FIXME
998ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Bridge.getLog().fidelityWarning(LayoutLog.TAG_UNSUPPORTED,
999ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                "Canvas.drawTextOnPath is not supported.", null, null /*data*/);
1000ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1001ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1002ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    @LayoutlibDelegate
1003ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    /*package*/ static void finalizer(long nativeCanvas) {
1004ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int so that it can be disposed.
1005ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
1006ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
1007ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
1008ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
1009ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1010ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.dispose();
1011ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1012ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // remove it from the manager.
1013ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        sManager.removeJavaReferenceFor(nativeCanvas);
1014ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1015ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1016ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    // ---- Private delegate/helper methods ----
1017ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1018ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
1019ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Executes a {@link GcSnapshot.Drawable} with a given canvas and paint.
1020ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * <p>Note that the drawable may actually be executed several times if there are
1021ce5414e0eb1aeb76e6df5f6c9c6385c5f45141bcDeepanshu Gupta     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
1022ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
1023ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    private static void draw(long nCanvas, long nPaint, boolean compositeOnly, boolean forceSrcMode,
1024ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            GcSnapshot.Drawable drawable) {
1025ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
1026ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
1027ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
1028ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
1029ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
1030ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1031ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the paint which can be null if nPaint is 0;
1032ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nPaint);
1033ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1034ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.getSnapshot().draw(drawable, paintDelegate, compositeOnly, forceSrcMode);
1035ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1036ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1037ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
1038ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Executes a {@link GcSnapshot.Drawable} with a given canvas. No paint object will be provided
1039ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * to {@link GcSnapshot.Drawable#draw(Graphics2D, Paint_Delegate)}.
1040ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * <p>Note that the drawable may actually be executed several times if there are
1041ce5414e0eb1aeb76e6df5f6c9c6385c5f45141bcDeepanshu Gupta     * layers involved (see {@link #saveLayer(RectF, Paint_Delegate, int)}.
1042ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
1043ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath    private static void draw(long nCanvas, GcSnapshot.Drawable drawable) {
1044ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
1045ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
1046ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
1047ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
1048ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
1049ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1050ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        canvasDelegate.mSnapshot.draw(drawable);
1051ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1052ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1053ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private Canvas_Delegate(Bitmap_Delegate bitmap) {
1054ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mSnapshot = GcSnapshot.createDefaultSnapshot(mBitmap = bitmap);
1055ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1056ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1057ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private Canvas_Delegate() {
1058ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mSnapshot = GcSnapshot.createDefaultSnapshot(null /*image*/);
1059ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1060ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1061ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
1062ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Disposes of the {@link Graphics2D} stack.
1063ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
1064ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private void dispose() {
1065ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mSnapshot.dispose();
1066ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1067ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1068ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private int save(int saveFlags) {
1069ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the current save count
1070ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int count = mSnapshot.size();
1071ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1072ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mSnapshot = mSnapshot.save(saveFlags);
1073ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1074ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // return the old save count
1075ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return count;
1076ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1077ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1078ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private int saveLayerAlpha(RectF rect, int alpha, int saveFlags) {
1079ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Paint_Delegate paint = new Paint_Delegate();
1080ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        paint.setAlpha(alpha);
1081ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return saveLayer(rect, paint, saveFlags);
1082ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1083ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1084ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private int saveLayer(RectF rect, Paint_Delegate paint, int saveFlags) {
1085ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the current save count
1086ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int count = mSnapshot.size();
1087ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1088ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mSnapshot = mSnapshot.saveLayer(rect, paint, saveFlags);
1089ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1090ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // return the old save count
1091ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return count;
1092ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1093ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1094ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
1095ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Restores the {@link GcSnapshot} to <var>saveCount</var>
1096ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param saveCount the saveCount
1097ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
1098ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private void restoreTo(int saveCount) {
1099ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mSnapshot = mSnapshot.restoreTo(saveCount);
1100ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1101ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1102ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
1103ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Restores the {@link GcSnapshot} to <var>saveCount</var>
1104ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param saveCount the saveCount
1105ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
1106ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private void restore() {
1107ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        mSnapshot = mSnapshot.restore();
1108ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1109ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1110ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private boolean clipRect(float left, float top, float right, float bottom, int regionOp) {
1111ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return mSnapshot.clipRect(left, top, right, bottom, regionOp);
1112ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1113ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1114ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private static void drawBitmap(
1115ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            long nativeCanvas,
1116ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            Bitmap_Delegate bitmap,
1117ec4118922fa844ef31b73d16adc76f4da4c6c8e6Narayan Kamath            long nativePaintOrZero,
1118ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            final int sleft, final int stop, final int sright, final int sbottom,
1119ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            final int dleft, final int dtop, final int dright, final int dbottom) {
1120ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the delegate from the native int.
1121ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
1122ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (canvasDelegate == null) {
1123ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            return;
1124ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
1125ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1126ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // get the paint, which could be null if the int is 0
1127ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
1128ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1129ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final BufferedImage image = getImageToDraw(bitmap, paintDelegate, sBoolOut);
1130ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1131ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        draw(nativeCanvas, nativePaintOrZero, true /*compositeOnly*/, sBoolOut[0],
1132ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                new GcSnapshot.Drawable() {
1133ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    @Override
1134ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    public void draw(Graphics2D graphics, Paint_Delegate paint) {
1135ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        if (paint != null && paint.isFilterBitmap()) {
1136ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
1137ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
1138ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        }
1139ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1140ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        //FIXME add support for canvas, screen and bitmap densities.
1141ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        graphics.drawImage(image, dleft, dtop, dright, dbottom,
1142ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                                sleft, stop, sright, sbottom, null);
1143ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    }
1144ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        });
1145ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1146ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1147ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1148ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    /**
1149ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * Returns a BufferedImage ready for drawing, based on the bitmap and paint delegate.
1150ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * The image returns, through a 1-size boolean array, whether the drawing code should
1151ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * use a SRC composite no matter what the paint says.
1152ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     *
1153ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param bitmap the bitmap
1154ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param paint the paint that will be used to draw
1155ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @param forceSrcMode whether the composite will have to be SRC
1156ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     * @return the image to draw
1157ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski     */
1158ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private static BufferedImage getImageToDraw(Bitmap_Delegate bitmap, Paint_Delegate paint,
1159ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            boolean[] forceSrcMode) {
1160ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        BufferedImage image = bitmap.getImage();
1161ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        forceSrcMode[0] = false;
1162ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1163ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // if the bitmap config is alpha_8, then we erase all color value from it
1164ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        // before drawing it.
1165ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        if (bitmap.getConfig() == Bitmap.Config.ALPHA_8) {
1166ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            fixAlpha8Bitmap(image);
1167ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        } else if (bitmap.hasAlpha() == false) {
1168ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // hasAlpha is merely a rendering hint. There can in fact be alpha values
1169ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // in the bitmap but it should be ignored at drawing time.
1170ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // There is two ways to do this:
1171ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // - override the composite to be SRC. This can only be used if the composite
1172ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            //   was going to be SRC or SRC_OVER in the first place
1173ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // - Create a different bitmap to draw in which all the alpha channel values is set
1174ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            //   to 0xFF.
1175ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            if (paint != null) {
1176ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                Xfermode_Delegate xfermodeDelegate = paint.getXfermode();
1177ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
1178ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    PorterDuff.Mode mode =
1179ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                        ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
1180ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1181ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                    forceSrcMode[0] = mode == PorterDuff.Mode.SRC_OVER ||
1182ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                            mode == PorterDuff.Mode.SRC;
1183ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                }
1184ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            }
1185ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1186ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            // if we can't force SRC mode, then create a temp bitmap of TYPE_RGB
1187ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            if (forceSrcMode[0] == false) {
1188ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski                image = Bitmap_Delegate.createCopy(image, BufferedImage.TYPE_INT_RGB, 0xFF);
1189ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            }
1190ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
1191ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1192ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        return image;
1193ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1194ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1195ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    private static void fixAlpha8Bitmap(final BufferedImage image) {
1196ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int w = image.getWidth();
1197ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int h = image.getHeight();
1198ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        int[] argb = new int[w * h];
1199ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        image.getRGB(0, 0, image.getWidth(), image.getHeight(), argb, 0, image.getWidth());
1200ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1201ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        final int length = argb.length;
1202ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        for (int i = 0 ; i < length; i++) {
1203ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski            argb[i] &= 0xFF000000;
1204ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        }
1205ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski        image.setRGB(0, 0, w, h, argb, 0, w);
1206ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski    }
1207ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski}
1208ab775ecdd189b32e35b0d3f4a821502f88b03a4bAdam Lesinski
1209