PageRenderTime 39ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/core/jni/android/graphics/Path.cpp

https://gitlab.com/AvayKumar/android_frameworks_base
C++ | 528 lines | 418 code | 69 blank | 41 comment | 25 complexity | af3ee6c29023c6a3ef61a18adb7cca4b MD5 | raw file
  1. /* libs/android_runtime/android/graphics/Path.cpp
  2. **
  3. ** Copyright 2006, The Android Open Source Project
  4. **
  5. ** Licensed under the Apache License, Version 2.0 (the "License");
  6. ** you may not use this file except in compliance with the License.
  7. ** You may obtain a copy of the License at
  8. **
  9. ** http://www.apache.org/licenses/LICENSE-2.0
  10. **
  11. ** Unless required by applicable law or agreed to in writing, software
  12. ** distributed under the License is distributed on an "AS IS" BASIS,
  13. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. ** See the License for the specific language governing permissions and
  15. ** limitations under the License.
  16. */
  17. // This file was generated from the C++ include file: SkPath.h
  18. // Any changes made to this file will be discarded by the build.
  19. // To change this file, either edit the include, or device/tools/gluemaker/main.cpp,
  20. // or one of the auxilary file specifications in device/tools/gluemaker.
  21. #include "jni.h"
  22. #include "GraphicsJNI.h"
  23. #include <android_runtime/AndroidRuntime.h>
  24. #include "SkPath.h"
  25. #include "SkPathOps.h"
  26. #include <ResourceCache.h>
  27. #include <vector>
  28. #include <map>
  29. namespace android {
  30. class SkPathGlue {
  31. public:
  32. static void finalizer(JNIEnv* env, jobject clazz, jlong objHandle) {
  33. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  34. #ifdef USE_OPENGL_RENDERER
  35. if (android::uirenderer::ResourceCache::hasInstance()) {
  36. android::uirenderer::ResourceCache::getInstance().destructor(obj);
  37. return;
  38. }
  39. #endif
  40. delete obj;
  41. }
  42. static jlong init1(JNIEnv* env, jobject clazz) {
  43. return reinterpret_cast<jlong>(new SkPath());
  44. }
  45. static jlong init2(JNIEnv* env, jobject clazz, jlong valHandle) {
  46. SkPath* val = reinterpret_cast<SkPath*>(valHandle);
  47. return reinterpret_cast<jlong>(new SkPath(*val));
  48. }
  49. static void reset(JNIEnv* env, jobject clazz, jlong objHandle) {
  50. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  51. obj->reset();
  52. }
  53. static void rewind(JNIEnv* env, jobject clazz, jlong objHandle) {
  54. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  55. obj->rewind();
  56. }
  57. static void assign(JNIEnv* env, jobject clazz, jlong dstHandle, jlong srcHandle) {
  58. SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
  59. const SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
  60. *dst = *src;
  61. }
  62. static jboolean isConvex(JNIEnv* env, jobject clazz, jlong objHandle) {
  63. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  64. return obj->isConvex();
  65. }
  66. static jint getFillType(JNIEnv* env, jobject clazz, jlong objHandle) {
  67. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  68. return obj->getFillType();
  69. }
  70. static void setFillType(JNIEnv* env, jobject clazz, jlong pathHandle, jint ftHandle) {
  71. SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
  72. SkPath::FillType ft = static_cast<SkPath::FillType>(ftHandle);
  73. path->setFillType(ft);
  74. }
  75. static jboolean isEmpty(JNIEnv* env, jobject clazz, jlong objHandle) {
  76. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  77. return obj->isEmpty();
  78. }
  79. static jboolean isRect(JNIEnv* env, jobject clazz, jlong objHandle, jobject jrect) {
  80. SkRect rect;
  81. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  82. jboolean result = obj->isRect(&rect);
  83. GraphicsJNI::rect_to_jrectf(rect, env, jrect);
  84. return result;
  85. }
  86. static void computeBounds(JNIEnv* env, jobject clazz, jlong objHandle, jobject jbounds) {
  87. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  88. const SkRect& bounds = obj->getBounds();
  89. GraphicsJNI::rect_to_jrectf(bounds, env, jbounds);
  90. }
  91. static void incReserve(JNIEnv* env, jobject clazz, jlong objHandle, jint extraPtCount) {
  92. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  93. obj->incReserve(extraPtCount);
  94. }
  95. static void moveTo__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x, jfloat y) {
  96. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  97. obj->moveTo(x, y);
  98. }
  99. static void rMoveTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) {
  100. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  101. obj->rMoveTo(dx, dy);
  102. }
  103. static void lineTo__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x, jfloat y) {
  104. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  105. obj->lineTo(x, y);
  106. }
  107. static void rLineTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) {
  108. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  109. obj->rLineTo(dx, dy);
  110. }
  111. static void quadTo__FFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, jfloat y2) {
  112. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  113. obj->quadTo(x1, y1, x2, y2);
  114. }
  115. static void rQuadTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx1, jfloat dy1, jfloat dx2, jfloat dy2) {
  116. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  117. obj->rQuadTo(dx1, dy1, dx2, dy2);
  118. }
  119. static void cubicTo__FFFFFF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, jfloat y2, jfloat x3, jfloat y3) {
  120. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  121. obj->cubicTo(x1, y1, x2, y2, x3, y3);
  122. }
  123. static void rCubicTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x1, jfloat y1, jfloat x2, jfloat y2, jfloat x3, jfloat y3) {
  124. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  125. obj->rCubicTo(x1, y1, x2, y2, x3, y3);
  126. }
  127. static void arcTo(JNIEnv* env, jobject clazz, jlong objHandle, jfloat left, jfloat top,
  128. jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle,
  129. jboolean forceMoveTo) {
  130. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  131. SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
  132. obj->arcTo(oval, startAngle, sweepAngle, forceMoveTo);
  133. }
  134. static void close(JNIEnv* env, jobject clazz, jlong objHandle) {
  135. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  136. obj->close();
  137. }
  138. static void addRect(JNIEnv* env, jobject clazz, jlong objHandle,
  139. jfloat left, jfloat top, jfloat right, jfloat bottom, jint dirHandle) {
  140. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  141. SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle);
  142. obj->addRect(left, top, right, bottom, dir);
  143. }
  144. static void addOval(JNIEnv* env, jobject clazz, jlong objHandle,
  145. jfloat left, jfloat top, jfloat right, jfloat bottom, jint dirHandle) {
  146. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  147. SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle);
  148. SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
  149. obj->addOval(oval, dir);
  150. }
  151. static void addCircle(JNIEnv* env, jobject clazz, jlong objHandle, jfloat x, jfloat y, jfloat radius, jint dirHandle) {
  152. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  153. SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle);
  154. obj->addCircle(x, y, radius, dir);
  155. }
  156. static void addArc(JNIEnv* env, jobject clazz, jlong objHandle, jfloat left, jfloat top,
  157. jfloat right, jfloat bottom, jfloat startAngle, jfloat sweepAngle) {
  158. SkRect oval = SkRect::MakeLTRB(left, top, right, bottom);
  159. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  160. obj->addArc(oval, startAngle, sweepAngle);
  161. }
  162. static void addRoundRectXY(JNIEnv* env, jobject clazz, jlong objHandle, jfloat left, jfloat top,
  163. jfloat right, jfloat bottom, jfloat rx, jfloat ry, jint dirHandle) {
  164. SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
  165. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  166. SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle);
  167. obj->addRoundRect(rect, rx, ry, dir);
  168. }
  169. static void addRoundRect8(JNIEnv* env, jobject, jlong objHandle, jfloat left, jfloat top,
  170. jfloat right, jfloat bottom, jfloatArray array, jint dirHandle) {
  171. SkRect rect = SkRect::MakeLTRB(left, top, right, bottom);
  172. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  173. SkPath::Direction dir = static_cast<SkPath::Direction>(dirHandle);
  174. AutoJavaFloatArray afa(env, array, 8);
  175. #ifdef SK_SCALAR_IS_FLOAT
  176. const float* src = afa.ptr();
  177. #else
  178. #error Need to convert float array to SkScalar array before calling the following function.
  179. #endif
  180. obj->addRoundRect(rect, src, dir);
  181. }
  182. static void addPath__PathFF(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jfloat dx, jfloat dy) {
  183. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  184. SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
  185. obj->addPath(*src, dx, dy);
  186. }
  187. static void addPath__Path(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle) {
  188. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  189. SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
  190. obj->addPath(*src);
  191. }
  192. static void addPath__PathMatrix(JNIEnv* env, jobject clazz, jlong objHandle, jlong srcHandle, jlong matrixHandle) {
  193. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  194. SkPath* src = reinterpret_cast<SkPath*>(srcHandle);
  195. SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
  196. obj->addPath(*src, *matrix);
  197. }
  198. static void offset__FFPath(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy, jlong dstHandle) {
  199. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  200. SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
  201. obj->offset(dx, dy, dst);
  202. }
  203. static void offset__FF(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) {
  204. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  205. obj->offset(dx, dy);
  206. }
  207. static void setLastPoint(JNIEnv* env, jobject clazz, jlong objHandle, jfloat dx, jfloat dy) {
  208. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  209. obj->setLastPt(dx, dy);
  210. }
  211. static void transform__MatrixPath(JNIEnv* env, jobject clazz, jlong objHandle, jlong matrixHandle, jlong dstHandle) {
  212. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  213. SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
  214. SkPath* dst = reinterpret_cast<SkPath*>(dstHandle);
  215. obj->transform(*matrix, dst);
  216. }
  217. static void transform__Matrix(JNIEnv* env, jobject clazz, jlong objHandle, jlong matrixHandle) {
  218. SkPath* obj = reinterpret_cast<SkPath*>(objHandle);
  219. SkMatrix* matrix = reinterpret_cast<SkMatrix*>(matrixHandle);
  220. obj->transform(*matrix);
  221. }
  222. static jboolean op(JNIEnv* env, jobject clazz, jlong p1Handle, jlong p2Handle, jint opHandle, jlong rHandle) {
  223. SkPath* p1 = reinterpret_cast<SkPath*>(p1Handle);
  224. SkPath* p2 = reinterpret_cast<SkPath*>(p2Handle);
  225. SkPathOp op = static_cast<SkPathOp>(opHandle);
  226. SkPath* r = reinterpret_cast<SkPath*>(rHandle);
  227. return Op(*p1, *p2, op, r);
  228. }
  229. typedef SkPoint (*bezierCalculation)(float t, const SkPoint* points);
  230. static void addMove(std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths,
  231. const SkPoint& point) {
  232. float length = 0;
  233. if (!lengths.empty()) {
  234. length = lengths.back();
  235. }
  236. segmentPoints.push_back(point);
  237. lengths.push_back(length);
  238. }
  239. static void addLine(std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths,
  240. const SkPoint& toPoint) {
  241. if (segmentPoints.empty()) {
  242. segmentPoints.push_back(SkPoint::Make(0, 0));
  243. lengths.push_back(0);
  244. } else if (segmentPoints.back() == toPoint) {
  245. return; // Empty line
  246. }
  247. float length = lengths.back() + SkPoint::Distance(segmentPoints.back(), toPoint);
  248. segmentPoints.push_back(toPoint);
  249. lengths.push_back(length);
  250. }
  251. static float cubicCoordinateCalculation(float t, float p0, float p1, float p2, float p3) {
  252. float oneMinusT = 1 - t;
  253. float oneMinusTSquared = oneMinusT * oneMinusT;
  254. float oneMinusTCubed = oneMinusTSquared * oneMinusT;
  255. float tSquared = t * t;
  256. float tCubed = tSquared * t;
  257. return (oneMinusTCubed * p0) + (3 * oneMinusTSquared * t * p1)
  258. + (3 * oneMinusT * tSquared * p2) + (tCubed * p3);
  259. }
  260. static SkPoint cubicBezierCalculation(float t, const SkPoint* points) {
  261. float x = cubicCoordinateCalculation(t, points[0].x(), points[1].x(),
  262. points[2].x(), points[3].x());
  263. float y = cubicCoordinateCalculation(t, points[0].y(), points[1].y(),
  264. points[2].y(), points[3].y());
  265. return SkPoint::Make(x, y);
  266. }
  267. static float quadraticCoordinateCalculation(float t, float p0, float p1, float p2) {
  268. float oneMinusT = 1 - t;
  269. return oneMinusT * ((oneMinusT * p0) + (t * p1)) + t * ((oneMinusT * p1) + (t * p2));
  270. }
  271. static SkPoint quadraticBezierCalculation(float t, const SkPoint* points) {
  272. float x = quadraticCoordinateCalculation(t, points[0].x(), points[1].x(), points[2].x());
  273. float y = quadraticCoordinateCalculation(t, points[0].y(), points[1].y(), points[2].y());
  274. return SkPoint::Make(x, y);
  275. }
  276. // Subdivide a section of the Bezier curve, set the mid-point and the mid-t value.
  277. // Returns true if further subdivision is necessary as defined by errorSquared.
  278. static bool subdividePoints(const SkPoint* points, bezierCalculation bezierFunction,
  279. float t0, const SkPoint &p0, float t1, const SkPoint &p1,
  280. float& midT, SkPoint &midPoint, float errorSquared) {
  281. midT = (t1 + t0) / 2;
  282. float midX = (p1.x() + p0.x()) / 2;
  283. float midY = (p1.y() + p0.y()) / 2;
  284. midPoint = (*bezierFunction)(midT, points);
  285. float xError = midPoint.x() - midX;
  286. float yError = midPoint.y() - midY;
  287. float midErrorSquared = (xError * xError) + (yError * yError);
  288. return midErrorSquared > errorSquared;
  289. }
  290. // Divides Bezier curves until linear interpolation is very close to accurate, using
  291. // errorSquared as a metric. Cubic Bezier curves can have an inflection point that improperly
  292. // short-circuit subdivision. If you imagine an S shape, the top and bottom points being the
  293. // starting and end points, linear interpolation would mark the center where the curve places
  294. // the point. It is clearly not the case that we can linearly interpolate at that point.
  295. // doubleCheckDivision forces a second examination between subdivisions to ensure that linear
  296. // interpolation works.
  297. static void addBezier(const SkPoint* points,
  298. bezierCalculation bezierFunction, std::vector<SkPoint>& segmentPoints,
  299. std::vector<float>& lengths, float errorSquared, bool doubleCheckDivision) {
  300. typedef std::map<float, SkPoint> PointMap;
  301. PointMap tToPoint;
  302. tToPoint[0] = (*bezierFunction)(0, points);
  303. tToPoint[1] = (*bezierFunction)(1, points);
  304. PointMap::iterator iter = tToPoint.begin();
  305. PointMap::iterator next = iter;
  306. ++next;
  307. while (next != tToPoint.end()) {
  308. bool needsSubdivision = true;
  309. SkPoint midPoint;
  310. do {
  311. float midT;
  312. needsSubdivision = subdividePoints(points, bezierFunction, iter->first,
  313. iter->second, next->first, next->second, midT, midPoint, errorSquared);
  314. if (!needsSubdivision && doubleCheckDivision) {
  315. SkPoint quarterPoint;
  316. float quarterT;
  317. needsSubdivision = subdividePoints(points, bezierFunction, iter->first,
  318. iter->second, midT, midPoint, quarterT, quarterPoint, errorSquared);
  319. if (needsSubdivision) {
  320. // Found an inflection point. No need to double-check.
  321. doubleCheckDivision = false;
  322. }
  323. }
  324. if (needsSubdivision) {
  325. next = tToPoint.insert(iter, PointMap::value_type(midT, midPoint));
  326. }
  327. } while (needsSubdivision);
  328. iter = next;
  329. next++;
  330. }
  331. // Now that each division can use linear interpolation with less than the allowed error
  332. for (iter = tToPoint.begin(); iter != tToPoint.end(); ++iter) {
  333. addLine(segmentPoints, lengths, iter->second);
  334. }
  335. }
  336. static void createVerbSegments(SkPath::Verb verb, const SkPoint* points,
  337. std::vector<SkPoint>& segmentPoints, std::vector<float>& lengths, float errorSquared) {
  338. switch (verb) {
  339. case SkPath::kMove_Verb:
  340. addMove(segmentPoints, lengths, points[0]);
  341. break;
  342. case SkPath::kClose_Verb:
  343. addLine(segmentPoints, lengths, points[0]);
  344. break;
  345. case SkPath::kLine_Verb:
  346. addLine(segmentPoints, lengths, points[1]);
  347. break;
  348. case SkPath::kQuad_Verb:
  349. addBezier(points, quadraticBezierCalculation, segmentPoints, lengths,
  350. errorSquared, false);
  351. break;
  352. case SkPath::kCubic_Verb:
  353. addBezier(points, cubicBezierCalculation, segmentPoints, lengths,
  354. errorSquared, true);
  355. break;
  356. default:
  357. // Leave element as NULL, Conic sections are not supported.
  358. break;
  359. }
  360. }
  361. // Returns a float[] with each point along the path represented by 3 floats
  362. // * fractional length along the path that the point resides
  363. // * x coordinate
  364. // * y coordinate
  365. // Note that more than one point may have the same length along the path in
  366. // the case of a move.
  367. // NULL can be returned if the Path is empty.
  368. static jfloatArray approximate(JNIEnv* env, jclass, jlong pathHandle, float acceptableError)
  369. {
  370. SkPath* path = reinterpret_cast<SkPath*>(pathHandle);
  371. SkASSERT(path);
  372. SkPath::Iter pathIter(*path, false);
  373. SkPath::Verb verb;
  374. SkPoint points[4];
  375. std::vector<SkPoint> segmentPoints;
  376. std::vector<float> lengths;
  377. float errorSquared = acceptableError * acceptableError;
  378. while ((verb = pathIter.next(points, false)) != SkPath::kDone_Verb) {
  379. createVerbSegments(verb, points, segmentPoints, lengths, errorSquared);
  380. }
  381. if (segmentPoints.empty()) {
  382. int numVerbs = path->countVerbs();
  383. if (numVerbs == 1) {
  384. addMove(segmentPoints, lengths, path->getPoint(0));
  385. } else {
  386. // Invalid or empty path. Fall back to point(0,0)
  387. addMove(segmentPoints, lengths, SkPoint());
  388. }
  389. }
  390. float totalLength = lengths.back();
  391. if (totalLength == 0) {
  392. // Lone Move instructions should still be able to animate at the same value.
  393. segmentPoints.push_back(segmentPoints.back());
  394. lengths.push_back(1);
  395. totalLength = 1;
  396. }
  397. size_t numPoints = segmentPoints.size();
  398. size_t approximationArraySize = numPoints * 3;
  399. float* approximation = new float[approximationArraySize];
  400. int approximationIndex = 0;
  401. for (size_t i = 0; i < numPoints; i++) {
  402. const SkPoint& point = segmentPoints[i];
  403. approximation[approximationIndex++] = lengths[i] / totalLength;
  404. approximation[approximationIndex++] = point.x();
  405. approximation[approximationIndex++] = point.y();
  406. }
  407. jfloatArray result = env->NewFloatArray(approximationArraySize);
  408. env->SetFloatArrayRegion(result, 0, approximationArraySize, approximation);
  409. delete[] approximation;
  410. return result;
  411. }
  412. };
  413. static JNINativeMethod methods[] = {
  414. {"finalizer", "(J)V", (void*) SkPathGlue::finalizer},
  415. {"init1","()J", (void*) SkPathGlue::init1},
  416. {"init2","(J)J", (void*) SkPathGlue::init2},
  417. {"native_reset","(J)V", (void*) SkPathGlue::reset},
  418. {"native_rewind","(J)V", (void*) SkPathGlue::rewind},
  419. {"native_set","(JJ)V", (void*) SkPathGlue::assign},
  420. {"native_isConvex","(J)Z", (void*) SkPathGlue::isConvex},
  421. {"native_getFillType","(J)I", (void*) SkPathGlue::getFillType},
  422. {"native_setFillType","(JI)V", (void*) SkPathGlue::setFillType},
  423. {"native_isEmpty","(J)Z", (void*) SkPathGlue::isEmpty},
  424. {"native_isRect","(JLandroid/graphics/RectF;)Z", (void*) SkPathGlue::isRect},
  425. {"native_computeBounds","(JLandroid/graphics/RectF;)V", (void*) SkPathGlue::computeBounds},
  426. {"native_incReserve","(JI)V", (void*) SkPathGlue::incReserve},
  427. {"native_moveTo","(JFF)V", (void*) SkPathGlue::moveTo__FF},
  428. {"native_rMoveTo","(JFF)V", (void*) SkPathGlue::rMoveTo},
  429. {"native_lineTo","(JFF)V", (void*) SkPathGlue::lineTo__FF},
  430. {"native_rLineTo","(JFF)V", (void*) SkPathGlue::rLineTo},
  431. {"native_quadTo","(JFFFF)V", (void*) SkPathGlue::quadTo__FFFF},
  432. {"native_rQuadTo","(JFFFF)V", (void*) SkPathGlue::rQuadTo},
  433. {"native_cubicTo","(JFFFFFF)V", (void*) SkPathGlue::cubicTo__FFFFFF},
  434. {"native_rCubicTo","(JFFFFFF)V", (void*) SkPathGlue::rCubicTo},
  435. {"native_arcTo","(JFFFFFFZ)V", (void*) SkPathGlue::arcTo},
  436. {"native_close","(J)V", (void*) SkPathGlue::close},
  437. {"native_addRect","(JFFFFI)V", (void*) SkPathGlue::addRect},
  438. {"native_addOval","(JFFFFI)V", (void*) SkPathGlue::addOval},
  439. {"native_addCircle","(JFFFI)V", (void*) SkPathGlue::addCircle},
  440. {"native_addArc","(JFFFFFF)V", (void*) SkPathGlue::addArc},
  441. {"native_addRoundRect","(JFFFFFFI)V", (void*) SkPathGlue::addRoundRectXY},
  442. {"native_addRoundRect","(JFFFF[FI)V", (void*) SkPathGlue::addRoundRect8},
  443. {"native_addPath","(JJFF)V", (void*) SkPathGlue::addPath__PathFF},
  444. {"native_addPath","(JJ)V", (void*) SkPathGlue::addPath__Path},
  445. {"native_addPath","(JJJ)V", (void*) SkPathGlue::addPath__PathMatrix},
  446. {"native_offset","(JFFJ)V", (void*) SkPathGlue::offset__FFPath},
  447. {"native_offset","(JFF)V", (void*) SkPathGlue::offset__FF},
  448. {"native_setLastPoint","(JFF)V", (void*) SkPathGlue::setLastPoint},
  449. {"native_transform","(JJJ)V", (void*) SkPathGlue::transform__MatrixPath},
  450. {"native_transform","(JJ)V", (void*) SkPathGlue::transform__Matrix},
  451. {"native_op","(JJIJ)Z", (void*) SkPathGlue::op},
  452. {"native_approximate", "(JF)[F", (void*) SkPathGlue::approximate},
  453. };
  454. int register_android_graphics_Path(JNIEnv* env) {
  455. int result = AndroidRuntime::registerNativeMethods(env, "android/graphics/Path", methods,
  456. sizeof(methods) / sizeof(methods[0]));
  457. return result;
  458. }
  459. }