1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2021 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci 8cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 9cb93a386Sopenharmony_ci#include "include/core/SkColor.h" 10cb93a386Sopenharmony_ci#include "include/core/SkPaint.h" 11cb93a386Sopenharmony_ci#include "include/core/SkRRect.h" 12cb93a386Sopenharmony_ci#include "include/core/SkShader.h" 13cb93a386Sopenharmony_ci#include "modules/androidkit/src/Utils.h" 14cb93a386Sopenharmony_ci 15cb93a386Sopenharmony_ci#include <jni.h> 16cb93a386Sopenharmony_ci 17cb93a386Sopenharmony_cinamespace { 18cb93a386Sopenharmony_ci 19cb93a386Sopenharmony_cijint Canvas_GetWidth(JNIEnv* env, jobject, jlong native_instance) { 20cb93a386Sopenharmony_ci const auto* canvas = reinterpret_cast<const SkCanvas*>(native_instance); 21cb93a386Sopenharmony_ci return canvas ? canvas->imageInfo().width() : 0; 22cb93a386Sopenharmony_ci} 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_cijint Canvas_GetHeight(JNIEnv* env, jobject, jlong native_instance) { 25cb93a386Sopenharmony_ci const auto* canvas = reinterpret_cast<const SkCanvas*>(native_instance); 26cb93a386Sopenharmony_ci return canvas ? canvas->imageInfo().height() : 0; 27cb93a386Sopenharmony_ci} 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_cijint Canvas_Save(JNIEnv* env, jobject, jlong native_instance) { 30cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 31cb93a386Sopenharmony_ci return canvas->save(); 32cb93a386Sopenharmony_ci } 33cb93a386Sopenharmony_ci return 0; 34cb93a386Sopenharmony_ci} 35cb93a386Sopenharmony_ci 36cb93a386Sopenharmony_civoid Canvas_Restore(JNIEnv* env, jobject, jlong native_instance) { 37cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 38cb93a386Sopenharmony_ci canvas->restore(); 39cb93a386Sopenharmony_ci } 40cb93a386Sopenharmony_ci} 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_civoid Canvas_RestoreToCount(JNIEnv* env, jobject, jlong native_instance, jint count) { 43cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 44cb93a386Sopenharmony_ci canvas->restoreToCount(count); 45cb93a386Sopenharmony_ci } 46cb93a386Sopenharmony_ci} 47cb93a386Sopenharmony_ci 48cb93a386Sopenharmony_cijint Canvas_SaveLayer(JNIEnv* env, jobject, jlong native_instance, jlong native_paint) { 49cb93a386Sopenharmony_ci auto* paint = reinterpret_cast<SkPaint* >(native_paint); 50cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 51cb93a386Sopenharmony_ci return canvas->saveLayer(nullptr, paint); 52cb93a386Sopenharmony_ci } 53cb93a386Sopenharmony_ci return 0; 54cb93a386Sopenharmony_ci} 55cb93a386Sopenharmony_ci 56cb93a386Sopenharmony_cijlong Canvas_LocalToDevice(JNIEnv* env, jobject, jlong native_instance) { 57cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 58cb93a386Sopenharmony_ci SkM44* m = new SkM44(canvas->getLocalToDevice()); 59cb93a386Sopenharmony_ci return reinterpret_cast<jlong>(m); 60cb93a386Sopenharmony_ci } 61cb93a386Sopenharmony_ci return 0; 62cb93a386Sopenharmony_ci} 63cb93a386Sopenharmony_ci 64cb93a386Sopenharmony_civoid Canvas_Concat(JNIEnv* env, jobject, jlong native_instance, jlong native_matrix) { 65cb93a386Sopenharmony_ci auto* canvas = reinterpret_cast<SkCanvas*>(native_instance); 66cb93a386Sopenharmony_ci auto* matrix = reinterpret_cast<SkM44* >(native_matrix); 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci if (canvas && matrix) { 69cb93a386Sopenharmony_ci canvas->concat(*matrix); 70cb93a386Sopenharmony_ci } 71cb93a386Sopenharmony_ci} 72cb93a386Sopenharmony_ci 73cb93a386Sopenharmony_civoid Canvas_Concat16f(JNIEnv* env, jobject, jlong native_instance, jfloatArray jmatrix) { 74cb93a386Sopenharmony_ci SkASSERT(env->GetArrayLength(jmatrix) == 16); 75cb93a386Sopenharmony_ci 76cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 77cb93a386Sopenharmony_ci auto* m = env->GetFloatArrayElements(jmatrix, nullptr); 78cb93a386Sopenharmony_ci canvas->concat(SkM44::RowMajor(m)); 79cb93a386Sopenharmony_ci env->ReleaseFloatArrayElements(jmatrix, m, 0); 80cb93a386Sopenharmony_ci } 81cb93a386Sopenharmony_ci} 82cb93a386Sopenharmony_ci 83cb93a386Sopenharmony_civoid Canvas_Translate(JNIEnv* env, jobject, jlong native_instance, 84cb93a386Sopenharmony_ci jfloat tx, jfloat ty, jfloat tz) { 85cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 86cb93a386Sopenharmony_ci canvas->concat(SkM44::Translate(tx, ty, tz)); 87cb93a386Sopenharmony_ci } 88cb93a386Sopenharmony_ci} 89cb93a386Sopenharmony_ci 90cb93a386Sopenharmony_civoid Canvas_Scale(JNIEnv* env, jobject, jlong native_instance, jfloat sx, jfloat sy, jfloat sz) { 91cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 92cb93a386Sopenharmony_ci canvas->concat(SkM44::Scale(sx, sy, sz)); 93cb93a386Sopenharmony_ci } 94cb93a386Sopenharmony_ci} 95cb93a386Sopenharmony_ci 96cb93a386Sopenharmony_civoid Canvas_ClipPath(JNIEnv* env, jobject, jlong native_instance, jlong native_path, 97cb93a386Sopenharmony_ci jint native_clipOp, jboolean doAA) { 98cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 99cb93a386Sopenharmony_ci if (auto* path = reinterpret_cast<SkPath*>(native_path)) { 100cb93a386Sopenharmony_ci canvas->clipPath(*path, static_cast<SkClipOp>(native_clipOp), doAA); 101cb93a386Sopenharmony_ci } 102cb93a386Sopenharmony_ci } 103cb93a386Sopenharmony_ci} 104cb93a386Sopenharmony_ci 105cb93a386Sopenharmony_civoid Canvas_ClipRect(JNIEnv* env, jobject, jlong native_instance, jfloat l, jfloat t, jfloat r, jfloat b, 106cb93a386Sopenharmony_ci jint native_clipOp, jboolean doAA) { 107cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 108cb93a386Sopenharmony_ci canvas->clipRect(SkRect::MakeLTRB(l, t, r, b), static_cast<SkClipOp>(native_clipOp), doAA); 109cb93a386Sopenharmony_ci } 110cb93a386Sopenharmony_ci} 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_civoid Canvas_ClipRRect(JNIEnv* env, jobject, jlong native_instance, jfloat l, jfloat t, jfloat r, jfloat b, 113cb93a386Sopenharmony_ci jfloat xRad, jfloat yRad, 114cb93a386Sopenharmony_ci jint native_clipOp, jboolean doAA) { 115cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 116cb93a386Sopenharmony_ci canvas->clipRRect(SkRRect::MakeRectXY(SkRect::MakeLTRB(l, t, r, b), xRad, yRad), 117cb93a386Sopenharmony_ci static_cast<SkClipOp>(native_clipOp), doAA); 118cb93a386Sopenharmony_ci } 119cb93a386Sopenharmony_ci} 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_civoid Canvas_ClipShader(JNIEnv* env, jobject, jlong native_instance, jlong native_shader, jint native_clipOp) { 122cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 123cb93a386Sopenharmony_ci if (auto* shader = reinterpret_cast<SkShader*>(native_shader)) { 124cb93a386Sopenharmony_ci canvas->clipShader(sk_ref_sp(shader), static_cast<SkClipOp>(native_clipOp)); 125cb93a386Sopenharmony_ci } 126cb93a386Sopenharmony_ci } 127cb93a386Sopenharmony_ci} 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_civoid Canvas_DrawColor(JNIEnv* env, jobject, jlong native_instance, 130cb93a386Sopenharmony_ci float r, float g, float b, float a) { 131cb93a386Sopenharmony_ci if (auto* canvas = reinterpret_cast<SkCanvas*>(native_instance)) { 132cb93a386Sopenharmony_ci canvas->drawColor(SkColor4f{r, g, b, a}); 133cb93a386Sopenharmony_ci } 134cb93a386Sopenharmony_ci} 135cb93a386Sopenharmony_ci 136cb93a386Sopenharmony_civoid Canvas_DrawRect(JNIEnv* env, jobject, jlong native_instance, 137cb93a386Sopenharmony_ci jfloat left, jfloat top, jfloat right, jfloat bottom, 138cb93a386Sopenharmony_ci jlong native_paint) { 139cb93a386Sopenharmony_ci auto* canvas = reinterpret_cast<SkCanvas*>(native_instance); 140cb93a386Sopenharmony_ci auto* paint = reinterpret_cast<SkPaint* >(native_paint); 141cb93a386Sopenharmony_ci if (canvas && paint) { 142cb93a386Sopenharmony_ci canvas->drawRect(SkRect::MakeLTRB(left, top, right, bottom), *paint); 143cb93a386Sopenharmony_ci } 144cb93a386Sopenharmony_ci} 145cb93a386Sopenharmony_ci 146cb93a386Sopenharmony_civoid Canvas_DrawImage(JNIEnv* env, jobject, jlong native_instance, jlong native_image, 147cb93a386Sopenharmony_ci jfloat x, jfloat y, 148cb93a386Sopenharmony_ci jint sampling_desc, jfloat sampling_b, jfloat sampling_c) { 149cb93a386Sopenharmony_ci auto* canvas = reinterpret_cast<SkCanvas*>(native_instance); 150cb93a386Sopenharmony_ci auto* image = reinterpret_cast<SkImage *>(native_image); 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_ci if (canvas && image) { 153cb93a386Sopenharmony_ci canvas->drawImage(image, x, y, 154cb93a386Sopenharmony_ci androidkit::utils::SamplingOptions(sampling_desc, sampling_b, sampling_c)); 155cb93a386Sopenharmony_ci } 156cb93a386Sopenharmony_ci} 157cb93a386Sopenharmony_ci 158cb93a386Sopenharmony_civoid Canvas_DrawPath(JNIEnv* env, jobject, jlong native_instance, jlong native_path, 159cb93a386Sopenharmony_ci jlong native_paint) { 160cb93a386Sopenharmony_ci auto* canvas = reinterpret_cast<SkCanvas*>(native_instance); 161cb93a386Sopenharmony_ci auto* path = reinterpret_cast<SkPath* >(native_path); 162cb93a386Sopenharmony_ci auto* paint = reinterpret_cast<SkPaint* >(native_paint); 163cb93a386Sopenharmony_ci if (canvas && paint && path) { 164cb93a386Sopenharmony_ci canvas->drawPath(*path, *paint); 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci} 167cb93a386Sopenharmony_ci 168cb93a386Sopenharmony_ci// jPos: a composite array in the form of [x1, y1, x2, y2, ... ,xn, yn] 169cb93a386Sopenharmony_ci// callers of this function check should throw IllegalArgumentException in Java 170cb93a386Sopenharmony_civoid Canvas_DrawGlyphs(JNIEnv* env, jobject, jlong native_instance, jcharArray jglyphs, 171cb93a386Sopenharmony_ci jfloatArray jPos, jfloat xOrigin, jfloat yOrigin, 172cb93a386Sopenharmony_ci jlong native_font, jlong native_paint) { 173cb93a386Sopenharmony_ci auto* canvas = reinterpret_cast<SkCanvas*>(native_instance); 174cb93a386Sopenharmony_ci auto* font = reinterpret_cast<SkFont*>(native_font); 175cb93a386Sopenharmony_ci auto* paint = reinterpret_cast<SkPaint* >(native_paint); 176cb93a386Sopenharmony_ci if (canvas && font && paint) { 177cb93a386Sopenharmony_ci int count = env->GetArrayLength(jglyphs); 178cb93a386Sopenharmony_ci auto* compositePositions = env->GetFloatArrayElements(jPos, nullptr); 179cb93a386Sopenharmony_ci auto* positions = reinterpret_cast<SkPoint*>(compositePositions); 180cb93a386Sopenharmony_ci auto* glyphs = env->GetCharArrayElements(jglyphs, nullptr); 181cb93a386Sopenharmony_ci canvas->drawGlyphs(count, glyphs, positions, {xOrigin, yOrigin}, *font, *paint); 182cb93a386Sopenharmony_ci 183cb93a386Sopenharmony_ci env->ReleaseCharArrayElements(jglyphs, glyphs, 0); 184cb93a386Sopenharmony_ci env->ReleaseFloatArrayElements(jPos, compositePositions, 0); 185cb93a386Sopenharmony_ci } 186cb93a386Sopenharmony_ci} 187cb93a386Sopenharmony_ci 188cb93a386Sopenharmony_ci} // namespace 189cb93a386Sopenharmony_ci 190cb93a386Sopenharmony_ciint register_androidkit_Canvas(JNIEnv* env) { 191cb93a386Sopenharmony_ci static const JNINativeMethod methods[] = { 192cb93a386Sopenharmony_ci {"nGetWidth" , "(J)I" , reinterpret_cast<void*>(Canvas_GetWidth) }, 193cb93a386Sopenharmony_ci {"nGetHeight" , "(J)I" , reinterpret_cast<void*>(Canvas_GetHeight) }, 194cb93a386Sopenharmony_ci {"nSave" , "(J)I" , reinterpret_cast<void*>(Canvas_Save) }, 195cb93a386Sopenharmony_ci {"nSaveLayer" , "(JJ)I" , reinterpret_cast<void*>(Canvas_SaveLayer) }, 196cb93a386Sopenharmony_ci {"nRestore" , "(J)V" , reinterpret_cast<void*>(Canvas_Restore) }, 197cb93a386Sopenharmony_ci {"nRestoreToCount" , "(JI)V" , reinterpret_cast<void*>(Canvas_RestoreToCount)}, 198cb93a386Sopenharmony_ci {"nGetLocalToDevice", "(J)J" , reinterpret_cast<void*>(Canvas_LocalToDevice) }, 199cb93a386Sopenharmony_ci {"nConcat" , "(JJ)V" , reinterpret_cast<void*>(Canvas_Concat) }, 200cb93a386Sopenharmony_ci {"nConcat16f" , "(J[F)V" , reinterpret_cast<void*>(Canvas_Concat16f) }, 201cb93a386Sopenharmony_ci {"nTranslate" , "(JFFF)V" , reinterpret_cast<void*>(Canvas_Translate) }, 202cb93a386Sopenharmony_ci {"nScale" , "(JFFF)V" , reinterpret_cast<void*>(Canvas_Scale) }, 203cb93a386Sopenharmony_ci {"nClipPath" , "(JJIZ)V" , reinterpret_cast<void*>(Canvas_ClipPath) }, 204cb93a386Sopenharmony_ci {"nClipRect" , "(JFFFFIZ)V" , reinterpret_cast<void*>(Canvas_ClipRect) }, 205cb93a386Sopenharmony_ci {"nClipRRect" , "(JFFFFFFIZ)V" , reinterpret_cast<void*>(Canvas_ClipRRect) }, 206cb93a386Sopenharmony_ci {"nClipShader" , "(JJI)V" , reinterpret_cast<void*>(Canvas_ClipShader) }, 207cb93a386Sopenharmony_ci {"nDrawColor" , "(JFFFF)V" , reinterpret_cast<void*>(Canvas_DrawColor) }, 208cb93a386Sopenharmony_ci {"nDrawRect" , "(JFFFFJ)V" , reinterpret_cast<void*>(Canvas_DrawRect) }, 209cb93a386Sopenharmony_ci {"nDrawImage" , "(JJFFIFF)V" , reinterpret_cast<void*>(Canvas_DrawImage) }, 210cb93a386Sopenharmony_ci {"nDrawPath" , "(JJJ)V" , reinterpret_cast<void*>(Canvas_DrawPath) }, 211cb93a386Sopenharmony_ci {"nDrawGlyphs" , "(J[C[FFFJJ)V", reinterpret_cast<void*>(Canvas_DrawGlyphs) }, 212cb93a386Sopenharmony_ci 213cb93a386Sopenharmony_ci }; 214cb93a386Sopenharmony_ci 215cb93a386Sopenharmony_ci const auto clazz = env->FindClass("org/skia/androidkit/Canvas"); 216cb93a386Sopenharmony_ci return clazz 217cb93a386Sopenharmony_ci ? env->RegisterNatives(clazz, methods, SK_ARRAY_COUNT(methods)) 218cb93a386Sopenharmony_ci : JNI_ERR; 219cb93a386Sopenharmony_ci} 220