Path.java revision 8018c8db8221aa604b3c083e09d173cc27e53d83
1/* 2 * Copyright (C) 2006 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 android.view.HardwareRenderer; 20 21/** 22 * The Path class encapsulates compound (multiple contour) geometric paths 23 * consisting of straight line segments, quadratic curves, and cubic curves. 24 * It can be drawn with canvas.drawPath(path, paint), either filled or stroked 25 * (based on the paint's Style), or it can be used for clipping or to draw 26 * text on a path. 27 */ 28public class Path { 29 /** 30 * @hide 31 */ 32 public final int mNativePath; 33 34 /** 35 * @hide 36 */ 37 public boolean isSimplePath = true; 38 /** 39 * @hide 40 */ 41 public Region rects; 42 private boolean mDetectSimplePaths; 43 private Direction mLastDirection = null; 44 45 /** 46 * Create an empty path 47 */ 48 public Path() { 49 mNativePath = init1(); 50 mDetectSimplePaths = HardwareRenderer.isAvailable(); 51 } 52 53 /** 54 * Create a new path, copying the contents from the src path. 55 * 56 * @param src The path to copy from when initializing the new path 57 */ 58 public Path(Path src) { 59 int valNative = 0; 60 if (src != null) { 61 valNative = src.mNativePath; 62 isSimplePath = src.isSimplePath; 63 if (src.rects != null) { 64 rects = new Region(src.rects); 65 } 66 } 67 mNativePath = init2(valNative); 68 mDetectSimplePaths = HardwareRenderer.isAvailable(); 69 } 70 71 /** 72 * Clear any lines and curves from the path, making it empty. 73 * This does NOT change the fill-type setting. 74 */ 75 public void reset() { 76 isSimplePath = true; 77 if (mDetectSimplePaths) { 78 mLastDirection = null; 79 if (rects != null) rects.setEmpty(); 80 } 81 native_reset(mNativePath); 82 } 83 84 /** 85 * Rewinds the path: clears any lines and curves from the path but 86 * keeps the internal data structure for faster reuse. 87 */ 88 public void rewind() { 89 isSimplePath = true; 90 if (mDetectSimplePaths) { 91 mLastDirection = null; 92 if (rects != null) rects.setEmpty(); 93 } 94 native_rewind(mNativePath); 95 } 96 97 /** Replace the contents of this with the contents of src. 98 */ 99 public void set(Path src) { 100 if (this != src) { 101 isSimplePath = src.isSimplePath; 102 native_set(mNativePath, src.mNativePath); 103 } 104 } 105 106 /** 107 * The logical operations that can be performed when combining two paths. 108 * 109 * @see #op(Path, android.graphics.Path.Op) 110 * @see #op(Path, Path, android.graphics.Path.Op) 111 */ 112 public enum Op { 113 /** 114 * Subtract the second path from the first path. 115 */ 116 DIFFERENCE, 117 /** 118 * Intersect the two paths. 119 */ 120 INTERSECT, 121 /** 122 * Union (inclusive-or) the two paths. 123 */ 124 UNION, 125 /** 126 * Exclusive-or the two paths. 127 */ 128 XOR, 129 /** 130 * Subtract the first path from the second path. 131 */ 132 REVERSE_DIFFERENCE 133 } 134 135 /** 136 * Set this path to the result of applying the Op to this path and the specified path. 137 * The resulting path will be constructed from non-overlapping contours. 138 * The curve order is reduced where possible so that cubics may be turned 139 * into quadratics, and quadratics maybe turned into lines. 140 * 141 * @param path The second operand (for difference, the subtrahend) 142 * 143 * @return True if operation succeeded, false otherwise and this path remains unmodified. 144 * 145 * @see Op 146 * @see #op(Path, Path, android.graphics.Path.Op) 147 */ 148 public boolean op(Path path, Op op) { 149 return op(this, path, op); 150 } 151 152 /** 153 * Set this path to the result of applying the Op to the two specified paths. 154 * The resulting path will be constructed from non-overlapping contours. 155 * The curve order is reduced where possible so that cubics may be turned 156 * into quadratics, and quadratics maybe turned into lines. 157 * 158 * @param path1 The first operand (for difference, the minuend) 159 * @param path2 The second operand (for difference, the subtrahend) 160 * 161 * @return True if operation succeeded, false otherwise and this path remains unmodified. 162 * 163 * @see Op 164 * @see #op(Path, android.graphics.Path.Op) 165 */ 166 public boolean op(Path path1, Path path2, Op op) { 167 if (native_op(path1.mNativePath, path2.mNativePath, op.ordinal(), this.mNativePath)) { 168 isSimplePath = false; 169 rects = null; 170 return true; 171 } 172 return false; 173 } 174 175 /** 176 * Enum for the ways a path may be filled. 177 */ 178 public enum FillType { 179 // these must match the values in SkPath.h 180 /** 181 * Specifies that "inside" is computed by a non-zero sum of signed 182 * edge crossings. 183 */ 184 WINDING (0), 185 /** 186 * Specifies that "inside" is computed by an odd number of edge 187 * crossings. 188 */ 189 EVEN_ODD (1), 190 /** 191 * Same as {@link #WINDING}, but draws outside of the path, rather than inside. 192 */ 193 INVERSE_WINDING (2), 194 /** 195 * Same as {@link #EVEN_ODD}, but draws outside of the path, rather than inside. 196 */ 197 INVERSE_EVEN_ODD(3); 198 199 FillType(int ni) { 200 nativeInt = ni; 201 } 202 203 final int nativeInt; 204 } 205 206 // these must be in the same order as their native values 207 static final FillType[] sFillTypeArray = { 208 FillType.WINDING, 209 FillType.EVEN_ODD, 210 FillType.INVERSE_WINDING, 211 FillType.INVERSE_EVEN_ODD 212 }; 213 214 /** 215 * Return the path's fill type. This defines how "inside" is 216 * computed. The default value is WINDING. 217 * 218 * @return the path's fill type 219 */ 220 public FillType getFillType() { 221 return sFillTypeArray[native_getFillType(mNativePath)]; 222 } 223 224 /** 225 * Set the path's fill type. This defines how "inside" is computed. 226 * 227 * @param ft The new fill type for this path 228 */ 229 public void setFillType(FillType ft) { 230 native_setFillType(mNativePath, ft.nativeInt); 231 } 232 233 /** 234 * Returns true if the filltype is one of the INVERSE variants 235 * 236 * @return true if the filltype is one of the INVERSE variants 237 */ 238 public boolean isInverseFillType() { 239 final int ft = native_getFillType(mNativePath); 240 return (ft & 2) != 0; 241 } 242 243 /** 244 * Toggles the INVERSE state of the filltype 245 */ 246 public void toggleInverseFillType() { 247 int ft = native_getFillType(mNativePath); 248 ft ^= 2; 249 native_setFillType(mNativePath, ft); 250 } 251 252 /** 253 * Returns true if the path is empty (contains no lines or curves) 254 * 255 * @return true if the path is empty (contains no lines or curves) 256 */ 257 public boolean isEmpty() { 258 return native_isEmpty(mNativePath); 259 } 260 261 /** 262 * Returns true if the path specifies a rectangle. If so, and if rect is 263 * not null, set rect to the bounds of the path. If the path does not 264 * specify a rectangle, return false and ignore rect. 265 * 266 * @param rect If not null, returns the bounds of the path if it specifies 267 * a rectangle 268 * @return true if the path specifies a rectangle 269 */ 270 public boolean isRect(RectF rect) { 271 return native_isRect(mNativePath, rect); 272 } 273 274 /** 275 * Compute the bounds of the control points of the path, and write the 276 * answer into bounds. If the path contains 0 or 1 points, the bounds is 277 * set to (0,0,0,0) 278 * 279 * @param bounds Returns the computed bounds of the path's control points. 280 * @param exact This parameter is no longer used. 281 */ 282 @SuppressWarnings({"UnusedDeclaration"}) 283 public void computeBounds(RectF bounds, boolean exact) { 284 native_computeBounds(mNativePath, bounds); 285 } 286 287 /** 288 * Hint to the path to prepare for adding more points. This can allow the 289 * path to more efficiently allocate its storage. 290 * 291 * @param extraPtCount The number of extra points that may be added to this 292 * path 293 */ 294 public void incReserve(int extraPtCount) { 295 native_incReserve(mNativePath, extraPtCount); 296 } 297 298 /** 299 * Set the beginning of the next contour to the point (x,y). 300 * 301 * @param x The x-coordinate of the start of a new contour 302 * @param y The y-coordinate of the start of a new contour 303 */ 304 public void moveTo(float x, float y) { 305 native_moveTo(mNativePath, x, y); 306 } 307 308 /** 309 * Set the beginning of the next contour relative to the last point on the 310 * previous contour. If there is no previous contour, this is treated the 311 * same as moveTo(). 312 * 313 * @param dx The amount to add to the x-coordinate of the end of the 314 * previous contour, to specify the start of a new contour 315 * @param dy The amount to add to the y-coordinate of the end of the 316 * previous contour, to specify the start of a new contour 317 */ 318 public void rMoveTo(float dx, float dy) { 319 native_rMoveTo(mNativePath, dx, dy); 320 } 321 322 /** 323 * Add a line from the last point to the specified point (x,y). 324 * If no moveTo() call has been made for this contour, the first point is 325 * automatically set to (0,0). 326 * 327 * @param x The x-coordinate of the end of a line 328 * @param y The y-coordinate of the end of a line 329 */ 330 public void lineTo(float x, float y) { 331 isSimplePath = false; 332 native_lineTo(mNativePath, x, y); 333 } 334 335 /** 336 * Same as lineTo, but the coordinates are considered relative to the last 337 * point on this contour. If there is no previous point, then a moveTo(0,0) 338 * is inserted automatically. 339 * 340 * @param dx The amount to add to the x-coordinate of the previous point on 341 * this contour, to specify a line 342 * @param dy The amount to add to the y-coordinate of the previous point on 343 * this contour, to specify a line 344 */ 345 public void rLineTo(float dx, float dy) { 346 isSimplePath = false; 347 native_rLineTo(mNativePath, dx, dy); 348 } 349 350 /** 351 * Add a quadratic bezier from the last point, approaching control point 352 * (x1,y1), and ending at (x2,y2). If no moveTo() call has been made for 353 * this contour, the first point is automatically set to (0,0). 354 * 355 * @param x1 The x-coordinate of the control point on a quadratic curve 356 * @param y1 The y-coordinate of the control point on a quadratic curve 357 * @param x2 The x-coordinate of the end point on a quadratic curve 358 * @param y2 The y-coordinate of the end point on a quadratic curve 359 */ 360 public void quadTo(float x1, float y1, float x2, float y2) { 361 isSimplePath = false; 362 native_quadTo(mNativePath, x1, y1, x2, y2); 363 } 364 365 /** 366 * Same as quadTo, but the coordinates are considered relative to the last 367 * point on this contour. If there is no previous point, then a moveTo(0,0) 368 * is inserted automatically. 369 * 370 * @param dx1 The amount to add to the x-coordinate of the last point on 371 * this contour, for the control point of a quadratic curve 372 * @param dy1 The amount to add to the y-coordinate of the last point on 373 * this contour, for the control point of a quadratic curve 374 * @param dx2 The amount to add to the x-coordinate of the last point on 375 * this contour, for the end point of a quadratic curve 376 * @param dy2 The amount to add to the y-coordinate of the last point on 377 * this contour, for the end point of a quadratic curve 378 */ 379 public void rQuadTo(float dx1, float dy1, float dx2, float dy2) { 380 isSimplePath = false; 381 native_rQuadTo(mNativePath, dx1, dy1, dx2, dy2); 382 } 383 384 /** 385 * Add a cubic bezier from the last point, approaching control points 386 * (x1,y1) and (x2,y2), and ending at (x3,y3). If no moveTo() call has been 387 * made for this contour, the first point is automatically set to (0,0). 388 * 389 * @param x1 The x-coordinate of the 1st control point on a cubic curve 390 * @param y1 The y-coordinate of the 1st control point on a cubic curve 391 * @param x2 The x-coordinate of the 2nd control point on a cubic curve 392 * @param y2 The y-coordinate of the 2nd control point on a cubic curve 393 * @param x3 The x-coordinate of the end point on a cubic curve 394 * @param y3 The y-coordinate of the end point on a cubic curve 395 */ 396 public void cubicTo(float x1, float y1, float x2, float y2, 397 float x3, float y3) { 398 isSimplePath = false; 399 native_cubicTo(mNativePath, x1, y1, x2, y2, x3, y3); 400 } 401 402 /** 403 * Same as cubicTo, but the coordinates are considered relative to the 404 * current point on this contour. If there is no previous point, then a 405 * moveTo(0,0) is inserted automatically. 406 */ 407 public void rCubicTo(float x1, float y1, float x2, float y2, 408 float x3, float y3) { 409 isSimplePath = false; 410 native_rCubicTo(mNativePath, x1, y1, x2, y2, x3, y3); 411 } 412 413 /** 414 * Append the specified arc to the path as a new contour. If the start of 415 * the path is different from the path's current last point, then an 416 * automatic lineTo() is added to connect the current contour to the 417 * start of the arc. However, if the path is empty, then we call moveTo() 418 * with the first point of the arc. The sweep angle is tread mod 360. 419 * 420 * @param oval The bounds of oval defining shape and size of the arc 421 * @param startAngle Starting angle (in degrees) where the arc begins 422 * @param sweepAngle Sweep angle (in degrees) measured clockwise, treated 423 * mod 360. 424 * @param forceMoveTo If true, always begin a new contour with the arc 425 */ 426 public void arcTo(RectF oval, float startAngle, float sweepAngle, 427 boolean forceMoveTo) { 428 isSimplePath = false; 429 native_arcTo(mNativePath, oval, startAngle, sweepAngle, forceMoveTo); 430 } 431 432 /** 433 * Append the specified arc to the path as a new contour. If the start of 434 * the path is different from the path's current last point, then an 435 * automatic lineTo() is added to connect the current contour to the 436 * start of the arc. However, if the path is empty, then we call moveTo() 437 * with the first point of the arc. 438 * 439 * @param oval The bounds of oval defining shape and size of the arc 440 * @param startAngle Starting angle (in degrees) where the arc begins 441 * @param sweepAngle Sweep angle (in degrees) measured clockwise 442 */ 443 public void arcTo(RectF oval, float startAngle, float sweepAngle) { 444 isSimplePath = false; 445 native_arcTo(mNativePath, oval, startAngle, sweepAngle, false); 446 } 447 448 /** 449 * Close the current contour. If the current point is not equal to the 450 * first point of the contour, a line segment is automatically added. 451 */ 452 public void close() { 453 isSimplePath = false; 454 native_close(mNativePath); 455 } 456 457 /** 458 * Specifies how closed shapes (e.g. rects, ovals) are oriented when they 459 * are added to a path. 460 */ 461 public enum Direction { 462 /** clockwise */ 463 CW (1), // must match enum in SkPath.h 464 /** counter-clockwise */ 465 CCW (2); // must match enum in SkPath.h 466 467 Direction(int ni) { 468 nativeInt = ni; 469 } 470 final int nativeInt; 471 } 472 473 private void detectSimplePath(float left, float top, float right, float bottom, Direction dir) { 474 if (mDetectSimplePaths) { 475 if (mLastDirection == null) { 476 mLastDirection = dir; 477 } 478 if (mLastDirection != dir) { 479 isSimplePath = false; 480 } else { 481 if (rects == null) rects = new Region(); 482 rects.op((int) left, (int) top, (int) right, (int) bottom, Region.Op.UNION); 483 } 484 } 485 } 486 487 /** 488 * Add a closed rectangle contour to the path 489 * 490 * @param rect The rectangle to add as a closed contour to the path 491 * @param dir The direction to wind the rectangle's contour 492 */ 493 public void addRect(RectF rect, Direction dir) { 494 if (rect == null) { 495 throw new NullPointerException("need rect parameter"); 496 } 497 detectSimplePath(rect.left, rect.top, rect.right, rect.bottom, dir); 498 native_addRect(mNativePath, rect, dir.nativeInt); 499 } 500 501 /** 502 * Add a closed rectangle contour to the path 503 * 504 * @param left The left side of a rectangle to add to the path 505 * @param top The top of a rectangle to add to the path 506 * @param right The right side of a rectangle to add to the path 507 * @param bottom The bottom of a rectangle to add to the path 508 * @param dir The direction to wind the rectangle's contour 509 */ 510 public void addRect(float left, float top, float right, float bottom, Direction dir) { 511 detectSimplePath(left, top, right, bottom, dir); 512 native_addRect(mNativePath, left, top, right, bottom, dir.nativeInt); 513 } 514 515 /** 516 * Add a closed oval contour to the path 517 * 518 * @param oval The bounds of the oval to add as a closed contour to the path 519 * @param dir The direction to wind the oval's contour 520 */ 521 public void addOval(RectF oval, Direction dir) { 522 if (oval == null) { 523 throw new NullPointerException("need oval parameter"); 524 } 525 isSimplePath = false; 526 native_addOval(mNativePath, oval, dir.nativeInt); 527 } 528 529 /** 530 * Add a closed circle contour to the path 531 * 532 * @param x The x-coordinate of the center of a circle to add to the path 533 * @param y The y-coordinate of the center of a circle to add to the path 534 * @param radius The radius of a circle to add to the path 535 * @param dir The direction to wind the circle's contour 536 */ 537 public void addCircle(float x, float y, float radius, Direction dir) { 538 isSimplePath = false; 539 native_addCircle(mNativePath, x, y, radius, dir.nativeInt); 540 } 541 542 /** 543 * Add the specified arc to the path as a new contour. 544 * 545 * @param oval The bounds of oval defining the shape and size of the arc 546 * @param startAngle Starting angle (in degrees) where the arc begins 547 * @param sweepAngle Sweep angle (in degrees) measured clockwise 548 */ 549 public void addArc(RectF oval, float startAngle, float sweepAngle) { 550 if (oval == null) { 551 throw new NullPointerException("need oval parameter"); 552 } 553 isSimplePath = false; 554 native_addArc(mNativePath, oval, startAngle, sweepAngle); 555 } 556 557 /** 558 * Add a closed round-rectangle contour to the path 559 * 560 * @param rect The bounds of a round-rectangle to add to the path 561 * @param rx The x-radius of the rounded corners on the round-rectangle 562 * @param ry The y-radius of the rounded corners on the round-rectangle 563 * @param dir The direction to wind the round-rectangle's contour 564 */ 565 public void addRoundRect(RectF rect, float rx, float ry, Direction dir) { 566 if (rect == null) { 567 throw new NullPointerException("need rect parameter"); 568 } 569 isSimplePath = false; 570 native_addRoundRect(mNativePath, rect, rx, ry, dir.nativeInt); 571 } 572 573 /** 574 * Add a closed round-rectangle contour to the path. Each corner receives 575 * two radius values [X, Y]. The corners are ordered top-left, top-right, 576 * bottom-right, bottom-left 577 * 578 * @param rect The bounds of a round-rectangle to add to the path 579 * @param radii Array of 8 values, 4 pairs of [X,Y] radii 580 * @param dir The direction to wind the round-rectangle's contour 581 */ 582 public void addRoundRect(RectF rect, float[] radii, Direction dir) { 583 if (rect == null) { 584 throw new NullPointerException("need rect parameter"); 585 } 586 if (radii.length < 8) { 587 throw new ArrayIndexOutOfBoundsException("radii[] needs 8 values"); 588 } 589 isSimplePath = false; 590 native_addRoundRect(mNativePath, rect, radii, dir.nativeInt); 591 } 592 593 /** 594 * Add a copy of src to the path, offset by (dx,dy) 595 * 596 * @param src The path to add as a new contour 597 * @param dx The amount to translate the path in X as it is added 598 */ 599 public void addPath(Path src, float dx, float dy) { 600 isSimplePath = false; 601 native_addPath(mNativePath, src.mNativePath, dx, dy); 602 } 603 604 /** 605 * Add a copy of src to the path 606 * 607 * @param src The path that is appended to the current path 608 */ 609 public void addPath(Path src) { 610 isSimplePath = false; 611 native_addPath(mNativePath, src.mNativePath); 612 } 613 614 /** 615 * Add a copy of src to the path, transformed by matrix 616 * 617 * @param src The path to add as a new contour 618 */ 619 public void addPath(Path src, Matrix matrix) { 620 if (!src.isSimplePath) isSimplePath = false; 621 native_addPath(mNativePath, src.mNativePath, matrix.native_instance); 622 } 623 624 /** 625 * Offset the path by (dx,dy), returning true on success 626 * 627 * @param dx The amount in the X direction to offset the entire path 628 * @param dy The amount in the Y direction to offset the entire path 629 * @param dst The translated path is written here. If this is null, then 630 * the original path is modified. 631 */ 632 public void offset(float dx, float dy, Path dst) { 633 int dstNative = 0; 634 if (dst != null) { 635 dstNative = dst.mNativePath; 636 dst.isSimplePath = false; 637 } 638 native_offset(mNativePath, dx, dy, dstNative); 639 } 640 641 /** 642 * Offset the path by (dx,dy), returning true on success 643 * 644 * @param dx The amount in the X direction to offset the entire path 645 * @param dy The amount in the Y direction to offset the entire path 646 */ 647 public void offset(float dx, float dy) { 648 isSimplePath = false; 649 native_offset(mNativePath, dx, dy); 650 } 651 652 /** 653 * Sets the last point of the path. 654 * 655 * @param dx The new X coordinate for the last point 656 * @param dy The new Y coordinate for the last point 657 */ 658 public void setLastPoint(float dx, float dy) { 659 isSimplePath = false; 660 native_setLastPoint(mNativePath, dx, dy); 661 } 662 663 /** 664 * Transform the points in this path by matrix, and write the answer 665 * into dst. If dst is null, then the the original path is modified. 666 * 667 * @param matrix The matrix to apply to the path 668 * @param dst The transformed path is written here. If dst is null, 669 * then the the original path is modified 670 */ 671 public void transform(Matrix matrix, Path dst) { 672 int dstNative = 0; 673 if (dst != null) { 674 dst.isSimplePath = false; 675 dstNative = dst.mNativePath; 676 } 677 native_transform(mNativePath, matrix.native_instance, dstNative); 678 } 679 680 /** 681 * Transform the points in this path by matrix. 682 * 683 * @param matrix The matrix to apply to the path 684 */ 685 public void transform(Matrix matrix) { 686 isSimplePath = false; 687 native_transform(mNativePath, matrix.native_instance); 688 } 689 690 protected void finalize() throws Throwable { 691 try { 692 finalizer(mNativePath); 693 } finally { 694 super.finalize(); 695 } 696 } 697 698 final int ni() { 699 return mNativePath; 700 } 701 702 private static native int init1(); 703 private static native int init2(int nPath); 704 private static native void native_reset(int nPath); 705 private static native void native_rewind(int nPath); 706 private static native void native_set(int native_dst, int native_src); 707 private static native int native_getFillType(int nPath); 708 private static native void native_setFillType(int nPath, int ft); 709 private static native boolean native_isEmpty(int nPath); 710 private static native boolean native_isRect(int nPath, RectF rect); 711 private static native void native_computeBounds(int nPath, RectF bounds); 712 private static native void native_incReserve(int nPath, int extraPtCount); 713 private static native void native_moveTo(int nPath, float x, float y); 714 private static native void native_rMoveTo(int nPath, float dx, float dy); 715 private static native void native_lineTo(int nPath, float x, float y); 716 private static native void native_rLineTo(int nPath, float dx, float dy); 717 private static native void native_quadTo(int nPath, float x1, float y1, 718 float x2, float y2); 719 private static native void native_rQuadTo(int nPath, float dx1, float dy1, 720 float dx2, float dy2); 721 private static native void native_cubicTo(int nPath, float x1, float y1, 722 float x2, float y2, float x3, float y3); 723 private static native void native_rCubicTo(int nPath, float x1, float y1, 724 float x2, float y2, float x3, float y3); 725 private static native void native_arcTo(int nPath, RectF oval, 726 float startAngle, float sweepAngle, boolean forceMoveTo); 727 private static native void native_close(int nPath); 728 private static native void native_addRect(int nPath, RectF rect, int dir); 729 private static native void native_addRect(int nPath, float left, float top, 730 float right, float bottom, int dir); 731 private static native void native_addOval(int nPath, RectF oval, int dir); 732 private static native void native_addCircle(int nPath, float x, float y, float radius, int dir); 733 private static native void native_addArc(int nPath, RectF oval, 734 float startAngle, float sweepAngle); 735 private static native void native_addRoundRect(int nPath, RectF rect, 736 float rx, float ry, int dir); 737 private static native void native_addRoundRect(int nPath, RectF r, float[] radii, int dir); 738 private static native void native_addPath(int nPath, int src, float dx, float dy); 739 private static native void native_addPath(int nPath, int src); 740 private static native void native_addPath(int nPath, int src, int matrix); 741 private static native void native_offset(int nPath, float dx, float dy, int dst_path); 742 private static native void native_offset(int nPath, float dx, float dy); 743 private static native void native_setLastPoint(int nPath, float dx, float dy); 744 private static native void native_transform(int nPath, int matrix, int dst_path); 745 private static native void native_transform(int nPath, int matrix); 746 private static native boolean native_op(int path1, int path2, int op, int result); 747 private static native void finalizer(int nPath); 748} 749