blob: b116d2b3bc2d258990fef4e1d68994f79d31d6fb [file] [log] [blame]
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.graphics;
18
Xavier Ducrohet3054fe62010-12-06 10:11:44 -080019import com.android.layoutlib.bridge.Bridge;
Xavier Ducrohet3bd98982010-11-09 18:25:03 -080020import com.android.layoutlib.bridge.impl.DelegateManager;
Xavier Ducrohetf7c92072010-11-19 15:48:17 -080021import com.android.layoutlib.bridge.impl.Stack;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070022
Xavier Ducrohet37f21802010-11-01 16:17:18 -070023import android.graphics.Paint_Delegate.FontInfo;
24import android.text.TextUtils;
25
26import java.awt.AlphaComposite;
27import java.awt.BasicStroke;
28import java.awt.Color;
29import java.awt.Composite;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070030import java.awt.Graphics2D;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070031import java.awt.Rectangle;
32import java.awt.RenderingHints;
33import java.awt.geom.AffineTransform;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070034import java.awt.image.BufferedImage;
Xavier Ducrohet37f21802010-11-01 16:17:18 -070035import java.util.List;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070036
Xavier Ducrohet37f21802010-11-01 16:17:18 -070037
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070038/**
39 * Delegate implementing the native methods of android.graphics.Canvas
40 *
41 * Through the layoutlib_create tool, the original native methods of Canvas have been replaced
42 * by calls to methods of the same name in this delegate class.
43 *
44 * This class behaves like the original native implementation, but in Java, keeping previously
45 * native data into its own objects and mapping them to int that are sent back and forth between
46 * it and the original Canvas class.
47 *
48 * @see DelegateManager
49 *
50 */
51public class Canvas_Delegate {
52
53 // ---- delegate manager ----
54 private static final DelegateManager<Canvas_Delegate> sManager =
55 new DelegateManager<Canvas_Delegate>();
56
57 // ---- delegate helper data ----
58
59 // ---- delegate data ----
60 private BufferedImage mBufferedImage;
61 private final Stack<Graphics2D> mGraphicsStack = new Stack<Graphics2D>();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070062
63 // ---- Public Helper methods ----
64
65 /**
66 * Returns the native delegate associated to a given {@link Canvas} object.
67 */
68 public static Canvas_Delegate getDelegate(Canvas canvas) {
69 return sManager.getDelegate(canvas.mNativeCanvas);
70 }
71
72 /**
73 * Returns the native delegate associated to a given an int referencing a {@link Canvas} object.
74 */
75 public static Canvas_Delegate getDelegate(int native_canvas) {
76 return sManager.getDelegate(native_canvas);
77 }
78
79 /**
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070080 * Returns the current {@link Graphics2D} used to draw.
81 */
82 public Graphics2D getGraphics2d() {
83 return mGraphicsStack.peek();
84 }
85
Xavier Ducrohetef44aea2010-10-28 11:52:00 -070086 // ---- native methods ----
87
88 /*package*/ static boolean isOpaque(Canvas thisCanvas) {
89 // FIXME
90 throw new UnsupportedOperationException();
91 }
92
93 /*package*/ static int getWidth(Canvas thisCanvas) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -070094 // get the delegate from the native int.
95 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
96 if (canvasDelegate == null) {
97 assert false;
98 return 0;
99 }
100
101 return canvasDelegate.mBufferedImage.getWidth();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700102 }
103
104 /*package*/ static int getHeight(Canvas thisCanvas) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700105 // get the delegate from the native int.
106 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
107 if (canvasDelegate == null) {
108 assert false;
109 return 0;
110 }
111
112 return canvasDelegate.mBufferedImage.getHeight();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700113 }
114
115 /*package*/ static void translate(Canvas thisCanvas, float dx, float dy) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700116 // get the delegate from the native int.
117 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
118 if (canvasDelegate == null) {
119 assert false;
120 return;
121 }
122
123 canvasDelegate.getGraphics2d().translate(dx, dy);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700124 }
125
126 /*package*/ static void rotate(Canvas thisCanvas, float degrees) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700127 // get the delegate from the native int.
128 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
129 if (canvasDelegate == null) {
130 assert false;
131 return;
132 }
133
134 canvasDelegate.getGraphics2d().rotate(Math.toRadians(degrees));
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700135 }
136
137 /*package*/ static void scale(Canvas thisCanvas, float sx, float sy) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700138 // get the delegate from the native int.
139 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
140 if (canvasDelegate == null) {
141 assert false;
142 return;
143 }
144
145 canvasDelegate.getGraphics2d().scale(sx, sy);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700146 }
147
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700148 /*package*/ static void skew(Canvas thisCanvas, float kx, float ky) {
149 // get the delegate from the native int.
150 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
151 if (canvasDelegate == null) {
152 assert false;
153 return;
154 }
155
156 // get the current top graphics2D object.
157 Graphics2D g = canvasDelegate.getGraphics2d();
158
159 // get its current matrix
160 AffineTransform currentTx = g.getTransform();
161 // get the AffineTransform for the given skew.
162 float[] mtx = Matrix_Delegate.getSkew(kx, ky);
163 AffineTransform matrixTx = Matrix_Delegate.getAffineTransform(mtx);
164
165 // combine them so that the given matrix is applied after.
166 currentTx.preConcatenate(matrixTx);
167
168 // give it to the graphics2D as a new matrix replacing all previous transform
169 g.setTransform(currentTx);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700170 }
171
172 /*package*/ static boolean clipRect(Canvas thisCanvas, RectF rect) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700173 return clipRect(thisCanvas, rect.left, rect.top, rect.right, rect.bottom);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700174 }
175
176 /*package*/ static boolean clipRect(Canvas thisCanvas, Rect rect) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700177 return clipRect(thisCanvas, rect.left, rect.top, rect.right, rect.bottom);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700178 }
179
180 /*package*/ static boolean clipRect(Canvas thisCanvas, float left, float top, float right,
181 float bottom) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700182 // get the delegate from the native int.
183 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
184 if (canvasDelegate == null) {
185 assert false;
186 return false;
187 }
188
189 canvasDelegate.getGraphics2d().clipRect((int)left, (int)top, (int)(right-left),
190 (int)(bottom-top));
191 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700192 }
193
194 /*package*/ static boolean clipRect(Canvas thisCanvas, int left, int top, int right,
195 int bottom) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700196 // get the delegate from the native int.
197 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
198 if (canvasDelegate == null) {
199 assert false;
200 return false;
201 }
202
203 canvasDelegate.getGraphics2d().clipRect(left, top, right - left, bottom - top);
204 return true;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700205 }
206
207 /*package*/ static int save(Canvas thisCanvas) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700208 // get the delegate from the native int.
209 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
210 if (canvasDelegate == null) {
211 assert false;
212 return 0;
213 }
214
215 // get the current save count
216 int count = canvasDelegate.mGraphicsStack.size();
217
218 // create a new graphics and add it to the stack
219 Graphics2D g = (Graphics2D)canvasDelegate.getGraphics2d().create();
220 canvasDelegate.mGraphicsStack.push(g);
221
222 // return the old save count
223 return count;
224
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700225 }
226
227 /*package*/ static int save(Canvas thisCanvas, int saveFlags) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700228 // FIXME implement save(flags)
229 return save(thisCanvas);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700230 }
231
232 /*package*/ static void restore(Canvas thisCanvas) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700233 // get the delegate from the native int.
234 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
235 if (canvasDelegate == null) {
236 assert false;
237 return;
238 }
239
240 canvasDelegate.mGraphicsStack.pop();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700241 }
242
243 /*package*/ static int getSaveCount(Canvas thisCanvas) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700244 // get the delegate from the native int.
245 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
246 if (canvasDelegate == null) {
247 assert false;
248 return 0;
249 }
250
251 return canvasDelegate.mGraphicsStack.size();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700252 }
253
254 /*package*/ static void restoreToCount(Canvas thisCanvas, int saveCount) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700255 // get the delegate from the native int.
256 Canvas_Delegate canvasDelegate = sManager.getDelegate(thisCanvas.mNativeCanvas);
257 if (canvasDelegate == null) {
258 assert false;
259 return;
260 }
261
262 while (canvasDelegate.mGraphicsStack.size() > saveCount) {
263 canvasDelegate.mGraphicsStack.pop();
264 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700265 }
266
267 /*package*/ static void drawPoints(Canvas thisCanvas, float[] pts, int offset, int count,
268 Paint paint) {
269 // FIXME
270 throw new UnsupportedOperationException();
271 }
272
273 /*package*/ static void drawPoint(Canvas thisCanvas, float x, float y, Paint paint) {
274 // FIXME
275 throw new UnsupportedOperationException();
276 }
277
278 /*package*/ static void drawLines(Canvas thisCanvas, float[] pts, int offset, int count,
279 Paint paint) {
280 // FIXME
281 throw new UnsupportedOperationException();
282 }
283
284 /*package*/ static void freeCaches() {
285 // FIXME
286 throw new UnsupportedOperationException();
287 }
288
289 /*package*/ static int initRaster(int nativeBitmapOrZero) {
290 if (nativeBitmapOrZero > 0) {
291 // get the Bitmap from the int
292 Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(nativeBitmapOrZero);
293
294 // create a new Canvas_Delegate with the given bitmap and return its new native int.
295 Canvas_Delegate newDelegate = new Canvas_Delegate(bitmapDelegate.getImage());
296
297 return sManager.addDelegate(newDelegate);
298 } else {
299 // create a new Canvas_Delegate and return its new native int.
300 Canvas_Delegate newDelegate = new Canvas_Delegate();
301
302 return sManager.addDelegate(newDelegate);
303 }
304 }
305
306 /*package*/ static void native_setBitmap(int nativeCanvas, int bitmap) {
307 // get the delegate from the native int.
308 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
309 if (canvasDelegate == null) {
310 assert false;
311 return;
312 }
313
314 // get the delegate from the native int.
315 Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
316 if (bitmapDelegate == null) {
317 assert false;
318 return;
319 }
320
321 canvasDelegate.setBitmap(bitmapDelegate.getImage());
322 }
323
324 /*package*/ static int native_saveLayer(int nativeCanvas, RectF bounds,
325 int paint, int layerFlags) {
326 // FIXME
327 throw new UnsupportedOperationException();
328 }
329
330 /*package*/ static int native_saveLayer(int nativeCanvas, float l,
331 float t, float r, float b,
332 int paint, int layerFlags) {
333 // FIXME
334 throw new UnsupportedOperationException();
335 }
336
337 /*package*/ static int native_saveLayerAlpha(int nativeCanvas,
338 RectF bounds, int alpha,
339 int layerFlags) {
340 // FIXME
341 throw new UnsupportedOperationException();
342 }
343
344 /*package*/ static int native_saveLayerAlpha(int nativeCanvas, float l,
345 float t, float r, float b,
346 int alpha, int layerFlags) {
347 // FIXME
348 throw new UnsupportedOperationException();
349 }
350
351
352 /*package*/ static void native_concat(int nCanvas, int nMatrix) {
Xavier Ducrohetddea50d2010-11-24 11:26:40 -0800353 // get the delegate from the native int.
354 Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
355 if (canvasDelegate == null) {
356 assert false;
357 return;
358 }
359
360 Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
361 if (matrixDelegate == null) {
362 assert false;
363 return;
364 }
365
366 // get the current top graphics2D object.
367 Graphics2D g = canvasDelegate.getGraphics2d();
368
369 // get its current matrix
370 AffineTransform currentTx = g.getTransform();
371 // get the AffineTransform of the given matrix
372 AffineTransform matrixTx = matrixDelegate.getAffineTransform();
373
374 // combine them so that the given matrix is applied after.
375 currentTx.preConcatenate(matrixTx);
376
377 // give it to the graphics2D as a new matrix replacing all previous transform
378 g.setTransform(currentTx);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700379 }
380
381 /*package*/ static void native_setMatrix(int nCanvas, int nMatrix) {
Xavier Ducrohetddea50d2010-11-24 11:26:40 -0800382 // get the delegate from the native int.
383 Canvas_Delegate canvasDelegate = sManager.getDelegate(nCanvas);
384 if (canvasDelegate == null) {
385 assert false;
386 }
387
388 Matrix_Delegate matrixDelegate = Matrix_Delegate.getDelegate(nMatrix);
389 if (matrixDelegate == null) {
390 assert false;
391 }
392
393 // get the current top graphics2D object.
394 Graphics2D g = canvasDelegate.getGraphics2d();
395
396 // get the AffineTransform of the given matrix
397 AffineTransform matrixTx = matrixDelegate.getAffineTransform();
398
399 // give it to the graphics2D as a new matrix replacing all previous transform
400 g.setTransform(matrixTx);
401
Xavier Ducrohet3054fe62010-12-06 10:11:44 -0800402 if (matrixDelegate.hasPerspective()) {
403 Bridge.getLog().warning(null,
404 "android.graphics.Canvas#setMatrix(android.graphics.Matrix) only " +
405 "supports affine transformations in the Layout Preview.");
406 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700407 }
408
409 /*package*/ static boolean native_clipRect(int nCanvas,
410 float left, float top,
411 float right, float bottom,
412 int regionOp) {
413 // FIXME
414 throw new UnsupportedOperationException();
415 }
416
417 /*package*/ static boolean native_clipPath(int nativeCanvas,
418 int nativePath,
419 int regionOp) {
420 // FIXME
421 throw new UnsupportedOperationException();
422 }
423
424 /*package*/ static boolean native_clipRegion(int nativeCanvas,
425 int nativeRegion,
426 int regionOp) {
427 // FIXME
428 throw new UnsupportedOperationException();
429 }
430
431 /*package*/ static void nativeSetDrawFilter(int nativeCanvas,
432 int nativeFilter) {
433 // FIXME
434 throw new UnsupportedOperationException();
435 }
436
437 /*package*/ static boolean native_getClipBounds(int nativeCanvas,
438 Rect bounds) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700439 // get the delegate from the native int.
440 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
441 if (canvasDelegate == null) {
442 assert false;
443 return false;
444 }
445
446 Rectangle rect = canvasDelegate.getGraphics2d().getClipBounds();
447 if (rect != null) {
448 bounds.left = rect.x;
449 bounds.top = rect.y;
450 bounds.right = rect.x + rect.width;
451 bounds.bottom = rect.y + rect.height;
452 return true;
453 }
454 return false;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700455 }
456
457 /*package*/ static void native_getCTM(int canvas, int matrix) {
458 // FIXME
459 throw new UnsupportedOperationException();
460 }
461
462 /*package*/ static boolean native_quickReject(int nativeCanvas,
463 RectF rect,
464 int native_edgeType) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700465 // FIXME properly implement quickReject
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700466 return false;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700467 }
468
469 /*package*/ static boolean native_quickReject(int nativeCanvas,
470 int path,
471 int native_edgeType) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700472 // FIXME properly implement quickReject
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700473 return false;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700474 }
475
476 /*package*/ static boolean native_quickReject(int nativeCanvas,
477 float left, float top,
478 float right, float bottom,
479 int native_edgeType) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700480 // FIXME properly implement quickReject
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700481 return false;
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700482 }
483
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700484 /*package*/ static void native_drawRGB(int nativeCanvas, int r, int g, int b) {
485 native_drawColor(nativeCanvas, 0xFF000000 | r << 16 | (g&0xFF) << 8 | (b&0xFF),
486 PorterDuff.Mode.SRC_OVER.nativeInt);
487
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700488 }
489
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700490 /*package*/ static void native_drawARGB(int nativeCanvas, int a, int r, int g, int b) {
491 native_drawColor(nativeCanvas, a << 24 | (r&0xFF) << 16 | (g&0xFF) << 8 | (b&0xFF),
492 PorterDuff.Mode.SRC_OVER.nativeInt);
493 }
494
495 /*package*/ static void native_drawColor(int nativeCanvas, int color) {
496 native_drawColor(nativeCanvas, color, PorterDuff.Mode.SRC_OVER.nativeInt);
497 }
498
499 /*package*/ static void native_drawColor(int nativeCanvas, int color, int mode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700500 // get the delegate from the native int.
501 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
502 if (canvasDelegate == null) {
503 assert false;
504 return;
505 }
506
507 // get a new graphics context.
508 Graphics2D graphics = (Graphics2D)canvasDelegate.getGraphics2d().create();
509 try {
510 // reset its transform just in case
511 graphics.setTransform(new AffineTransform());
512
513 // set the color
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -0800514 graphics.setColor(new Color(color, true /*alpha*/));
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700515
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -0800516 setModeInGraphics(graphics, mode);
Xavier Ducroheta313b652010-11-01 18:45:20 -0700517
518 graphics.fillRect(0, 0, canvasDelegate.mBufferedImage.getWidth(),
519 canvasDelegate.mBufferedImage.getHeight());
520 } finally {
521 // dispose Graphics2D object
522 graphics.dispose();
523 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700524 }
525
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700526 /*package*/ static void native_drawPaint(int nativeCanvas, int paint) {
527 // FIXME
528 throw new UnsupportedOperationException();
529 }
530
531 /*package*/ static void native_drawLine(int nativeCanvas, float startX,
532 float startY, float stopX,
533 float stopY, int paint) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700534 // get the delegate from the native int.
535 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
536 if (canvasDelegate == null) {
537 assert false;
538 return;
539 }
540
541 // get the delegate from the native int.
542 Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
543 if (paintDelegate == null) {
544 assert false;
545 return;
546 }
547
548 // get a Graphics2D object configured with the drawing parameters.
549 Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
550
551 g.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY);
552
553 // dispose Graphics2D object
554 g.dispose();
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700555 }
556
557 /*package*/ static void native_drawRect(int nativeCanvas, RectF rect,
558 int paint) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700559 native_drawRect(nativeCanvas, rect.left, rect.top, rect.right, rect.bottom, paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700560 }
561
562 /*package*/ static void native_drawRect(int nativeCanvas, float left,
563 float top, float right,
564 float bottom, int paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700565 // get the delegate from the native int.
566 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
567 if (canvasDelegate == null) {
568 assert false;
569 return;
570 }
571
572 // get the delegate from the native int.
573 Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
574 if (paintDelegate == null) {
575 assert false;
576 return;
577 }
578
579 if (right > left && bottom > top) {
580 // get a Graphics2D object configured with the drawing parameters.
581 Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
582
583 int style = paintDelegate.getStyle();
584
585 // draw
586 if (style == Paint.Style.FILL.nativeInt ||
587 style == Paint.Style.FILL_AND_STROKE.nativeInt) {
588 g.fillRect((int)left, (int)top, (int)(right-left), (int)(bottom-top));
589 }
590
591 if (style == Paint.Style.STROKE.nativeInt ||
592 style == Paint.Style.FILL_AND_STROKE.nativeInt) {
593 g.drawRect((int)left, (int)top, (int)(right-left), (int)(bottom-top));
594 }
595
596 // dispose Graphics2D object
597 g.dispose();
598 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700599 }
600
601 /*package*/ static void native_drawOval(int nativeCanvas, RectF oval,
602 int paint) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700603 // get the delegate from the native int.
604 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
605 if (canvasDelegate == null) {
606 assert false;
607 return;
608 }
609
610 // get the delegate from the native int.
611 Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
612 if (paintDelegate == null) {
613 assert false;
614 return;
615 }
616
617 if (oval.right > oval.left && oval.bottom > oval.top) {
618 // get a Graphics2D object configured with the drawing parameters.
619 Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
620
621 int style = paintDelegate.getStyle();
622
623 // draw
624 if (style == Paint.Style.FILL.nativeInt ||
625 style == Paint.Style.FILL_AND_STROKE.nativeInt) {
626 g.fillOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height());
627 }
628
629 if (style == Paint.Style.STROKE.nativeInt ||
630 style == Paint.Style.FILL_AND_STROKE.nativeInt) {
631 g.drawOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height());
632 }
633
634 // dispose Graphics2D object
635 g.dispose();
636 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700637 }
638
639 /*package*/ static void native_drawCircle(int nativeCanvas, float cx,
640 float cy, float radius,
641 int paint) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700642 native_drawOval(nativeCanvas,
643 new RectF(cx - radius, cy - radius, radius*2, radius*2),
644 paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700645 }
646
647 /*package*/ static void native_drawArc(int nativeCanvas, RectF oval,
648 float startAngle, float sweep,
649 boolean useCenter, int paint) {
650 // FIXME
651 throw new UnsupportedOperationException();
652 }
653
654 /*package*/ static void native_drawRoundRect(int nativeCanvas,
655 RectF rect, float rx,
656 float ry, int paint) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700657 // get the delegate from the native int.
658 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
659 if (canvasDelegate == null) {
660 assert false;
661 return;
662 }
663
664 // get the delegate from the native int.
665 Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
666 if (paintDelegate == null) {
667 assert false;
668 return;
669 }
670
671 if (rect.right > rect.left && rect.bottom > rect.top) {
672 // get a Graphics2D object configured with the drawing parameters.
673 Graphics2D g = canvasDelegate.getCustomGraphics(paintDelegate);
674
675 int style = paintDelegate.getStyle();
676
677 // draw
678 if (style == Paint.Style.FILL.nativeInt ||
679 style == Paint.Style.FILL_AND_STROKE.nativeInt) {
680 g.fillRoundRect(
681 (int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(),
682 (int)rx, (int)ry);
683 }
684
685 if (style == Paint.Style.STROKE.nativeInt ||
686 style == Paint.Style.FILL_AND_STROKE.nativeInt) {
687 g.drawRoundRect(
688 (int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(),
689 (int)rx, (int)ry);
690 }
691
692 // dispose Graphics2D object
693 g.dispose();
694 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700695 }
696
697 /*package*/ static void native_drawPath(int nativeCanvas, int path,
698 int paint) {
699 // FIXME
700 throw new UnsupportedOperationException();
701 }
702
703 /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
704 float left, float top,
705 int nativePaintOrZero,
706 int canvasDensity,
707 int screenDensity,
708 int bitmapDensity) {
709 // FIXME
710 throw new UnsupportedOperationException();
711 }
712
713 /*package*/ static void native_drawBitmap(Canvas thisCanvas, int nativeCanvas, int bitmap,
714 Rect src, RectF dst,
715 int nativePaintOrZero,
716 int screenDensity,
717 int bitmapDensity) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700718 // get the delegate from the native int.
719 Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
720 if (bitmapDelegate == null) {
721 assert false;
722 return;
723 }
724
725 BufferedImage image = bitmapDelegate.getImage();
726
727 if (src == null) {
728 drawBitmap(nativeCanvas, image, nativePaintOrZero,
729 0, 0, image.getWidth(), image.getHeight(),
730 (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
731 } else {
732 drawBitmap(nativeCanvas, image, nativePaintOrZero,
733 src.left, src.top, src.width(), src.height(),
734 (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom);
735 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700736 }
737
738 /*package*/ static void native_drawBitmap(int nativeCanvas, int bitmap,
739 Rect src, Rect dst,
740 int nativePaintOrZero,
741 int screenDensity,
742 int bitmapDensity) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700743 // get the delegate from the native int.
744 Bitmap_Delegate bitmapDelegate = Bitmap_Delegate.getDelegate(bitmap);
745 if (bitmapDelegate == null) {
746 assert false;
747 return;
748 }
749
750 BufferedImage image = bitmapDelegate.getImage();
751
752 if (src == null) {
753 drawBitmap(nativeCanvas, image, nativePaintOrZero,
754 0, 0, image.getWidth(), image.getHeight(),
755 dst.left, dst.top, dst.right, dst.bottom);
756 } else {
757 drawBitmap(nativeCanvas, image, nativePaintOrZero,
758 src.left, src.top, src.width(), src.height(),
759 dst.left, dst.top, dst.right, dst.bottom);
760 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700761 }
762
763 /*package*/ static void native_drawBitmap(int nativeCanvas, int[] colors,
764 int offset, int stride, float x,
765 float y, int width, int height,
766 boolean hasAlpha,
767 int nativePaintOrZero) {
768 // FIXME
769 throw new UnsupportedOperationException();
770 }
771
772 /*package*/ static void nativeDrawBitmapMatrix(int nCanvas, int nBitmap,
773 int nMatrix, int nPaint) {
774 // FIXME
775 throw new UnsupportedOperationException();
776 }
777
778 /*package*/ static void nativeDrawBitmapMesh(int nCanvas, int nBitmap,
779 int meshWidth, int meshHeight,
780 float[] verts, int vertOffset,
781 int[] colors, int colorOffset, int nPaint) {
782 // FIXME
783 throw new UnsupportedOperationException();
784 }
785
786 /*package*/ static void nativeDrawVertices(int nCanvas, int mode, int n,
787 float[] verts, int vertOffset, float[] texs, int texOffset,
788 int[] colors, int colorOffset, short[] indices,
789 int indexOffset, int indexCount, int nPaint) {
790 // FIXME
791 throw new UnsupportedOperationException();
792 }
793
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700794 /*package*/ static void native_drawText(int nativeCanvas, char[] text,
795 int index, int count, float x,
796 float y, int flags, int paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700797 // WARNING: the logic in this method is similar to Paint.measureText.
798 // Any change to this method should be reflected in Paint.measureText
799
800 // get the delegate from the native int.
801 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
802 if (canvasDelegate == null) {
803 assert false;
804 return;
805 }
806
807 // get the delegate from the native int.
808 Paint_Delegate paintDelegate = Paint_Delegate.getDelegate(paint);
809 if (paintDelegate == null) {
810 assert false;
811 return;
812 }
813
Xavier Ducrohetf1a174522010-11-01 22:02:08 -0700814 Graphics2D g = (Graphics2D) canvasDelegate.getCustomGraphics(paintDelegate);
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700815 try {
Xavier Ducroheta313b652010-11-01 18:45:20 -0700816 // Paint.TextAlign indicates how the text is positioned relative to X.
817 // LEFT is the default and there's nothing to do.
818 if (paintDelegate.getTextAlign() != Paint.Align.LEFT.nativeInt) {
819 float m = paintDelegate.measureText(text, index, count);
820 if (paintDelegate.getTextAlign() == Paint.Align.CENTER.nativeInt) {
821 x -= m / 2;
822 } else if (paintDelegate.getTextAlign() == Paint.Align.RIGHT.nativeInt) {
823 x -= m;
824 }
825 }
826
827 List<FontInfo> fonts = paintDelegate.getFonts();
828
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700829 if (fonts.size() > 0) {
830 FontInfo mainFont = fonts.get(0);
831 int i = index;
832 int lastIndex = index + count;
833 while (i < lastIndex) {
834 // always start with the main font.
835 int upTo = mainFont.mFont.canDisplayUpTo(text, i, lastIndex);
836 if (upTo == -1) {
837 // draw all the rest and exit.
838 g.setFont(mainFont.mFont);
839 g.drawChars(text, i, lastIndex - i, (int)x, (int)y);
840 return;
841 } else if (upTo > 0) {
842 // draw what's possible
843 g.setFont(mainFont.mFont);
844 g.drawChars(text, i, upTo - i, (int)x, (int)y);
845
846 // compute the width that was drawn to increase x
847 x += mainFont.mMetrics.charsWidth(text, i, upTo - i);
848
849 // move index to the first non displayed char.
850 i = upTo;
851
852 // don't call continue at this point. Since it is certain the main font
853 // cannot display the font a index upTo (now ==i), we move on to the
854 // fallback fonts directly.
855 }
856
857 // no char supported, attempt to read the next char(s) with the
858 // fallback font. In this case we only test the first character
859 // and then go back to test with the main font.
860 // Special test for 2-char characters.
861 boolean foundFont = false;
862 for (int f = 1 ; f < fonts.size() ; f++) {
863 FontInfo fontInfo = fonts.get(f);
864
865 // need to check that the font can display the character. We test
866 // differently if the char is a high surrogate.
867 int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
868 upTo = fontInfo.mFont.canDisplayUpTo(text, i, i + charCount);
869 if (upTo == -1) {
870 // draw that char
871 g.setFont(fontInfo.mFont);
872 g.drawChars(text, i, charCount, (int)x, (int)y);
873
874 // update x
875 x += fontInfo.mMetrics.charsWidth(text, i, charCount);
876
877 // update the index in the text, and move on
878 i += charCount;
879 foundFont = true;
880 break;
881
882 }
883 }
884
885 // in case no font can display the char, display it with the main font.
886 // (it'll put a square probably)
887 if (foundFont == false) {
888 int charCount = Character.isHighSurrogate(text[i]) ? 2 : 1;
889
890 g.setFont(mainFont.mFont);
891 g.drawChars(text, i, charCount, (int)x, (int)y);
892
893 // measure it to advance x
894 x += mainFont.mMetrics.charsWidth(text, i, charCount);
895
896 // and move to the next chars.
897 i += charCount;
898 }
899 }
900 }
901 } finally {
902 g.dispose();
903 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700904 }
905
906 /*package*/ static void native_drawText(int nativeCanvas, String text,
907 int start, int end, float x,
908 float y, int flags, int paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -0700909 int count = end - start;
910 char[] buffer = TemporaryBuffer.obtain(count);
911 TextUtils.getChars(text, start, end, buffer, 0);
912
913 native_drawText(nativeCanvas, buffer, 0, count, x, y, flags, paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700914 }
915
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700916 /*package*/ static void native_drawTextRun(int nativeCanvas, String text,
917 int start, int end, int contextStart, int contextEnd,
918 float x, float y, int flags, int paint) {
Xavier Ducrohet571dce72010-11-04 18:04:27 -0700919 int count = end - start;
920 char[] buffer = TemporaryBuffer.obtain(count);
921 TextUtils.getChars(text, start, end, buffer, 0);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700922
Xavier Ducrohet571dce72010-11-04 18:04:27 -0700923 native_drawText(nativeCanvas, buffer, start, end, x, y, flags, paint);
924 }
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700925
926 /*package*/ static void native_drawTextRun(int nativeCanvas, char[] text,
927 int start, int count, int contextStart, int contextCount,
928 float x, float y, int flags, int paint) {
Xavier Ducrohet571dce72010-11-04 18:04:27 -0700929 native_drawText(nativeCanvas, text, 0, count, x, y, flags, paint);
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700930 }
931
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700932 /*package*/ static void native_drawPosText(int nativeCanvas,
933 char[] text, int index,
934 int count, float[] pos,
935 int paint) {
936 // FIXME
937 throw new UnsupportedOperationException();
938 }
939
940 /*package*/ static void native_drawPosText(int nativeCanvas,
941 String text, float[] pos,
942 int paint) {
943 // FIXME
944 throw new UnsupportedOperationException();
945 }
946
947 /*package*/ static void native_drawTextOnPath(int nativeCanvas,
948 char[] text, int index,
949 int count, int path,
950 float hOffset,
951 float vOffset, int bidiFlags,
952 int paint) {
953 // FIXME
954 throw new UnsupportedOperationException();
955 }
956
957 /*package*/ static void native_drawTextOnPath(int nativeCanvas,
958 String text, int path,
959 float hOffset,
960 float vOffset,
961 int flags, int paint) {
962 // FIXME
963 throw new UnsupportedOperationException();
964 }
965
966 /*package*/ static void native_drawPicture(int nativeCanvas,
967 int nativePicture) {
968 // FIXME
969 throw new UnsupportedOperationException();
970 }
971
972 /*package*/ static void finalizer(int nativeCanvas) {
Xavier Ducrohet13926152010-12-01 12:28:43 -0800973 // get the delegate from the native int so that it can be disposed.
974 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
975 if (canvasDelegate == null) {
976 assert false;
977 return;
978 }
979
980 canvasDelegate.dispose();
981
982 // remove it from the manager.
Xavier Ducrohetef44aea2010-10-28 11:52:00 -0700983 sManager.removeDelegate(nativeCanvas);
984 }
985
986 // ---- Private delegate/helper methods ----
987
988 private Canvas_Delegate(BufferedImage image) {
989 setBitmap(image);
990 }
991
992 private Canvas_Delegate() {
993 }
994
Xavier Ducrohet13926152010-12-01 12:28:43 -0800995 /**
996 * Disposes of the {@link Graphics2D} stack.
997 */
998 private void dispose() {
999 while (mGraphicsStack.size() > 0) {
1000 mGraphicsStack.pop().dispose();
1001 }
1002 }
1003
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001004 private void setBitmap(BufferedImage image) {
1005 mBufferedImage = image;
1006 mGraphicsStack.push(mBufferedImage.createGraphics());
1007 }
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001008
1009 /**
1010 * Creates a new {@link Graphics2D} based on the {@link Paint} parameters.
1011 * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used.
1012 */
Xavier Ducrohete4d97872010-11-22 20:09:55 -08001013 /*package*/ Graphics2D getCustomGraphics(Paint_Delegate paint) {
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001014 // make new one
1015 Graphics2D g = getGraphics2d();
1016 g = (Graphics2D)g.create();
1017
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001018 // configure it
1019
Xavier Ducroheta313b652010-11-01 18:45:20 -07001020 if (paint.isAntiAliased()) {
1021 g.setRenderingHint(
1022 RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Xavier Ducrohetf1a174522010-11-01 22:02:08 -07001023 g.setRenderingHint(
1024 RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
Xavier Ducroheta313b652010-11-01 18:45:20 -07001025 }
1026
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001027 boolean useColorPaint = true;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001028
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001029 // get the shader first, as it'll replace the color if it can be used it.
1030 Shader_Delegate shaderDelegate = Shader_Delegate.getDelegate(paint.getShader());
Xavier Ducrohetf1a174522010-11-01 22:02:08 -07001031 if (shaderDelegate != null) {
1032 java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001033 if (shaderPaint != null) {
1034 g.setPaint(shaderPaint);
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001035 useColorPaint = false;
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001036 } else {
Xavier Ducrohet3054fe62010-12-06 10:11:44 -08001037 Bridge.getLog().warning(null,
1038 String.format(
1039 "Shader '%1$s' is not supported in the Layout Preview.",
Xavier Ducrohetf1a174522010-11-01 22:02:08 -07001040 shaderDelegate.getClass().getCanonicalName()));
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001041 }
1042 }
Xavier Ducrohetf1a174522010-11-01 22:02:08 -07001043
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001044 if (useColorPaint) {
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001045 g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001046 }
1047
1048 int style = paint.getStyle();
1049 if (style == Paint.Style.STROKE.nativeInt ||
1050 style == Paint.Style.FILL_AND_STROKE.nativeInt) {
1051
1052 PathEffect_Delegate effectDelegate = PathEffect_Delegate.getDelegate(
1053 paint.getPathEffect());
1054
1055 if (effectDelegate instanceof DashPathEffect_Delegate) {
1056 DashPathEffect_Delegate dpe = (DashPathEffect_Delegate)effectDelegate;
1057 g.setStroke(new BasicStroke(
1058 paint.getStrokeWidth(),
1059 paint.getJavaCap(),
1060 paint.getJavaJoin(),
1061 paint.getStrokeMiter(),
1062 dpe.getIntervals(),
1063 dpe.getPhase()));
1064 } else {
1065 g.setStroke(new BasicStroke(
1066 paint.getStrokeWidth(),
1067 paint.getJavaCap(),
1068 paint.getJavaJoin(),
1069 paint.getStrokeMiter()));
1070 }
1071 }
1072
1073 Xfermode_Delegate xfermodeDelegate = Xfermode_Delegate.getDelegate(paint.getXfermode());
1074 if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
1075 int mode = ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
1076
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001077 setModeInGraphics(g, mode);
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001078 } else {
1079 // default mode is src_over
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001080 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001081
1082 // if xfermode wasn't null, then it's something we don't support. log it.
Xavier Ducrohet3054fe62010-12-06 10:11:44 -08001083 if (xfermodeDelegate != null) {
1084 Bridge.getLog().warning(null,
1085 String.format(
1086 "Xfermode '%1$s' is not supported in the Layout Preview.",
1087 xfermodeDelegate.getClass().getCanonicalName()));
Xavier Ducrohet3cff5722010-11-03 17:40:17 -07001088 }
1089 }
1090
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001091 return g;
1092 }
1093
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001094 private static void setModeInGraphics(Graphics2D g, int mode) {
Xavier Ducrohetf1a174522010-11-01 22:02:08 -07001095 for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
1096 if (m.nativeInt == mode) {
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001097 setModeInGraphics(g, m);
Xavier Ducrohetf1a174522010-11-01 22:02:08 -07001098 return;
1099 }
1100 }
1101 }
1102
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001103 private static void setModeInGraphics(Graphics2D g, PorterDuff.Mode mode) {
Xavier Ducroheta313b652010-11-01 18:45:20 -07001104 switch (mode) {
1105 case CLEAR:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001106 g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001107 break;
1108 case DARKEN:
1109 break;
1110 case DST:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001111 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001112 break;
1113 case DST_ATOP:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001114 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001115 break;
1116 case DST_IN:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001117 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001118 break;
1119 case DST_OUT:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001120 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001121 break;
1122 case DST_OVER:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001123 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001124 break;
1125 case LIGHTEN:
1126 break;
1127 case MULTIPLY:
1128 break;
1129 case SCREEN:
1130 break;
1131 case SRC:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001132 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001133 break;
1134 case SRC_ATOP:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001135 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001136 break;
1137 case SRC_IN:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001138 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001139 break;
1140 case SRC_OUT:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001141 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001142 break;
1143 case SRC_OVER:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001144 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001145 break;
1146 case XOR:
Xavier Ducrohet70a04aa2010-11-12 14:20:45 -08001147 g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, 1.0f /*alpha*/));
Xavier Ducroheta313b652010-11-01 18:45:20 -07001148 break;
1149 }
1150 }
1151
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001152
1153 private static void drawBitmap(
1154 int nativeCanvas,
1155 BufferedImage image,
1156 int nativePaintOrZero,
1157 int sleft, int stop, int sright, int sbottom,
1158 int dleft, int dtop, int dright, int dbottom) {
1159 // get the delegate from the native int.
1160 Canvas_Delegate canvasDelegate = sManager.getDelegate(nativeCanvas);
1161 if (canvasDelegate == null) {
1162 assert false;
1163 return;
1164 }
1165
1166 // get the delegate from the native int.
1167 Paint_Delegate paintDelegate = null;
1168 if (nativePaintOrZero > 0) {
1169 paintDelegate = Paint_Delegate.getDelegate(nativePaintOrZero);
1170 if (paintDelegate == null) {
1171 assert false;
1172 return;
1173 }
1174 }
1175
1176 drawBitmap(canvasDelegate, image, paintDelegate,
1177 sleft, stop, sright, sbottom,
1178 dleft, dtop, dright, dbottom);
1179 }
1180
1181 private static void drawBitmap(
1182 Canvas_Delegate canvasDelegate,
1183 BufferedImage image,
1184 Paint_Delegate paintDelegate,
1185 int sleft, int stop, int sright, int sbottom,
1186 int dleft, int dtop, int dright, int dbottom) {
1187
1188 Graphics2D g = canvasDelegate.getGraphics2d();
1189
1190 Composite c = null;
1191
1192 if (paintDelegate != null) {
1193 if (paintDelegate.isFilterBitmap()) {
1194 g = (Graphics2D)g.create();
1195 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
1196 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
1197 }
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001198 }
1199
1200 g.drawImage(image, dleft, dtop, dright, dbottom,
1201 sleft, stop, sright, sbottom, null);
1202
1203 if (paintDelegate != null) {
1204 if (paintDelegate.isFilterBitmap()) {
1205 g.dispose();
1206 }
1207 if (c != null) {
1208 g.setComposite(c);
1209 }
1210 }
1211 }
1212
Xavier Ducrohetef44aea2010-10-28 11:52:00 -07001213}
Xavier Ducrohet37f21802010-11-01 16:17:18 -07001214