1 /* ComponentGraphics.java -- 2 Copyright (C) 2006 Free Software Foundation, Inc. 3 4 This file is part of GNU Classpath. 5 6 GNU Classpath is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2, or (at your option) 9 any later version. 10 11 GNU Classpath is distributed in the hope that it will be useful, but 12 WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GNU Classpath; see the file COPYING. If not, write to the 18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 02110-1301 USA. 20 21 Linking this library statically or dynamically with other modules is 22 making a combined work based on this library. Thus, the terms and 23 conditions of the GNU General Public License cover the whole 24 combination. 25 26 As a special exception, the copyright holders of this library give you 27 permission to link this library with independent modules to produce an 28 executable, regardless of the license terms of these independent 29 modules, and to copy and distribute the resulting executable under 30 terms of your choice, provided that you also meet, for each linked 31 independent module, the terms and conditions of the license of that 32 module. An independent module is a module which is not derived from 33 or based on this library. If you modify this library, you may extend 34 this exception to your version of the library, but you are not 35 obligated to do so. If you do not wish to do so, delete this 36 exception statement from your version. */ 37 38 39 package gnu.java.awt.peer.gtk; 40 41 import gnu.classpath.Pointer; 42 43 import java.awt.AlphaComposite; 44 import java.awt.Color; 45 import java.awt.Graphics; 46 import java.awt.Graphics2D; 47 import java.awt.GraphicsConfiguration; 48 import java.awt.Image; 49 import java.awt.Point; 50 import java.awt.Rectangle; 51 import java.awt.Shape; 52 import java.awt.Toolkit; 53 import java.awt.font.GlyphVector; 54 import java.awt.geom.AffineTransform; 55 import java.awt.geom.Point2D; 56 import java.awt.geom.Rectangle2D; 57 import java.awt.image.BufferedImage; 58 import java.awt.image.ColorModel; 59 import java.awt.image.ImageObserver; 60 import java.awt.image.ImageProducer; 61 import java.awt.image.Raster; 62 import java.awt.image.RenderedImage; 63 import java.awt.image.WritableRaster; 64 import java.util.Hashtable; 65 66 /** 67 * ComponentGraphics - context for drawing directly to a component, 68 * as this is an X drawable, it requires that we use GTK locks. 69 * 70 * This context draws directly to the drawable and requires xrender. 71 */ 72 public class ComponentGraphics extends CairoGraphics2D 73 { 74 private static final boolean hasXRenderExtension = hasXRender(); 75 76 private GtkComponentPeer component; 77 protected long cairo_t; 78 private BufferedImage buffer, componentBuffer; 79 80 private static ThreadLocal<Integer> hasLock = new ThreadLocal<Integer>(); 81 private static Integer ONE = Integer.valueOf(1); 82 ComponentGraphics()83 ComponentGraphics() 84 { 85 } 86 ComponentGraphics(GtkComponentPeer component)87 private ComponentGraphics(GtkComponentPeer component) 88 { 89 this.component = component; 90 cairo_t = initState(component); 91 setup( cairo_t ); 92 Rectangle bounds = component.awtComponent.getBounds(); 93 setClip( new Rectangle( 0, 0, bounds.width, bounds.height) ); 94 setBackground(component.awtComponent.getBackground()); 95 setColor(component.awtComponent.getForeground()); 96 } 97 ComponentGraphics(ComponentGraphics cg)98 private ComponentGraphics(ComponentGraphics cg) 99 { 100 component = cg.component; 101 cairo_t = initState(component); 102 copy( cg, cairo_t ); 103 Rectangle bounds = component.awtComponent.getBounds(); 104 setClip( new Rectangle( 0, 0, bounds.width, bounds.height) ); 105 setBackground(component.awtComponent.getBackground()); 106 setColor(component.awtComponent.getForeground()); 107 } 108 109 /** 110 * Creates a cairo_t for the component surface and return it. 111 */ initState(GtkComponentPeer component)112 private native long initState(GtkComponentPeer component); 113 114 /** 115 * Obtain and hold a GDK lock, which is required for all drawing operations 116 * in this graphics context (since it is backed by an X surface). 117 * 118 * This method causes the GDK locking behaviour to be re-entrant. No race 119 * conditions are caused since a ThreadLocal is used and each thread has its 120 * own lock counter. 121 */ lock()122 private void lock() 123 { 124 Integer i = hasLock.get(); 125 if (i == null) 126 { 127 start_gdk_drawing(); 128 hasLock.set(ONE); 129 } 130 else 131 hasLock.set(Integer.valueOf(i.intValue() + 1)); 132 } 133 134 /** 135 * Release the re-entrant GDK lock. 136 */ unlock()137 private void unlock() 138 { 139 Integer i = hasLock.get(); 140 if (i == null) 141 throw new IllegalStateException(); 142 if (i == ONE) 143 { 144 hasLock.set(null); 145 end_gdk_drawing(); 146 } 147 else if (i.intValue() == 2) 148 hasLock.set(ONE); 149 else 150 hasLock.set(Integer.valueOf(i.intValue() - 1)); 151 } 152 153 /** 154 * Creates a cairo_t for a volatile image 155 */ initFromVolatile( long pixmapPtr)156 protected native long initFromVolatile( long pixmapPtr); 157 158 /** 159 * Grab lock 160 */ start_gdk_drawing()161 private native void start_gdk_drawing(); 162 163 /** 164 * Release lock 165 */ end_gdk_drawing()166 private native void end_gdk_drawing(); 167 168 /** 169 * Query if the system has the XRender extension. 170 */ hasXRender()171 public static native boolean hasXRender(); 172 173 /** 174 * This is a utility method (used by GtkComponentPeer) for grabbing the 175 * image of a component. 176 */ nativeGrab(GtkComponentPeer component)177 private static native Pointer nativeGrab(GtkComponentPeer component); 178 copyAreaNative(GtkComponentPeer component, int x, int y, int width, int height, int dx, int dy)179 private native void copyAreaNative(GtkComponentPeer component, int x, int y, 180 int width, int height, int dx, int dy); 181 drawVolatile(GtkComponentPeer component, long vimg, int x, int y, int width, int height, int cx, int cy, int cw, int ch)182 private native void drawVolatile(GtkComponentPeer component, 183 long vimg, int x, int y, 184 int width, int height, int cx, int cy, 185 int cw, int ch); 186 187 /** 188 * Not really related (moveme?). Utility method used by GtkComponent. 189 */ grab( GtkComponentPeer component )190 public static GtkImage grab( GtkComponentPeer component ) 191 { 192 return new GtkImage( nativeGrab( component ) ); 193 } 194 195 /** 196 * Returns a Graphics2D object for a component, either an instance of this 197 * class (if xrender is supported), or a context which copies. 198 */ getComponentGraphics(GtkComponentPeer component)199 public static Graphics2D getComponentGraphics(GtkComponentPeer component) 200 { 201 if( hasXRenderExtension ) 202 return new ComponentGraphics(component); 203 204 Rectangle r = component.awtComponent.getBounds(); 205 return new ComponentGraphicsCopy(r.width, r.height, component); 206 } 207 getDeviceConfiguration()208 public GraphicsConfiguration getDeviceConfiguration() 209 { 210 return component.getGraphicsConfiguration(); 211 } 212 create()213 public Graphics create() 214 { 215 return new ComponentGraphics(this); 216 } 217 getRealBounds()218 protected Rectangle2D getRealBounds() 219 { 220 return component.awtComponent.getBounds(); 221 } 222 copyAreaImpl(int x, int y, int width, int height, int dx, int dy)223 public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy) 224 { 225 copyAreaNative(component, x, y, width, height, dx, dy); 226 } 227 228 /** 229 * Overloaded methods that do actual drawing need to enter the gdk threads 230 * and also do certain things before and after. 231 */ draw(Shape s)232 public void draw(Shape s) 233 { 234 if (comp == null || comp instanceof AlphaComposite) 235 super.draw(s); 236 237 else 238 { 239 createBuffer(); 240 241 Graphics2D g2d = (Graphics2D)buffer.getGraphics(); 242 g2d.setStroke(this.getStroke()); 243 g2d.setColor(this.getColor()); 244 g2d.draw(s); 245 246 drawComposite(s.getBounds2D(), null); 247 } 248 } 249 fill(Shape s)250 public void fill(Shape s) 251 { 252 if (comp == null || comp instanceof AlphaComposite) 253 super.fill(s); 254 255 else 256 { 257 createBuffer(); 258 259 Graphics2D g2d = (Graphics2D)buffer.getGraphics(); 260 g2d.setPaint(this.getPaint()); 261 g2d.setColor(this.getColor()); 262 g2d.fill(s); 263 264 drawComposite(s.getBounds2D(), null); 265 } 266 } 267 drawRenderedImage(RenderedImage image, AffineTransform xform)268 public void drawRenderedImage(RenderedImage image, AffineTransform xform) 269 { 270 if (comp == null || comp instanceof AlphaComposite) 271 super.drawRenderedImage(image, xform); 272 273 else 274 { 275 createBuffer(); 276 277 Graphics2D g2d = (Graphics2D)buffer.getGraphics(); 278 g2d.setRenderingHints(this.getRenderingHints()); 279 g2d.drawRenderedImage(image, xform); 280 281 drawComposite(buffer.getRaster().getBounds(), null); 282 } 283 } 284 drawImage(Image img, AffineTransform xform, Color bgcolor, ImageObserver obs)285 protected boolean drawImage(Image img, AffineTransform xform, 286 Color bgcolor, ImageObserver obs) 287 { 288 boolean rv; 289 if (comp == null || comp instanceof AlphaComposite) 290 rv = super.drawImage(img, xform, bgcolor, obs); 291 292 else 293 { 294 // Get buffered image of source 295 if( !(img instanceof BufferedImage) ) 296 { 297 ImageProducer source = img.getSource(); 298 if (source == null) 299 return false; 300 img = Toolkit.getDefaultToolkit().createImage(source); 301 } 302 BufferedImage bImg = (BufferedImage) img; 303 304 // Find translated bounds 305 Point2D origin = new Point2D.Double(bImg.getMinX(), bImg.getMinY()); 306 Point2D pt = new Point2D.Double(bImg.getWidth() + bImg.getMinX(), 307 bImg.getHeight() + bImg.getMinY()); 308 if (xform != null) 309 { 310 origin = xform.transform(origin, origin); 311 pt = xform.transform(pt, pt); 312 } 313 314 // Create buffer and draw image 315 createBuffer(); 316 317 Graphics2D g2d = (Graphics2D)buffer.getGraphics(); 318 g2d.setRenderingHints(this.getRenderingHints()); 319 g2d.drawImage(img, xform, obs); 320 321 // Perform compositing 322 rv = drawComposite(new Rectangle2D.Double(origin.getX(), 323 origin.getY(), 324 pt.getX(), pt.getY()), 325 obs); 326 } 327 return rv; 328 } 329 drawGlyphVector(GlyphVector gv, float x, float y)330 public void drawGlyphVector(GlyphVector gv, float x, float y) 331 { 332 if (comp == null || comp instanceof AlphaComposite) 333 super.drawGlyphVector(gv, x, y); 334 335 else 336 { 337 createBuffer(); 338 339 Graphics2D g2d = (Graphics2D)buffer.getGraphics(); 340 g2d.setPaint(this.getPaint()); 341 g2d.setStroke(this.getStroke()); 342 g2d.drawGlyphVector(gv, x, y); 343 344 Rectangle2D bounds = gv.getLogicalBounds(); 345 bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(), 346 bounds.getWidth(), bounds.getHeight()); 347 drawComposite(bounds, null); 348 } 349 } 350 drawImage(Image img, int x, int y, ImageObserver observer)351 public boolean drawImage(Image img, int x, int y, ImageObserver observer) 352 { 353 // If it is a GtkVolatileImage with an "easy" transform then 354 // draw directly. Always pass a BufferedImage to super to avoid 355 // deadlock (see Note in CairoGraphics.drawImage()). 356 if (img instanceof GtkVolatileImage) 357 { 358 GtkVolatileImage vimg = (GtkVolatileImage) img; 359 int type = transform.getType(); 360 if ((type == AffineTransform.TYPE_IDENTITY 361 || type == AffineTransform.TYPE_TRANSLATION) 362 && (clip == null || clip instanceof Rectangle2D)) 363 { 364 Rectangle2D r = (Rectangle2D) clip; 365 if (r == null) 366 r = getRealBounds(); 367 x += transform.getTranslateX(); 368 y += transform.getTranslateY(); 369 drawVolatile(component, vimg.nativePointer, 370 x, y, vimg.width, vimg.height, 371 (int) (r.getX() + transform.getTranslateX()), 372 (int) (r.getY() + transform.getTranslateY()), 373 (int) r.getWidth(), 374 (int) r.getHeight()); 375 return true; 376 } 377 else 378 return super.drawImage(vimg.getSnapshot(), x, y, observer); 379 } 380 381 BufferedImage bimg; 382 if (img instanceof BufferedImage) 383 bimg = (BufferedImage) img; 384 else 385 { 386 ImageProducer source = img.getSource(); 387 if (source == null) 388 return false; 389 bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source); 390 } 391 return super.drawImage(bimg, x, y, observer); 392 } 393 drawImage(Image img, int x, int y, int width, int height, ImageObserver observer)394 public boolean drawImage(Image img, int x, int y, int width, int height, 395 ImageObserver observer) 396 { 397 // If it is a GtkVolatileImage with an "easy" transform then 398 // draw directly. Always pass a BufferedImage to super to avoid 399 // deadlock (see Note in CairoGraphics.drawImage()). 400 if (img instanceof GtkVolatileImage 401 && (clip == null || clip instanceof Rectangle2D)) 402 { 403 GtkVolatileImage vimg = (GtkVolatileImage) img; 404 int type = transform.getType(); 405 if ((type == AffineTransform.TYPE_IDENTITY 406 || type == AffineTransform.TYPE_TRANSLATION) 407 && (clip == null || clip instanceof Rectangle2D)) 408 { 409 Rectangle2D r = (Rectangle2D) clip; 410 if (r == null) 411 r = getRealBounds(); 412 x += transform.getTranslateX(); 413 y += transform.getTranslateY(); 414 drawVolatile(component, vimg.nativePointer, 415 x, y, width, height, 416 (int) (r.getX() + transform.getTranslateX()), 417 (int) (r.getY() + transform.getTranslateY()), 418 (int) r.getWidth(), 419 (int) r.getHeight()); 420 return true; 421 } 422 else 423 return super.drawImage(vimg.getSnapshot(), x, y, 424 width, height, observer); 425 } 426 427 BufferedImage bimg; 428 img = AsyncImage.realImage(img, observer); 429 if (img instanceof BufferedImage) 430 bimg = (BufferedImage) img; 431 else 432 { 433 ImageProducer source = img.getSource(); 434 if (source == null) 435 return false; 436 bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source); 437 } 438 return super.drawImage(bimg, x, y, width, height, observer); 439 } 440 drawComposite(Rectangle2D bounds, ImageObserver observer)441 private boolean drawComposite(Rectangle2D bounds, ImageObserver observer) 442 { 443 // Clip source to visible areas that need updating 444 Rectangle2D clip = this.getClipBounds(); 445 Rectangle2D.intersect(bounds, clip, bounds); 446 clip = new Rectangle(buffer.getMinX(), buffer.getMinY(), 447 buffer.getWidth(), buffer.getHeight()); 448 Rectangle2D.intersect(bounds, clip, bounds); 449 450 BufferedImage buffer2 = buffer; 451 if (!bounds.equals(buffer2.getRaster().getBounds())) 452 buffer2 = buffer2.getSubimage((int)bounds.getX(), (int)bounds.getY(), 453 (int)bounds.getWidth(), 454 (int)bounds.getHeight()); 455 456 // Get destination clip to bounds 457 double[] points = new double[] {bounds.getX(), bounds.getY(), 458 bounds.getMaxX(), bounds.getMaxY()}; 459 transform.transform(points, 0, points, 0, 2); 460 461 Rectangle2D deviceBounds = new Rectangle2D.Double(points[0], points[1], 462 points[2] - points[0], 463 points[3] - points[1]); 464 465 Rectangle2D.intersect(deviceBounds, this.getClipInDevSpace(), deviceBounds); 466 467 // Get current image on the component 468 GtkImage img = grab(component); 469 Graphics gr = componentBuffer.createGraphics(); 470 gr.drawImage(img, 0, 0, null); 471 gr.dispose(); 472 473 BufferedImage cBuffer = componentBuffer; 474 if (!deviceBounds.equals(cBuffer.getRaster().getBounds())) 475 cBuffer = cBuffer.getSubimage((int)deviceBounds.getX(), 476 (int)deviceBounds.getY(), 477 (int)deviceBounds.getWidth(), 478 (int)deviceBounds.getHeight()); 479 480 // Perform actual composite operation 481 compCtx.compose(buffer2.getRaster(), cBuffer.getRaster(), 482 cBuffer.getRaster()); 483 484 // This MUST call directly into the "action" method in CairoGraphics2D, 485 // not one of the wrappers, to ensure that the composite isn't processed 486 // more than once! 487 boolean rv = super.drawImage(cBuffer, 488 AffineTransform.getTranslateInstance(bounds.getX(), 489 bounds.getY()), 490 null, null); 491 return rv; 492 } 493 createBuffer()494 private void createBuffer() 495 { 496 if (buffer == null) 497 { 498 WritableRaster rst; 499 rst = Raster.createWritableRaster(GtkVolatileImage.createGdkSampleModel(component.awtComponent.getWidth(), 500 component.awtComponent.getHeight()), 501 new Point(0,0)); 502 503 buffer = new BufferedImage(GtkVolatileImage.gdkColorModel, rst, 504 GtkVolatileImage.gdkColorModel.isAlphaPremultiplied(), 505 new Hashtable()); 506 } 507 else 508 { 509 Graphics2D g2d = ((Graphics2D)buffer.getGraphics()); 510 511 g2d.setBackground(new Color(0,0,0,0)); 512 g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight()); 513 } 514 515 if (componentBuffer == null) 516 { 517 WritableRaster rst; 518 rst = Raster.createWritableRaster(GtkVolatileImage.createGdkSampleModel(component.awtComponent.getWidth(), 519 component.awtComponent.getHeight()), 520 new Point(0,0)); 521 522 componentBuffer = new BufferedImage(GtkVolatileImage.gdkColorModel, rst, 523 GtkVolatileImage.gdkColorModel.isAlphaPremultiplied(), 524 new Hashtable()); 525 } 526 } 527 getNativeCM()528 protected ColorModel getNativeCM() 529 { 530 return GtkVolatileImage.gdkColorModel; 531 } 532 533 /* --- START OVERRIDDEN NATIVE METHODS ---- 534 * All native methods in CairoGraphics2D should be overridden here and 535 * enclosed in locks, since the cairo surface is backed by an X surface 536 * in this graphics context and the X surface requires external locking. 537 * 538 * We lock everything "just in case", since it's difficult to know which 539 * calls are and aren't thread-safe. Overriding and locking the native 540 * methods allows superclass code in CairoGraphics2D to execute properly, 541 * without the need to override every single method. 542 * 543 * CAVEAT: if native code obtains a lock (using gdk_threads_enter(), not the 544 * lock() method provided here) and then calls back into Java and one of these 545 * methods ends up being called, we will deadlock. The lock is only reentrant 546 * when called via our lock() method. 547 */ 548 549 /* These methods are already locked in the superclass CairoGraphics2D 550 * so they do not need to be overridden: 551 * 552 * public void disposeNative 553 * 554 * protected void cairoDrawGlyphVector 555 * 556 * protected void cairoSetFont 557 */ 558 559 @Override init(long pointer)560 protected long init(long pointer) 561 { 562 long ret; 563 564 try 565 { 566 lock(); 567 ret = super.init(pointer); 568 } 569 finally 570 { 571 unlock(); 572 } 573 574 return ret; 575 } 576 577 @Override drawPixels(long pointer, int[] pixels, int w, int h, int stride, double[] i2u, double alpha, int interpolation)578 protected void drawPixels(long pointer, int[] pixels, int w, int h, 579 int stride, double[] i2u, double alpha, 580 int interpolation) 581 { 582 try 583 { 584 lock(); 585 super.drawPixels(pointer, pixels, w, h, stride, i2u, alpha, 586 interpolation); 587 } 588 finally 589 { 590 unlock(); 591 } 592 } 593 594 @Override setGradient(long pointer, double x1, double y1, double x2, double y2, int r1, int g1, int b1, int a1, int r2, int g2, int b2, int a2, boolean cyclic)595 protected void setGradient(long pointer, double x1, double y1, 596 double x2, double y2, 597 int r1, int g1, int b1, int a1, 598 int r2, int g2, int b2, int a2, boolean cyclic) 599 { 600 try 601 { 602 lock(); 603 super.setGradient(pointer, x1, y1, x2, y2, r1, g1, b1, a1, r2, g2, b2, a2, 604 cyclic); 605 } 606 finally 607 { 608 unlock(); 609 } 610 } 611 612 @Override setPaintPixels(long pointer, int[] pixels, int w, int h, int stride, boolean repeat, int x, int y)613 protected void setPaintPixels(long pointer, int[] pixels, int w, int h, 614 int stride, boolean repeat, int x, int y) 615 { 616 try 617 { 618 lock(); 619 super.setPaintPixels(pointer, pixels, w, h, stride, repeat, x, y); 620 } 621 finally 622 { 623 unlock(); 624 } 625 } 626 627 @Override cairoSetMatrix(long pointer, double[] m)628 protected void cairoSetMatrix(long pointer, double[] m) 629 { 630 try 631 { 632 lock(); 633 super.cairoSetMatrix(pointer, m); 634 } 635 finally 636 { 637 unlock(); 638 } 639 } 640 641 @Override cairoScale(long pointer, double x, double y)642 protected void cairoScale(long pointer, double x, double y) 643 { 644 try 645 { 646 lock(); 647 super.cairoScale(pointer, x, y); 648 } 649 finally 650 { 651 unlock(); 652 } 653 } 654 655 @Override cairoSetOperator(long pointer, int cairoOperator)656 protected void cairoSetOperator(long pointer, int cairoOperator) 657 { 658 try 659 { 660 lock(); 661 super.cairoSetOperator(pointer, cairoOperator); 662 } 663 finally 664 { 665 unlock(); 666 } 667 } 668 669 @Override cairoSetRGBAColor(long pointer, double red, double green, double blue, double alpha)670 protected void cairoSetRGBAColor(long pointer, double red, double green, 671 double blue, double alpha) 672 { 673 try 674 { 675 lock(); 676 super.cairoSetRGBAColor(pointer, red, green, blue, alpha); 677 } 678 finally 679 { 680 unlock(); 681 } 682 } 683 684 @Override cairoSetFillRule(long pointer, int cairoFillRule)685 protected void cairoSetFillRule(long pointer, int cairoFillRule) 686 { 687 try 688 { 689 lock(); 690 super.cairoSetFillRule(pointer, cairoFillRule); 691 } 692 finally 693 { 694 unlock(); 695 } 696 } 697 698 @Override cairoSetLine(long pointer, double width, int cap, int join, double miterLimit)699 protected void cairoSetLine(long pointer, double width, int cap, int join, 700 double miterLimit) 701 { 702 try 703 { 704 lock(); 705 super.cairoSetLine(pointer, width, cap, join, miterLimit); 706 } 707 finally 708 { 709 unlock(); 710 } 711 } 712 713 @Override cairoSetDash(long pointer, double[] dashes, int ndash, double offset)714 protected void cairoSetDash(long pointer, double[] dashes, int ndash, 715 double offset) 716 { 717 try 718 { 719 lock(); 720 super.cairoSetDash(pointer, dashes, ndash, offset); 721 } 722 finally 723 { 724 unlock(); 725 } 726 } 727 728 @Override cairoRectangle(long pointer, double x, double y, double width, double height)729 protected void cairoRectangle(long pointer, double x, double y, 730 double width, double height) 731 { 732 try 733 { 734 lock(); 735 super.cairoRectangle(pointer, x, y, width, height); 736 } 737 finally 738 { 739 unlock(); 740 } 741 } 742 743 @Override cairoArc(long pointer, double x, double y, double radius, double angle1, double angle2)744 protected void cairoArc(long pointer, double x, double y, 745 double radius, double angle1, double angle2) 746 { 747 try 748 { 749 lock(); 750 super.cairoArc(pointer, x, y, radius, angle1, angle2); 751 } 752 finally 753 { 754 unlock(); 755 } 756 } 757 758 @Override cairoSave(long pointer)759 protected void cairoSave(long pointer) 760 { 761 try 762 { 763 lock(); 764 super.cairoSave(pointer); 765 } 766 finally 767 { 768 unlock(); 769 } 770 } 771 772 @Override cairoRestore(long pointer)773 protected void cairoRestore(long pointer) 774 { 775 try 776 { 777 lock(); 778 super.cairoRestore(pointer); 779 } 780 finally 781 { 782 unlock(); 783 } 784 } 785 786 @Override cairoNewPath(long pointer)787 protected void cairoNewPath(long pointer) 788 { 789 try 790 { 791 lock(); 792 super.cairoNewPath(pointer); 793 } 794 finally 795 { 796 unlock(); 797 } 798 } 799 800 @Override cairoClosePath(long pointer)801 protected void cairoClosePath(long pointer) 802 { 803 try 804 { 805 lock(); 806 super.cairoClosePath(pointer); 807 } 808 finally 809 { 810 unlock(); 811 } 812 } 813 814 @Override cairoMoveTo(long pointer, double x, double y)815 protected void cairoMoveTo(long pointer, double x, double y) 816 { 817 try 818 { 819 lock(); 820 super.cairoMoveTo(pointer, x, y); 821 } 822 finally 823 { 824 unlock(); 825 } 826 } 827 828 @Override cairoLineTo(long pointer, double x, double y)829 protected void cairoLineTo(long pointer, double x, double y) 830 { 831 try 832 { 833 lock(); 834 super.cairoLineTo(pointer, x, y); 835 } 836 finally 837 { 838 unlock(); 839 } 840 } 841 842 @Override cairoCurveTo(long pointer, double x1, double y1, double x2, double y2, double x3, double y3)843 protected void cairoCurveTo(long pointer, double x1, double y1, double x2, 844 double y2, double x3, double y3) 845 { 846 try 847 { 848 lock(); 849 super.cairoCurveTo(pointer, x1, y1, x2, y2, x3, y3); 850 } 851 finally 852 { 853 unlock(); 854 } 855 } 856 857 @Override cairoStroke(long pointer)858 protected void cairoStroke(long pointer) 859 { 860 try 861 { 862 lock(); 863 super.cairoStroke(pointer); 864 } 865 finally 866 { 867 unlock(); 868 } 869 } 870 871 @Override cairoFill(long pointer, double alpha)872 protected void cairoFill(long pointer, double alpha) 873 { 874 try 875 { 876 lock(); 877 super.cairoFill(pointer, alpha); 878 } 879 finally 880 { 881 unlock(); 882 } 883 } 884 885 @Override cairoClip(long pointer)886 protected void cairoClip(long pointer) 887 { 888 try 889 { 890 lock(); 891 super.cairoClip(pointer); 892 } 893 finally 894 { 895 unlock(); 896 } 897 } 898 899 @Override cairoResetClip(long pointer)900 protected void cairoResetClip(long pointer) 901 { 902 try 903 { 904 lock(); 905 super.cairoResetClip(pointer); 906 } 907 finally 908 { 909 unlock(); 910 } 911 } 912 913 @Override cairoSetAntialias(long pointer, boolean aa)914 protected void cairoSetAntialias(long pointer, boolean aa) 915 { 916 try 917 { 918 lock(); 919 super.cairoSetAntialias(pointer, aa); 920 } 921 finally 922 { 923 unlock(); 924 } 925 } 926 927 @Override drawCairoSurface(CairoSurface surface, AffineTransform tx, double alpha, int interpolation)928 protected void drawCairoSurface(CairoSurface surface, AffineTransform tx, 929 double alpha, int interpolation) 930 { 931 try 932 { 933 lock(); 934 super.drawCairoSurface(surface, tx, alpha, interpolation); 935 } 936 finally 937 { 938 unlock(); 939 } 940 } 941 } 942