1 /*
2 * Copyright (C) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "ani_drawing_utils.h"
17 #include "lattice_ani/ani_lattice.h"
18 #include "brush_ani/ani_brush.h"
19 #include "canvas_ani/ani_canvas.h"
20 #include "color_filter_ani/ani_color_filter.h"
21 #include "font_ani/ani_font.h"
22 #include "matrix_ani/ani_matrix.h"
23 #include "path_ani/ani_path.h"
24 #include "path_iterator_ani/ani_path_iterator.h"
25 #include "pen_ani/ani_pen.h"
26 #include "region_ani/ani_region.h"
27 #include "round_rect_ani/ani_round_rect.h"
28 #include "sampling_options_ani/ani_sampling_options.h"
29 #include "typeface_ani/ani_typeface.h"
30 #include "typeface_arguments_ani/ani_typeface_arguments.h"
31
32 const char* ANI_CLASS_CLEANER_NAME = "L@ohos/graphics/drawing/drawing/Cleaner;";
33
34 template <typename T>
SafeDelete(ani_long & ptr)35 void SafeDelete(ani_long& ptr)
36 {
37 if (ptr == 0) {
38 ROSEN_LOGE("SafeDelete ptr is 0");
39 return;
40 }
41 T* pointer = reinterpret_cast<T*>(ptr);
42 delete pointer;
43 pointer = nullptr;
44 ptr = 0;
45 }
46
Clean(ani_env * env,ani_object object)47 static void Clean(ani_env* env, ani_object object)
48 {
49 ani_long ptr;
50 ani_status ret = env->Object_GetFieldByName_Long(object, "ptr", &ptr);
51 if (ret != ANI_OK) {
52 ROSEN_LOGE("Clean can't find ptr");
53 return;
54 }
55 ani_ref stringRef = nullptr;
56 ret = env->Object_GetFieldByName_Ref(object, "className", &stringRef);
57 if (ret != ANI_OK) {
58 ROSEN_LOGE("Clean can't find className");
59 return;
60 }
61
62 std::string className = OHOS::Rosen::Drawing::CreateStdString(env, reinterpret_cast<ani_string>(stringRef));
63 using DeleteFunc = void (*)(ani_long&);
64 static const std::unordered_map<std::string, DeleteFunc> deleteMap = {
65 {"Brush", SafeDelete<OHOS::Rosen::Drawing::AniBrush>},
66 {"Canvas", SafeDelete<OHOS::Rosen::Drawing::AniCanvas>},
67 {"ColorFilter", SafeDelete<OHOS::Rosen::Drawing::AniColorFilter>},
68 {"Font", SafeDelete<OHOS::Rosen::Drawing::AniFont>},
69 {"Lattice", SafeDelete<OHOS::Rosen::Drawing::AniLattice>},
70 {"Matrix", SafeDelete<OHOS::Rosen::Drawing::AniMatrix>},
71 {"Path", SafeDelete<OHOS::Rosen::Drawing::AniPath>},
72 {"PathIterator", SafeDelete<OHOS::Rosen::Drawing::AniPathIterator>},
73 {"Pen", SafeDelete<OHOS::Rosen::Drawing::AniPen>},
74 {"Region", SafeDelete<OHOS::Rosen::Drawing::AniRegion>},
75 {"RoundRect", SafeDelete<OHOS::Rosen::Drawing::AniRoundRect>},
76 {"SamplingOptions", SafeDelete<OHOS::Rosen::Drawing::AniSamplingOptions>},
77 {"Typeface", SafeDelete<OHOS::Rosen::Drawing::AniTypeface>},
78 {"TypefaceArguments", SafeDelete<OHOS::Rosen::Drawing::AniTypefaceArguments>}};
79
80 auto it = deleteMap.find(className);
81 if (it != deleteMap.end()) {
82 it->second(ptr);
83 } else {
84 ROSEN_LOGE("Clean can't find className: %{public}s in deleteMap", className.c_str());
85 }
86 }
87
AniCleanerInit(ani_env * env)88 static ani_status AniCleanerInit(ani_env* env)
89 {
90 ani_class cls = nullptr;
91 ani_status ret = env->FindClass(ANI_CLASS_CLEANER_NAME, &cls);
92 if (ret != ANI_OK) {
93 ROSEN_LOGE("[ANI] can't find class: %{public}s", ANI_CLASS_CLEANER_NAME);
94 return ANI_NOT_FOUND;
95 }
96
97 std::array methods = {
98 ani_native_function{"clean", ":V", reinterpret_cast<void*>(Clean)},
99 };
100
101 ret = env->Class_BindNativeMethods(cls, methods.data(), methods.size());
102 if (ret != ANI_OK) {
103 ROSEN_LOGE("[ANI] bind methods fail: %{public}s", ANI_CLASS_CLEANER_NAME);
104 return ANI_NOT_FOUND;
105 }
106
107 return ANI_OK;
108 }
109
110 extern "C" {
ANI_Constructor(ani_vm * vm,uint32_t * result)111 ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result)
112 {
113 ani_env* env;
114 if (vm->GetEnv(ANI_VERSION_1, &env) != ANI_OK) {
115 ROSEN_LOGE("ANI_Constructor Unsupported ANI_VERSION_1");
116 return ANI_ERROR;
117 }
118
119 if (AniCleanerInit(env) != ANI_OK ||
120 OHOS::Rosen::Drawing::AniBrush::AniInit(env) != ANI_OK ||
121 OHOS::Rosen::Drawing::AniCanvas::AniInit(env) != ANI_OK ||
122 OHOS::Rosen::Drawing::AniColorFilter::AniInit(env) != ANI_OK ||
123 OHOS::Rosen::Drawing::AniFont::AniInit(env) != ANI_OK ||
124 OHOS::Rosen::Drawing::AniPen::AniInit(env) != ANI_OK ||
125 OHOS::Rosen::Drawing::AniSamplingOptions::AniInit(env) != ANI_OK ||
126 OHOS::Rosen::Drawing::AniTypeface::AniInit(env) != ANI_OK ||
127 OHOS::Rosen::Drawing::AniLattice::AniInit(env) != ANI_OK ||
128 OHOS::Rosen::Drawing::AniMatrix::AniInit(env) != ANI_OK ||
129 OHOS::Rosen::Drawing::AniPath::AniInit(env) != ANI_OK ||
130 OHOS::Rosen::Drawing::AniPathIterator::AniInit(env) != ANI_OK ||
131 OHOS::Rosen::Drawing::AniRegion::AniInit(env) != ANI_OK ||
132 OHOS::Rosen::Drawing::AniRoundRect::AniInit(env) != ANI_OK ||
133 OHOS::Rosen::Drawing::AniTypefaceArguments::AniInit(env) != ANI_OK) {
134 ROSEN_LOGE("[ANI_Constructor] Init failed");
135 return ANI_ERROR;
136 }
137
138 *result = ANI_VERSION_1;
139 return ANI_OK;
140 }
141 }