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