diff --git a/Drawing/NDKGraphicsDraw/.gitignore b/Drawing/NDKGraphicsDraw/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/Drawing/NDKGraphicsDraw/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/AppScope/app.json5 b/Drawing/NDKGraphicsDraw/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7223d94d0bde908987ed4dd212f20785af5e88c7 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "app": { + "bundleName": "com.samples.NDKGraphicsDraw", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/Drawing/NDKGraphicsDraw/AppScope/resources/base/element/string.json b/Drawing/NDKGraphicsDraw/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..69c82505ab2e26ab9a6b256c426ae53de9de1d53 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "NDKGraphicsDraw" + } + ] +} diff --git a/Drawing/NDKGraphicsDraw/AppScope/resources/base/media/app_icon.png b/Drawing/NDKGraphicsDraw/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3 Binary files /dev/null and b/Drawing/NDKGraphicsDraw/AppScope/resources/base/media/app_icon.png differ diff --git a/Drawing/NDKGraphicsDraw/README.md b/Drawing/NDKGraphicsDraw/README.md new file mode 100644 index 0000000000000000000000000000000000000000..af222ccaa2317ffe1c4ec0aef2092e0eb67460ff --- /dev/null +++ b/Drawing/NDKGraphicsDraw/README.md @@ -0,0 +1,107 @@ +# NDKGraphicsDraw + +## 介绍 + +本示例基于开发>图形->ArkGraphics 2D(方舟2D图形服务)-> [图形绘制与显示](https://gitee.com/openharmony/docs/tree/OpenHarmony-5.0.1-Release/zh-cn/application-dev/graphics#/openharmony/docs/blob/OpenHarmony-5.0.1-Release/zh-cn/application-dev/graphics/textblock-drawing-arkts.md)中的NDK部分开发。 + +本示例主要功能如下: + +- 演示画布的获取与绘制结果的显示,画布的类型分为直接画布与离屏画布。 +- 演示画布操作及状态处理,通过对画布进行裁剪、平移等操作控制绘图结果 +- 演示绘制效果,绘制经过填充、描边、着色器、滤波器等效果处理过后的图形。 +- 演示图元绘制,绘制多种几何形状、绘制位图及绘制字块。 + +## 效果预览 + +| 主页 | 画布获取 | 绘制效果 | 图元绘制 | +| --------------------------------- | ----------------------------------- | ----------------------------------- | --------------------------------- | +| ![index](./screenshot/index.jpeg) | ![canvas](./screenshot/canvas.jpeg) | ![effect](./screenshot/effect.jpeg) | ![shape](./screenshot/Shape.jpeg) | + + +使用说明: + +1. 点击主页的导航标签组件,进入对应的演示页面。演示页面包括: + - 画布的获取与绘制结果的显示 + - 画布操作及状态处理 + - 基础绘制效果 + - 复杂绘制效果 + - 几何图形绘制 + - 图片绘制 + - 字块绘制 +2. 在演示页面内点击绘制按钮,界面绘制出对应图案。 +3. 点击返回按钮,退出应用。 + +## 工程目录 + +``` +NDKGraphicsDraw +entry/src/main +├──cpp +│ ├──common +│ │ └──log_common.h (Log相关定义声明) +│ ├──plugin +│ │ ├──plugin_manager.cpp (生命周期管理类) +│ │ └──plugin_manager.h +│ ├──samples +│ │ ├──sample_graphics.cpp (图形绘制类) +│ │ └──sample_graphics.h +│ ├──CMakeLists.txt (CMake编译配置文件) +│ └──napi_init.cpp (初始化Napi接口) +├──ets +│ ├──drawing +| | └──pages +| | ├──BasicEffect.ets (基础渲染效果界面) +| | ├──CanvasGetResult.ets (画布的获取与绘制结果的显示界面) +| | ├──CanvasOperationState.ets (画布操作及状态处理界面) +| | ├──ComplexEffect.ets (复杂绘制效果界面) +| | ├──PixelMapDrawing.ets (图片绘制界面) +| | ├──ShapeDrawing.ets (几何形状绘制界面) +| | └──TextBlockDrawing.ets (字块绘制界面) +| ├──interface +│ │ └──XComponentContext.ts (声明Napi接口,供ts侧调用) +│ └──pages +│ └──Index.ets (UI主界面) +└──resources (资源文件) +entry/src/ohosTest/ets/ +├── test +| ├── Ability.test.ets (UI测试代码) +| └── List.test.ets (测试套件列表) +└── utils + └── Logger.ets (logger日志类) +``` + +## 具体实现 + +1. 利用Native XComponent来获取NativeWindow实例、获取布局/事件信息、注册事件回调并通过Drawing API实现在页面上绘制形状。功能主要包括演示画布获取、画布操作、绘制效果和绘制图形、图形、文字。 +2. 通过在IDE中创建Native c++ 工程,在c++代码中定义对外接口为draw,在js侧调用该接口。draw通过解析传入的参数创建不同的画布类型,初始化并调用对应的具体绘图函数。 +3. 在XComponent的OnSurfaceCreated回调中获取NativeWindow实例并初始化NativeWindow环境。调用OH_NativeXComponent_GetXComponentSize接口获取XComponent的宽高,并以此为输入调用Drawing相关的绘制接口在NativeWindow上绘制出图案。 + +## 相关权限 + +不涉及 + +## 依赖 + +不涉及。 + +## 约束和限制 + +1. 本示例仅支持标准系统上运行,支持设备:华为手机。 + +2. HarmonyOS系统:HarmonyOS 5.0.4 Release及以上。 + +3. DevEco Studio版本:DevEco Studio 5.0.4 Release及以上。 + +4. HarmonyOS SDK版本:HarmonyOS 5.0.4 Release及以上。 + +## 下载 + +如需单独下载本工程,执行如下命令: + +``` +git init +git config core.sparsecheckout true +echo code/DocsSample/Drawing/NDKGraphicsDraw/ > .git/info/sparse-checkout +git remote add origin OpenHarmony/applications_app_samples +git pull origin master +``` \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/build-profile.json5 b/Drawing/NDKGraphicsDraw/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2f3c86865016b9cfbc04190d6b99d9b149ec7d7c --- /dev/null +++ b/Drawing/NDKGraphicsDraw/build-profile.json5 @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "app": { + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.4(16)", + "targetSdkVersion": "5.0.4(16)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "strictMode": { + "caseSensitiveCheck": true, + "useNormalizedOHMUrl": true + } + } + } + ], + "buildModeSet": [ + { + "name": "debug" + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/code-linter.json5 b/Drawing/NDKGraphicsDraw/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..28586467ee7a761c737d8654a73aed6fddbc3c71 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/code-linter.json5 @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "files": [ + "**/*.ets" + ], + "ignore": [ + "**/src/ohosTest/**/*", + "**/src/test/**/*", + "**/src/mock/**/*", + "**/node_modules/**/*", + "**/oh_modules/**/*", + "**/build/**/*", + "**/.preview/**/*" + ], + "ruleSet": [ + "plugin:@performance/recommended", + "plugin:@typescript-eslint/recommended" + ], + "rules": { + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/.gitignore b/Drawing/NDKGraphicsDraw/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/build-profile.json5 b/Drawing/NDKGraphicsDraw/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f24addba76d1c74999c890245fdc45a1c681db97 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/build-profile.json5 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "apiType": "stageMode", + "buildOption": { + "externalNativeOptions": { + "abiFilters": ["arm64-v8a", "x86_64"], + "path": "./src/main/cpp/CMakeLists.txt", + "arguments": "", + "cppFlags": "", + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": false, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + }, + "nativeLib": { + "debugSymbol": { + "strip": true, + "exclude": [] + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/hvigorfile.ts b/Drawing/NDKGraphicsDraw/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..e4f43d54667f8327c367c8096bd08bb8c75aff54 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/hvigorfile.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { hapTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Drawing/NDKGraphicsDraw/entry/obfuscation-rules.txt b/Drawing/NDKGraphicsDraw/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/obfuscation-rules.txt @@ -0,0 +1,23 @@ +# Define project specific obfuscation rules here. +# You can include the obfuscation configuration files in the current module's build-profile.json5. +# +# For more details, see +# https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope + +-enable-property-obfuscation +-enable-toplevel-obfuscation +-enable-filename-obfuscation +-enable-export-obfuscation \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/oh-package.json5 b/Drawing/NDKGraphicsDraw/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..118bdd4fe7699368a010e04c24f5bfc887cf1298 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/oh-package.json5 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "name": "entry", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "", + "author": "", + "license": "", + "dependencies": { + "libentry.so": "file:./src/main/cpp/types/libentry" + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/CMakeLists.txt b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..926129846bb235e8db49edd7bfe46e6655dd4d23 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,32 @@ +# the minimum version of CMake. +cmake_minimum_required(VERSION 3.5.0) +project(NDKGraphicDraw) + +set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}) + +if(DEFINED PACKAGE_FIND_FILE) + include(${PACKAGE_FIND_FILE}) +endif() + +include_directories(${NATIVERENDER_ROOT_PATH} + ${NATIVERENDER_ROOT_PATH}/include + ) + +add_library(entry SHARED + napi_init.cpp + samples/sample_graphics.cpp + plugin/plugin_manager.cpp + utils/adaptation_util.cpp + ) +target_link_libraries(entry PUBLIC + EGL + GLESv3 + libhilog_ndk.z.so + libace_napi.z.so + libnative_drawing.so + libnative_window.so + libace_ndk.z.so + libnative_display_soloist.so + libpixelmap.so + libnative_display_manager.so + ) \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/common/log_common.h b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/common/log_common.h new file mode 100644 index 0000000000000000000000000000000000000000..d6f6a00c0040707eceeff100274ac6b8acbe7801 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/common/log_common.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LOG_COMMON_H +#define LOG_COMMON_H +#include +#define LOG_PRINT_DOMAIN 0xFF00 +#define APP_LOG_DOMAIN 0x0001 +constexpr const char *APP_LOG_TAG = "NDKGraphicsDrawSample"; +#define SAMPLE_LOGI(...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define SAMPLE_LOGD(...) ((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define SAMPLE_LOGW(...) ((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) +#define SAMPLE_LOGE(...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__)) + +#endif // LOG_COMMON_H diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/napi_init.cpp b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a7afa7d28f7a8fed7cda89806bad5668bba65825 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/napi_init.cpp @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "napi/native_api.h" +#include "common/log_common.h" +#include "plugin/plugin_manager.h" + +EXTERN_C_START +static napi_value Init(napi_env env, napi_value exports) +{ + SAMPLE_LOGI("napi init"); + PluginManager::GetInstance()->Export(env, exports); + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + .nm_version = 1, + .nm_flags = 0, + .nm_filename = nullptr, + .nm_register_func = Init, + .nm_modname = "entry", + .nm_priv = ((void*)0), + .reserved = { 0 }, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) +{ + napi_module_register(&demoModule); +} diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/plugin/plugin_manager.cpp b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/plugin/plugin_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a24d9a076df77d16bee97a6bbb75927a9bce1e39 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/plugin/plugin_manager.cpp @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include "common/log_common.h" +#include "plugin_manager.h" + +PluginManager *PluginManager::GetInstance() +{ + static PluginManager pluginManager; + return &pluginManager; +} + +PluginManager::~PluginManager() +{ + SAMPLE_LOGI("~PluginManager"); + for (auto iter = nativeXComponentMap_.begin(); iter != nativeXComponentMap_.end(); ++iter) { + if (iter->second != nullptr) { + delete iter->second; + iter->second = nullptr; + } + } + nativeXComponentMap_.clear(); + + for (auto iter = pluginRenderMap_.begin(); iter != pluginRenderMap_.end(); ++iter) { + if (iter->second != nullptr) { + delete iter->second; + iter->second = nullptr; + } + } + pluginRenderMap_.clear(); +} + +void PluginManager::Export(napi_env env, napi_value exports) +{ + nativeXComponentMap_.clear(); + pluginRenderMap_.clear(); + if ((env == nullptr) || (exports == nullptr)) { + SAMPLE_LOGE("Export: env or exports is null"); + return; + } + + napi_value exportInstance = nullptr; + if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) { + SAMPLE_LOGE("Export: napi_get_named_property fail"); + return; + } + + OH_NativeXComponent *nativeXComponent = nullptr; + if (napi_unwrap(env, exportInstance, reinterpret_cast(&nativeXComponent)) != napi_ok) { + SAMPLE_LOGE("Export: napi_unwrap fail"); + return; + } + + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + SAMPLE_LOGE("Export: OH_NativeXComponent_GetXComponentId fail"); + return; + } + + std::string id(idStr); + auto context = PluginManager::GetInstance(); + if ((context != nullptr) && (nativeXComponent != nullptr)) { + context->SetNativeXComponent(id, nativeXComponent); + auto render = context->GetRender(id); + if (render != nullptr) { + render->RegisterCallback(nativeXComponent); + render->Export(env, exports); + } else { + SAMPLE_LOGE("render is nullptr"); + } + } +} + +void PluginManager::SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent) +{ + SAMPLE_LOGI("set native xComponent, ID = %{public}s.", id.c_str()); + if (nativeXComponent == nullptr) { + SAMPLE_LOGE("xcomponent null"); + return; + } + + if (nativeXComponentMap_.find(id) == nativeXComponentMap_.end()) { + nativeXComponentMap_[id] = nativeXComponent; + return; + } + + if (nativeXComponentMap_[id] != nativeXComponent) { + OH_NativeXComponent *tmp = nativeXComponentMap_[id]; + delete tmp; + tmp = nullptr; + nativeXComponentMap_[id] = nativeXComponent; + } +} + +SampleGraphics *PluginManager::GetRender(std::string &id) +{ + if (pluginRenderMap_.find(id) == pluginRenderMap_.end()) { + SampleGraphics *instance = SampleGraphics::GetInstance(id); + pluginRenderMap_[id] = instance; + return instance; + } + return pluginRenderMap_[id]; +} diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/plugin/plugin_manager.h b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/plugin/plugin_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..6ed97b62f8dda964d068a04d79a3adf05fa07455 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/plugin/plugin_manager.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef PLUGIN_MANAGER_H +#define PLUGIN_MANAGER_H + +#include +#include +#include +#include +#include +#include "samples/sample_graphics.h" + +class PluginManager { +public: + ~PluginManager(); + + static PluginManager *GetInstance(); + + void SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent); + SampleGraphics *GetRender(std::string &id); + void Export(napi_env env, napi_value exports); +private: + + std::unordered_map nativeXComponentMap_; + std::unordered_map pluginRenderMap_; +}; +#endif // PLUGIN_MANAGER_H diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/samples/sample_graphics.cpp b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/samples/sample_graphics.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1e9afea7007e9af2940213176a915f5331c3a0c6 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/samples/sample_graphics.cpp @@ -0,0 +1,1427 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +// [Start ndk_graphics_draw_include_native_drawing_surface_and_gpu_context] +#include +#include +// [End ndk_graphics_draw_include_native_drawing_surface_and_gpu_context] +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/log_common.h" +#include "sample_graphics.h" +#include "utils/adaptation_util.h" + +const uint16_t RGBA_MIN = 0x00; +const uint16_t RGBA_MAX = 0xFF; +const uint16_t RGBA_SIZE = 4; + +static std::unordered_map g_displaySync; +// 多设备适配工具类,按设备宽度等比例缩放适配 +AdaptationUtil* adaptationUtil = AdaptationUtil::GetInstance(); +float SampleGraphics::value100_ = adaptationUtil->GetWidth(100.f); +float SampleGraphics::value150_ = adaptationUtil->GetWidth(150.f); +float SampleGraphics::value200_ = adaptationUtil->GetWidth(200.f); +float SampleGraphics::value300_ = adaptationUtil->GetWidth(300.f); +float SampleGraphics::value400_ = adaptationUtil->GetWidth(400.f); +float SampleGraphics::value500_ = adaptationUtil->GetWidth(500.f); +float SampleGraphics::value551_ = adaptationUtil->GetWidth(551.f); +float SampleGraphics::value600_ = adaptationUtil->GetWidth(600.f); +float SampleGraphics::value630_ = adaptationUtil->GetWidth(630.f); +float SampleGraphics::value700_ = adaptationUtil->GetWidth(700.f); +float SampleGraphics::value800_ = adaptationUtil->GetWidth(800.f); +float SampleGraphics::value900_ = adaptationUtil->GetWidth(900.f); +float SampleGraphics::value1000_ = adaptationUtil->GetWidth(1000.f); +float SampleGraphics::value1200_ = adaptationUtil->GetWidth(1200.f); + +// [Start ndk_graphics_draw_initialize_egl_context] +EGLConfig getConfig(int version, EGLDisplay eglDisplay) +{ + int attribList[] = {EGL_SURFACE_TYPE, + EGL_WINDOW_BIT, + EGL_RED_SIZE, + 8, + EGL_GREEN_SIZE, + 8, + EGL_BLUE_SIZE, + 8, + EGL_ALPHA_SIZE, + 8, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_ES2_BIT, + EGL_NONE}; + EGLConfig configs = NULL; + int configsNum; + + if (!eglChooseConfig(eglDisplay, attribList, &configs, 1, &configsNum)) { + SAMPLE_LOGE("eglChooseConfig ERROR"); + return NULL; + } + + return configs; +} + +int32_t SampleGraphics::InitializeEglContext() +{ + EGLDisplay_ = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (EGLDisplay_ == EGL_NO_DISPLAY) { + SAMPLE_LOGE("unable to get EGL display."); + return -1; + } + + EGLint eglMajVers; + EGLint eglMinVers; + if (!eglInitialize(EGLDisplay_, &eglMajVers, &eglMinVers)) { + EGLDisplay_ = EGL_NO_DISPLAY; + SAMPLE_LOGE("unable to initialize display"); + return -1; + } + + int version = 3; + EGLConfig_ = getConfig(version, EGLDisplay_); + if (EGLConfig_ == nullptr) { + SAMPLE_LOGE("GLContextInit config ERROR"); + return -1; + } + + /* Create EGLContext from */ + int attribList[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE}; // 2 size + + EGLContext_ = eglCreateContext(EGLDisplay_, EGLConfig_, EGL_NO_CONTEXT, attribList); + + EGLint attribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE}; + EGLSurface_ = eglCreatePbufferSurface(EGLDisplay_, EGLConfig_, attribs); + if (!eglMakeCurrent(EGLDisplay_, EGLSurface_, EGLSurface_, EGLContext_)) { + SAMPLE_LOGE("eglMakeCurrent error = %{public}d", eglGetError()); + return -1; + } + + SAMPLE_LOGE("Init success."); + return 0; +} +// [End ndk_graphics_draw_initialize_egl_context] + +// [Start ndk_graphics_draw_deinitialize_egl_context] +void SampleGraphics::DeInitializeEglContext() +{ + EGLBoolean ret = eglDestroySurface(EGLDisplay_, EGLSurface_); + if (!ret) { + SAMPLE_LOGE("eglDestroySurface failure."); + } + + ret = eglDestroyContext(EGLDisplay_, EGLContext_); + if (!ret) { + SAMPLE_LOGE("eglDestroyContext failure."); + } + + ret = eglTerminate(EGLDisplay_); + if (!ret) { + SAMPLE_LOGE("eglTerminate failure."); + } + + EGLSurface_ = NULL; + EGLContext_ = NULL; + EGLDisplay_ = NULL; +} +// [End ndk_graphics_draw_deinitialize_egl_context] + +static void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) +{ + SAMPLE_LOGI("OnSurfaceCreatedCB"); + if ((component == nullptr) || (window == nullptr)) { + SAMPLE_LOGE("OnSurfaceCreatedCB: component or window is null"); + return; + } + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + SAMPLE_LOGE("OnSurfaceCreatedCB: Unable to get XComponent id"); + return; + } + std::string id(idStr); + auto render = SampleGraphics::GetInstance(id); + OHNativeWindow *nativeWindow = static_cast(window); + render->SetNativeWindow(nativeWindow); + + uint64_t width; + uint64_t height; + int32_t xSize = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height); + if ((xSize == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) { + render->SetHeight(height); + render->SetWidth(width); + SAMPLE_LOGI("xComponent width = %{public}llu, height = %{public}llu", width, height); + } +} + +static void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) +{ + SAMPLE_LOGI("OnSurfaceDestroyedCB"); + if ((component == nullptr) || (window == nullptr)) { + SAMPLE_LOGE("OnSurfaceDestroyedCB: component or window is null"); + return; + } + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + if (OH_NativeXComponent_GetXComponentId(component, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + SAMPLE_LOGE("OnSurfaceDestroyedCB: Unable to get XComponent id"); + return; + } + std::string id(idStr); + SampleGraphics::Release(id); +} + +static std::unordered_map g_instance; + +void SampleGraphics::SetWidth(uint64_t width) { width_ = width; } + +void SampleGraphics::SetHeight(uint64_t height) { height_ = height; } + +void SampleGraphics::SetNativeWindow(OHNativeWindow *nativeWindow) { nativeWindow_ = nativeWindow; } + +void SampleGraphics::Prepare() +{ + if (nativeWindow_ == nullptr) { + SAMPLE_LOGE("nativeWindow_ is nullptr"); + return; + } + // 这里的nativeWindow是从上一步骤中的回调函数中获得的 + // [Start ndk_graphics_draw_get_buffer_handle] + // 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例 + int ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer_, &fenceFd_); + SAMPLE_LOGI("request buffer ret = %{public}d", ret); + // 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle + bufferHandle_ = OH_NativeWindow_GetBufferHandleFromNative(buffer_); + // [End ndk_graphics_draw_get_buffer_handle] + // [Start ndk_graphics_draw_get_mapped_addr] + // 使用系统mmap接口拿到bufferHandle的内存虚拟地址 + mappedAddr_ = static_cast( + mmap(bufferHandle_->virAddr, bufferHandle_->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle_->fd, 0)); + if (mappedAddr_ == MAP_FAILED) { + SAMPLE_LOGE("mmap failed"); + } + // [End ndk_graphics_draw_get_mapped_addr] +} + +void SampleGraphics::Create() +{ + uint32_t width = static_cast(bufferHandle_->stride / 4); + // [Start ndk_graphics_draw_create_canvas] + // 创建一个bitmap对象 + cScreenBitmap_ = OH_Drawing_BitmapCreate(); + // 定义bitmap的像素格式 + OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE}; + // 构造对应格式的bitmap + OH_Drawing_BitmapBuild(cScreenBitmap_, width, height_, &cFormat); + + // 创建一个canvas对象 + cScreenCanvas_ = OH_Drawing_CanvasCreate(); + // 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中 + OH_Drawing_CanvasBind(cScreenCanvas_, cScreenBitmap_); + // [End ndk_graphics_draw_create_canvas] + // 使用白色清除画布内容 + OH_Drawing_CanvasClear(cScreenCanvas_, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MAX, 0xFF)); +} + +void SampleGraphics::CreateByCPU() +{ + // [Start ndk_graphics_draw_create_canvas_by_cpu] + // 创建一个离屏位图对象 + cOffScreenBitmap_ = OH_Drawing_BitmapCreate(); + // 设置位图属性 + OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_PREMUL}; + // 设置位图长宽(按需设置) + uint32_t width = 800; + uint32_t height = 800; + // 初始化位图 + OH_Drawing_BitmapBuild(cOffScreenBitmap_, width, height, &cFormat); + // 创建一个离屏Canvas对象 + cCPUCanvas_ = OH_Drawing_CanvasCreate(); + // 将离屏Canvas与离屏bitmap绑定,离屏Canvas绘制的内容会输出到绑定的离屏bitmap内存中 + OH_Drawing_CanvasBind(cCPUCanvas_, cOffScreenBitmap_); + // [End ndk_graphics_draw_create_canvas_by_cpu] + // [Start ndk_graphics_draw_clear_canvas_cpu] + // 将背景设置为白色 + OH_Drawing_CanvasClear(cCPUCanvas_, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MAX, 0xFF)); + // [End ndk_graphics_draw_clear_canvas_cpu] + + // 创建一个bitmap对象 + cScreenBitmap_ = OH_Drawing_BitmapCreate(); + // 构造对应格式的bitmap + OH_Drawing_BitmapBuild(cScreenBitmap_, width_, height_, &cFormat); + // 创建一个canvas对象 + cScreenCanvas_ = OH_Drawing_CanvasCreate(); + // 将Canvas与bitmap绑定,Canvas绘制的内容会输出到绑定的bitmap内存中 + OH_Drawing_CanvasBind(cScreenCanvas_, cScreenBitmap_); +} + +void SampleGraphics::CreateByGPU() +{ + // 创建一个bitmap对象 + cScreenBitmap_ = OH_Drawing_BitmapCreate(); + // 定义bitmap的像素格式 + OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE}; + // 构造对应格式的bitmap + OH_Drawing_BitmapBuild(cScreenBitmap_, width_, height_, &cFormat); + // 创建一个canvas对象 + cScreenCanvas_ = OH_Drawing_CanvasCreate(); + // 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中 + OH_Drawing_CanvasBind(cScreenCanvas_, cScreenBitmap_); + + // [Start ndk_graphics_draw_create_canvas_by_gpu] + // 设置宽高(按需设定) + int32_t cWidth = 800; + int32_t cHeight = 800; + // 设置图像,包括宽度、高度、颜色格式和透明度格式 + OH_Drawing_Image_Info imageInfo = {cWidth, cHeight, COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_PREMUL}; + // GPU上下文的选项 + OH_Drawing_GpuContextOptions options{true}; + + // 创建一个使用OpenGL(GL)作为其GPU后端的绘图上下文 + OH_Drawing_GpuContext *gpuContext = OH_Drawing_GpuContextCreateFromGL(options); + // 创建surface对象 + OH_Drawing_Surface *surface = OH_Drawing_SurfaceCreateFromGpuContext(gpuContext, true, imageInfo); + // 创建一个canvas对象 + cGPUCanvas_ = OH_Drawing_SurfaceGetCanvas(surface); + // [End ndk_graphics_draw_create_canvas_by_gpu] + // [Start ndk_graphics_draw_clear_canvas_gpu] + // 将背景设置为白色 + OH_Drawing_CanvasClear(cGPUCanvas_, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MAX, 0xFF)); + // [End ndk_graphics_draw_clear_canvas_gpu] +} + +void SampleGraphics::DisPlay() +{ + // 画完后获取像素地址,地址指向的内存包含画布画的像素数据 + void *bitmapAddr = OH_Drawing_BitmapGetPixels(cScreenBitmap_); + uint32_t *value = static_cast(bitmapAddr); + + uint32_t *pixel = static_cast(mappedAddr_); // 使用mmap获取到的地址来访问内存 + if (pixel == nullptr) { + SAMPLE_LOGE("pixel is null"); + return; + } + if (value == nullptr) { + SAMPLE_LOGE("value is null"); + return; + } + for (uint32_t x = 0; x < width_; x++) { + for (uint32_t y = 0; y < height_; y++) { + *pixel++ = *value++; + } + } + // [Start ndk_graphics_draw_native_window_flush_buffer] + // 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。 + Region region{nullptr, 0}; + // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。 + OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer_, fenceFd_, region); + // [End ndk_graphics_draw_native_window_flush_buffer] + // 内存使用完记得去掉内存映射 + int result = munmap(mappedAddr_, bufferHandle_->size); + if (result == -1) { + SAMPLE_LOGE("munmap failed!"); + } +} + +void SampleGraphics::DisPlayCPU() +{ + // [Start ndk_graphics_draw_drawing_to_window_canvas_cpu] + // 将离屏bitmap中的内容绘制到屏幕画布,实现上屏操作 + OH_Drawing_CanvasDrawBitmap(cScreenCanvas_, cOffScreenBitmap_, 0, 0); + // [End ndk_graphics_draw_drawing_to_window_canvas_cpu] + DisPlay(); +} + +void SampleGraphics::DisPlayGPU() +{ + // 设置宽高(按需设定) + int32_t cWidth = 800; + int32_t cHeight = 800; + // 设置图像,包括宽度、高度、颜色格式和透明度格式 + OH_Drawing_Image_Info imageInfo = {cWidth, cHeight, COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_PREMUL}; + // [Start ndk_graphics_draw_drawing_to_window_canvas_gpu] + void* dstPixels = malloc(cWidth * cHeight * RGBA_SIZE); // 4 for rgba + OH_Drawing_CanvasReadPixels(cGPUCanvas_, &imageInfo, dstPixels, RGBA_SIZE * cWidth, 0, 0); + OH_Drawing_Bitmap* cOffScreenBitmap_ = OH_Drawing_BitmapCreateFromPixels(&imageInfo, dstPixels, + RGBA_SIZE * cWidth); + OH_Drawing_CanvasDrawBitmap(cScreenCanvas_, cOffScreenBitmap_, 0, 0); + // [End ndk_graphics_draw_drawing_to_window_canvas_gpu] + DisPlay(); +} + +void SampleGraphics::DrawClipOperation(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_canvas_clip] + // 创建画刷对象 + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + // 设置画刷填充颜色为蓝色 + OH_Drawing_BrushSetColor(brush, 0xff0000ff); + // 在画布中设置画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value400_, value400_, value1200_, value1200_); + // 裁剪矩形区域 + OH_Drawing_CanvasClipRect(canvas, rect, OH_Drawing_CanvasClipOp::INTERSECT, true); + OH_Drawing_Point *point = OH_Drawing_PointCreate(value600_, value600_); + // 绘制圆形 + OH_Drawing_CanvasDrawCircle(canvas, point, value600_); + // 去除画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁画刷对象并收回其占的内存 + OH_Drawing_BrushDestroy(brush); + // [End ndk_graphics_draw_canvas_clip] +} + +void SampleGraphics::DrawTranslationOperation(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_canvas_translation] + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 设置填充颜色 + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画布中的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建在水平和垂直方向分别平移300px的矩阵对象 + OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreateTranslation(value300_, value300_); + // 对Canvas进行矩阵变换 + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制矩形 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value200_, value300_, value700_, value600_); + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + // [End ndk_graphics_draw_canvas_translation] +} + +void SampleGraphics::DrawRotationOperation(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_canvas_rotation] + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 设置填充颜色 + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画布中的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建旋转的矩阵对象,三个参数分别是旋转角度和旋转中心坐标 + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateRotation(45, value200_, value300_); + // 对Canvas进行矩阵变换 + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制矩形 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value200_, value300_, value700_, value600_); + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + // [End ndk_graphics_draw_canvas_rotation] +} + +void SampleGraphics::DrawScaleOperation(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_canvas_scale] + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 设置填充颜色 + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画布中的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建缩放的矩阵对象,4个参数分别是旋转中心坐标和水平垂直方向的缩放因子 + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateScale(2, 2, value200_, value300_); + // 对Canvas进行矩阵变换 + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制矩形 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value200_, value300_, value700_, value600_); + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + // [End ndk_graphics_draw_canvas_scale] +} + +void SampleGraphics::DrawStateOperation(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_canvas_state_operation] + // 创建画笔对象 + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + // 设置画笔描边颜色 + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画笔线宽为20 + OH_Drawing_PenSetWidth(pen, 20); + // 在画布中设置画笔 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 保存当前画布状态,当前是不存在放大等操作的,这个原始状态会被保存下来 + OH_Drawing_CanvasSave(canvas); + OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreateScale(2, 2, 2, 2); + // 放大画布 + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + OH_Drawing_Point* point = OH_Drawing_PointCreate(value300_, value300_); + // 绘制圆形,因为执行过放大操作,所以此时绘制的是大圆 + OH_Drawing_CanvasDrawCircle(canvas, point, value200_); + // 恢复操作,将恢复到没有放大的原始状态 + OH_Drawing_CanvasRestore(canvas); + // 绘制圆形,因为已经恢复没有放大的原始状态,所以此时绘制的小圆 + OH_Drawing_CanvasDrawCircle(canvas, point, value200_); + // 去除画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁画笔对象并收回其占的内存 + OH_Drawing_PenDestroy(pen); + OH_Drawing_PointDestroy(point); + OH_Drawing_MatrixDestroy(matrix); + // [End ndk_graphics_draw_canvas_state_operation] +} + +void SampleGraphics::DrawFilling(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_create_brush] + // 创建画刷 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // [End ndk_graphics_draw_create_brush] + // [Start ndk_graphics_draw_brush_set_color] + // 设置填充颜色为红色 + uint32_t color = 0xffff0000; + OH_Drawing_BrushSetColor(brush, color); + // [End ndk_graphics_draw_brush_set_color] + // [Start ndk_graphics_draw_brush_set_antialias] + // 开启抗锯齿效果 + OH_Drawing_BrushSetAntiAlias(brush, true); + // [End ndk_graphics_draw_brush_set_antialias] + // [Start ndk_graphics_draw_canvas_attach_brush] + // 设置画布的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // [End ndk_graphics_draw_canvas_attach_brush] + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(0, 0, value800_, value800_); + // 绘制椭圆 + OH_Drawing_CanvasDrawOval(canvas, rect); + // [Start ndk_graphics_draw_canvas_detach_brush] + // 去除画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // [End ndk_graphics_draw_canvas_detach_brush] + // [Start ndk_graphics_draw_brush_destroy] + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + // [End ndk_graphics_draw_brush_destroy] + OH_Drawing_RectDestroy(rect); +} + +void SampleGraphics::DrawStroke(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_create_drawing_pen] + // 创建画笔 + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + // [End ndk_graphics_draw_create_drawing_pen] + // [Start ndk_graphics_draw_pen_set_color] + // 设置画笔颜色为红色 + uint32_t color = 0xffff0000; + OH_Drawing_PenSetColor(pen, color); + // [End ndk_graphics_draw_pen_set_color] + // [Start ndk_graphics_draw_pen_set_stroke_width] + // 设置画笔的线宽为50像素 + float width = 50.0; + OH_Drawing_PenSetWidth(pen, width); + // [End ndk_graphics_draw_pen_set_stroke_width] + // [Start ndk_graphics_draw_pen_set_antialias] + // 设置画笔抗锯齿 + OH_Drawing_PenSetAntiAlias(pen, true); + // [End ndk_graphics_draw_pen_set_antialias] + // [Start ndk_graphics_draw_pen_set_cap_style] + // 设置画笔线帽样式 + OH_Drawing_PenSetCap(pen, OH_Drawing_PenLineCapStyle::LINE_ROUND_CAP); + // [End ndk_graphics_draw_pen_set_cap_style] + // [Start ndk_graphics_draw_pen_set_join_style] + // 设置画笔转角样式 + OH_Drawing_PenSetJoin(pen, OH_Drawing_PenLineJoinStyle::LINE_BEVEL_JOIN); + // [End ndk_graphics_draw_pen_set_join_style] + // [Start ndk_graphics_draw_canvas_attach_pen] + // 设置画布的画笔 + OH_Drawing_CanvasAttachPen(canvas, pen); + // [End ndk_graphics_draw_canvas_attach_pen] + // 创建路径 + OH_Drawing_Path* path = OH_Drawing_PathCreate(); + float aX = value100_; + float aY = value100_; + float bX = value100_; + float bY = value800_; + float cX = value800_; + float cY = value800_; + float dX = value800_; + float dY = value100_; + // 到起始点 + OH_Drawing_PathMoveTo(path, aX, aY); + // 绘制直线 + OH_Drawing_PathLineTo(path, bX, bY); + OH_Drawing_PathLineTo(path, cX, cY); + OH_Drawing_PathLineTo(path, dX, dY); + // 绘制闭合路径 + OH_Drawing_CanvasDrawPath(canvas, path); + // [Start ndk_graphics_draw_canvas_detach_pen] + // 去除掉画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // [End ndk_graphics_draw_canvas_detach_pen] + // [Start ndk_graphics_draw_pen_destroy] + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + // [End ndk_graphics_draw_pen_destroy] + OH_Drawing_PathDestroy(path); +} + +void SampleGraphics::DrawMixedMode(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_CanvasClear(canvas, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MIN, RGBA_MIN, RGBA_MIN)); + // [Start ndk_graphics_draw_mixed_mode] + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 设置目标像素颜色 + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 将目标像素的画刷效果设置到Canvas中 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建矩形对象 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value100_, value100_, value600_, value600_); + // 绘制矩形(目标像素) + OH_Drawing_CanvasDrawRect(canvas, rect); + // 设置源像素颜色 + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MIN, RGBA_MIN, 0xFF)); + // 设置混合模式为叠加模式 + OH_Drawing_BrushSetBlendMode(brush, OH_Drawing_BlendMode::BLEND_MODE_PLUS); + // 将源像素的画刷效果设置到Canvas中 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建圆心的点对象 + OH_Drawing_Point *point = OH_Drawing_PointCreate(value600_, value600_); + // 绘制圆(源像素) + OH_Drawing_CanvasDrawCircle(canvas, point, value300_); + // 去除掉画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_RectDestroy(rect); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_PointDestroy(point); + // [End ndk_graphics_draw_mixed_mode] +} + +void SampleGraphics::DrawPathEffect(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_path_effect] + // 创建画笔 + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + // 设置画笔描边颜色 + OH_Drawing_PenSetColor(pen, 0xffff0000); + // 设置画笔线宽为10 + OH_Drawing_PenSetWidth(pen, 10); + // 表示10px的实线,5px的间隔,2px的实线,5px的间隔,以此循环 + float intervals[] = {10, 5, 2, 5}; + // 设置虚线路径效果 + OH_Drawing_PathEffect *pathEffect = OH_Drawing_CreateDashPathEffect(intervals, 4, 0.0); + OH_Drawing_PenSetPathEffect(pen, pathEffect); + // 在画布上设置画笔,请确保已获取得到画布对象 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 创建矩形 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value900_, value900_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除掉画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_RectDestroy(rect); + OH_Drawing_PathEffectDestroy(pathEffect); + // [End ndk_graphics_draw_path_effect] +} + +void SampleGraphics::DrawLinearGradient(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_linear_gradient] + // 开始点 + OH_Drawing_Point *startPt = OH_Drawing_PointCreate(20, 20); + // 结束点 + OH_Drawing_Point *endPt = OH_Drawing_PointCreate(value900_, value900_); + // 颜色数组 + uint32_t colors[] = {0xFFFFFF00, 0xFFFF0000, 0xFF0000FF}; + // 相对位置数组 + float pos[] = {0.0f, 0.5f, 1.0f}; + // 创建线性渐变着色器效果 + OH_Drawing_ShaderEffect *colorShaderEffect = + OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 基于画刷设置着色器效果 + OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect); + // 在画布上设置画刷,请确保已获取得到画布对象 + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value100_, value100_, value900_, value900_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除掉画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + OH_Drawing_ShaderEffectDestroy(colorShaderEffect); + OH_Drawing_PointDestroy(startPt); + OH_Drawing_PointDestroy(endPt); + // [End ndk_graphics_draw_linear_gradient] +} + +void SampleGraphics::DrawPathGradient(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_path_gradient] + // 圆心坐标 + OH_Drawing_Point *centerPt = OH_Drawing_PointCreate(value500_, value500_); + // 半径 + float radius = value600_; + // 颜色数组 + uint32_t gColors[] = {0xFFFF0000, 0xFF00FF00, 0xFF0000FF}; + // 相对位置数组 + float_t gPos[] = {0.0f, 0.25f, 0.75f}; + // 创建径向渐变着色器效果 + OH_Drawing_ShaderEffect *colorShaderEffect = + OH_Drawing_ShaderEffectCreateRadialGradient(centerPt, radius, gColors, gPos, 3, OH_Drawing_TileMode::REPEAT); + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 基于画刷设置着色器效果 + OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect); + // 在画布上设置画刷,请确保已获取得到画布对象 + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value100_, value100_, value900_, value900_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除掉画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + OH_Drawing_ShaderEffectDestroy(colorShaderEffect); + OH_Drawing_PointDestroy(centerPt); + // [End ndk_graphics_draw_path_gradient] +} + +void SampleGraphics::DrawSectorGradient(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_sector_gradient] + // 中心点 + OH_Drawing_Point *centerPt = OH_Drawing_PointCreate(value500_, value500_); + // 颜色数组 + uint32_t colors[3] = {0xFF00FFFF, 0xFFFF00FF, 0xFFFFFF00}; + // 相对位置数组 + float pos[3] = {0.0f, 0.5f, 1.0f}; + // 创建扇形渐变着色器效果 + OH_Drawing_ShaderEffect* colorShaderEffect = + OH_Drawing_ShaderEffectCreateSweepGradient(centerPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 基于画刷设置着色器效果 + OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect); + // 在画布上设置画刷,请确保已获取得到画布对象 + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value100_, value100_, value900_, value900_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除掉画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + OH_Drawing_ShaderEffectDestroy(colorShaderEffect); + OH_Drawing_PointDestroy(centerPt); + // [End ndk_graphics_draw_sector_gradient] +} + +void SampleGraphics::DrawColorFilter(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_color_filter] + // 创建画刷 + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + // 设置画刷抗锯齿 + OH_Drawing_BrushSetAntiAlias(brush, true); + // 设置画刷填充颜色 + OH_Drawing_BrushSetColor(brush, 0xffff0000); + // 设置颜色矩阵 + const float matrix[20] = { + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 0.5f, 0.5f, 0, + 0, 0, 0.5f, 0.5f, 0 + }; + + // 创建滤波器颜色 + OH_Drawing_ColorFilter* colorFilter = OH_Drawing_ColorFilterCreateMatrix(matrix); + // 创建一个滤波器对象 + OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); + // 为滤波器对象设置颜色滤波器 + OH_Drawing_FilterSetColorFilter(filter, colorFilter); + // 设置画刷的滤波器效果 + OH_Drawing_BrushSetFilter(brush, filter); + // 在画布上设置画刷,请确保已获取得到画布对象 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建矩形 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value900_, value900_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除掉画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_ColorFilterDestroy(colorFilter); + OH_Drawing_RectDestroy(rect); + OH_Drawing_FilterDestroy(filter); + // [End ndk_graphics_draw_color_filter] +} + +void SampleGraphics::DrawImageFilter(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_image_filter] + // 创建画笔 + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + // 设置画笔抗锯齿 + OH_Drawing_PenSetAntiAlias(pen, true); + // 设置画笔描边颜色 + OH_Drawing_PenSetColor(pen, 0xffff0000); + // 设置画笔线宽为20 + OH_Drawing_PenSetWidth(pen, 20); + // 创建图像滤波器实现模糊效果 + OH_Drawing_ImageFilter *imageFilter = + OH_Drawing_ImageFilterCreateBlur(20.0f, 20.0f, OH_Drawing_TileMode::CLAMP, nullptr); + // 创建一个滤波器对象 + OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); + // 为滤波器对象设置图像滤波器 + OH_Drawing_FilterSetImageFilter(filter, imageFilter); + // 设置画笔的滤波器效果 + OH_Drawing_PenSetFilter(pen, filter); + // 在画布上设置画笔,请确保已获取得到画布对象 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 创建矩形 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value900_, value900_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除掉画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_ImageFilterDestroy(imageFilter); + OH_Drawing_RectDestroy(rect); + OH_Drawing_FilterDestroy(filter); + // [End ndk_graphics_draw_image_filter] +} + +void SampleGraphics::DrawMaskFilter(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_mask_filter] + // 创建画笔 + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + // 设置画笔抗锯齿 + OH_Drawing_PenSetAntiAlias(pen, true); + // 设置画笔描边颜色 + OH_Drawing_PenSetColor(pen, 0xffff0000); + // 设置画笔线宽为20 + OH_Drawing_PenSetWidth(pen, 20); + // 创建蒙版滤波器 + OH_Drawing_MaskFilter *maskFilter = OH_Drawing_MaskFilterCreateBlur(OH_Drawing_BlurType::NORMAL, 20, true); + // 创建一个滤波器对象 + OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); + // 为滤波器对象设置蒙版滤波器 + OH_Drawing_FilterSetMaskFilter(filter, maskFilter); + // 设置画笔的滤波器效果 + OH_Drawing_PenSetFilter(pen, filter); + // 在画布上设置画笔,请确保已获取得到画布对象 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 创建矩形 + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value900_, value900_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除掉画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_MaskFilterDestroy(maskFilter); + OH_Drawing_RectDestroy(rect); + OH_Drawing_FilterDestroy(filter); + // [End ndk_graphics_draw_mask_filter] +} + +void SampleGraphics::DrawPoint(OH_Drawing_Canvas *canvas) +{ + SAMPLE_LOGI("DrawPoint"); + // [Start ndk_graphics_draw_point] + // 创建画笔对象 + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + // 设置画笔颜色 + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画笔线宽为40 + OH_Drawing_PenSetWidth(pen, 40); + // 设置画布的画笔 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 绘制5个点 + AdaptationUtil* adaptationUtil = AdaptationUtil::GetInstance(); + OH_Drawing_Point2D point1 = {value200_, value200_}; + OH_Drawing_CanvasDrawPoint(canvas, &point1); + OH_Drawing_Point2D point2 = {value400_, value400_}; + OH_Drawing_CanvasDrawPoint(canvas, &point2); + OH_Drawing_Point2D point3 = {value600_, value600_}; + OH_Drawing_CanvasDrawPoint(canvas, &point3); + OH_Drawing_Point2D point4 = {value800_, value800_}; + OH_Drawing_CanvasDrawPoint(canvas, &point4); + OH_Drawing_Point2D point5 = {value1000_, value1000_}; + OH_Drawing_CanvasDrawPoint(canvas, &point5); + // 去除掉画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + // [End ndk_graphics_draw_point] +} + +void SampleGraphics::DrawArc(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_arc] + // 创建画笔对象 + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + // 设置画笔描边颜色 + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画笔线宽为20 + OH_Drawing_PenSetWidth(pen, 20); + // 设置画布的画笔 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 创建矩形对象,左上坐标为(100,200)右下坐标为(500,300) + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(100, 200, 500, 300); + // 基于矩形对象绘制圆弧,其实角度10°,扫描角度200° + OH_Drawing_CanvasDrawArc(canvas, rect, 10, 200); + // 去除掉画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_RectDestroy(rect); + // [End ndk_graphics_draw_arc] +} + +void SampleGraphics::DrawCircle(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_circle] + // 创建画笔对象 + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + // 设置画笔描边颜色 + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画笔线宽为20 + OH_Drawing_PenSetWidth(pen, 20); + // 设置画布的画笔 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 创建圆心点 + OH_Drawing_Point *point = OH_Drawing_PointCreate(value700_, value700_); + // 基于圆心点和半径在画布上绘制圆 + OH_Drawing_CanvasDrawCircle(canvas, point, value600_); + // 去除掉画布中的画笔 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_PointDestroy(point); + // [End ndk_graphics_draw_circle] +} + +void SampleGraphics::DrawPath(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_path] + // 创建画笔对象 + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + // 设置画笔描边颜色 + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画笔线宽为10 + OH_Drawing_PenSetWidth(pen, 10); + // 设置 画笔转角样式 + OH_Drawing_PenSetJoin(pen, LINE_ROUND_JOIN); + // 设置画布中的画笔 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 创建画刷,此例对闭合路径进行了颜色填充,所以需要使用画刷 + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MIN, RGBA_MAX, RGBA_MIN)); + // 设置画布中的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + int len = value551_; + float aX = value630_; + float aY = value551_; + float dX = aX - len * std::sin(18.0f); + float dY = aY + len * std::cos(18.0f); + float cX = aX + len * std::sin(18.0f); + float cY = dY; + float bX = aX + (len / 2.0); + float bY = aY + std::sqrt((cX - dX) * (cX - dX) + (len / 2.0) * (len / 2.0)); + float eX = aX - (len / 2.0); + float eY = bY; + // 创建路径 + OH_Drawing_Path* path = OH_Drawing_PathCreate(); + // 到起始点 + OH_Drawing_PathMoveTo(path, aX, aY); + // 绘制直线 + OH_Drawing_PathLineTo(path, bX, bY); + OH_Drawing_PathLineTo(path, cX, cY); + OH_Drawing_PathLineTo(path, dX, dY); + OH_Drawing_PathLineTo(path, eX, eY); + // 直线闭合,形成五角星 + OH_Drawing_PathClose(path); + // 绘制闭合路径 + OH_Drawing_CanvasDrawPath(canvas, path); + // 去除掉画布中的画笔和画刷 + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_PathDestroy(path); + // [End ndk_graphics_draw_path] +} + +void SampleGraphics::DrawRegion(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_region] + // 创建画刷对象 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 设置画刷填充颜色 + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置画布的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 矩形区域1 + OH_Drawing_Region *region1 = OH_Drawing_RegionCreate(); + OH_Drawing_Rect *rect1 = OH_Drawing_RectCreate(value100_, value100_, value600_, value600_); + OH_Drawing_RegionSetRect(region1, rect1); + // 矩形区域2 + OH_Drawing_Region *region2 = OH_Drawing_RegionCreate(); + OH_Drawing_Rect *rect2 = OH_Drawing_RectCreate(value300_, value300_, value900_, value900_); + OH_Drawing_RegionSetRect(region2, rect2); + // 两个矩形区域组合 + OH_Drawing_RegionOp(region1, region2, OH_Drawing_RegionOpMode::REGION_OP_MODE_XOR); + OH_Drawing_CanvasDrawRegion(canvas, region1); + // 去除掉画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RegionDestroy(region1); + OH_Drawing_RegionDestroy(region2); + OH_Drawing_RectDestroy(rect1); + OH_Drawing_RectDestroy(rect2); + // [End ndk_graphics_draw_region] +} + +void SampleGraphics::DrawRect(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_rect] + // 创建画刷对象 + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + // 设置画刷的填充颜色 + OH_Drawing_BrushSetColor(brush, 0xffff0000); + // 设置画布的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(0, 0, value800_, value800_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 去除画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + // [End ndk_graphics_draw_rect] +} + +void SampleGraphics::DrawRoundRect(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_round_rect] + // 创建画刷对象 + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + // 设置画刷的填充颜色 + OH_Drawing_BrushSetColor(brush, 0xffff0000); + // 设置画布的画刷 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建矩形 + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(value100_, value100_, value900_, value600_); + // 创建圆角矩形 + OH_Drawing_RoundRect* roundRect = OH_Drawing_RoundRectCreate(rect, 30, 30); + // 绘制圆角矩形 + OH_Drawing_CanvasDrawRoundRect(canvas, roundRect); + // 去除掉画布中的画刷 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + OH_Drawing_RoundRectDestroy(roundRect); + // [End ndk_graphics_draw_round_rect] +} + +void SampleGraphics::DrawPixelMap(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_image] + // 图片宽高分别为 600 * 400 + uint32_t width = 600; + uint32_t height = 400; + // 字节长度,RGBA_8888每个像素占4字节 + size_t bufferSize = width * height * 4; + uint8_t *pixels = new uint8_t[bufferSize]; + for (uint32_t i = 0; i < width * height; ++i) { + // 遍历并编辑每个像素,从而形成红绿蓝相间的条纹 + uint32_t n = i / 20 % 3; + pixels[i * RGBA_SIZE] = RGBA_MIN; // 红色通道 + pixels[i * RGBA_SIZE + 1] = RGBA_MIN; // +1表示绿色通道 + pixels[i * RGBA_SIZE + 2] = RGBA_MIN; // +2表示蓝色通道 + pixels[i * RGBA_SIZE + 3] = 0xFF; // +3表示不透明度通道 + if (n == 0) { + pixels[i * RGBA_SIZE] = 0xFF; // 红色通道赋值,颜色显红色 + } else if (n == 1) { + pixels[i * RGBA_SIZE + 1] = 0xFF; // +1表示绿色通道赋值,其余通道为0,颜色显绿色 + } else { + pixels[i * RGBA_SIZE + 2] = 0xFF; // +2表示蓝色通道赋值,其余通道为0,颜色显蓝色 + } + } + // 设置位图格式(长、宽、颜色类型、透明度类型) + OH_Pixelmap_InitializationOptions *createOps = nullptr; + OH_PixelmapInitializationOptions_Create(&createOps); + OH_PixelmapInitializationOptions_SetWidth(createOps, width); + OH_PixelmapInitializationOptions_SetHeight(createOps, height); + OH_PixelmapInitializationOptions_SetPixelFormat(createOps, PIXEL_FORMAT_RGBA_8888); + OH_PixelmapInitializationOptions_SetAlphaType(createOps, PIXELMAP_ALPHA_TYPE_UNKNOWN); + // 创建OH_PixelmapNative对象 + OH_PixelmapNative *pixelMapNative = nullptr; + OH_PixelmapNative_CreatePixelmap(pixels, bufferSize, createOps, &pixelMapNative); + OH_Drawing_PixelMap *pixelMap = OH_Drawing_PixelMapGetFromOhPixelMapNative(pixelMapNative); + // PixelMap中像素的截取区域 + OH_Drawing_Rect *src = OH_Drawing_RectCreate(0, 0, 600, 400); + // 画布中显示的区域 + OH_Drawing_Rect *dst = OH_Drawing_RectCreate(value200_, value200_, value800_, value600_); + // 采样选项对象 + OH_Drawing_SamplingOptions* samplingOptions = OH_Drawing_SamplingOptionsCreate( + OH_Drawing_FilterMode::FILTER_MODE_LINEAR, OH_Drawing_MipmapMode::MIPMAP_MODE_LINEAR); + // 绘制PixelMap + OH_Drawing_CanvasDrawPixelMapRect(canvas, pixelMap, src, dst, samplingOptions); + OH_PixelmapNative_Release(pixelMapNative); + delete[] pixels; + // [End ndk_graphics_draw_image] +} + +void SampleGraphics::DrawBaseText(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_base_text] + // 创建字体对象 + OH_Drawing_Font *font = OH_Drawing_FontCreate(); + // 设置字体大小 + OH_Drawing_FontSetTextSize(font, value100_); + // 需要绘制的文字 + const char *str = "Hello world"; + // 创建字块对象 + OH_Drawing_TextBlob *textBlob = + OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8); + // 绘制字块 + OH_Drawing_CanvasDrawTextBlob(canvas, textBlob, value200_, value800_); + // 释放字块对象 + OH_Drawing_TextBlobDestroy(textBlob); + // 释放字体对象 + OH_Drawing_FontDestroy(font); + // [End ndk_graphics_draw_base_text] +} + +void SampleGraphics::DrawStrokeText(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_stroke_text] + // 创建画笔 + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + // 设置抗锯齿 + OH_Drawing_PenSetAntiAlias(pen, true); + // 设置描边颜色 + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 设置描边线宽为3 + OH_Drawing_PenSetWidth(pen, 3); + // 设置画笔描边效果 + OH_Drawing_CanvasAttachPen(canvas, pen); + // 创建字型对象 + OH_Drawing_Font *font = OH_Drawing_FontCreate(); + // 设置字体大小 + OH_Drawing_FontSetTextSize(font, value150_); + const char *str = "Hello world"; + // 创建字块对象 + OH_Drawing_TextBlob *textBlob = + OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8); + // 绘制字块 + OH_Drawing_CanvasDrawTextBlob(canvas, textBlob, value200_, value800_); + // 去除描边效果 + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_TextBlobDestroy(textBlob); + OH_Drawing_FontDestroy(font); + OH_Drawing_PenDestroy(pen); + // [End ndk_graphics_draw_stroke_text] +} + +void SampleGraphics::DrawGradientText(OH_Drawing_Canvas *canvas) +{ + // [Start ndk_graphics_draw_gradient_text] + // 开始点 + OH_Drawing_Point *startPt = OH_Drawing_PointCreate(value100_, value100_); + // 结束点 + OH_Drawing_Point *endPt = OH_Drawing_PointCreate(value900_, value900_); + // 颜色数组 + uint32_t colors[] = {0xFFFFFF00, 0xFFFF0000, 0xFF0000FF}; + // 相对位置数组 + float pos[] = {0.0f, 0.5f, 1.0f}; + // 创建线性渐变着色器效果 + OH_Drawing_ShaderEffect *colorShaderEffect = + OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); + // 创建画刷对象 + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + // 基于画刷设置着色器效果 + OH_Drawing_BrushSetShaderEffect(brush, colorShaderEffect); + // 设置画刷填充效果 + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建字型对象 + OH_Drawing_Font *font = OH_Drawing_FontCreate(); + // 设置字体大小 + OH_Drawing_FontSetTextSize(font, value150_); + const char *str = "Hello world"; + // 创建字块对象 + OH_Drawing_TextBlob *textBlob = + OH_Drawing_TextBlobCreateFromString(str, font, OH_Drawing_TextEncoding::TEXT_ENCODING_UTF8); + // 绘制字块 + OH_Drawing_CanvasDrawTextBlob(canvas, textBlob, value200_, value800_); + // 取消填充效果 + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_TextBlobDestroy(textBlob); + OH_Drawing_FontDestroy(font); + OH_Drawing_BrushDestroy(brush); + // [End ndk_graphics_draw_gradient_text] +} + +void SampleGraphics::InitDrawFunction(std::string id) +{ + if (strcmp(id.c_str(), "canvasGetResultXComponent") == 0) { + this->drawFunctionMap_.insert({"Point", &SampleGraphics::DrawPoint}); + this->drawFunctionMap_.insert({"Arc", &SampleGraphics::DrawArc}); + this->drawFunctionMap_.insert({"Circle", &SampleGraphics::DrawCircle}); + } else if (strcmp(id.c_str(), "canvasOperationStateXComponent") == 0) { + this->drawFunctionMap_.insert({"ClipOperation", &SampleGraphics::DrawClipOperation}); + this->drawFunctionMap_.insert({"TranslationOperation", &SampleGraphics::DrawTranslationOperation}); + this->drawFunctionMap_.insert({"RotationOperation", &SampleGraphics::DrawRotationOperation}); + this->drawFunctionMap_.insert({"ScaleOperation", &SampleGraphics::DrawScaleOperation}); + this->drawFunctionMap_.insert({"StateOperation", &SampleGraphics::DrawStateOperation}); + } else if (strcmp(id.c_str(), "basicEffectXComponent") == 0) { + this->drawFunctionMap_.insert({"Filling", &SampleGraphics::DrawFilling}); + this->drawFunctionMap_.insert({"Stroke", &SampleGraphics::DrawStroke}); + } else if (strcmp(id.c_str(), "complexEffectXComponent") == 0) { + this->drawFunctionMap_.insert({"MixedMode", &SampleGraphics::DrawMixedMode}); + this->drawFunctionMap_.insert({"PathEffect", &SampleGraphics::DrawPathEffect}); + this->drawFunctionMap_.insert({"LinearGradient", &SampleGraphics::DrawLinearGradient}); + this->drawFunctionMap_.insert({"PathGradient", &SampleGraphics::DrawPathGradient}); + this->drawFunctionMap_.insert({"SectorGradient", &SampleGraphics::DrawSectorGradient}); + this->drawFunctionMap_.insert({"ColorFilter", &SampleGraphics::DrawColorFilter}); + this->drawFunctionMap_.insert({"ImageFilter", &SampleGraphics::DrawImageFilter}); + this->drawFunctionMap_.insert({"MaskFilter", &SampleGraphics::DrawMaskFilter}); + } else if (strcmp(id.c_str(), "shapeDrawingXComponent") == 0) { + this->drawFunctionMap_.insert({"Point", &SampleGraphics::DrawPoint}); + this->drawFunctionMap_.insert({"Arc", &SampleGraphics::DrawArc}); + this->drawFunctionMap_.insert({"Circle", &SampleGraphics::DrawCircle}); + this->drawFunctionMap_.insert({"Path", &SampleGraphics::DrawPath}); + this->drawFunctionMap_.insert({"Region", &SampleGraphics::DrawRegion}); + this->drawFunctionMap_.insert({"Rect", &SampleGraphics::DrawRect}); + this->drawFunctionMap_.insert({"RoundRect", &SampleGraphics::DrawRoundRect}); + } else if (strcmp(id.c_str(), "pixelMapDrawingXComponent") == 0) { + this->drawFunctionMap_.insert({"PixelMap", &SampleGraphics::DrawPixelMap}); + } else if (strcmp(id.c_str(), "textBlockDrawingXComponent") == 0) { + this->drawFunctionMap_.insert({"BaseText", &SampleGraphics::DrawBaseText}); + this->drawFunctionMap_.insert({"StrokeText", &SampleGraphics::DrawStrokeText}); + this->drawFunctionMap_.insert({"GradientText", &SampleGraphics::DrawGradientText}); + } +} + +void SampleGraphics::DoRender(SampleGraphics *render, char* canvasType, char* shapeType) +{ + SAMPLE_LOGI("DoRender"); + render->Prepare(); + // 不同画布 + if (strcmp(canvasType, "CanvasGet") == 0) { + SAMPLE_LOGI("CanvasGet"); + render->Create(); + // 绘制图案 + auto it = render->drawFunctionMap_.find(shapeType); + if (it != render->drawFunctionMap_.end()) { + (render->*(it->second))(render->cScreenCanvas_); + } else { + SAMPLE_LOGI("Unsupported shape type: %{public}s", shapeType); + } + render->DisPlay(); + } else if (strcmp(canvasType, "CanvasGetByCPU") == 0) { + render->CreateByCPU(); + // 绘制图案 + auto it = render->drawFunctionMap_.find(shapeType); + if (it != render->drawFunctionMap_.end()) { + (render->*(it->second))(render->cCPUCanvas_); + } else { + SAMPLE_LOGI("Unsupported shape type: %{public}s", shapeType); + } + render->DisPlayCPU(); + } else if (strcmp(canvasType, "CanvasGetByGPU") == 0) { + render->CreateByGPU(); + // 绘制图案 + auto it = render->drawFunctionMap_.find(shapeType); + if (it != render->drawFunctionMap_.end()) { + (render->*(it->second))(render->cGPUCanvas_); + } else { + SAMPLE_LOGI("Unsupported shape type: %{public}s", shapeType); + } + render->DisPlayGPU(); + } + render->Destroy(); +} + +napi_value SampleGraphics::Draw(napi_env env, napi_callback_info info) +{ + SAMPLE_LOGI("Draw"); + if ((env == nullptr) || (info == nullptr)) { + SAMPLE_LOGE("NapiRegister: env or info is null"); + return nullptr; + } + + napi_value thisArg; + size_t argc = 2; + napi_value args[2]; + if (napi_get_cb_info(env, info, &argc, args, &thisArg, nullptr) != napi_ok) { + SAMPLE_LOGE("NapiRegister: napi_get_cb_info fail"); + return nullptr; + } + + napi_value exportInstance; + if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) { + SAMPLE_LOGE("NapiRegister: napi_get_named_property fail"); + return nullptr; + } + + OH_NativeXComponent *nativeXComponent = nullptr; + if (napi_unwrap(env, exportInstance, reinterpret_cast(&nativeXComponent)) != napi_ok) { + SAMPLE_LOGE("NapiRegister: napi_unwrap fail"); + return nullptr; + } + + char idStr[OH_XCOMPONENT_ID_LEN_MAX + 1] = {'\0'}; + uint64_t idSize = OH_XCOMPONENT_ID_LEN_MAX + 1; + if (OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize) != OH_NATIVEXCOMPONENT_RESULT_SUCCESS) { + SAMPLE_LOGE("NapiRegister: Unable to get XComponent id"); + return nullptr; + } + SAMPLE_LOGI("RegisterID = %{public}s", idStr); + std::string id(idStr); + + // 获取形状参数 + char canvasType[32] = {0}; + napi_get_value_string_utf8(env, args[0], canvasType, sizeof(canvasType), nullptr); + + // 获取形状参数 + char shapeType[32] = {0}; + napi_get_value_string_utf8(env, args[1], shapeType, sizeof(shapeType), nullptr); + + SampleGraphics *render = SampleGraphics().GetInstance(id); + if (render != nullptr) { + render->DoRender(render, canvasType, shapeType); + } + return nullptr; +} + +SampleGraphics::~SampleGraphics() +{ + // 销毁canvas对象 + OH_Drawing_CanvasDestroy(cScreenCanvas_); + cScreenCanvas_ = nullptr; + OH_Drawing_CanvasDestroy(cCPUCanvas_); + cCPUCanvas_ = nullptr; + // 销毁bitmap对象 + OH_Drawing_BitmapDestroy(cScreenBitmap_); + cScreenBitmap_ = nullptr; + OH_Drawing_BitmapDestroy(cOffScreenBitmap_); + cOffScreenBitmap_ = nullptr; + + buffer_ = nullptr; + bufferHandle_ = nullptr; + nativeWindow_ = nullptr; + mappedAddr_ = nullptr; + DeInitializeEglContext(); +} + +void SampleGraphics::Destroy() +{ + // 销毁canvas对象 + OH_Drawing_CanvasDestroy(cScreenCanvas_); + cScreenCanvas_ = nullptr; + OH_Drawing_CanvasDestroy(cCPUCanvas_); + cCPUCanvas_ = nullptr; + // 销毁bitmap对象 + OH_Drawing_BitmapDestroy(cScreenBitmap_); + cScreenBitmap_ = nullptr; + OH_Drawing_BitmapDestroy(cOffScreenBitmap_); + cOffScreenBitmap_ = nullptr; + DeInitializeEglContext(); +} + +void SampleGraphics::Release(std::string &id) +{ + SampleGraphics *render = SampleGraphics::GetInstance(id); + if (render != nullptr) { + delete render; + render = nullptr; + g_instance.erase(g_instance.find(id)); + } +} + +void SampleGraphics::Export(napi_env env, napi_value exports) +{ + if ((env == nullptr) || (exports == nullptr)) { + SAMPLE_LOGE("Export: env or exports is null"); + return; + } + napi_property_descriptor desc[] = { + {"draw", nullptr, SampleGraphics::Draw, nullptr, nullptr, nullptr, napi_default, nullptr} + }; + napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc); + if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) { + SAMPLE_LOGE("Export: napi_define_properties failed"); + } +} + +void SampleGraphics::RegisterCallback(OH_NativeXComponent *nativeXComponent) +{ + SAMPLE_LOGI("register callback"); + renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB; + renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB; + // Callback must be initialized + renderCallback_.DispatchTouchEvent = nullptr; + renderCallback_.OnSurfaceChanged = nullptr; + OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_); +} + + +SampleGraphics *SampleGraphics::GetInstance(std::string &id) +{ + if (g_instance.find(id) == g_instance.end()) { + SampleGraphics *render = new SampleGraphics(id); + g_instance[id] = render; + render->InitDrawFunction(id); + return render; + } else { + return g_instance[id]; + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/samples/sample_graphics.h b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/samples/sample_graphics.h new file mode 100644 index 0000000000000000000000000000000000000000..962c8fdc7d8279487d7d28fdde587217b88edb5e --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/samples/sample_graphics.h @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SAMPLE_GRAPHICS_H +#define SAMPLE_GRAPHICS_H +#include +#include +// [Start ndk_graphics_draw_include_native_drawing_canvas_and_bitmap] +#include +// [StartExclude ndk_graphics_draw_include_native_drawing_canvas_and_bitmap] +#include +// [EndExclude ndk_graphics_draw_include_native_drawing_canvas_and_bitmap] +#include +// [End ndk_graphics_draw_include_native_drawing_canvas_and_bitmap] +#include +#include +#include +#include +#include +#include +// [Start ndk_graphics_draw_include_egl_module] +#include +#include +// [End ndk_graphics_draw_include_egl_module] +#include +#include "napi/native_api.h" + + +class SampleGraphics { +public: + SampleGraphics() = default; + ~SampleGraphics(); + explicit SampleGraphics(std::string id) : id_(id) + { + InitializeEglContext(); + } + static napi_value Draw(napi_env env, napi_callback_info info); + static void Release(std::string &id); + void SetWidth(uint64_t width); + void SetHeight(uint64_t height); + void SetNativeWindow(OHNativeWindow *nativeWindow); + + // 画布操作 + void DrawClipOperation(OH_Drawing_Canvas *canvas); + void DrawTranslationOperation(OH_Drawing_Canvas *canvas); + void DrawRotationOperation(OH_Drawing_Canvas *canvas); + void DrawScaleOperation(OH_Drawing_Canvas *canvas); + void DrawStateOperation(OH_Drawing_Canvas *canvas); + // 绘制效果 + void DrawFilling(OH_Drawing_Canvas *canvas); + void DrawStroke(OH_Drawing_Canvas *canvas); + void DrawMixedMode(OH_Drawing_Canvas *canvas); + void DrawPathEffect(OH_Drawing_Canvas *canvas); + void DrawLinearGradient(OH_Drawing_Canvas *canvas); + void DrawPathGradient(OH_Drawing_Canvas *canvas); + void DrawSectorGradient(OH_Drawing_Canvas *canvas); + void DrawColorFilter(OH_Drawing_Canvas *canvas); + void DrawImageFilter(OH_Drawing_Canvas *canvas); + void DrawMaskFilter(OH_Drawing_Canvas *canvas); + // 图元绘制 + void DrawPoint(OH_Drawing_Canvas *canvas); + void DrawArc(OH_Drawing_Canvas *canvas); + void DrawCircle(OH_Drawing_Canvas *canvas); + void DrawPath(OH_Drawing_Canvas *canvas); + void DrawRegion(OH_Drawing_Canvas *canvas); + void DrawRect(OH_Drawing_Canvas *canvas); + void DrawRoundRect(OH_Drawing_Canvas *canvas); + void DrawPixelMap(OH_Drawing_Canvas *canvas); + void DrawBaseText(OH_Drawing_Canvas *canvas); + void DrawStrokeText(OH_Drawing_Canvas *canvas); + void DrawGradientText(OH_Drawing_Canvas *canvas); + // 创建画布及绘图结果显示 + void Prepare(); + void Create(); + void CreateByCPU(); + void CreateByGPU(); + void DisPlay(); + void DisPlayCPU(); + void DisPlayGPU(); + + void Export(napi_env env, napi_value exports); + void RegisterCallback(OH_NativeXComponent *nativeXComponent); + void Destroy(); + static SampleGraphics *GetInstance(std::string &id); + std::string id_; +private: + std::unordered_map drawFunctionMap_; + void InitDrawFunction(std::string id); + void DoRender(SampleGraphics *render, char* canvasType, char* shapeType); + int32_t InitializeEglContext(); + void DeInitializeEglContext(); + OH_NativeXComponent_Callback renderCallback_; + + uint64_t width_ = 0; + uint64_t height_ = 0; + + static float value100_; + static float value150_; + static float value200_; + static float value300_; + static float value400_; + static float value500_; + static float value551_; + static float value600_; + static float value630_; + static float value700_; + static float value800_; + static float value900_; + static float value1000_; + static float value1200_; + bool desc = false; + + // [Start ndk_graphics_draw_initialize_egl_context_parameter] + EGLDisplay EGLDisplay_ = EGL_NO_DISPLAY; + EGLConfig EGLConfig_ = nullptr; + EGLContext EGLContext_ = EGL_NO_CONTEXT; + EGLSurface EGLSurface_ = nullptr; + // [End ndk_graphics_draw_initialize_egl_context_parameter] + + OH_Drawing_Bitmap *cScreenBitmap_ = nullptr; + OH_Drawing_Canvas *cScreenCanvas_ = nullptr; + OH_Drawing_Bitmap *cOffScreenBitmap_ = nullptr; + OH_Drawing_Canvas *cCPUCanvas_ = nullptr; + OH_Drawing_Canvas *cGPUCanvas_ = nullptr; + + OHNativeWindow *nativeWindow_ = nullptr; + uint32_t *mappedAddr_ = nullptr; + BufferHandle *bufferHandle_ = nullptr; + struct NativeWindowBuffer *buffer_ = nullptr; + int fenceFd_ = 0; +}; + +#endif // SAMPLE_GRAPHICS_H diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/types/libentry/Index.d.ts b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/types/libentry/Index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..6c07bc3e6ca89c2cf37df36794d286dff08f7e2f --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/types/libentry/Index.d.ts @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const add: (a: number, b: number) => number; diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/types/libentry/oh-package.json5 b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..6abf3b7c20f22c62aaac6a995a25cae672f73f35 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/types/libentry/oh-package.json5 @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "name": "libentry.so", + "types": "./Index.d.ts", + "version": "1.0.0", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/utils/adaptation_util.cpp b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/utils/adaptation_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cea2d962e9f2f5c3d495f2c0b5e7b5c5ce02e88d --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/utils/adaptation_util.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "adaptation_util.h" +#include "common/log_common.h" + +AdaptationUtil* AdaptationUtil::instance_ = nullptr; + +AdaptationUtil* AdaptationUtil::GetInstance() +{ + if (instance_ == nullptr) { + instance_ = new AdaptationUtil(); + } + return instance_; +} + +float AdaptationUtil::GetWidth(float width) +{ + return width * screenWidth_ / standardWidth_; +} + +float AdaptationUtil::GetHeight(float height) +{ + return height * screenHeight_ / standardHeight_; +} + +AdaptationUtil::AdaptationUtil() +{ + NativeDisplayManager_ErrorCode errorCode = OH_NativeDisplayManager_GetDefaultDisplayWidth(&screenWidth_); + if (errorCode != NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) { + SAMPLE_LOGE("GetDefaultDisplayWidth failed"); + } + errorCode = OH_NativeDisplayManager_GetDefaultDisplayHeight(&screenHeight_); + if (errorCode != NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) { + SAMPLE_LOGE("GetDefaultDisplayHeight failed"); + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/cpp/utils/adaptation_util.h b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/utils/adaptation_util.h new file mode 100644 index 0000000000000000000000000000000000000000..7c449b601910fd4966e94ab7f213d677ba21529b --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/cpp/utils/adaptation_util.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ADAPTATION_UTIL_H +#define ADAPTATION_UTIL_H + +// 多设备适配类,用于适配不同尺寸的设备 +class AdaptationUtil { +public: + static AdaptationUtil* GetInstance(); + float GetWidth(float width); + float GetHeight(float height); +private: + AdaptationUtil(); + static AdaptationUtil *instance_; + + int screenWidth_ = 720; + int screenHeight_ = 1280; + const int standardWidth_ = 1260; // 指南文档默认运行设备为真机 + const int standardHeight_ = 2720; +}; + +#endif // ADAPTATION_UTIL_H diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/BasicEffect.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/BasicEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..fcf9e2690297f1e00b8d1f82fa5dbef339874613 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/BasicEffect.ets @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct BasicEffect { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'basicEffectXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('70%') + Row() { + Button($r('app.string.Filling')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Filling'); + } + }) + Button($r('app.string.Stroke')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Stroke'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('10%') + } + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/CanvasGetResult.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/CanvasGetResult.ets new file mode 100644 index 0000000000000000000000000000000000000000..a84b753a88fe7358ff66d5fd32186919f680e187 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/CanvasGetResult.ets @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct CanvasGetResult { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'canvasGetResultXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + console.info('XComponent loaded successfully'); + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('70%') + Row() { + Button($r('app.string.CanvasGet')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Point'); + } + }) + Button($r('app.string.CanvasGetByCPU')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGetByCPU', 'Arc'); + } + }) + Button($r('app.string.CanvasGetByGPU')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGetByGPU', 'Circle'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('8%') + } + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/CanvasOperationState.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/CanvasOperationState.ets new file mode 100644 index 0000000000000000000000000000000000000000..5df9b9f57167c57de8acbae667962e1359647194 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/CanvasOperationState.ets @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct CanvasOperationState { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'canvasOperationStateXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('70%') + Row() { + Button($r('app.string.ClipOperation')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ClipOperation'); + } + }) + Button($r('app.string.TranslationOperation')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'TranslationOperation'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('8%') + Row() { + Button($r('app.string.RotationOperation')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'RotationOperation'); + } + }) + Button($r('app.string.ScaleOperation')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ScaleOperation'); + } + }) + Button($r('app.string.StateOperation')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'StateOperation'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('8%') + } + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/ComplexEffect.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/ComplexEffect.ets new file mode 100644 index 0000000000000000000000000000000000000000..5c70ea9b6ac9466c0b0d933be83201336a845930 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/ComplexEffect.ets @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct ComplexEffect { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'complexEffectXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('70%') + Row() { + Button($r('app.string.MixedMode')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'MixedMode'); + } + }) + Button($r('app.string.PathEffect')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PathEffect'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('8%') + Row() { + Button($r('app.string.LinearGradient')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'LinearGradient'); + } + }) + Button($r('app.string.PathGradient')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PathGradient'); + } + }) + Button($r('app.string.SectorGradient')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'SectorGradient'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('8%') + Row() { + Button($r('app.string.ColorFilter')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ColorFilter'); + } + }) + Button($r('app.string.ImageFilter')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ImageFilter'); + } + }) + Button($r('app.string.MaskFilter')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'MaskFilter'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('8%') + } + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/PixelMapDrawing.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/PixelMapDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..d8140bf962d83bafcf2390e159f25297d9645ebe --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/PixelMapDrawing.ets @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct PixelMapDrawing { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'pixelMapDrawingXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('70%') + Row() { + Button($r('app.string.PixelMap')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PixelMap'); + } + }) + } + } + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/ShapeDrawing.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/ShapeDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..d473b4a3c5e24f53de522b618e2eedccf9d0e32f --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/ShapeDrawing.ets @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct ShapeDrawing { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'shapeDrawingXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('80%') + Row() { + Button($r('app.string.Point')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Point'); + } + }) + Button($r('app.string.Arc')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Arc'); + } + }) + Button($r('app.string.Circle')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Circle'); + } + }) + Button($r('app.string.Path')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Path'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('7%') + Row() { + Button($r('app.string.Region')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Region'); + } + }) + Button($r('app.string.Rect')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Rect'); + } + }) + Button($r('app.string.RoundRect')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'RoundRect'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('7%') + } + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/TextBlockDrawing.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/TextBlockDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..1332085d70290b7e074bc3c9220aabb0a48dbecf --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/drawing/pages/TextBlockDrawing.ets @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct TextBlockDrawing { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'textBlockDrawingXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('70%') + Row() { + Button($r('app.string.BaseText')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'BaseText'); + } + }) + Button($r('app.string.StrokeText')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'StrokeText'); + } + }) + Button($r('app.string.GradientText')) + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'GradientText'); + } + }) + } + .justifyContent(FlexAlign.SpaceEvenly) + .width('100%') + .height('8%') + } + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/entryability/EntryAbility.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..965554bb3a331e2418180b86da1993baf5e8d536 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { AbilityConstant, ConfigurationConstant, UIAbility, Want } from '@kit.AbilityKit'; +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { window } from '@kit.ArkUI'; + +export default class EntryAbility extends UIAbility { + onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { + this.context.getApplicationContext().setColorMode(ConfigurationConstant.ColorMode.COLOR_MODE_NOT_SET); + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); + } + + onDestroy(): void { + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage): void { + // Main window is created, set main page for this ability + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); + + windowStage.loadContent('pages/Index', (err) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content.'); + }); + } + + onWindowStageDestroy(): void { + // Main window is destroyed, release UI related resources + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy'); + } + + onForeground(): void { + // Ability has brought to foreground + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground'); + } + + onBackground(): void { + // Ability has back to background + hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground'); + } +}; \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..b1e212947256c5533c7b06285a597c94f840a6e3 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { hilog } from '@kit.PerformanceAnalysisKit'; +import { BackupExtensionAbility, BundleVersion } from '@kit.CoreFileKit'; + +export default class EntryBackupAbility extends BackupExtensionAbility { + async onBackup() { + hilog.info(0x0000, 'testTag', 'onBackup ok'); + } + + async onRestore(bundleVersion: BundleVersion) { + hilog.info(0x0000, 'testTag', 'onRestore ok %{public}s', JSON.stringify(bundleVersion)); + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/interface/XComponentContext.ts b/Drawing/NDKGraphicsDraw/entry/src/main/ets/interface/XComponentContext.ts new file mode 100644 index 0000000000000000000000000000000000000000..27ee689e1438384f9abcba0552e8f6aa683ac682 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/interface/XComponentContext.ts @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export default interface XComponentContext { + draw(canvasType:string, shapeType: string):void; +}; diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/ets/pages/Index.ets b/Drawing/NDKGraphicsDraw/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..a29adae0ebff15247cb7344f2ea50a9e3d23b47f --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import router from '@ohos.router'; + +interface Item { + text: string; +} + + +const operationUrls: string[] = [ + 'drawing/pages/CanvasGetResult', + 'drawing/pages/CanvasOperationState', + 'drawing/pages/BasicEffect', + 'drawing/pages/ComplexEffect', + 'drawing/pages/ShapeDrawing', + 'drawing/pages/PixelMapDrawing', + 'drawing/pages/TextBlockDrawing' +]; + +@Entry +@Component +struct Index { + ResourceToString(resource: Resource): string { + return getContext(this).resourceManager.getStringSync(resource); + } + + @State listItem: Item[] = [ + { text: this.ResourceToString($r('app.string.CanvasGetResult')) }, + { text: this.ResourceToString($r('app.string.CanvasOperationState')) }, + { text: this.ResourceToString($r("app.string.BasicEffect")) }, + { text: this.ResourceToString($r('app.string.ComplexEffect')) }, + { text: this.ResourceToString($r('app.string.Shape_Drawing')) }, + { text: this.ResourceToString($r("app.string.PixelMap_Drawing")) }, + { text: this.ResourceToString($r("app.string.TextBlock_Drawing")) } + ] + + build() { + Column() { + List() { + ForEach(this.listItem, (item: Item, index) => { + ListItem() { + Row() { + Blank().width('4%') + Text(item.text) + .fontSize(16) + .fontColor('black') + .width('90%') + Image($r('app.media.right')) + .height(12) + .width(12) + } + .onClick(() => { + router.pushUrl({ + url: operationUrls[index] + }); + }) + .border({ radius: 20 }) + .width('90%') + .height('8%') + .backgroundColor(Color.White) + .margin({ top: 12, left: 15, right: 8 }) + } + }) + } + .height('90%') + .width('100%') + } + .width('100%') + .height('100%') + .backgroundColor('#F1F3F5') + } +} diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/module.json5 b/Drawing/NDKGraphicsDraw/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4144486d1af4c03b0d767cce1cda86fc0d697f91 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/module.json5 @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:layered_image", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:startIcon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "extensionAbilities": [ + { + "name": "EntryBackupAbility", + "srcEntry": "./ets/entrybackupability/EntryBackupAbility.ets", + "type": "backup", + "exported": false, + "metadata": [ + { + "name": "ohos.extension.backup", + "resource": "$profile:backup_config" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/element/color.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/element/string.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..b4d8313d95eafb3f06010baee043374086613a27 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/element/string.json @@ -0,0 +1,160 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "NDKGraphicsDraw" + }, + { + "name": "CanvasGetResult", + "value": "画布的获取与绘制结果的显示" + }, + { + "name": "CanvasOperationState", + "value": "画布操作及状态处理" + }, + { + "name": "BasicEffect", + "value": "基础绘制效果" + }, + { + "name": "ComplexEffect", + "value": "复杂绘制效果" + }, + { + "name": "Shape_Drawing", + "value": "几何图形绘制" + }, + { + "name": "PixelMap_Drawing", + "value": "图片绘制" + }, + { + "name": "TextBlock_Drawing", + "value": "字块绘制" + }, + { + "name": "CanvasGet", + "value": "获取直接画布" + }, + { + "name": "CanvasGetByCPU", + "value": "获取CPU后端画布" + }, + { + "name": "CanvasGetByGPU", + "value": "获取GPU后端画布" + }, + { + "name": "ClipOperation", + "value": "裁剪操作" + }, + { + "name": "TranslationOperation", + "value": "平移操作" + }, + { + "name": "RotationOperation", + "value": "旋转操作" + }, + { + "name": "ScaleOperation", + "value": "缩放操作" + }, + { + "name": "StateOperation", + "value": "画布状态操作" + }, + { + "name": "Filling", + "value": "填充效果" + }, + { + "name": "Stroke", + "value": "描边效果" + }, + { + "name": "MixedMode", + "value": "混合模式" + }, + { + "name": "PathEffect", + "value": "路径效果" + }, + { + "name": "LinearGradient", + "value": "线性渐变" + }, + { + "name": "PathGradient", + "value": "径向渐变" + }, + { + "name": "SectorGradient", + "value": "扇形渐变" + }, + { + "name": "ColorFilter", + "value": "颜色滤波器" + }, + { + "name": "ImageFilter", + "value": "图像滤波器" + }, + { + "name": "MaskFilter", + "value": "蒙版滤波器" + }, + { + "name": "Point", + "value": "点" + }, + { + "name": "Arc", + "value": "圆弧" + }, + { + "name": "Circle", + "value": "圆" + }, + { + "name": "Path", + "value": "路径" + }, + { + "name": "Region", + "value": "区域" + }, + { + "name": "Rect", + "value": "矩形" + }, + { + "name": "RoundRect", + "value": "圆角矩形" + }, + { + "name": "PixelMap", + "value": "绘制图片" + }, + { + "name": "BaseText", + "value": "基本文字" + }, + { + "name": "StrokeText", + "value": "文字描边" + }, + { + "name": "GradientText", + "value": "文字渐变" + } + ] +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/background.png b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d Binary files /dev/null and b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/background.png differ diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/foreground.png b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902 Binary files /dev/null and b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/foreground.png differ diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/layered_image.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/layered_image.json @@ -0,0 +1,7 @@ +{ + "layered-image": + { + "background" : "$media:background", + "foreground" : "$media:foreground" + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/right.png b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/right.png new file mode 100644 index 0000000000000000000000000000000000000000..812a7bd2dc2efcb999d962575b43139077cb7d16 Binary files /dev/null and b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/right.png differ diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/startIcon.png b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/media/startIcon.png differ diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/backup_config.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/main_pages.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..30c4bf1b2b5fec8fe999887459487c804b018afa --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,12 @@ +{ + "src": [ + "pages/Index", + "drawing/pages/CanvasGetResult", + "drawing/pages/CanvasOperationState", + "drawing/pages/BasicEffect", + "drawing/pages/ComplexEffect", + "drawing/pages/ShapeDrawing", + "drawing/pages/PixelMapDrawing", + "drawing/pages/TextBlockDrawing" + ] +} diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/dark/element/color.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/mock/Libentry.mock.ets b/Drawing/NDKGraphicsDraw/entry/src/mock/Libentry.mock.ets new file mode 100644 index 0000000000000000000000000000000000000000..133fac9027ff6bbdcccfe98838fdbb2dc34639ab --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/mock/Libentry.mock.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const nativeMock: Record = { + 'add': (a: number, b: number) => { + return a + b; + }, +}; + +export default nativeMock; \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/mock/mock-config.json5 b/Drawing/NDKGraphicsDraw/entry/src/mock/mock-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2c7d2ba82b796a2850ced0a277d261d7d7355416 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/mock/mock-config.json5 @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "libentry.so": { + "source": "src/mock/Libentry.mock.ets" + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/Ability.test.ets b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd422eaf568ac910918d5fb56b430cc152486911 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, it, expect } from '@ohos/hypium'; +import { Driver, ON } from '@ohos.UiTest'; +import Logger from '../utils/Logger'; +import { abilityDelegatorRegistry } from '@kit.TestKit'; +import { UIAbility, Want } from '@kit.AbilityKit'; + +const TAG = '[Sample_NDKGraphicsDraw]'; +const DELAY_SHORT = 400; +const DELAY_LONG = 1000; + +const delegator = abilityDelegatorRegistry.getAbilityDelegator(); +const bundleName = abilityDelegatorRegistry.getArguments().bundleName; + +function getString(resourceData: Resource): string { + let manage = delegator.getAppContext().resourceManager; + return manage.getStringSync(resourceData); +} + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + /** + * @tc.number StartAbility_001 + * @tc.name StartAbility_001 + * @tc.desc 启动Ability + */ + it('NDKGraphicsDraw_StartAbility_001',0, async (done: Function) => { + console.info('uitest: StartAbility_001 begin'); + //start tested ability + const want: Want = { + bundleName: bundleName, + abilityName: 'EntryAbility' + }; + await delegator.startAbility(want); + let driver = Driver.create(); + await driver.delayMs(DELAY_LONG); + //check top display ability + const ability: UIAbility = await delegator.getCurrentTopAbility(); + console.info('get top ability'); + expect(ability.context.abilityInfo.name).assertEqual('EntryAbility'); + done(); + console.info('uitest: StartAbility_001 end'); + }) + + /** + * @tc.number:CanvasGetResult_001 + * @tc.name:CanvasGetResult_001 + * @tc.desc:画布的获取与绘制结果测试 + */ + it('NDKGraphicsDraw_CanvasGetResult_001', 0, async (done: Function) => { + Logger.info(TAG, 'CanvasGetResult_001 begin'); + let driver = Driver.create(); + let canvasGetResultStr = getString($r('app.string.CanvasGetResult')); + await driver.assertComponentExist(ON.text(canvasGetResultStr)); + let canvasButton = await driver.findComponent(ON.text(canvasGetResultStr)); + await canvasButton.click(); + await driver.delayMs(DELAY_SHORT); + + let canvasGetStr = getString($r('app.string.CanvasGet')); + await driver.assertComponentExist(ON.text(canvasGetStr)); + let canvasGetButton = await driver.findComponent(ON.text(canvasGetStr)); + await canvasGetButton.click(); + await driver.delayMs(DELAY_SHORT); + + let getStringByCPUStr = getString($r('app.string.CanvasGetByCPU')); + await driver.assertComponentExist(ON.text(getStringByCPUStr)); + let canvasGetByCPUButton = await driver.findComponent(ON.text(getStringByCPUStr)); + await canvasGetByCPUButton.click(); + await driver.delayMs(DELAY_SHORT); + + let getStringByGPUStr = getString($r('app.string.CanvasGetByGPU')); + await driver.assertComponentExist(ON.text(getStringByGPUStr)); + let canvasGetByGPUButton = await driver.findComponent(ON.text(getStringByGPUStr)); + await canvasGetByGPUButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'CanvasGetResult_001 end'); + }); + + /** + * @tc.number:CanvasOperationState_001 + * @tc.name:CanvasOperationState_001 + * @tc.desc:画布操作与状态操作结果测试 + */ + it('NDKGraphicsDraw_CanvasOperationState_001', 0, async (done: Function) => { + Logger.info(TAG, 'CanvasGet_001 begin'); + let driver = Driver.create(); + let canvasOperationStr = getString($r('app.string.CanvasOperationState')); + await driver.assertComponentExist(ON.text(canvasOperationStr)); + let canvasOperationButton = await driver.findComponent(ON.text(canvasOperationStr)); + await canvasOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let clipOperationStr = getString($r('app.string.ClipOperation')); + await driver.assertComponentExist(ON.text(clipOperationStr)); + let clipOperationButton = await driver.findComponent(ON.text(clipOperationStr)); + await clipOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let translationOperationStr = getString($r('app.string.TranslationOperation')); + await driver.assertComponentExist(ON.text(translationOperationStr)); + let translationOperationButton = await driver.findComponent(ON.text(translationOperationStr)); + await translationOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let rotationOperationStr = getString($r('app.string.RotationOperation')); + await driver.assertComponentExist(ON.text(rotationOperationStr)); + let rotationOperationButton = await driver.findComponent(ON.text(rotationOperationStr)); + await rotationOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let scaleOperationStr = getString($r('app.string.ScaleOperation')); + await driver.assertComponentExist(ON.text(scaleOperationStr)); + let scaleOperationButton = await driver.findComponent(ON.text(scaleOperationStr)); + await scaleOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let stateOperationStr = getString($r('app.string.StateOperation')); + await driver.assertComponentExist(ON.text(stateOperationStr)); + let stateOperationButton = await driver.findComponent(ON.text(stateOperationStr)); + await stateOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'CanvasGet_001 end'); + }); + + /** + * @tc.number:BasicEffect_001 + * @tc.name:BasicEffect_001 + * @tc.desc:基础绘制效果结果测试 + */ + it('NDKGraphicsDraw_BasicEffect_001', 0, async (done: Function) => { + Logger.info(TAG, 'BasicEffect_001 begin'); + let driver = Driver.create(); + let basicEffectStr = getString($r('app.string.BasicEffect')); + await driver.assertComponentExist(ON.text(basicEffectStr)); + let basicEffectButton = await driver.findComponent(ON.text(basicEffectStr)); + await basicEffectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let fillingStr = getString($r('app.string.Filling')); + await driver.assertComponentExist(ON.text(fillingStr)); + let fillingButton = await driver.findComponent(ON.text(fillingStr)); + await fillingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let strokeStr = getString($r('app.string.Stroke')); + await driver.assertComponentExist(ON.text(strokeStr)); + let strokeButton = await driver.findComponent(ON.text(strokeStr)); + await strokeButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'BasicEffect_001 end'); + }); + + /** + * @tc.number:ComplexEffect_001 + * @tc.name:ComplexEffect_001 + * @tc.desc:复杂绘制效果结果测试 + */ + it('NDKGraphicsDraw_ComplexEffect_001', 0, async (done: Function) => { + Logger.info(TAG, 'ComplexEffect_001 begin'); + let driver = Driver.create(); + let complexEffectStr = getString($r('app.string.ComplexEffect')); + await driver.assertComponentExist(ON.text(complexEffectStr)); + let complexEffectButton = await driver.findComponent(ON.text(complexEffectStr)); + await complexEffectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let mixedModeStr = getString($r('app.string.MixedMode')); + await driver.assertComponentExist(ON.text(mixedModeStr)); + let mixedModeButton = await driver.findComponent(ON.text(mixedModeStr)); + await mixedModeButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pathEffectStr = getString($r('app.string.PathEffect')); + await driver.assertComponentExist(ON.text(pathEffectStr)); + let pathEffectButton = await driver.findComponent(ON.text(pathEffectStr)); + await pathEffectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let linearGradientStr = getString($r('app.string.LinearGradient')); + await driver.assertComponentExist(ON.text(linearGradientStr)); + let linearGradientButton = await driver.findComponent(ON.text(linearGradientStr)); + await linearGradientButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pathGradientStr = getString($r('app.string.PathGradient')); + await driver.assertComponentExist(ON.text(pathGradientStr)); + let pathGradientButton = await driver.findComponent(ON.text(pathGradientStr)); + await pathGradientButton.click(); + await driver.delayMs(DELAY_SHORT); + + let sectorGradientStr = getString($r('app.string.SectorGradient')); + await driver.assertComponentExist(ON.text(sectorGradientStr)); + let sectorGradientButton = await driver.findComponent(ON.text(sectorGradientStr)); + await sectorGradientButton.click(); + await driver.delayMs(DELAY_SHORT); + + let colorFilterStr = getString($r('app.string.ColorFilter')); + await driver.assertComponentExist(ON.text(colorFilterStr)); + let colorFilterButton = await driver.findComponent(ON.text(colorFilterStr)); + await colorFilterButton.click(); + await driver.delayMs(DELAY_SHORT); + + let imageFilterStr = getString($r('app.string.ImageFilter')); + await driver.assertComponentExist(ON.text(imageFilterStr)); + let imageFilterStrButton = await driver.findComponent(ON.text(imageFilterStr)); + await imageFilterStrButton.click(); + await driver.delayMs(DELAY_SHORT); + + let maskFilterStr = getString($r('app.string.MaskFilter')); + await driver.assertComponentExist(ON.text(maskFilterStr)); + let maskFilterButton = await driver.findComponent(ON.text(maskFilterStr)); + await maskFilterButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'ComplexEffect_001 end'); + }); + + /** + * @tc.number:ShapeDrawing_001 + * @tc.name:ShapeDrawing_001 + * @tc.desc:几何形状绘制结果测试 + */ + it('NDKGraphicsDraw_ShapeDrawing_001', 0, async (done: Function) => { + Logger.info(TAG, 'ShapeDrawing_001 begin'); + let driver = Driver.create(); + let shapeDrawingStr = getString($r('app.string.Shape_Drawing')); + await driver.assertComponentExist(ON.text(shapeDrawingStr)); + let shapeDrawingButton = await driver.findComponent(ON.text(shapeDrawingStr)); + await shapeDrawingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pointStr = getString($r('app.string.Point')); + await driver.assertComponentExist(ON.text(pointStr)); + let pointButton = await driver.findComponent(ON.text(pointStr)); + await pointButton.click(); + await driver.delayMs(DELAY_SHORT); + + let arcStr = getString($r('app.string.Arc')); + await driver.assertComponentExist(ON.text(arcStr)); + let arcButton = await driver.findComponent(ON.text(arcStr)); + await arcButton.click(); + await driver.delayMs(DELAY_SHORT); + + let circleStr = getString($r('app.string.Circle')); + await driver.assertComponentExist(ON.text(circleStr)); + let circleButton = await driver.findComponent(ON.text(circleStr)); + await circleButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pathStr = getString($r('app.string.Path')); + await driver.assertComponentExist(ON.text(pathStr)); + let pathButton = await driver.findComponent(ON.text(pathStr)); + await pathButton.click(); + await driver.delayMs(DELAY_SHORT); + + let regionStr = getString($r('app.string.Region')); + await driver.assertComponentExist(ON.text(regionStr)); + let regionButton = await driver.findComponent(ON.text(regionStr)); + await regionButton.click(); + await driver.delayMs(DELAY_SHORT); + + let rectStr = getString($r('app.string.Rect')); + await driver.assertComponentExist(ON.text(rectStr)); + let rectButton = await driver.findComponent(ON.text(rectStr)); + await rectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let roundRectStr = getString($r('app.string.RoundRect')); + await driver.assertComponentExist(ON.text(roundRectStr)); + let roundRectButton = await driver.findComponent(ON.text(roundRectStr)); + await roundRectButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'ShapeDrawing_001 end'); + }); + + it('NDKGraphicsDraw_PixelMapDrawing_001', 0, async (done: Function) => { + Logger.info(TAG, 'PixelMapDrawing_001 begin'); + let driver = Driver.create(); + let pixelMapDrawingStr = getString($r('app.string.PixelMap_Drawing')); + await driver.assertComponentExist(ON.text(pixelMapDrawingStr)); + let pixelMapDrawingButton = await driver.findComponent(ON.text(pixelMapDrawingStr)); + await pixelMapDrawingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pixelMapStr = getString($r('app.string.PixelMap')); + await driver.assertComponentExist(ON.text(pixelMapStr)); + let pixelMapButton = await driver.findComponent(ON.text(pixelMapStr)); + await pixelMapButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'PixelMapDrawing_001 end'); + }); + + it('NDKGraphicsDraw_TextBlockDrawing_001', 0, async (done: Function) => { + Logger.info(TAG, 'TextBlockDrawing_001 begin'); + let driver = Driver.create(); + let textBlockDrawingStr = getString($r('app.string.TextBlock_Drawing')); + await driver.assertComponentExist(ON.text(textBlockDrawingStr)); + let textBlockDrawingButton = await driver.findComponent(ON.text(textBlockDrawingStr)); + await textBlockDrawingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let baseTextStr = getString($r('app.string.BaseText')); + await driver.assertComponentExist(ON.text(baseTextStr)); + let baseTextButton = await driver.findComponent(ON.text(baseTextStr)); + await baseTextButton.click(); + await driver.delayMs(DELAY_SHORT); + + let strokeTextStr = getString($r('app.string.StrokeText')); + await driver.assertComponentExist(ON.text(strokeTextStr)); + let strokeTextButton = await driver.findComponent(ON.text(strokeTextStr)); + await strokeTextButton.click(); + await driver.delayMs(DELAY_SHORT); + + let gradientTextStr = getString($r('app.string.GradientText')); + await driver.assertComponentExist(ON.text(gradientTextStr)); + let gradientTextButton = await driver.findComponent(ON.text(gradientTextStr)); + await gradientTextButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'TextBlockDrawing_001 end'); + }); + }) +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/List.test.ets b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..1eac52fcebe8958e19a7b8fed2e8f39c520a3e42 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/utils/Logger.ets b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/utils/Logger.ets new file mode 100644 index 0000000000000000000000000000000000000000..61ed537de317bc72e7cc0bbe7f471e7971162f68 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/utils/Logger.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import hilog from '@ohos.hilog'; + +class Logger { + private domain: number = 0xF811; + private prefix: string = ''; + private format: string = '%{public}s, %{public}s'; + + constructor(prefix: string) { + this.prefix = prefix; + this.domain = 0xF811; + } + + debug(...args: string[]): void { + hilog.debug(this.domain, this.prefix, this.format, args); + } + + info(...args: string[]): void { + hilog.info(this.domain, this.prefix, this.format, args); + } + + warn(...args: string[]): void { + hilog.warn(this.domain, this.prefix, this.format, args); + } + + error(...args: string[]): void { + hilog.error(this.domain, this.prefix, this.format, args); + } +} + +export default new Logger('[Sample_NDKGraphicsDraw]'); \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/module.json5 b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c3fd9dda3040d888d9d8b0b62bcb5d3b6fbeb614 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/module.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/Drawing/NDKGraphicsDraw/hvigor/hvigor-config.json5 b/Drawing/NDKGraphicsDraw/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d584c19c247db9a7caee4b606bb931aa9279c637 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/hvigor/hvigor-config.json5 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "modelVersion": "5.0.1", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/Drawing/NDKGraphicsDraw/hvigorfile.ts b/Drawing/NDKGraphicsDraw/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..2a5e543f190732c159beb574dfc9fa37bc94e156 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/hvigorfile.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Drawing/NDKGraphicsDraw/oh-package.json5 b/Drawing/NDKGraphicsDraw/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e41bae026aab3b50d0abb42fece08ba43b4a772b --- /dev/null +++ b/Drawing/NDKGraphicsDraw/oh-package.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "modelVersion": "5.0.1", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.19", + "@ohos/hamock": "1.0.0" + } +} diff --git a/Drawing/NDKGraphicsDraw/ohosTest.md b/Drawing/NDKGraphicsDraw/ohosTest.md new file mode 100644 index 0000000000000000000000000000000000000000..7b49fd8c6851d4af346066a3461281c976236d4d --- /dev/null +++ b/Drawing/NDKGraphicsDraw/ohosTest.md @@ -0,0 +1,14 @@ +# NDKGraphicDraw测试用例归档 + +## 用例表 + +| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 | +| ---------------------- | ------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------ | -------- | -------- | +| 拉起应用 | 设备正常运行 | | 成功拉起应用 | 是 | Pass | +| 画布获取功能 | 进入“画布的获取与绘制结果的显示”页面 | | 页面显示“获取直接绘图结果”与“获取离屏画布绘图结果” | 是 | Pass | +| 画布操作及状态处理功能 | 进入“画布操作及状态处理”界面 | 依次点击裁剪操作、平移操作、旋转操作、缩放操作、画布状态操作五个按钮 | 在每个按钮点击后,绘制出对应的操作结果图案 | 是 | Pass | +| 基础绘制效果功能 | 进入“基础绘制效果”界面 | 依次点击填充效果、描边效果两个按钮 | 页面显示填充效果图案、描边效果图案 | 是 | Pass | +| 复杂绘制效果功能 | 进入“复杂绘制效果”界面 | 依次点击混合模式、路径效果、线性渐变、径向渐变、扇形渐变、颜色滤波器、图像滤波器、蒙版滤波器八个按钮 | 在每个按钮点击后,绘制出对应的绘制效果图案 | 是 | Pass | +| 几何图形绘制功能 | 进入“几何图形绘制”界面 | 依次点击点、圆弧、圆、路径、区域、矩形、圆角矩形七个按钮 | 在每个按钮点击后,绘制出对应的图案 | 是 | Pass | +| 图片绘制功能 | 进入“图片绘制”界面 | 依次点击绘制图片、编辑中间像素两个按钮 | 先绘制出一幅矩形像素图,而后像素图中间的像素变为黑白色 | 是 | Pass | +| 字块绘制功能 | 进入“字块绘制”界面 | 依次点击基本文字、文字描边、文字渐变三个按钮 | 依次绘制出基本文字图案、描边文字图案和渐变文字图案 | 是 | Pass | \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/screenshot/Shape.jpeg b/Drawing/NDKGraphicsDraw/screenshot/Shape.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..9aa3382108acca02184a7681b93cffb66e5461d4 Binary files /dev/null and b/Drawing/NDKGraphicsDraw/screenshot/Shape.jpeg differ diff --git a/Drawing/NDKGraphicsDraw/screenshot/canvas.jpeg b/Drawing/NDKGraphicsDraw/screenshot/canvas.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..86fc16dd606a93c78710f768d5ec166f428b8164 Binary files /dev/null and b/Drawing/NDKGraphicsDraw/screenshot/canvas.jpeg differ diff --git a/Drawing/NDKGraphicsDraw/screenshot/effect.jpeg b/Drawing/NDKGraphicsDraw/screenshot/effect.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..be41d49159d3f4ca9f58a161732faeb3ee877dd3 Binary files /dev/null and b/Drawing/NDKGraphicsDraw/screenshot/effect.jpeg differ diff --git a/Drawing/NDKGraphicsDraw/screenshot/index.jpeg b/Drawing/NDKGraphicsDraw/screenshot/index.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1b85aa811a34c8b9ac67bd5bfcd16ed88d062a20 Binary files /dev/null and b/Drawing/NDKGraphicsDraw/screenshot/index.jpeg differ