1/*
2 * Copyright 2021 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include <jni.h>
9
10#include "include/core/SkPathBuilder.h"
11
12namespace {
13
14static jlong PathBuilder_Create(JNIEnv* env, jobject) {
15    return reinterpret_cast<jlong>(new SkPathBuilder());
16}
17
18static void PathBuilder_Release(JNIEnv* env, jobject, jlong native_pathBuilder) {
19    delete reinterpret_cast<SkPathBuilder*>(native_pathBuilder);
20}
21
22static void PathBuilder_MoveTo(JNIEnv* env, jobject, jlong native_pathBuilder, jfloat x, jfloat y) {
23    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
24        pathBuilder->moveTo(x, y);
25    }
26}
27
28static void PathBuilder_LineTo(JNIEnv* env, jobject, jlong native_pathBuilder, jfloat x, jfloat y) {
29    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
30        pathBuilder->lineTo(x, y);
31    }
32}
33
34static void PathBuilder_QuadTo(JNIEnv* env, jobject, jlong native_pathBuilder, jfloat x1, jfloat y1, jfloat x2, jfloat y2) {
35    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
36        pathBuilder->quadTo(x1, y1, x2, y2);
37    }
38}
39
40static void PathBuilder_ConicTo(JNIEnv* env, jobject, jlong native_pathBuilder, jfloat x1, jfloat y1, jfloat x2, jfloat y2, jfloat w) {
41    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
42        pathBuilder->conicTo(x1, y1, x2, y2, w);
43    }
44}
45
46static void PathBuilder_CubicTo(JNIEnv* env, jobject, jlong native_pathBuilder, jfloat x1, jfloat y1,
47                                                                                jfloat x2, jfloat y2,
48                                                                                jfloat x3, jfloat y3) {
49    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
50        pathBuilder->cubicTo(x1, y1, x2, y2, x3, y3);
51    }
52}
53
54static void PathBuilder_Close(JNIEnv* env, jobject, jlong native_pathBuilder) {
55    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
56        pathBuilder->close();
57    }
58}
59
60static void PathBuilder_SetFillType(JNIEnv* env, jobject, jlong native_pathBuilder, jint fill) {
61    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
62        switch(fill) {
63            case 0:
64                pathBuilder->setFillType(SkPathFillType::kWinding);
65                break;
66            case 1:
67                pathBuilder->setFillType(SkPathFillType::kEvenOdd);
68                break;
69            case 2:
70                pathBuilder->setFillType(SkPathFillType::kInverseWinding);
71                break;
72            case 3:
73                pathBuilder->setFillType(SkPathFillType::kInverseEvenOdd);
74                break;
75        }
76    }
77}
78
79static jlong PathBuilder_MakePath(JNIEnv* env, jobject, jlong native_pathBuilder) {
80    if (auto* pathBuilder = reinterpret_cast<SkPathBuilder*>(native_pathBuilder)) {
81        SkPath* path = new SkPath(pathBuilder->detach());
82        return reinterpret_cast<jlong>(path);
83    }
84
85    return 0;
86}
87
88}  // namespace
89
90int register_androidkit_PathBuilder(JNIEnv* env) {
91    static const JNINativeMethod methods[] = {
92        {"nCreate"      , "()J"       , reinterpret_cast<void*>(PathBuilder_Create)},
93        {"nRelease"     , "(J)V"      , reinterpret_cast<void*>(PathBuilder_Release)},
94        {"nMoveTo"      , "(JFF)V"    , reinterpret_cast<void*>(PathBuilder_MoveTo)},
95        {"nLineTo"      , "(JFF)V"    , reinterpret_cast<void*>(PathBuilder_LineTo)},
96        {"nQuadTo"      , "(JFFFF)V"  , reinterpret_cast<void*>(PathBuilder_QuadTo)},
97        {"nConicTo"     , "(JFFFFF)V" , reinterpret_cast<void*>(PathBuilder_ConicTo)},
98        {"nCubicTo"     , "(JFFFFFF)V", reinterpret_cast<void*>(PathBuilder_CubicTo)},
99        {"nClose"       , "(J)V"      , reinterpret_cast<void*>(PathBuilder_Close)},
100        {"nSetFillType" , "(JI)V"     , reinterpret_cast<void*>(PathBuilder_SetFillType)},
101        {"nMake"        , "(J)J"      , reinterpret_cast<void*>(PathBuilder_MakePath)},
102    };
103
104    const auto clazz = env->FindClass("org/skia/androidkit/PathBuilder");
105    return clazz
106        ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods))
107        : JNI_ERR;
108}
109