• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }