1/* 2 * Copyright (C) 2008 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 19import com.android.layoutlib.api.ILayoutLog; 20 21import android.graphics.DrawFilter; 22import android.graphics.Picture; 23import android.graphics.PorterDuff; 24import android.graphics.Rect; 25import android.graphics.RectF; 26import android.graphics.Region; 27import android.graphics.Xfermode; 28import android.graphics.Paint.Align; 29import android.graphics.Paint.Style; 30import android.graphics.Region.Op; 31 32import java.awt.AlphaComposite; 33import java.awt.Color; 34import java.awt.Composite; 35import java.awt.Graphics2D; 36import java.awt.Rectangle; 37import java.awt.RenderingHints; 38import java.awt.geom.AffineTransform; 39import java.awt.image.BufferedImage; 40import java.util.Stack; 41 42import javax.microedition.khronos.opengles.GL; 43 44/** 45 * Re-implementation of the Canvas, 100% in java on top of a BufferedImage. 46 */ 47public class Canvas extends _Original_Canvas { 48 49 private BufferedImage mBufferedImage; 50 private final Stack<Graphics2D> mGraphicsStack = new Stack<Graphics2D>(); 51 private final ILayoutLog mLogger; 52 53 public Canvas() { 54 mLogger = null; 55 // the mBufferedImage will be taken from a bitmap in #setBitmap() 56 } 57 58 public Canvas(Bitmap bitmap) { 59 mLogger = null; 60 mBufferedImage = bitmap.getImage(); 61 mGraphicsStack.push(mBufferedImage.createGraphics()); 62 } 63 64 public Canvas(int nativeCanvas) { 65 mLogger = null; 66 throw new UnsupportedOperationException("Can't create Canvas(int)"); 67 } 68 69 public Canvas(javax.microedition.khronos.opengles.GL gl) { 70 mLogger = null; 71 throw new UnsupportedOperationException("Can't create Canvas(javax.microedition.khronos.opengles.GL)"); 72 } 73 74 // custom constructors for our use. 75 public Canvas(int width, int height, ILayoutLog logger) { 76 mLogger = logger; 77 mBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 78 mGraphicsStack.push(mBufferedImage.createGraphics()); 79 } 80 81 public Canvas(int width, int height) { 82 this(width, height, null /* logger*/); 83 } 84 85 // custom mehtods 86 public BufferedImage getImage() { 87 return mBufferedImage; 88 } 89 90 public Graphics2D getGraphics2d() { 91 return mGraphicsStack.peek(); 92 } 93 94 public void dispose() { 95 while (mGraphicsStack.size() > 0) { 96 mGraphicsStack.pop().dispose(); 97 } 98 } 99 100 /** 101 * Creates a new {@link Graphics2D} based on the {@link Paint} parameters. 102 * <p/>The object must be disposed ({@link Graphics2D#dispose()}) after being used. 103 */ 104 private Graphics2D getNewGraphics(Paint paint, Graphics2D g) { 105 // make new one 106 g = (Graphics2D)g.create(); 107 g.setColor(new Color(paint.getColor())); 108 int alpha = paint.getAlpha(); 109 float falpha = alpha / 255.f; 110 111 Xfermode xfermode = paint.getXfermode(); 112 if (xfermode instanceof PorterDuffXfermode) { 113 PorterDuff.Mode mode = ((PorterDuffXfermode)xfermode).getMode(); 114 115 setModeInGraphics(mode, g, falpha); 116 } else { 117 if (mLogger != null && xfermode != null) { 118 mLogger.warning(String.format( 119 "Xfermode '%1$s' is not supported in the Layout Editor.", 120 xfermode.getClass().getCanonicalName())); 121 } 122 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha)); 123 } 124 125 Shader shader = paint.getShader(); 126 if (shader instanceof LinearGradient) { 127 g.setPaint(((LinearGradient)shader).getPaint()); 128 } else { 129 if (mLogger != null && shader != null) { 130 mLogger.warning(String.format( 131 "Shader '%1$s' is not supported in the Layout Editor.", 132 shader.getClass().getCanonicalName())); 133 } 134 } 135 136 return g; 137 } 138 139 private void setModeInGraphics(PorterDuff.Mode mode, Graphics2D g, float falpha) { 140 switch (mode) { 141 case CLEAR: 142 g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha)); 143 break; 144 case DARKEN: 145 break; 146 case DST: 147 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, falpha)); 148 break; 149 case DST_ATOP: 150 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha)); 151 break; 152 case DST_IN: 153 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha)); 154 break; 155 case DST_OUT: 156 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha)); 157 break; 158 case DST_OVER: 159 g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha)); 160 break; 161 case LIGHTEN: 162 break; 163 case MULTIPLY: 164 break; 165 case SCREEN: 166 break; 167 case SRC: 168 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, falpha)); 169 break; 170 case SRC_ATOP: 171 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha)); 172 break; 173 case SRC_IN: 174 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha)); 175 break; 176 case SRC_OUT: 177 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha)); 178 break; 179 case SRC_OVER: 180 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha)); 181 break; 182 case XOR: 183 g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, falpha)); 184 break; 185 } 186 } 187 188 189 // -------------------- 190 // OVERRIDEN ENUMS 191 // This is needed since we rename Canvas into _Original_Canvas 192 // -------------------- 193 194 public enum EdgeType { 195 BW(0), //!< treat edges by just rounding to nearest pixel boundary 196 AA(1); //!< treat edges by rounding-out, since they may be antialiased 197 198 EdgeType(int nativeInt) { 199 this.nativeInt = nativeInt; 200 } 201 final int nativeInt; 202 } 203 204 205 // -------------------- 206 // OVERRIDEN METHODS 207 // -------------------- 208 209 @Override 210 public void finalize() throws Throwable { 211 // pass 212 } 213 214 /* (non-Javadoc) 215 * @see android.graphics.Canvas#setBitmap(android.graphics.Bitmap) 216 */ 217 @Override 218 public void setBitmap(Bitmap bitmap) { 219 mBufferedImage = bitmap.getImage(); 220 mGraphicsStack.push(mBufferedImage.createGraphics()); 221 } 222 223 224 /* (non-Javadoc) 225 * @see android.graphics.Canvas#translate(float, float) 226 */ 227 @Override 228 public void translate(float dx, float dy) { 229 getGraphics2d().translate(dx, dy); 230 } 231 232 /* (non-Javadoc) 233 * @see android.graphics.Canvas#save() 234 */ 235 @Override 236 public int save() { 237 Graphics2D g = (Graphics2D)getGraphics2d().create(); 238 mGraphicsStack.push(g); 239 240 return mGraphicsStack.size() - 1; 241 } 242 243 /* (non-Javadoc) 244 * @see android.graphics.Canvas#save(int) 245 */ 246 @Override 247 public int save(int saveFlags) { 248 // For now we ignore saveFlags 249 return save(); 250 } 251 252 /* (non-Javadoc) 253 * @see android.graphics.Canvas#restore() 254 */ 255 @Override 256 public void restore() { 257 mGraphicsStack.pop(); 258 } 259 260 /* (non-Javadoc) 261 * @see android.graphics.Canvas#restoreToCount(int) 262 */ 263 @Override 264 public void restoreToCount(int saveCount) { 265 while (mGraphicsStack.size() > saveCount) { 266 mGraphicsStack.pop(); 267 } 268 } 269 270 /* (non-Javadoc) 271 * @see android.graphics.Canvas#getSaveCount() 272 */ 273 @Override 274 public int getSaveCount() { 275 return mGraphicsStack.size() - 1; 276 } 277 278 279 /* (non-Javadoc) 280 * @see android.graphics.Canvas#clipRect(float, float, float, float, android.graphics.Region.Op) 281 */ 282 @Override 283 public boolean clipRect(float left, float top, float right, float bottom, Op op) { 284 return clipRect(left, top, right, bottom); 285 } 286 287 /* (non-Javadoc) 288 * @see android.graphics.Canvas#clipRect(float, float, float, float) 289 */ 290 @Override 291 public boolean clipRect(float left, float top, float right, float bottom) { 292 getGraphics2d().clipRect((int)left, (int)top, (int)(right-left), (int)(bottom-top)); 293 return true; 294 } 295 296 /* (non-Javadoc) 297 * @see android.graphics.Canvas#clipRect(int, int, int, int) 298 */ 299 @Override 300 public boolean clipRect(int left, int top, int right, int bottom) { 301 getGraphics2d().clipRect(left, top, right-left, bottom-top); 302 return true; 303 } 304 305 /* (non-Javadoc) 306 * @see android.graphics.Canvas#clipRect(android.graphics.Rect, android.graphics.Region.Op) 307 */ 308 @Override 309 public boolean clipRect(Rect rect, Op op) { 310 return clipRect(rect.left, rect.top, rect.right, rect.bottom); 311 } 312 313 /* (non-Javadoc) 314 * @see android.graphics.Canvas#clipRect(android.graphics.Rect) 315 */ 316 @Override 317 public boolean clipRect(Rect rect) { 318 return clipRect(rect.left, rect.top, rect.right, rect.bottom); 319 } 320 321 /* (non-Javadoc) 322 * @see android.graphics.Canvas#clipRect(android.graphics.RectF, android.graphics.Region.Op) 323 */ 324 @Override 325 public boolean clipRect(RectF rect, Op op) { 326 return clipRect(rect.left, rect.top, rect.right, rect.bottom); 327 } 328 329 /* (non-Javadoc) 330 * @see android.graphics.Canvas#clipRect(android.graphics.RectF) 331 */ 332 @Override 333 public boolean clipRect(RectF rect) { 334 return clipRect(rect.left, rect.top, rect.right, rect.bottom); 335 } 336 337 public boolean quickReject(RectF rect, EdgeType type) { 338 return false; 339 } 340 341 @Override 342 public boolean quickReject(RectF rect, _Original_Canvas.EdgeType type) { 343 throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); 344 } 345 346 public boolean quickReject(Path path, EdgeType type) { 347 return false; 348 } 349 350 @Override 351 public boolean quickReject(Path path, _Original_Canvas.EdgeType type) { 352 throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); 353 } 354 355 public boolean quickReject(float left, float top, float right, float bottom, 356 EdgeType type) { 357 return false; 358 } 359 360 @Override 361 public boolean quickReject(float left, float top, float right, float bottom, 362 _Original_Canvas.EdgeType type) { 363 throw new UnsupportedOperationException("CALL TO PARENT FORBIDDEN"); 364 } 365 366 /** 367 * Retrieve the clip bounds, returning true if they are non-empty. 368 * 369 * @param bounds Return the clip bounds here. If it is null, ignore it but 370 * still return true if the current clip is non-empty. 371 * @return true if the current clip is non-empty. 372 */ 373 @Override 374 public boolean getClipBounds(Rect bounds) { 375 Rectangle rect = getGraphics2d().getClipBounds(); 376 if (rect != null) { 377 bounds.left = rect.x; 378 bounds.top = rect.y; 379 bounds.right = rect.x + rect.width; 380 bounds.bottom = rect.y + rect.height; 381 return true; 382 } 383 return false; 384 } 385 386 /* (non-Javadoc) 387 * @see android.graphics.Canvas#drawColor(int, android.graphics.PorterDuff.Mode) 388 */ 389 @Override 390 public void drawColor(int color, PorterDuff.Mode mode) { 391 Graphics2D g = getGraphics2d(); 392 393 // save old color 394 Color c = g.getColor(); 395 396 Composite composite = g.getComposite(); 397 398 // get the alpha from the color 399 int alpha = color >>> 24; 400 float falpha = alpha / 255.f; 401 402 setModeInGraphics(mode, g, falpha); 403 404 g.setColor(new Color(color)); 405 406 getGraphics2d().fillRect(0, 0, getWidth(), getHeight()); 407 408 g.setComposite(composite); 409 410 // restore color 411 g.setColor(c); 412 } 413 414 /* (non-Javadoc) 415 * @see android.graphics.Canvas#drawColor(int) 416 */ 417 @Override 418 public void drawColor(int color) { 419 drawColor(color, PorterDuff.Mode.SRC_OVER); 420 } 421 422 /* (non-Javadoc) 423 * @see android.graphics.Canvas#drawARGB(int, int, int, int) 424 */ 425 @Override 426 public void drawARGB(int a, int r, int g, int b) { 427 drawColor(a << 24 | r << 16 | g << 8 | b, PorterDuff.Mode.SRC_OVER); 428 } 429 430 /* (non-Javadoc) 431 * @see android.graphics.Canvas#drawRGB(int, int, int) 432 */ 433 @Override 434 public void drawRGB(int r, int g, int b) { 435 drawColor(0xFF << 24 | r << 16 | g << 8 | b, PorterDuff.Mode.SRC_OVER); 436 } 437 438 439 /* (non-Javadoc) 440 * @see android.graphics.Canvas#getWidth() 441 */ 442 @Override 443 public int getWidth() { 444 return mBufferedImage.getWidth(); 445 } 446 447 /* (non-Javadoc) 448 * @see android.graphics.Canvas#getHeight() 449 */ 450 @Override 451 public int getHeight() { 452 return mBufferedImage.getHeight(); 453 } 454 455 /* (non-Javadoc) 456 * @see android.graphics.Canvas#drawPaint(android.graphics.Paint) 457 */ 458 @Override 459 public void drawPaint(Paint paint) { 460 drawColor(paint.getColor()); 461 } 462 463 /* (non-Javadoc) 464 * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, float, float, android.graphics.Paint) 465 */ 466 @Override 467 public void drawBitmap(Bitmap bitmap, float left, float top, Paint paint) { 468 drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), 469 (int)left, (int)top, 470 (int)left+bitmap.getWidth(), (int)top+bitmap.getHeight(), paint); 471 } 472 473 /* (non-Javadoc) 474 * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Matrix, android.graphics.Paint) 475 */ 476 @Override 477 public void drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint) { 478 boolean needsRestore = false; 479 if (matrix.isIdentity() == false) { 480 // create a new graphics and apply the matrix to it 481 save(); // this creates a new Graphics2D, and stores it for children call to use 482 needsRestore = true; 483 Graphics2D g = getGraphics2d(); // get the newly create Graphics2D 484 485 // get the Graphics2D current matrix 486 AffineTransform currentTx = g.getTransform(); 487 // get the AffineTransform from the matrix 488 AffineTransform matrixTx = matrix.getTransform(); 489 490 // combine them so that the matrix is applied after. 491 currentTx.preConcatenate(matrixTx); 492 493 // give it to the graphics as a new matrix replacing all previous transform 494 g.setTransform(currentTx); 495 } 496 497 // draw the bitmap 498 drawBitmap(bitmap, 0, 0, paint); 499 500 if (needsRestore) { 501 // remove the new graphics 502 restore(); 503 } 504 } 505 506 /* (non-Javadoc) 507 * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.Rect, android.graphics.Paint) 508 */ 509 @Override 510 public void drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) { 511 if (src == null) { 512 drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), 513 dst.left, dst.top, dst.right, dst.bottom, paint); 514 } else { 515 drawBitmap(bitmap, src.left, src.top, src.width(), src.height(), 516 dst.left, dst.top, dst.right, dst.bottom, paint); 517 } 518 } 519 520 /* (non-Javadoc) 521 * @see android.graphics.Canvas#drawBitmap(android.graphics.Bitmap, android.graphics.Rect, android.graphics.RectF, android.graphics.Paint) 522 */ 523 @Override 524 public void drawBitmap(Bitmap bitmap, Rect src, RectF dst, Paint paint) { 525 if (src == null) { 526 drawBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), 527 (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom, paint); 528 } else { 529 drawBitmap(bitmap, src.left, src.top, src.width(), src.height(), 530 (int)dst.left, (int)dst.top, (int)dst.right, (int)dst.bottom, paint); 531 } 532 } 533 534 /* (non-Javadoc) 535 * @see android.graphics.Canvas#drawBitmap(int[], int, int, int, int, int, int, boolean, android.graphics.Paint) 536 */ 537 @Override 538 public void drawBitmap(int[] colors, int offset, int stride, int x, int y, int width, 539 int height, boolean hasAlpha, Paint paint) { 540 throw new UnsupportedOperationException(); 541 } 542 543 private void drawBitmap(Bitmap bitmap, int sleft, int stop, int sright, int sbottom, int dleft, 544 int dtop, int dright, int dbottom, Paint paint) { 545 BufferedImage image = bitmap.getImage(); 546 547 Graphics2D g = getGraphics2d(); 548 549 Composite c = null; 550 551 if (paint != null) { 552 if (paint.isFilterBitmap()) { 553 g = (Graphics2D)g.create(); 554 g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, 555 RenderingHints.VALUE_INTERPOLATION_BILINEAR); 556 } 557 558 if (paint.getAlpha() != 0xFF) { 559 c = g.getComposite(); 560 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 561 paint.getAlpha()/255.f)); 562 } 563 } 564 565 g.drawImage(image, dleft, dtop, dright, dbottom, 566 sleft, stop, sright, sbottom, null); 567 568 if (paint != null) { 569 if (paint.isFilterBitmap()) { 570 g.dispose(); 571 } 572 if (c != null) { 573 g.setComposite(c); 574 } 575 } 576 } 577 578 /* (non-Javadoc) 579 * @see android.graphics.Canvas#rotate(float, float, float) 580 */ 581 @Override 582 public void rotate(float degrees, float px, float py) { 583 if (degrees != 0) { 584 Graphics2D g = getGraphics2d(); 585 g.translate(px, py); 586 g.rotate(Math.toRadians(degrees)); 587 g.translate(-px, -py); 588 } 589 } 590 591 /* (non-Javadoc) 592 * @see android.graphics.Canvas#rotate(float) 593 */ 594 @Override 595 public void rotate(float degrees) { 596 getGraphics2d().rotate(Math.toRadians(degrees)); 597 } 598 599 /* (non-Javadoc) 600 * @see android.graphics.Canvas#scale(float, float, float, float) 601 */ 602 @Override 603 public void scale(float sx, float sy, float px, float py) { 604 Graphics2D g = getGraphics2d(); 605 g.translate(px, py); 606 g.scale(sx, sy); 607 g.translate(-px, -py); 608 } 609 610 /* (non-Javadoc) 611 * @see android.graphics.Canvas#scale(float, float) 612 */ 613 @Override 614 public void scale(float sx, float sy) { 615 getGraphics2d().scale(sx, sy); 616 } 617 618 /* (non-Javadoc) 619 * @see android.graphics.Canvas#drawText(char[], int, int, float, float, android.graphics.Paint) 620 */ 621 @Override 622 public void drawText(char[] text, int index, int count, float x, float y, Paint paint) { 623 Graphics2D g = getGraphics2d(); 624 625 g = (Graphics2D)g.create(); 626 g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 627 628 g.setFont(paint.getFont()); 629 630 // set the color. because this only handles RGB we have to handle the alpha separately 631 g.setColor(new Color(paint.getColor())); 632 int alpha = paint.getAlpha(); 633 float falpha = alpha / 255.f; 634 g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha)); 635 636 // Paint.TextAlign indicates how the text is positioned relative to X. 637 // LEFT is the default and there's nothing to do. 638 if (paint.getTextAlign() != Align.LEFT) { 639 float m = paint.measureText(text, index, count); 640 if (paint.getTextAlign() == Align.CENTER) { 641 x -= m / 2; 642 } else if (paint.getTextAlign() == Align.RIGHT) { 643 x -= m; 644 } 645 } 646 647 g.drawChars(text, index, count, (int)x, (int)y); 648 649 g.dispose(); 650 } 651 652 /* (non-Javadoc) 653 * @see android.graphics.Canvas#drawText(java.lang.CharSequence, int, int, float, float, android.graphics.Paint) 654 */ 655 @Override 656 public void drawText(CharSequence text, int start, int end, float x, float y, Paint paint) { 657 drawText(text.toString().toCharArray(), start, end - start, x, y, paint); 658 } 659 660 /* (non-Javadoc) 661 * @see android.graphics.Canvas#drawText(java.lang.String, float, float, android.graphics.Paint) 662 */ 663 @Override 664 public void drawText(String text, float x, float y, Paint paint) { 665 drawText(text.toCharArray(), 0, text.length(), x, y, paint); 666 } 667 668 /* (non-Javadoc) 669 * @see android.graphics.Canvas#drawText(java.lang.String, int, int, float, float, android.graphics.Paint) 670 */ 671 @Override 672 public void drawText(String text, int start, int end, float x, float y, Paint paint) { 673 drawText(text.toCharArray(), start, end - start, x, y, paint); 674 } 675 676 /* (non-Javadoc) 677 * @see android.graphics.Canvas#drawRect(android.graphics.RectF, android.graphics.Paint) 678 */ 679 @Override 680 public void drawRect(RectF rect, Paint paint) { 681 doDrawRect((int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(), paint); 682 } 683 684 /* (non-Javadoc) 685 * @see android.graphics.Canvas#drawRect(float, float, float, float, android.graphics.Paint) 686 */ 687 @Override 688 public void drawRect(float left, float top, float right, float bottom, Paint paint) { 689 doDrawRect((int)left, (int)top, (int)(right-left), (int)(bottom-top), paint); 690 } 691 692 /* (non-Javadoc) 693 * @see android.graphics.Canvas#drawRect(android.graphics.Rect, android.graphics.Paint) 694 */ 695 @Override 696 public void drawRect(Rect r, Paint paint) { 697 doDrawRect(r.left, r.top, r.width(), r.height(), paint); 698 } 699 700 private final void doDrawRect(int left, int top, int width, int height, Paint paint) { 701 // get current graphisc 702 Graphics2D g = getGraphics2d(); 703 704 g = getNewGraphics(paint, g); 705 706 Style style = paint.getStyle(); 707 708 // draw 709 if (style == Style.FILL || style == Style.FILL_AND_STROKE) { 710 g.fillRect(left, top, width, height); 711 } 712 713 if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { 714 g.drawRect(left, top, width, height); 715 } 716 717 // dispose Graphics2D object 718 g.dispose(); 719 } 720 721 /* (non-Javadoc) 722 * @see android.graphics.Canvas#drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint) 723 */ 724 @Override 725 public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) { 726 // get current graphisc 727 Graphics2D g = getGraphics2d(); 728 729 g = getNewGraphics(paint, g); 730 731 Style style = paint.getStyle(); 732 733 // draw 734 735 int arcWidth = (int)(rx * 2); 736 int arcHeight = (int)(ry * 2); 737 738 if (style == Style.FILL || style == Style.FILL_AND_STROKE) { 739 g.fillRoundRect((int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(), 740 arcWidth, arcHeight); 741 } 742 743 if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { 744 g.drawRoundRect((int)rect.left, (int)rect.top, (int)rect.width(), (int)rect.height(), 745 arcWidth, arcHeight); 746 } 747 748 // dispose Graphics2D object 749 g.dispose(); 750 } 751 752 753 /* (non-Javadoc) 754 * @see android.graphics.Canvas#drawLine(float, float, float, float, android.graphics.Paint) 755 */ 756 @Override 757 public void drawLine(float startX, float startY, float stopX, float stopY, Paint paint) { 758 // get current graphisc 759 Graphics2D g = getGraphics2d(); 760 761 g = getNewGraphics(paint, g); 762 763 g.drawLine((int)startX, (int)startY, (int)stopX, (int)stopY); 764 765 // dispose Graphics2D object 766 g.dispose(); 767 } 768 769 /* (non-Javadoc) 770 * @see android.graphics.Canvas#drawLines(float[], int, int, android.graphics.Paint) 771 */ 772 @Override 773 public void drawLines(float[] pts, int offset, int count, Paint paint) { 774 // get current graphisc 775 Graphics2D g = getGraphics2d(); 776 777 g = getNewGraphics(paint, g); 778 779 for (int i = 0 ; i < count ; i += 4) { 780 g.drawLine((int)pts[i + offset], (int)pts[i + offset + 1], 781 (int)pts[i + offset + 2], (int)pts[i + offset + 3]); 782 } 783 784 // dispose Graphics2D object 785 g.dispose(); 786 } 787 788 /* (non-Javadoc) 789 * @see android.graphics.Canvas#drawLines(float[], android.graphics.Paint) 790 */ 791 @Override 792 public void drawLines(float[] pts, Paint paint) { 793 drawLines(pts, 0, pts.length, paint); 794 } 795 796 /* (non-Javadoc) 797 * @see android.graphics.Canvas#drawCircle(float, float, float, android.graphics.Paint) 798 */ 799 @Override 800 public void drawCircle(float cx, float cy, float radius, Paint paint) { 801 // get current graphisc 802 Graphics2D g = getGraphics2d(); 803 804 g = getNewGraphics(paint, g); 805 806 Style style = paint.getStyle(); 807 808 int size = (int)(radius * 2); 809 810 // draw 811 if (style == Style.FILL || style == Style.FILL_AND_STROKE) { 812 g.fillOval((int)(cx - radius), (int)(cy - radius), size, size); 813 } 814 815 if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { 816 g.drawOval((int)(cx - radius), (int)(cy - radius), size, size); 817 } 818 819 // dispose Graphics2D object 820 g.dispose(); 821 } 822 823 /* (non-Javadoc) 824 * @see android.graphics.Canvas#drawOval(android.graphics.RectF, android.graphics.Paint) 825 */ 826 @Override 827 public void drawOval(RectF oval, Paint paint) { 828 // get current graphics 829 Graphics2D g = getGraphics2d(); 830 831 g = getNewGraphics(paint, g); 832 833 Style style = paint.getStyle(); 834 835 // draw 836 if (style == Style.FILL || style == Style.FILL_AND_STROKE) { 837 g.fillOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height()); 838 } 839 840 if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { 841 g.drawOval((int)oval.left, (int)oval.top, (int)oval.width(), (int)oval.height()); 842 } 843 844 // dispose Graphics2D object 845 g.dispose(); 846 } 847 848 /* (non-Javadoc) 849 * @see android.graphics.Canvas#drawPath(android.graphics.Path, android.graphics.Paint) 850 */ 851 @Override 852 public void drawPath(Path path, Paint paint) { 853 // get current graphics 854 Graphics2D g = getGraphics2d(); 855 856 g = getNewGraphics(paint, g); 857 858 Style style = paint.getStyle(); 859 860 // draw 861 if (style == Style.FILL || style == Style.FILL_AND_STROKE) { 862 g.fill(path.getAwtShape()); 863 } 864 865 if (style == Style.STROKE || style == Style.FILL_AND_STROKE) { 866 g.draw(path.getAwtShape()); 867 } 868 869 // dispose Graphics2D object 870 g.dispose(); 871 } 872 873 /* (non-Javadoc) 874 * @see android.graphics.Canvas#setMatrix(android.graphics.Matrix) 875 */ 876 @Override 877 public void setMatrix(Matrix matrix) { 878 // since SetMatrix *replaces* all the other transformation, we have to restore/save 879 restore(); 880 save(); 881 882 // get the new current graphics 883 Graphics2D g = getGraphics2d(); 884 885 // and apply the matrix 886 g.setTransform(matrix.getTransform()); 887 888 if (mLogger != null && matrix.hasPerspective()) { 889 mLogger.warning("android.graphics.Canvas#setMatrix(android.graphics.Matrix) only supports affine transformations in the Layout Editor."); 890 } 891 } 892 893 // -------------------- 894 895 /* (non-Javadoc) 896 * @see android.graphics.Canvas#clipPath(android.graphics.Path, android.graphics.Region.Op) 897 */ 898 @Override 899 public boolean clipPath(Path path, Op op) { 900 // TODO Auto-generated method stub 901 return super.clipPath(path, op); 902 } 903 904 /* (non-Javadoc) 905 * @see android.graphics.Canvas#clipPath(android.graphics.Path) 906 */ 907 @Override 908 public boolean clipPath(Path path) { 909 // TODO Auto-generated method stub 910 return super.clipPath(path); 911 } 912 913 914 /* (non-Javadoc) 915 * @see android.graphics.Canvas#clipRegion(android.graphics.Region, android.graphics.Region.Op) 916 */ 917 @Override 918 public boolean clipRegion(Region region, Op op) { 919 // TODO Auto-generated method stub 920 return super.clipRegion(region, op); 921 } 922 923 /* (non-Javadoc) 924 * @see android.graphics.Canvas#clipRegion(android.graphics.Region) 925 */ 926 @Override 927 public boolean clipRegion(Region region) { 928 // TODO Auto-generated method stub 929 return super.clipRegion(region); 930 } 931 932 /* (non-Javadoc) 933 * @see android.graphics.Canvas#concat(android.graphics.Matrix) 934 */ 935 @Override 936 public void concat(Matrix matrix) { 937 // TODO Auto-generated method stub 938 super.concat(matrix); 939 } 940 941 /* (non-Javadoc) 942 * @see android.graphics.Canvas#drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint) 943 */ 944 @Override 945 public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, 946 Paint paint) { 947 // TODO Auto-generated method stub 948 super.drawArc(oval, startAngle, sweepAngle, useCenter, paint); 949 } 950 951 /* (non-Javadoc) 952 * @see android.graphics.Canvas#drawBitmapMesh(android.graphics.Bitmap, int, int, float[], int, int[], int, android.graphics.Paint) 953 */ 954 @Override 955 public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, 956 int vertOffset, int[] colors, int colorOffset, Paint paint) { 957 // TODO Auto-generated method stub 958 super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset, paint); 959 } 960 961 /* (non-Javadoc) 962 * @see android.graphics.Canvas#drawPicture(android.graphics.Picture, android.graphics.Rect) 963 */ 964 @Override 965 public void drawPicture(Picture picture, Rect dst) { 966 // TODO Auto-generated method stub 967 super.drawPicture(picture, dst); 968 } 969 970 /* (non-Javadoc) 971 * @see android.graphics.Canvas#drawPicture(android.graphics.Picture, android.graphics.RectF) 972 */ 973 @Override 974 public void drawPicture(Picture picture, RectF dst) { 975 // TODO Auto-generated method stub 976 super.drawPicture(picture, dst); 977 } 978 979 /* (non-Javadoc) 980 * @see android.graphics.Canvas#drawPicture(android.graphics.Picture) 981 */ 982 @Override 983 public void drawPicture(Picture picture) { 984 // TODO Auto-generated method stub 985 super.drawPicture(picture); 986 } 987 988 /* (non-Javadoc) 989 * @see android.graphics.Canvas#drawPoint(float, float, android.graphics.Paint) 990 */ 991 @Override 992 public void drawPoint(float x, float y, Paint paint) { 993 // TODO Auto-generated method stub 994 super.drawPoint(x, y, paint); 995 } 996 997 /* (non-Javadoc) 998 * @see android.graphics.Canvas#drawPoints(float[], int, int, android.graphics.Paint) 999 */ 1000 @Override 1001 public void drawPoints(float[] pts, int offset, int count, Paint paint) { 1002 // TODO Auto-generated method stub 1003 super.drawPoints(pts, offset, count, paint); 1004 } 1005 1006 /* (non-Javadoc) 1007 * @see android.graphics.Canvas#drawPoints(float[], android.graphics.Paint) 1008 */ 1009 @Override 1010 public void drawPoints(float[] pts, Paint paint) { 1011 // TODO Auto-generated method stub 1012 super.drawPoints(pts, paint); 1013 } 1014 1015 /* (non-Javadoc) 1016 * @see android.graphics.Canvas#drawPosText(char[], int, int, float[], android.graphics.Paint) 1017 */ 1018 @Override 1019 public void drawPosText(char[] text, int index, int count, float[] pos, Paint paint) { 1020 // TODO Auto-generated method stub 1021 super.drawPosText(text, index, count, pos, paint); 1022 } 1023 1024 /* (non-Javadoc) 1025 * @see android.graphics.Canvas#drawPosText(java.lang.String, float[], android.graphics.Paint) 1026 */ 1027 @Override 1028 public void drawPosText(String text, float[] pos, Paint paint) { 1029 // TODO Auto-generated method stub 1030 super.drawPosText(text, pos, paint); 1031 } 1032 1033 /* (non-Javadoc) 1034 * @see android.graphics.Canvas#drawTextOnPath(char[], int, int, android.graphics.Path, float, float, android.graphics.Paint) 1035 */ 1036 @Override 1037 public void drawTextOnPath(char[] text, int index, int count, Path path, float offset, 1038 float offset2, Paint paint) { 1039 // TODO Auto-generated method stub 1040 super.drawTextOnPath(text, index, count, path, offset, offset2, paint); 1041 } 1042 1043 /* (non-Javadoc) 1044 * @see android.graphics.Canvas#drawTextOnPath(java.lang.String, android.graphics.Path, float, float, android.graphics.Paint) 1045 */ 1046 @Override 1047 public void drawTextOnPath(String text, Path path, float offset, float offset2, Paint paint) { 1048 // TODO Auto-generated method stub 1049 super.drawTextOnPath(text, path, offset, offset2, paint); 1050 } 1051 1052 /* (non-Javadoc) 1053 * @see android.graphics.Canvas#drawVertices(android.graphics.Canvas.VertexMode, int, float[], int, float[], int, int[], int, short[], int, int, android.graphics.Paint) 1054 */ 1055 @Override 1056 public void drawVertices(VertexMode mode, int vertexCount, float[] verts, int vertOffset, 1057 float[] texs, int texOffset, int[] colors, int colorOffset, short[] indices, 1058 int indexOffset, int indexCount, Paint paint) { 1059 // TODO Auto-generated method stub 1060 super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset, colors, colorOffset, 1061 indices, indexOffset, indexCount, paint); 1062 } 1063 1064 /* (non-Javadoc) 1065 * @see android.graphics.Canvas#getDrawFilter() 1066 */ 1067 @Override 1068 public DrawFilter getDrawFilter() { 1069 // TODO Auto-generated method stub 1070 return super.getDrawFilter(); 1071 } 1072 1073 /* (non-Javadoc) 1074 * @see android.graphics.Canvas#getGL() 1075 */ 1076 @Override 1077 public GL getGL() { 1078 // TODO Auto-generated method stub 1079 return super.getGL(); 1080 } 1081 1082 /* (non-Javadoc) 1083 * @see android.graphics.Canvas#getMatrix() 1084 */ 1085 @Override 1086 public Matrix getMatrix() { 1087 // TODO Auto-generated method stub 1088 return super.getMatrix(); 1089 } 1090 1091 /* (non-Javadoc) 1092 * @see android.graphics.Canvas#getMatrix(android.graphics.Matrix) 1093 */ 1094 @Override 1095 public void getMatrix(Matrix ctm) { 1096 // TODO Auto-generated method stub 1097 super.getMatrix(ctm); 1098 } 1099 1100 /* (non-Javadoc) 1101 * @see android.graphics.Canvas#isOpaque() 1102 */ 1103 @Override 1104 public boolean isOpaque() { 1105 // TODO Auto-generated method stub 1106 return super.isOpaque(); 1107 } 1108 1109 /* (non-Javadoc) 1110 * @see android.graphics.Canvas#saveLayer(float, float, float, float, android.graphics.Paint, int) 1111 */ 1112 @Override 1113 public int saveLayer(float left, float top, float right, float bottom, Paint paint, 1114 int saveFlags) { 1115 // TODO Auto-generated method stub 1116 return super.saveLayer(left, top, right, bottom, paint, saveFlags); 1117 } 1118 1119 /* (non-Javadoc) 1120 * @see android.graphics.Canvas#saveLayer(android.graphics.RectF, android.graphics.Paint, int) 1121 */ 1122 @Override 1123 public int saveLayer(RectF bounds, Paint paint, int saveFlags) { 1124 // TODO Auto-generated method stub 1125 return super.saveLayer(bounds, paint, saveFlags); 1126 } 1127 1128 /* (non-Javadoc) 1129 * @see android.graphics.Canvas#saveLayerAlpha(float, float, float, float, int, int) 1130 */ 1131 @Override 1132 public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha, 1133 int saveFlags) { 1134 // TODO Auto-generated method stub 1135 return super.saveLayerAlpha(left, top, right, bottom, alpha, saveFlags); 1136 } 1137 1138 /* (non-Javadoc) 1139 * @see android.graphics.Canvas#saveLayerAlpha(android.graphics.RectF, int, int) 1140 */ 1141 @Override 1142 public int saveLayerAlpha(RectF bounds, int alpha, int saveFlags) { 1143 // TODO Auto-generated method stub 1144 return super.saveLayerAlpha(bounds, alpha, saveFlags); 1145 } 1146 1147 /* (non-Javadoc) 1148 * @see android.graphics.Canvas#setDrawFilter(android.graphics.DrawFilter) 1149 */ 1150 @Override 1151 public void setDrawFilter(DrawFilter filter) { 1152 // TODO Auto-generated method stub 1153 super.setDrawFilter(filter); 1154 } 1155 1156 /* (non-Javadoc) 1157 * @see android.graphics.Canvas#setViewport(int, int) 1158 */ 1159 @Override 1160 public void setViewport(int width, int height) { 1161 // TODO Auto-generated method stub 1162 super.setViewport(width, height); 1163 } 1164 1165 /* (non-Javadoc) 1166 * @see android.graphics.Canvas#skew(float, float) 1167 */ 1168 @Override 1169 public void skew(float sx, float sy) { 1170 // TODO Auto-generated method stub 1171 super.skew(sx, sy); 1172 } 1173 1174 1175 1176} 1177