diff --git a/NdkDrawingApiSamples/.gitignore b/NdkDrawingApiSamples/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2ff20141ceed86d87c0ea5d99481973005bab2b --- /dev/null +++ b/NdkDrawingApiSamples/.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/NdkDrawingApiSamples/AppScope/app.json5 b/NdkDrawingApiSamples/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..37314d5cca56eb4012ca547257a3f7e0fde45e82 --- /dev/null +++ b/NdkDrawingApiSamples/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.ndkdrawingapisamples", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/NdkDrawingApiSamples/AppScope/resources/base/element/string.json b/NdkDrawingApiSamples/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9d3e58622afb1bcd437acbc52d2cfc8233b804a1 --- /dev/null +++ b/NdkDrawingApiSamples/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "NdkDrawingApiSamples" + } + ] +} diff --git a/NdkDrawingApiSamples/AppScope/resources/base/media/app_icon.png b/NdkDrawingApiSamples/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a39445dc87828b76fed6d2ec470dd455c45319e3 Binary files /dev/null and b/NdkDrawingApiSamples/AppScope/resources/base/media/app_icon.png differ diff --git a/NdkDrawingApiSamples/LICENSE b/NdkDrawingApiSamples/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..0668671ebed3940a437e39190bdf67d05389946a --- /dev/null +++ b/NdkDrawingApiSamples/LICENSE @@ -0,0 +1,78 @@ + Copyright (c) 2025 Huawei Device Co., Ltd. All rights reserved. + + 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. + +Apache License, Version 2.0 +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + +"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. + +"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. + +"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. + +"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. + +"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. + +"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. + +"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). + +"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. + +"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." + +"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. + +2. Grant of Copyright License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. + +Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. + +4. Redistribution. + +You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: +1.You must give any other recipients of the Work or Derivative Works a copy of this License; and +2.You must cause any modified files to carry prominent notices stating that You changed the files; and +3.You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and +4.If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. + +You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. + +5. Submission of Contributions. + +Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. + +6. Trademarks. + +This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. + +Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. + +In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. + +While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS \ No newline at end of file diff --git a/NdkDrawingApiSamples/README.md b/NdkDrawingApiSamples/README.md new file mode 100644 index 0000000000000000000000000000000000000000..c843823b40aa98ffb666f2e19853981eb49a9868 --- /dev/null +++ b/NdkDrawingApiSamples/README.md @@ -0,0 +1,80 @@ +# Drawing API示例(C/C++) + +#### 介绍 + +Drawing模块提供包括2D图形渲染、文字绘制和图片显示等功能函数。这是一个基于Drawing图形库API(C/C++)的示例项目,展示如何使用Drawing API进行基础的2D图形绘制操作,具体API详见[drawing-V5](https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/_drawing-V5)。 + +#### 效果预览 + +![Screenshot_20250418143325437](screenshots/device/Screenshot_20250418143325437.jpeg) +![Screenshot_20250418150845623](screenshots/device/Screenshot_20250418150845623.jpeg) +![Screenshot_20250418150909597](screenshots/device/Screenshot_20250418150909597.jpeg) +![Screenshot_20250418150925879](screenshots/device/Screenshot_20250418150925879.jpeg) +![Screenshot_20250418150945891](screenshots/device/Screenshot_20250418150945891.jpeg) +![Screenshot_20250418151048183](screenshots/device/Screenshot_20250418151048183.jpeg) +![Screenshot_20250418151107524](screenshots/device/Screenshot_20250418151107524.jpeg) +![Screenshot_20250418151125603](screenshots/device/Screenshot_20250418151125603.jpeg) +![Screenshot_20250418151143671](screenshots/device/Screenshot_20250418151143671.jpeg) +![Screenshot_20250418151155313](screenshots/device/Screenshot_20250418151155313.jpeg) + +#### 具体实现 + +使用Drawing进行图形绘制与显示时,需要使用Native Drawing模块的画布画笔绘制一个基本的2D图形;并将图形内容写入[NativeWindow](https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/native-window-guidelines-V5)提供的图形Buffer,将Buffer提交到图形队列;再利用XComponent将C++代码层与ArkTS层对接,实现在ArkTS层调用绘制和显示的逻辑,最终在应用上显示图形。 + +#### 使用说明 + +使用DevEco Studio 5.0.0及以上版本打开此工程,编译并安装到测试机中,打开应用。 + +#### 工程目录 + +``` +├──entry/src/main +│ ├──cpp // C++代码区 +│ │ ├──CMakeLists.txt // CMake配置文件 +│ │ ├──napi_init.cpp // Napi模块注册 +│ │ ├──common // 日志封装定义文件 +│ │ │ └──log_common.h +│ │ ├──plugin // 生命周期管理模块 +│ │ │ ├──plugin_manager.cpp +│ │ │ └──plugin_manager.h +│ │ ├──samples // samples渲染模块 +│ │ │ ├──sample_graphics.cpp // 示例代码所在的cpp文件 +│ │ │ └──sample_graphics.h // 示例代码相关代码头文件 +│ │ ├──types // 不涉及 +│ │ ├──utils // 多设备适配工具类 +│ │ │ ├──adaptation_utils.cpp +│ │ │ └──adaptation_utils.h +│ ├──ets // ets代码区 +│ │ ├──drawing +│ │ │ ├──pages +│ │ │ │ ├──BitmapDrawing.ets // drawing_bitmap.h对应的示例展示界面 +│ │ │ │ ├──BrushDrawing.ets // drawing_brush.h对应的示例展示界面 +│ │ │ │ ├──CanvasDrawing.ets // drawing_canvas.h对应的示例展示界面 +│ │ │ │ ├──ImageDrawing.ets // drawing_image.h对应的示例展示界面 +│ │ │ │ ├──MatrixDrawing.ets // drawing_matrix.h对应的示例展示界面 +│ │ │ │ ├──PathDrawing.ets // drawing_path.h对应的示例展示界面 +│ │ │ │ ├──PenDrawing.ets // drawing_pen.h对应的示例展示界面 +│ │ │ │ ├──PixelMapDrawing.ets // drawing_pixel_map.h对应的示例展示界面 +│ │ │ │ └──RectDrawing.ets // drawing_rect.h对应的示例展示界面 +│ │ ├──entryability // 不涉及 +│ │ ├──entrybackupability // 不涉及 +| | ├──interface +│ │ │ └──XComponentContext.ts // XComponentContext +│ │ └──pages // 页面文件 +│ │ └──Index.ets // 主界面 +| ├──resources // 资源文件目录(不涉及) +``` + +#### 相关权限 + +暂无 + +#### 依赖 + +暂无 + +#### 约束与限制 + +1. HarmonyOS系统:HarmonyOS 5.0.0 Release及以上; +2. DevEco Studio版本:DevEco Studio 5.0.0 Release及以上; +3. HarmonyOS SDK版本:API 12及以上版本; diff --git a/NdkDrawingApiSamples/build-profile.json5 b/NdkDrawingApiSamples/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..ccd704e1c66508f04553a863f2ffd1c229faf7de --- /dev/null +++ b/NdkDrawingApiSamples/build-profile.json5 @@ -0,0 +1,43 @@ +{ + "app": { + "signingConfigs": [], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS", + "buildOption": { + "externalNativeOptions": { + "abiFilters": [ + "arm64-v8a", + "x86_64" + ] + } + } + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/code-linter.json5 b/NdkDrawingApiSamples/code-linter.json5 new file mode 100644 index 0000000000000000000000000000000000000000..77b31b517a3e5c2f34c3ae1bf44083c0c06cbd6d --- /dev/null +++ b/NdkDrawingApiSamples/code-linter.json5 @@ -0,0 +1,20 @@ +{ + "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/NdkDrawingApiSamples/entry/.gitignore b/NdkDrawingApiSamples/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..e2713a2779c5a3e0eb879efe6115455592caeea5 --- /dev/null +++ b/NdkDrawingApiSamples/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/build-profile.json5 b/NdkDrawingApiSamples/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..14bbd03b5cd8ccf4c6bec74c0b9550228d792cb5 --- /dev/null +++ b/NdkDrawingApiSamples/entry/build-profile.json5 @@ -0,0 +1,39 @@ +{ + "apiType": "stageMode", + "buildOption": { + "externalNativeOptions": { + "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/NdkDrawingApiSamples/entry/hvigorfile.ts b/NdkDrawingApiSamples/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6edcd90486dd5a853cf7d34c8647f08414ca7a3 --- /dev/null +++ b/NdkDrawingApiSamples/entry/hvigorfile.ts @@ -0,0 +1,6 @@ +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/NdkDrawingApiSamples/entry/obfuscation-rules.txt b/NdkDrawingApiSamples/entry/obfuscation-rules.txt new file mode 100644 index 0000000000000000000000000000000000000000..272efb6ca3f240859091bbbfc7c5802d52793b0b --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/oh-package.json5 b/NdkDrawingApiSamples/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..b9c1d4cca76ac664388dd6b1cf96697184c5133b --- /dev/null +++ b/NdkDrawingApiSamples/entry/oh-package.json5 @@ -0,0 +1,11 @@ +{ + "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/NdkDrawingApiSamples/entry/src/main/cpp/CMakeLists.txt b/NdkDrawingApiSamples/entry/src/main/cpp/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..d275c84d1bc0504af865e611d8bd8a54f40f5f31 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/cpp/CMakeLists.txt @@ -0,0 +1,33 @@ +# 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 + libpixelmap_ndk.z.so + libnative_display_manager.so + ) \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/cpp/common/log_common.h b/NdkDrawingApiSamples/entry/src/main/cpp/common/log_common.h new file mode 100644 index 0000000000000000000000000000000000000000..d6f6a00c0040707eceeff100274ac6b8acbe7801 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/cpp/napi_init.cpp b/NdkDrawingApiSamples/entry/src/main/cpp/napi_init.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a7afa7d28f7a8fed7cda89806bad5668bba65825 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/cpp/plugin/plugin_manager.cpp b/NdkDrawingApiSamples/entry/src/main/cpp/plugin/plugin_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a24d9a076df77d16bee97a6bbb75927a9bce1e39 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/cpp/plugin/plugin_manager.h b/NdkDrawingApiSamples/entry/src/main/cpp/plugin/plugin_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..6ed97b62f8dda964d068a04d79a3adf05fa07455 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/cpp/samples/sample_graphics.cpp b/NdkDrawingApiSamples/entry/src/main/cpp/samples/sample_graphics.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d4443df0790505217f7e9dcc57e27f05ace3fffc --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/cpp/samples/sample_graphics.cpp @@ -0,0 +1,2063 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common/log_common.h" +#include "sample_graphics.h" +#include "utils/adaptation_util.h" + +#include +#include + +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::value1100_ = adaptationUtil->GetWidth(1100.f); +float SampleGraphics::value1200_ = adaptationUtil->GetWidth(1200.f); + +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; +} + +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; +} + +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是从上一步骤中的回调函数中获得的 + // 通过 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_); + // 使用系统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"); + } +} + +void SampleGraphics::Create() +{ + uint32_t width = static_cast(bufferHandle_->stride / 4); + // 创建一个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_); + // 使用白色清除画布内容 + OH_Drawing_CanvasClear(cScreenCanvas_, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MAX, 0xFF)); +} + +void SampleGraphics::CreateByCPU() +{ + // 创建一个离屏位图对象 + 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_); + // 将背景设置为白色 + OH_Drawing_CanvasClear(cCPUCanvas_, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MAX, 0xFF)); + + // 创建一个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_); + + // 设置宽高(按需设定) + 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); + // 将背景设置为白色 + OH_Drawing_CanvasClear(cGPUCanvas_, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MAX, 0xFF)); +} + +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++; + } + } + // 设置刷新区域,如果Region中的Rect为nullptr,或者rectNumber为0,则认为OHNativeWindowBuffer全部有内容更改。 + Region region{nullptr, 0}; + // 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。 + OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer_, fenceFd_, region); + // 内存使用完记得去掉内存映射 + int result = munmap(mappedAddr_, bufferHandle_->size); + if (result == -1) { + SAMPLE_LOGE("munmap failed!"); + } +} + +void SampleGraphics::DisPlayCPU() +{ + // 将离屏bitmap中的内容绘制到屏幕画布,实现上屏操作 + OH_Drawing_CanvasDrawBitmap(cScreenCanvas_, cOffScreenBitmap_, 0, 0); + 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}; + 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); + DisPlay(); +} + +void SampleGraphics::DrawClipOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetColor(brush, 0xff0000ff); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value200_, value200_, value1000_, value1000_); + // 裁剪矩形区域 + OH_Drawing_CanvasClipRect(canvas, rect, OH_Drawing_CanvasClipOp::INTERSECT, true); + OH_Drawing_Rect* rect2 = OH_Drawing_RectCreate(0, 0, 0, 0); + OH_Drawing_CanvasGetLocalClipBounds(canvas, rect2); + SAMPLE_LOGI("Canvas-->ClipBounds:top=%{public}f,left=%{public}f,right=%{public}f,bottom=%{public}f", + OH_Drawing_RectGetTop(rect2), OH_Drawing_RectGetLeft(rect2), OH_Drawing_RectGetRight(rect2), + OH_Drawing_RectGetBottom(rect2)); + OH_Drawing_Path *path = OH_Drawing_PathCreate(); + OH_Drawing_PathAddCircle(path, value200_, value200_, value400_, PATH_DIRECTION_CCW); + // 裁剪圆形区域 + OH_Drawing_CanvasClipPath(canvas, path, OH_Drawing_CanvasClipOp::DIFFERENCE, true); + // 绘制背景 + OH_Drawing_CanvasDrawBackground(canvas, brush); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_PathDestroy(path); + OH_Drawing_RectDestroy(rect); + OH_Drawing_RectDestroy(rect2); +} + +void SampleGraphics::DrawMatrixBasic(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 创建矩阵对象 + OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreate(); + // 设置矩阵(平移) + OH_Drawing_MatrixSetMatrix(matrix, 1, 0, value300_, 0, 1, value300_, 0, 0, 1); + // 获取矩阵的值 + SAMPLE_LOGI("DrawMatrixBasic-->GetValue-matrix(%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f)", + OH_Drawing_MatrixGetValue(matrix, 0), OH_Drawing_MatrixGetValue(matrix, 1), + OH_Drawing_MatrixGetValue(matrix, 2), OH_Drawing_MatrixGetValue(matrix, 3), + OH_Drawing_MatrixGetValue(matrix, 4), OH_Drawing_MatrixGetValue(matrix, 5), + OH_Drawing_MatrixGetValue(matrix, 6), OH_Drawing_MatrixGetValue(matrix, 7), + OH_Drawing_MatrixGetValue(matrix, 8)); + OH_Drawing_Point2D src{value300_, value300_}; + OH_Drawing_Point2D dst; + // 源点坐标变换为目标点坐标 + OH_Drawing_MatrixMapPoints(matrix, &src, &dst, 1); + SAMPLE_LOGI("DrawMatrixBasic-->point(src) x=%{public}f,y=%{public}f", src.x, src.y); + SAMPLE_LOGI("DrawMatrixBasic-->point(dst) x=%{public}f,y=%{public}f", dst.x, dst.y); + OH_Drawing_Rect *rect2 = OH_Drawing_RectCreate(0, 0, 0, 0); + // 源矩形变换为目标矩形 + OH_Drawing_MatrixMapRect(matrix, rect, rect2); + SAMPLE_LOGI("DrawMatrixBasic-->rect(src) left=%{public}f,top=%{public}f,right=%{public}f,bottom=%{public}f", + OH_Drawing_RectGetLeft(rect), OH_Drawing_RectGetTop(rect), OH_Drawing_RectGetRight(rect), + OH_Drawing_RectGetBottom(rect)); + SAMPLE_LOGI("DrawMatrixBasic-->rect(dst) left=%{public}f,top=%{public}f,right=%{public}f,bottom=%{public}f", + OH_Drawing_RectGetLeft(rect2), OH_Drawing_RectGetTop(rect2), OH_Drawing_RectGetRight(rect2), + OH_Drawing_RectGetBottom(rect2)); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix *matrix2 = OH_Drawing_MatrixCreate(); + // 逆矩阵 + OH_Drawing_MatrixInvert(matrix2, matrix); + SAMPLE_LOGI("DrawMatrixBasic-->GetValue-matrix2(%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f)", + OH_Drawing_MatrixGetValue(matrix2, 0), OH_Drawing_MatrixGetValue(matrix2, 1), + OH_Drawing_MatrixGetValue(matrix2, 2), OH_Drawing_MatrixGetValue(matrix2, 3), + OH_Drawing_MatrixGetValue(matrix2, 4), OH_Drawing_MatrixGetValue(matrix2, 5), + OH_Drawing_MatrixGetValue(matrix2, 6), OH_Drawing_MatrixGetValue(matrix2, 7), + OH_Drawing_MatrixGetValue(matrix2, 8)); + // 重置矩阵 + OH_Drawing_MatrixReset(matrix); + // 获取矩阵的值 + SAMPLE_LOGI("DrawMatrixBasic-->GetValue-matrix-reset(%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f,%{public}f)", + OH_Drawing_MatrixGetValue(matrix, 0), OH_Drawing_MatrixGetValue(matrix, 1), + OH_Drawing_MatrixGetValue(matrix, 2), OH_Drawing_MatrixGetValue(matrix, 3), + OH_Drawing_MatrixGetValue(matrix, 4), OH_Drawing_MatrixGetValue(matrix, 5), + OH_Drawing_MatrixGetValue(matrix, 6), OH_Drawing_MatrixGetValue(matrix, 7), + OH_Drawing_MatrixGetValue(matrix, 8)); + OH_Drawing_CanvasDetachBrush(canvas); + // 释放对象 + OH_Drawing_RectDestroy(rect); + OH_Drawing_RectDestroy(rect2); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_MatrixDestroy(matrix2); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawTranslationOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 创建在水平和垂直方向分别平移300px的矩阵对象 + OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreateTranslation(value300_, value300_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawPreTranslationOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreate(); + // 旋转 + OH_Drawing_MatrixRotate(matrix, 45.f, value300_, value300_); + // 左乘平移(先平移后旋转) + OH_Drawing_MatrixPreTranslate(matrix, value200_, value200_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawPostTranslationOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreate(); + // 旋转 + OH_Drawing_MatrixRotate(matrix, 45.f, value300_, value300_); + // 右乘平移(先旋转后平移) + OH_Drawing_MatrixPostTranslate(matrix, value200_, value200_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawRotationOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 创建旋转的矩阵对象 + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateRotation(45, value300_, value300_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawPreRotationOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreate(); + // 平移 + OH_Drawing_MatrixTranslate(matrix, value200_, value200_); + // 左乘旋转(先旋转后平移) + OH_Drawing_MatrixPreRotate(matrix, 45, value300_, value300_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawPostRotationOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreate(); + // 平移 + OH_Drawing_MatrixTranslate(matrix, value200_, value200_); + // 右乘旋转(先平移后旋转) + OH_Drawing_MatrixPostRotate(matrix, 45, value300_, value300_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawScaleOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + // 创建缩放的矩阵对象 + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateScale(2, 2, value300_, value300_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_PenDestroy(pen); + OH_Drawing_MatrixDestroy(matrix); +} + +void SampleGraphics::DrawPreScaleOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateTranslation(value100_, value100_); + // 左乘缩放(先缩放后平移) + OH_Drawing_MatrixPreScale(matrix, 2, 2, value300_, value300_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_PenDestroy(pen); + OH_Drawing_MatrixDestroy(matrix); +} + +void SampleGraphics::DrawPostScaleOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreateTranslation(value100_, value100_); + // 右乘缩放(先平移后缩放) + OH_Drawing_MatrixPostScale(matrix, 2, 2, value300_, value300_); + OH_Drawing_CanvasConcatMatrix(canvas, matrix); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_PenDestroy(pen); + OH_Drawing_MatrixDestroy(matrix); +} + +void SampleGraphics::DrawConcatOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix* matrix1 = OH_Drawing_MatrixCreateTranslation(value100_, value100_); + OH_Drawing_Matrix* matrix2 = OH_Drawing_MatrixCreate(); + OH_Drawing_Matrix* matrix3 = OH_Drawing_MatrixCreate(); + OH_Drawing_MatrixScale(matrix2, 2, 2, value300_, value300_); + OH_Drawing_MatrixConcat(matrix3, matrix2, matrix1); + OH_Drawing_CanvasConcatMatrix(canvas, matrix3); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_PenDestroy(pen); + OH_Drawing_MatrixDestroy(matrix1); + OH_Drawing_MatrixDestroy(matrix2); + OH_Drawing_MatrixDestroy(matrix3); +} + +void SampleGraphics::CanvasSaveOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10.f); + OH_Drawing_CanvasAttachPen(canvas, pen); + // 保存当前画布状态 + OH_Drawing_CanvasSave(canvas); + // 平移 + OH_Drawing_CanvasTranslate(canvas, 0.f, value200_); + // 保存当前画布状态 + OH_Drawing_CanvasSave(canvas); + // 获取画布状态数量 + SAMPLE_LOGI("Canvas-->saveCount=%{public}d", OH_Drawing_CanvasGetSaveCount(canvas)); + // 放大 + OH_Drawing_CanvasScale(canvas, 2.f, 2.f); + OH_Drawing_Point* point = OH_Drawing_PointCreate(value300_, value300_); + // 绘制圆形(经过放大和移动) + OH_Drawing_CanvasDrawCircle(canvas, point, value100_); + // 恢复操作 + OH_Drawing_CanvasRestore(canvas); + // 绘制圆形(仅经过移动) + OH_Drawing_CanvasDrawCircle(canvas, point, value100_); + // 恢复操作至最初状态 + OH_Drawing_CanvasRestoreToCount(canvas, 0); + // 绘制圆形(原始状态) + OH_Drawing_CanvasDrawCircle(canvas, point, value100_); + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_PenDestroy(pen); + OH_Drawing_PointDestroy(point); +} + +void SampleGraphics::CanvasSaveLayerOperation(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Brush* brush1 = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetColor(brush1, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_CanvasAttachBrush(canvas, brush1); + OH_Drawing_Brush* brush2 = OH_Drawing_BrushCreate(); + // 创建图像滤波器实现模糊效果 + OH_Drawing_ImageFilter *imageFilter = + OH_Drawing_ImageFilterCreateBlur(30.0f, 30.0f, OH_Drawing_TileMode::CLAMP, nullptr); + OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); + OH_Drawing_FilterSetImageFilter(filter, imageFilter); + OH_Drawing_BrushSetFilter(brush2, filter); + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(0.f, 0.f, width_, height_); + // 保存当前画布状态 + OH_Drawing_CanvasSaveLayer(canvas, rect, brush2); + OH_Drawing_Point* point1 = OH_Drawing_PointCreate(value300_, value300_); + // 绘制圆形(经过模糊操作) + OH_Drawing_CanvasDrawCircle(canvas, point1, value100_); + // 恢复操作 + OH_Drawing_CanvasRestore(canvas); + OH_Drawing_Point* point2 = OH_Drawing_PointCreate(value300_, value700_); + // 绘制圆形 + OH_Drawing_CanvasDrawCircle(canvas, point2, value100_); + OH_Drawing_CanvasDetachBrush(canvas); + // 释放对象 + OH_Drawing_ImageFilterDestroy(imageFilter); + OH_Drawing_BrushDestroy(brush1); + OH_Drawing_BrushDestroy(brush2); + OH_Drawing_PointDestroy(point1); + OH_Drawing_PointDestroy(point2); + OH_Drawing_RectDestroy(rect); +} + +void SampleGraphics::DrawStroke(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + uint32_t color = 0xffff0000; + OH_Drawing_PenSetColor(pen, color); + float width = 50.0; + OH_Drawing_PenSetWidth(pen, width); + OH_Drawing_PenSetAntiAlias(pen, true); + // 设置画笔线帽样式 + OH_Drawing_PenSetCap(pen, OH_Drawing_PenLineCapStyle::LINE_ROUND_CAP); + // 设置画笔转角样式 + OH_Drawing_PenSetJoin(pen, OH_Drawing_PenLineJoinStyle::LINE_BEVEL_JOIN); + OH_Drawing_CanvasAttachPen(canvas, 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); + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_PenDestroy(pen); + 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)); + 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_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); + 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); +} + +void SampleGraphics::DrawPathEffect(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, 0xffff0000); + 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); +} + +void SampleGraphics::DrawShaderEffect(OH_Drawing_Canvas *canvas) +{ + // 线性渐变着色器 + OH_Drawing_Point *startPt = OH_Drawing_PointCreate(value100_, value100_); + OH_Drawing_Point *endPt = OH_Drawing_PointCreate(value300_, value300_); + uint32_t colors[] = {0xFFFFFF00, 0xFFFF0000, 0xFF0000FF}; + float pos[] = {0.0f, 0.5f, 1.0f}; + OH_Drawing_ShaderEffect *linearShaderEffect1 = + OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 基于画刷设置着色器 + OH_Drawing_BrushSetShaderEffect(brush, linearShaderEffect1); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value100_, value100_, value300_, value300_); + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + // 使用矩阵创建线性渐变着色器 + OH_Drawing_CanvasTranslate(canvas, value300_, 0.f); + OH_Drawing_Matrix* matrix = OH_Drawing_MatrixCreate(); + OH_Drawing_MatrixScale(matrix, 2.0f, 1.0f, value200_, value200_); + OH_Drawing_Point2D startPt2{value100_, value100_}; + OH_Drawing_Point2D endPt2{value300_, value300_}; + OH_Drawing_ShaderEffect *linearShaderEffect2 = OH_Drawing_ShaderEffectCreateLinearGradientWithLocalMatrix( + &startPt2, &endPt2, colors, pos, 3, OH_Drawing_TileMode::CLAMP, matrix); + OH_Drawing_BrushSetShaderEffect(brush, linearShaderEffect2); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + // 径向渐变着色器 + OH_Drawing_CanvasTranslate(canvas, 0.f, value300_); + OH_Drawing_Point *centerPt = OH_Drawing_PointCreate(value200_, value200_); + OH_Drawing_ShaderEffect *radialShaderEffect = + OH_Drawing_ShaderEffectCreateRadialGradient(centerPt, value200_, colors, pos, 3, OH_Drawing_TileMode::REPEAT); + OH_Drawing_BrushSetShaderEffect(brush, radialShaderEffect); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + // 扇形渐变着色器 + OH_Drawing_CanvasTranslate(canvas, value300_, 0.f); + OH_Drawing_ShaderEffect* sweepShaderEffect = + OH_Drawing_ShaderEffectCreateSweepGradient(centerPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); + OH_Drawing_BrushSetShaderEffect(brush, sweepShaderEffect); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + // 双圆锥渐变着色器 + OH_Drawing_CanvasTranslate(canvas, 0.f, value300_); + OH_Drawing_Point2D pt3{value200_, value200_}; + OH_Drawing_ShaderEffect *twoPointShaderEffect = OH_Drawing_ShaderEffectCreateTwoPointConicalGradient( + &pt3, 30.0f, &pt3, 100.0f, colors, pos, 3, OH_Drawing_TileMode::CLAMP, nullptr); + OH_Drawing_BrushSetShaderEffect(brush, twoPointShaderEffect); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + OH_Drawing_ShaderEffectDestroy(linearShaderEffect1); + OH_Drawing_ShaderEffectDestroy(linearShaderEffect2); + OH_Drawing_ShaderEffectDestroy(radialShaderEffect); + OH_Drawing_ShaderEffectDestroy(sweepShaderEffect); + OH_Drawing_ShaderEffectDestroy(twoPointShaderEffect); + OH_Drawing_PointDestroy(startPt); + OH_Drawing_PointDestroy(endPt); + OH_Drawing_MatrixDestroy(matrix); +} + +void SampleGraphics::DrawColorFilter(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetAntiAlias(brush, true); + OH_Drawing_BrushSetColor(brush, 0xffff0000); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value100_, value100_, value300_, value300_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + OH_Drawing_CanvasTranslate(canvas, 0.f, value300_); + // 创建luma亮度颜色滤波器 + OH_Drawing_ColorFilter* lumaColorFilter = OH_Drawing_ColorFilterCreateLuma(); + OH_Drawing_Filter *filter = OH_Drawing_FilterCreate(); + OH_Drawing_FilterSetColorFilter(filter, lumaColorFilter); + OH_Drawing_BrushSetFilter(brush, filter); + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 绘制经过luma亮度颜色滤波器效果的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + OH_Drawing_CanvasTranslate(canvas, 0.f, value300_); + 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 + }; + // 创建5*4矩阵颜色滤波器 + OH_Drawing_ColorFilter* matrixColorFilter = OH_Drawing_ColorFilterCreateMatrix(matrix); + // 创建从SRGB转换到线性颜色空间的颜色滤波器 + OH_Drawing_ColorFilter* s2lColorFilter = OH_Drawing_ColorFilterCreateSrgbGammaToLinear(); + // 创建从线性颜色空间转换到SRGB的颜色滤波器 + OH_Drawing_ColorFilter* l2sColorFilter = OH_Drawing_ColorFilterCreateLinearToSrgbGamma(); + // 创建合成滤波器 + OH_Drawing_ColorFilter* composeColorFilter1 = OH_Drawing_ColorFilterCreateCompose(matrixColorFilter, s2lColorFilter); + OH_Drawing_ColorFilter* composeColorFilter2 = OH_Drawing_ColorFilterCreateCompose(composeColorFilter1, l2sColorFilter); + OH_Drawing_FilterSetColorFilter(filter, composeColorFilter1); + OH_Drawing_BrushSetFilter(brush, filter); + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 绘制经过合成颜色滤波器效果的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_ColorFilterDestroy(matrixColorFilter); + OH_Drawing_ColorFilterDestroy(lumaColorFilter); + OH_Drawing_ColorFilterDestroy(s2lColorFilter); + OH_Drawing_ColorFilterDestroy(l2sColorFilter); + OH_Drawing_ColorFilterDestroy(composeColorFilter1); + OH_Drawing_ColorFilterDestroy(composeColorFilter2); + OH_Drawing_RectDestroy(rect); + OH_Drawing_FilterDestroy(filter); +} + +void SampleGraphics::DrawImageFilter(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetAntiAlias(pen, true); + OH_Drawing_PenSetColor(pen, 0xffff0000); + 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); +} + +void SampleGraphics::DrawMaskFilterPen(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetAntiAlias(pen, true); + OH_Drawing_PenSetColor(pen, 0xffff0000); + 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_, value600_, value600_); + // 绘制矩形 + 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); +} + +void SampleGraphics::DrawMaskFilterBrush(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Brush *brush = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetAntiAlias(brush, true); + OH_Drawing_BrushSetColor(brush, 0xffff0000); + // 创建模糊蒙版滤波器 + 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_BrushSetFilter(brush, filter); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value600_); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachBrush(canvas); + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_MaskFilterDestroy(maskFilter); + OH_Drawing_RectDestroy(rect); + OH_Drawing_FilterDestroy(filter); +} + +void SampleGraphics::DrawStar(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + 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); +} + +void SampleGraphics::DrawRegion(OH_Drawing_Canvas *canvas) +{ + 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); +} + +void SampleGraphics::DrawRoundRect(OH_Drawing_Canvas *canvas) +{ + 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_RoundRectSetCorner(roundRect, OH_Drawing_CornerPos::CORNER_POS_TOP_LEFT, {50, 50}); + OH_Drawing_Corner_Radii p = OH_Drawing_RoundRectGetCorner(roundRect, OH_Drawing_CornerPos::CORNER_POS_TOP_LEFT); + SAMPLE_LOGI("top-left-corner:x=%{public}f, y:%{public}f", p.x, p.y); + // 绘制圆角矩形 + OH_Drawing_CanvasDrawRoundRect(canvas, roundRect); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + OH_Drawing_RoundRectDestroy(roundRect); +} + +void SampleGraphics::DrawCustomPixelMap(OH_Drawing_Canvas *canvas) +{ + 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; + pixels[i * RGBA_SIZE + 2] = RGBA_MIN; + pixels[i * RGBA_SIZE + 3] = 0xFF; + if (n == 0) { + pixels[i * RGBA_SIZE] = 0xFF; + } else if (n == 1) { + pixels[i * RGBA_SIZE + 1] = 0xFF; + } else { + pixels[i * RGBA_SIZE + 2] = 0xFF; + } + } + // 设置位图格式(长、宽、颜色类型、透明度类型) + 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_PixelmapNative对象创建PixelMap对象 + OH_Drawing_PixelMap *pixelMap = OH_Drawing_PixelMapGetFromOhPixelMapNative(pixelMapNative); + 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); + OH_Drawing_PixelMapDissolve(pixelMap); + OH_Drawing_RectDestroy(src); + OH_Drawing_RectDestroy(dst); + OH_Drawing_SamplingOptionsDestroy(samplingOptions); + delete[] pixels; +} + +void SampleGraphics::DrawBrushBasic(OH_Drawing_Canvas *canvas) +{ + // 创建画刷 + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + // 设置填充颜色为红色 + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 开启抗锯齿效果 + OH_Drawing_BrushSetAntiAlias(brush, true); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect* rect1 = OH_Drawing_RectCreate(0, 0, value300_, value300_); + // 绘制矩形1 + OH_Drawing_CanvasDrawRect(canvas, rect1); + OH_Drawing_CanvasDetachBrush(canvas); + // 复制画刷 + OH_Drawing_Brush* brush_copy = OH_Drawing_BrushCopy(brush); + + // 画刷重置 + OH_Drawing_BrushReset(brush); + // 设置透明度 + OH_Drawing_BrushSetAlpha(brush, 0x40); + OH_Drawing_CanvasAttachBrush(canvas, brush); + OH_Drawing_Rect* rect2 = OH_Drawing_RectCreate(value400_, value400_, value700_, value700_); + // 绘制矩形2 + OH_Drawing_CanvasDrawRect(canvas, rect2); + OH_Drawing_CanvasDetachBrush(canvas); + + OH_Drawing_CanvasAttachBrush(canvas, brush_copy); + OH_Drawing_Rect* rect3 = OH_Drawing_RectCreate(value800_, value800_, value1100_, value1100_); + // 绘制矩形3 + OH_Drawing_CanvasDrawRect(canvas, rect3); + OH_Drawing_CanvasDetachBrush(canvas); + + // 销毁各类对象 + OH_Drawing_BrushDestroy(brush); + OH_Drawing_BrushDestroy(brush_copy); + OH_Drawing_RectDestroy(rect1); + OH_Drawing_RectDestroy(rect2); + OH_Drawing_RectDestroy(rect3); +} + +void SampleGraphics::DrawPenBasic(OH_Drawing_Canvas *canvas) +{ + // 创建画笔对象 + 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_PenSetAntiAlias(pen, true); + // 在画布中设置画笔 + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect* rect1 = OH_Drawing_RectCreate(0, 0, value300_, value300_); + // 绘制矩形1 + OH_Drawing_CanvasDrawRect(canvas, rect1); + OH_Drawing_CanvasDetachPen(canvas); + // 复制画笔 + OH_Drawing_Pen* pen_copy = OH_Drawing_PenCopy(pen); + + // 画刷重置 + OH_Drawing_PenReset(pen); + // 设置画笔线宽为20 + OH_Drawing_PenSetWidth(pen, 20); + // 设置透明度 + OH_Drawing_PenSetAlpha(pen, 0x40); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect* rect2 = OH_Drawing_RectCreate(value400_, value400_, value700_, value700_); + // 绘制矩形2 + OH_Drawing_CanvasDrawRect(canvas, rect2); + OH_Drawing_CanvasDetachPen(canvas); + + OH_Drawing_CanvasAttachPen(canvas, pen_copy); + OH_Drawing_Rect* rect3 = OH_Drawing_RectCreate(value800_, value800_, value1100_, value1100_); + // 绘制矩形3 + OH_Drawing_CanvasDrawRect(canvas, rect3); + OH_Drawing_CanvasDetachBrush(canvas); + + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_PenDestroy(pen_copy); + OH_Drawing_RectDestroy(rect1); + OH_Drawing_RectDestroy(rect2); + OH_Drawing_RectDestroy(rect3); +} + +void SampleGraphics::DrawPenLinearGradient(OH_Drawing_Canvas *canvas) +{ + 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 *shaderEffect = + OH_Drawing_ShaderEffectCreateLinearGradient(startPt, endPt, colors, pos, 3, OH_Drawing_TileMode::CLAMP); + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetWidth(pen, 40); + // 基于画笔设置着色器效果 + OH_Drawing_PenSetShaderEffect(pen, shaderEffect); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value100_, value100_, value900_, value900_); + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDetachPen(canvas); + // 销毁各类对象 + OH_Drawing_PenDestroy(pen); + OH_Drawing_RectDestroy(rect); + OH_Drawing_ShaderEffectDestroy(shaderEffect); + OH_Drawing_PointDestroy(startPt); + OH_Drawing_PointDestroy(endPt); +} + +void SampleGraphics::DrawMiterLimit(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + uint32_t color = 0xffff0000; + OH_Drawing_PenSetColor(pen, color); + float width = 50.0; + OH_Drawing_PenSetWidth(pen, width); + OH_Drawing_PenSetAntiAlias(pen, true); + // 设置画笔转角样式 + OH_Drawing_PenSetJoin(pen, OH_Drawing_PenLineJoinStyle::LINE_MITER_JOIN); + // 设置折角尖角的限制值 + OH_Drawing_PenSetMiterLimit(pen, 15.0f); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Path* path = OH_Drawing_PathCreate(); + float aX = value100_; + float aY = value100_; + float bX = value100_; + float bY = value800_; + float cX = value200_; + float cY = value100_; + OH_Drawing_PathMoveTo(path, aX, aY); + OH_Drawing_PathLineTo(path, bX, bY); + OH_Drawing_PathLineTo(path, cX, cY); + OH_Drawing_CanvasDrawPath(canvas, path); + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_PenDestroy(pen); + OH_Drawing_PathDestroy(path); +} + +void SampleGraphics::DrawRectBasic(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_BrushSetAntiAlias(brush, true); + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建矩形对象 + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(0, 0, value300_, value300_); + OH_Drawing_Rect* rect_copy = OH_Drawing_RectCreate(0, 0, 0, 0); + OH_Drawing_RectCopy(rect, rect_copy); + // 设置矩形left,right,top,bottom + OH_Drawing_RectSetLeft(rect, value100_); + OH_Drawing_RectSetTop(rect, value100_); + OH_Drawing_RectSetRight(rect, value400_); + OH_Drawing_RectSetBottom(rect, value400_); + // 获取矩形left,right,top,bottom,width,height + SAMPLE_LOGI("rect info-->left:%{public}f, right:%{public}f, top:%{public}f, bottom:%{public}f, width:%{public}f, height: %{public}f", + OH_Drawing_RectGetLeft(rect), OH_Drawing_RectGetRight(rect), OH_Drawing_RectGetTop(rect), + OH_Drawing_RectGetBottom(rect), OH_Drawing_RectGetWidth(rect), OH_Drawing_RectGetHeight(rect)); + SAMPLE_LOGI("rect_copy info-->left:%{public}f, right:%{public}f, top:%{public}f, bottom:%{public}f, width:%{public}f, height: %{public}f", + OH_Drawing_RectGetLeft(rect_copy), OH_Drawing_RectGetRight(rect_copy), OH_Drawing_RectGetTop(rect_copy), + OH_Drawing_RectGetBottom(rect_copy), OH_Drawing_RectGetWidth(rect_copy), OH_Drawing_RectGetHeight(rect_copy)); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_CanvasDrawRect(canvas, rect_copy); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect); + OH_Drawing_RectDestroy(rect_copy); +} + +void SampleGraphics::DrawRectIntersect(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_BrushSetAntiAlias(brush, true); + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建矩形对象 + OH_Drawing_Rect* rect1 = OH_Drawing_RectCreate(0, 0, value300_, value300_); + OH_Drawing_Rect* rect2 = OH_Drawing_RectCreate(value100_, value100_, value400_, value400_); + // 取交集 + OH_Drawing_RectIntersect(rect1, rect2); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect1); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect1); + OH_Drawing_RectDestroy(rect2); +} + +void SampleGraphics::DrawRectJoin(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Brush* brush = OH_Drawing_BrushCreate(); + OH_Drawing_BrushSetColor(brush, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_BrushSetAntiAlias(brush, true); + OH_Drawing_CanvasAttachBrush(canvas, brush); + // 创建矩形对象 + OH_Drawing_Rect* rect1 = OH_Drawing_RectCreate(0, 0, value300_, value300_); + OH_Drawing_Rect* rect2 = OH_Drawing_RectCreate(value100_, value100_, value400_, value400_); + // 取并集 + OH_Drawing_RectJoin(rect1, rect2); + // 绘制矩形 + OH_Drawing_CanvasDrawRect(canvas, rect1); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_RectDestroy(rect1); + OH_Drawing_RectDestroy(rect2); +} + +void SampleGraphics::DrawPathBasic(OH_Drawing_Canvas *canvas) +{ + int32_t w = width_ / 5; + float startX = 0; + float startY = 100.f; + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0x45, 0x71, 0xC4)); + OH_Drawing_PenSetAntiAlias(pen, true); + float penWidth = 3.f; + OH_Drawing_PenSetWidth(pen, penWidth); + OH_Drawing_CanvasAttachPen(canvas, pen); + + // 三角形1 + // 创建路径对象 + OH_Drawing_Path *path = OH_Drawing_PathCreate(); + // 设置填充路径规则 + OH_Drawing_PathSetFillType(path, OH_Drawing_PathFillType::PATH_FILL_TYPE_EVEN_ODD); + // 移动到起始点 + OH_Drawing_PathMoveTo(path, startX + 15.f, startY); + // 添加线段 + OH_Drawing_PathLineTo(path, startX + 15.f, startY + 150.f); + OH_Drawing_PathLineTo(path, startX + w - 15.f, startY + 150.f); + // 闭合路径 + OH_Drawing_PathClose(path); + // 判断路径是否包含坐标点 + SAMPLE_LOGI("PathBasic-->contains:%{public}d", OH_Drawing_PathContains(path, startX + 50.f, startY + 150.f) ? 1 : 0); + // 判断路径是否闭合 + SAMPLE_LOGI("PathBasic-->isClosed:%{public}d", OH_Drawing_PathIsClosed(path, false) ? 1 : 0); + // 获取路径长度 + SAMPLE_LOGI("PathBasic-->getLength:%{public}f", OH_Drawing_PathGetLength(path, false)); + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(0, 0, 0, 0); + // 获取边界 + OH_Drawing_PathGetBounds(path, rect); + SAMPLE_LOGI("PathBasic-->getBounds:left=%{public}f,top=%{public}f,right=%{public}f,bottom=%{public}f", + OH_Drawing_RectGetLeft(rect), OH_Drawing_RectGetTop(rect), OH_Drawing_RectGetRight(rect), + OH_Drawing_RectGetBottom(rect)); + OH_Drawing_Matrix *matrix = OH_Drawing_MatrixCreate(); + // 获取变换矩阵 + OH_Drawing_PathGetMatrix(path, false, 50, matrix, OH_Drawing_PathMeasureMatrixFlags::GET_POSITION_MATRIX); + OH_Drawing_Point2D point{startX + 50.f, startY + 150.f}; + OH_Drawing_Point2D tangent{0, 0}; + // 获取坐标点和切线 + OH_Drawing_PathGetPositionTangent(path, false, 1, &point, &tangent); + SAMPLE_LOGI("PathBasic-->tangent.x=%{public}f,tangent.y=%{public}f", tangent.x, tangent.y); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 三角形2 + // 复制路径 + OH_Drawing_Path *path_copy = OH_Drawing_PathCopy(path); + OH_Drawing_Matrix *matrix_translate = OH_Drawing_MatrixCreateTranslation(w, 0); + // 对路径进行矩阵变换 + OH_Drawing_PathTransform(path_copy, matrix_translate); + OH_Drawing_CanvasDrawPath(canvas, path_copy); + + // 三角形3 + OH_Drawing_Path *path_third = OH_Drawing_PathCreate(); + // 对路径进行矩阵变换 + OH_Drawing_PathTransformWithPerspectiveClip(path_copy, matrix_translate, path_third, false); + OH_Drawing_CanvasDrawPath(canvas, path_third); + + // 三角形4 + OH_Drawing_Path *path_fourth = OH_Drawing_PathCreate(); + OH_Drawing_PathOffset(path, path_fourth, w * 3, 0); + OH_Drawing_CanvasDrawPath(canvas, path_fourth); + + // 梯形 + startX += 4 * w; + OH_Drawing_Path *path_fifth = OH_Drawing_PathCreate(); + OH_Drawing_PathMoveTo(path_fifth, startX + 15.f, startY); + OH_Drawing_PathLineTo(path_fifth, startX + 15.f, startY + 100.f); + OH_Drawing_PathLineTo(path_fifth, startX + w - 15.f, startY + 100.f); + OH_Drawing_PathTransform(path_fourth, matrix_translate); + // 将两个路径合并(取差集) + OH_Drawing_PathOp(path_fifth, path_fourth, OH_Drawing_PathOpMode::PATH_OP_MODE_REVERSE_DIFFERENCE); + OH_Drawing_CanvasDrawPath(canvas, path_fifth); + + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_PathDestroy(path); + OH_Drawing_PathDestroy(path_copy); + OH_Drawing_PathDestroy(path_third); + OH_Drawing_PathDestroy(path_fourth); + OH_Drawing_PathDestroy(path_fifth); + OH_Drawing_MatrixDestroy(matrix); + OH_Drawing_MatrixDestroy(matrix_translate); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawPathTo(OH_Drawing_Canvas *canvas) +{ + int32_t w = width_ / 5; + float startX = 0; + float startY = 100.f; + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0x45, 0x71, 0xC4)); + OH_Drawing_PenSetAntiAlias(pen, true); + float penWidth = 3.f; + OH_Drawing_PenSetWidth(pen, penWidth); + OH_Drawing_CanvasAttachPen(canvas, pen); + + // 线段 + OH_Drawing_Path *path = OH_Drawing_PathCreate(); + OH_Drawing_PathMoveTo(path, startX + 15.f, startY + 70); + OH_Drawing_PathLineTo(path, startX + w - 15.f, startY + 70.f); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 弧线 + startX += w; + OH_Drawing_PathReset(path); + OH_Drawing_PathArcTo(path, startX + 15.f, startY + 30.f, startX + w - 15.f, startY + 150, 60, -240); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 二阶贝塞尔曲线 + startX += w; + OH_Drawing_PathReset(path); + OH_Drawing_PathMoveTo(path, startX + 15.f, startY); + OH_Drawing_PathQuadTo(path, startX + 50.f, startY + 100, startX + w - 15.f, startY + 150); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 二阶贝塞尔曲线(带权重) + startX += w; + OH_Drawing_PathReset(path); + OH_Drawing_PathMoveTo(path, startX + 15.f, startY); + OH_Drawing_PathConicTo(path, startX + 50.f, startY + 100, startX + w - 15.f, startY + 150, 5.f); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 三阶贝塞尔曲线 + startX += w; + OH_Drawing_PathReset(path); + OH_Drawing_PathMoveTo(path, startX + 15.f, startY); + OH_Drawing_PathCubicTo(path, startX + 30.f, startY + 120, startX + w - 30.f, startY + 30, startX + w - 15.f, startY + 150); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 线段 + startX = 0; + startY += 200; + OH_Drawing_PathReset(path); + OH_Drawing_PathMoveTo(path, startX, startY); + OH_Drawing_PathRMoveTo(path, 15.f, 70.f); + OH_Drawing_PathRLineTo(path, w - 30.f, 0); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 二阶贝塞尔曲线 + startX += w; + OH_Drawing_PathReset(path); + OH_Drawing_PathMoveTo(path, startX + 15.f, startY); + OH_Drawing_PathRQuadTo(path, 50.f, 100.f, w - 10.f, 150.f); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 二阶贝塞尔曲线(带权重) + startX += w; + OH_Drawing_PathReset(path); + OH_Drawing_PathMoveTo(path, startX + 15.f, startY); + OH_Drawing_PathRConicTo(path, 50.f, 100.f, w - 15.f, 150, 5.f); + OH_Drawing_CanvasDrawPath(canvas, path); + + // 三阶贝塞尔曲线 + startX += w; + OH_Drawing_PathReset(path); + OH_Drawing_PathMoveTo(path, startX + 15.f, startY); + OH_Drawing_PathRCubicTo(path, 30.f, 120.f, w - 30.f, 30.f, w - 10.f, 150); + OH_Drawing_CanvasDrawPath(canvas, path); + + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_PathDestroy(path); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawPathAdd(OH_Drawing_Canvas *canvas) +{ + int32_t w = width_ / 6; + float startX = 0; + float startY = 100.f; + OH_Drawing_Pen *pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(0xFF, 0x45, 0x71, 0xC4)); + OH_Drawing_PenSetAntiAlias(pen, true); + float penWidth = 3.f; + OH_Drawing_PenSetWidth(pen, penWidth); + OH_Drawing_CanvasAttachPen(canvas, pen); + // 圆 + OH_Drawing_Path *pathCircle = OH_Drawing_PathCreate(); + OH_Drawing_PathAddCircle(pathCircle, startX + w / 2, startY + 60, 40, PATH_DIRECTION_CCW); + OH_Drawing_CanvasDrawPath(canvas, pathCircle); + OH_Drawing_PathDestroy(pathCircle); + // 矩形 + startX += w; + OH_Drawing_Path *pathRect = OH_Drawing_PathCreate(); + OH_Drawing_PathAddRect(pathRect, startX + 10.f, startY + 30, startX + w - 10.f, startY + 90, PATH_DIRECTION_CCW); + OH_Drawing_CanvasDrawPath(canvas, pathRect); + OH_Drawing_PathDestroy(pathRect); + // 椭圆 + startX += w; + OH_Drawing_Path *pathOval = OH_Drawing_PathCreate(); + OH_Drawing_Rect *rectOval = OH_Drawing_RectCreate(startX + 10.f, startY + 30, startX + w - 10.f, startY + 90); + OH_Drawing_PathAddOval(pathOval, rectOval, OH_Drawing_PathDirection::PATH_DIRECTION_CW); + OH_Drawing_CanvasDrawPath(canvas, pathOval); + OH_Drawing_RectDestroy(rectOval); + OH_Drawing_PathDestroy(pathOval); + // 圆角矩形 + startX += w; + OH_Drawing_Path *pathRoundRect = OH_Drawing_PathCreate(); + OH_Drawing_Rect *rectRoundRect = OH_Drawing_RectCreate(startX + 10.f, startY + 30, startX + w - 10.f, startY + 90); + OH_Drawing_RoundRect *roundRect = OH_Drawing_RoundRectCreate(rectRoundRect, 20.f, 20.f); + OH_Drawing_PathAddRoundRect(pathRoundRect, roundRect, PATH_DIRECTION_CCW); + OH_Drawing_CanvasDrawPath(canvas, pathRoundRect); + OH_Drawing_RectDestroy(rectRoundRect); + OH_Drawing_PathDestroy(pathRoundRect); + OH_Drawing_RoundRectDestroy(roundRect); + // 多边形 + startX += w; + OH_Drawing_Path *pathPolygon = OH_Drawing_PathCreate(); + float leftPointX = startX + 10; + float rightPointX = startX + w - 10; + float middlePointX = (leftPointX + rightPointX) / 2; + OH_Drawing_Point2D points[] = {{middlePointX, startY + 30}, {leftPointX, startY + 90}, {rightPointX, startY + 90}}; + OH_Drawing_PathAddPolygon(pathPolygon, points, 3, true); // 3 is the size of point array + OH_Drawing_CanvasDrawPath(canvas, pathPolygon); + OH_Drawing_PathDestroy(pathPolygon); + // 曲线 + startX += w; + OH_Drawing_Rect *rectArc = OH_Drawing_RectCreate(startX - 50.f, startY + 30, startX + w - 10.f, startY + 150); + OH_Drawing_Path *pathArc = OH_Drawing_PathCreate(); + OH_Drawing_PathAddArc(pathArc, rectArc, 0, -90.f); + OH_Drawing_CanvasDrawPath(canvas, pathArc); + OH_Drawing_RectDestroy(rectArc); + OH_Drawing_PathDestroy(pathArc); + // 线段1 + startX = 0; + startY += 200; + OH_Drawing_Path *pathOuter1 = OH_Drawing_PathCreate(); + OH_Drawing_Path *pathInner1 = OH_Drawing_PathCreate(); + OH_Drawing_PathMoveTo(pathInner1, startX + 10, startY); + OH_Drawing_PathLineTo(pathInner1, startX + w - 10, startY); + OH_Drawing_Matrix *matrix1 = OH_Drawing_MatrixCreateTranslation(0, 50); + OH_Drawing_PathAddPath(pathOuter1, pathInner1, matrix1); + OH_Drawing_CanvasDrawPath(canvas, pathOuter1); + OH_Drawing_PathDestroy(pathOuter1); + OH_Drawing_PathDestroy(pathInner1); + OH_Drawing_MatrixDestroy(matrix1); + // 线段2 + startX += w; + OH_Drawing_Path *pathOuter2 = OH_Drawing_PathCreate(); + OH_Drawing_Path *pathInner2 = OH_Drawing_PathCreate(); + OH_Drawing_PathMoveTo(pathInner2, startX + 10, startY + 50); + OH_Drawing_PathLineTo(pathInner2, startX + w - 10, startY + 50); + OH_Drawing_PathAddPathWithMode(pathOuter2, pathInner2, OH_Drawing_PathAddMode::PATH_ADD_MODE_APPEND); + OH_Drawing_CanvasDrawPath(canvas, pathOuter2); + OH_Drawing_PathDestroy(pathOuter2); + OH_Drawing_PathDestroy(pathInner2); + // 线段3 + startX += w; + OH_Drawing_Path *pathOuter3 = OH_Drawing_PathCreate(); + OH_Drawing_Path *pathInner3 = OH_Drawing_PathCreate(); + OH_Drawing_PathMoveTo(pathInner3, startX + 10, startY); + OH_Drawing_PathLineTo(pathInner3, startX + w - 10, startY); + OH_Drawing_PathAddPathWithOffsetAndMode(pathOuter3, pathInner3, 0, 50, OH_Drawing_PathAddMode::PATH_ADD_MODE_APPEND); + OH_Drawing_CanvasDrawPath(canvas, pathOuter3); + OH_Drawing_PathDestroy(pathOuter3); + OH_Drawing_PathDestroy(pathInner3); + // 线段4 + startX += w; + OH_Drawing_Path *pathOuter4 = OH_Drawing_PathCreate(); + OH_Drawing_Path *pathInner4 = OH_Drawing_PathCreate(); + OH_Drawing_PathMoveTo(pathInner4, startX + 10, startY); + OH_Drawing_PathLineTo(pathInner4, startX + w - 10, startY); + OH_Drawing_Matrix *matrix2 = OH_Drawing_MatrixCreateTranslation(0, 50); + OH_Drawing_PathAddPathWithMatrixAndMode(pathOuter4, pathInner4, matrix2, OH_Drawing_PathAddMode::PATH_ADD_MODE_APPEND); + OH_Drawing_CanvasDrawPath(canvas, pathOuter4); + OH_Drawing_PathDestroy(pathOuter4); + OH_Drawing_PathDestroy(pathInner4); + OH_Drawing_MatrixDestroy(matrix2); + // 椭圆 + startX += w; + OH_Drawing_Path *pathOval2 = OH_Drawing_PathCreate(); + OH_Drawing_PathMoveTo(pathInner2, startX + 10, startY); + OH_Drawing_Rect *rectOval2 = OH_Drawing_RectCreate(startX + 10.f, startY + 30, startX + w - 10.f, startY + 90); + OH_Drawing_PathAddOvalWithInitialPoint(pathOval2, rectOval2, 1, OH_Drawing_PathDirection::PATH_DIRECTION_CW); + OH_Drawing_CanvasDrawPath(canvas, pathOval2); + OH_Drawing_RectDestroy(rectOval2); + OH_Drawing_PathDestroy(pathOval2); + // 矩形 + startX += w; + OH_Drawing_Path *pathRect2 = OH_Drawing_PathCreate(); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(startX + 10.f, startY + 30, startX + w - 10.f, startY + 90); + OH_Drawing_PathAddRectWithInitialCorner(pathRect2, rect, PATH_DIRECTION_CCW, 1); + OH_Drawing_CanvasDrawPath(canvas, pathRect2); + OH_Drawing_PathDestroy(pathRect2); + OH_Drawing_RectDestroy(rect); + + OH_Drawing_CanvasDetachPen(canvas); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::BuildFromSvgString(OH_Drawing_Canvas *canvas) +{ + 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); + char* str = "M150 30L30 300L270 300Z"; + OH_Drawing_Path* path = OH_Drawing_PathCreate(); + // 通过svg构建path + OH_Drawing_PathBuildFromSvgString(path, str); + OH_Drawing_CanvasDrawPath(canvas, path); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_BrushDestroy(brush); + OH_Drawing_PathDestroy(path); +} + +void SampleGraphics::DrawCreateCanvas(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Bitmap* bitmap = OH_Drawing_BitmapCreate(); + OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE}; + uint64_t width = width_ / 2; + uint64_t height = height_ / 2; + OH_Drawing_BitmapBuild(bitmap, width, height, &cFormat); + // 创建一个canvas对象 + OH_Drawing_Canvas* newCanvas = OH_Drawing_CanvasCreate(); + // 将画布与bitmap绑定,画布画的内容会输出到绑定的bitmap内存中 + OH_Drawing_CanvasBind(newCanvas, bitmap); + // 使用红色清除画布内容 + OH_Drawing_CanvasClear(newCanvas, OH_Drawing_ColorSetArgb(0x50, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 获取画布宽高 + SAMPLE_LOGI("Canvas-->width=%{public}d,height=%{public}d", OH_Drawing_CanvasGetWidth(newCanvas), + OH_Drawing_CanvasGetHeight(newCanvas)); + OH_Drawing_CanvasDrawBitmap(canvas, bitmap, 0, 0); + OH_Drawing_CanvasDestroy(newCanvas); + OH_Drawing_BitmapDestroy(bitmap); +} + +void SampleGraphics::DrawCanvasConcatMatrix(OH_Drawing_Canvas *canvas) +{ + OH_Drawing_Pen* pen = OH_Drawing_PenCreate(); + OH_Drawing_PenSetColor(pen, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + OH_Drawing_PenSetWidth(pen, 10); + OH_Drawing_CanvasAttachPen(canvas, pen); + OH_Drawing_Rect *rect = OH_Drawing_RectCreate(value300_, value300_, value600_, value500_); + // 绘制原始矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix *matrix1 = OH_Drawing_MatrixCreateTranslation(value300_, value300_); + // 对画布进行矩阵操作 + OH_Drawing_CanvasConcatMatrix(canvas, matrix1); + // 绘制变换后的矩形 + OH_Drawing_CanvasDrawRect(canvas, rect); + OH_Drawing_Matrix *matrix2 = OH_Drawing_MatrixCreate(); + OH_Drawing_CanvasGetTotalMatrix(canvas, matrix2); + SAMPLE_LOGI("Canvas-->MatrixIsEqual=%{public}d", OH_Drawing_MatrixIsEqual(matrix1, matrix2) ? 1 : 0); + OH_Drawing_CanvasDetachBrush(canvas); + OH_Drawing_RectDestroy(rect); + OH_Drawing_MatrixDestroy(matrix1); + OH_Drawing_MatrixDestroy(matrix2); + OH_Drawing_PenDestroy(pen); +} + +void SampleGraphics::DrawPixelMapRect(OH_Drawing_Canvas *canvas) +{ + // 从NativePixelMap中获取PixelMap对象 + OH_Drawing_PixelMap *pixelMap = OH_Drawing_PixelMapGetFromNativePixelMap(nativePixelMap_); + OH_Drawing_SamplingOptions *sampling = OH_Drawing_SamplingOptionsCreate(FILTER_MODE_LINEAR, MIPMAP_MODE_NONE); + float width = 650.f; + float height = 664.f; + OH_Drawing_Rect *src = OH_Drawing_RectCreate(0, 0, width, height); + OH_Drawing_Rect *dst = OH_Drawing_RectCreate(value100_, value100_, value700_, value700_); + // 绘制PixelMap + OH_Drawing_CanvasDrawPixelMapRect(canvas, pixelMap, src, dst, sampling); + // 解除NativePixelMap和PixelMap的关联 + OH_Drawing_PixelMapDissolve(pixelMap); + OH_Drawing_SamplingOptionsDestroy(sampling); + OH_Drawing_RectDestroy(src); + OH_Drawing_RectDestroy(dst); +} + +void SampleGraphics::DrawBitmap(OH_Drawing_Canvas *canvas) +{ + // 创建一个bitmap对象 + OH_Drawing_Bitmap* bitmap1 = OH_Drawing_BitmapCreate(); + OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE}; + uint64_t width = width_ / 2; + uint64_t height = height_ / 2; + // 构建bitmap对象 + OH_Drawing_BitmapBuild(bitmap1, width, height, &cFormat); + OH_Drawing_Canvas* newCanvas = OH_Drawing_CanvasCreate(); + OH_Drawing_CanvasBind(newCanvas, bitmap1); + OH_Drawing_CanvasClear(newCanvas, OH_Drawing_ColorSetArgb(0x50, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 获取位图宽高 + SAMPLE_LOGI("Bitmap-->width=%{public}d,height=%{public}d", OH_Drawing_BitmapGetWidth(bitmap1), + OH_Drawing_BitmapGetHeight(bitmap1)); + // 获取像素 + void *pixels = OH_Drawing_BitmapGetPixels(bitmap1); + OH_Drawing_Image_Info imageInfo; + imageInfo.width = width; + imageInfo.height = height; + imageInfo.colorType = COLOR_FORMAT_RGBA_8888; + imageInfo.alphaType = ALPHA_FORMAT_OPAQUE; + // 通过像素创建一个bitmap对象 + OH_Drawing_Bitmap* bitmap2 = OH_Drawing_BitmapCreateFromPixels(&imageInfo, pixels, width * 4); + OH_Drawing_CanvasDrawBitmap(canvas, bitmap1, 0, 0); + OH_Drawing_CanvasDrawBitmap(canvas, bitmap2, width, height); + OH_Drawing_CanvasDestroy(newCanvas); + OH_Drawing_BitmapDestroy(bitmap1); + OH_Drawing_BitmapDestroy(bitmap2); +} + +void SampleGraphics::DrawImage(OH_Drawing_Canvas *canvas) +{ + // 创建一个bitmap对象 + OH_Drawing_Bitmap* bitmap = OH_Drawing_BitmapCreate(); + OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE}; + uint64_t width = width_ / 2; + uint64_t height = height_ / 2; + OH_Drawing_BitmapBuild(bitmap, width, height, &cFormat); + OH_Drawing_Canvas* newCanvas = OH_Drawing_CanvasCreate(); + OH_Drawing_CanvasBind(newCanvas, bitmap); + OH_Drawing_CanvasClear(newCanvas, OH_Drawing_ColorSetArgb(RGBA_MAX, RGBA_MAX, RGBA_MIN, RGBA_MIN)); + // 创建image对象 + OH_Drawing_Image* image = OH_Drawing_ImageCreate(); + // 从bitmap构建image + OH_Drawing_ImageBuildFromBitmap(image, bitmap); + // 获取Image宽高 + SAMPLE_LOGI("Image-->width=%{public}d,height=%{public}d", OH_Drawing_ImageGetWidth(image), + OH_Drawing_ImageGetHeight(image)); + OH_Drawing_Rect* rect = OH_Drawing_RectCreate(0, 0, width / 2, height / 2); + OH_Drawing_SamplingOptions* options = OH_Drawing_SamplingOptionsCreate( + OH_Drawing_FilterMode::FILTER_MODE_LINEAR, OH_Drawing_MipmapMode::MIPMAP_MODE_LINEAR); + OH_Drawing_CanvasDrawImageRect(canvas, image, rect, options); + // 销毁对象 + OH_Drawing_CanvasDestroy(newCanvas); + OH_Drawing_BitmapDestroy(bitmap); + OH_Drawing_ImageDestroy(image); + OH_Drawing_RectDestroy(rect); + OH_Drawing_SamplingOptionsDestroy(options); +} + +void SampleGraphics::InitDrawFunction(std::string id) +{ + this->drawFunctionMap_.insert({"BrushBasic", &SampleGraphics::DrawBrushBasic}); + this->drawFunctionMap_.insert({"MixedMode", &SampleGraphics::DrawMixedMode}); + this->drawFunctionMap_.insert({"LinearGradient", &SampleGraphics::DrawShaderEffect}); + this->drawFunctionMap_.insert({"ColorFilter", &SampleGraphics::DrawColorFilter}); + this->drawFunctionMap_.insert({"MaskFilterBrush", &SampleGraphics::DrawMaskFilterBrush}); + + this->drawFunctionMap_.insert({"PenBasic", &SampleGraphics::DrawPenBasic}); + this->drawFunctionMap_.insert({"Stroke", &SampleGraphics::DrawStroke}); + this->drawFunctionMap_.insert({"MiterLimit", &SampleGraphics::DrawMiterLimit}); + this->drawFunctionMap_.insert({"ImageFilter", &SampleGraphics::DrawImageFilter}); + this->drawFunctionMap_.insert({"PathEffect", &SampleGraphics::DrawPathEffect}); + this->drawFunctionMap_.insert({"PenLinearGradient", &SampleGraphics::DrawPenLinearGradient}); + this->drawFunctionMap_.insert({"MaskFilterPen", &SampleGraphics::DrawMaskFilterPen}); + + this->drawFunctionMap_.insert({"RectBasic", &SampleGraphics::DrawRectBasic}); + this->drawFunctionMap_.insert({"RectIntersect", &SampleGraphics::DrawRectIntersect}); + this->drawFunctionMap_.insert({"RectJoin", &SampleGraphics::DrawRectJoin}); + this->drawFunctionMap_.insert({"RoundRect", &SampleGraphics::DrawRoundRect}); + + this->drawFunctionMap_.insert({"PathBasic", &SampleGraphics::DrawPathBasic}); + this->drawFunctionMap_.insert({"PathTo", &SampleGraphics::DrawPathTo}); + this->drawFunctionMap_.insert({"PathAdd", &SampleGraphics::DrawPathAdd}); + this->drawFunctionMap_.insert({"PathStar", &SampleGraphics::DrawStar}); + this->drawFunctionMap_.insert({"BuildFromSvgString", &SampleGraphics::BuildFromSvgString}); + + this->drawFunctionMap_.insert({"MatrixBasic", &SampleGraphics::DrawMatrixBasic}); + this->drawFunctionMap_.insert({"TranslationOperation", &SampleGraphics::DrawTranslationOperation}); + this->drawFunctionMap_.insert({"PreTranslationOperation", &SampleGraphics::DrawPreTranslationOperation}); + this->drawFunctionMap_.insert({"PostTranslationOperation", &SampleGraphics::DrawPostTranslationOperation}); + this->drawFunctionMap_.insert({"RotationOperation", &SampleGraphics::DrawRotationOperation}); + this->drawFunctionMap_.insert({"PreRotationOperation", &SampleGraphics::DrawPreRotationOperation}); + this->drawFunctionMap_.insert({"PostRotationOperation", &SampleGraphics::DrawPostRotationOperation}); + this->drawFunctionMap_.insert({"ScaleOperation", &SampleGraphics::DrawScaleOperation}); + this->drawFunctionMap_.insert({"PreScaleOperation", &SampleGraphics::DrawPreScaleOperation}); + this->drawFunctionMap_.insert({"PostScaleOperation", &SampleGraphics::DrawPostScaleOperation}); + this->drawFunctionMap_.insert({"ConcatOperation", &SampleGraphics::DrawConcatOperation}); + + this->drawFunctionMap_.insert({"CanvasCreate", &SampleGraphics::DrawCreateCanvas}); + this->drawFunctionMap_.insert({"ClipOperation", &SampleGraphics::DrawClipOperation}); + this->drawFunctionMap_.insert({"SaveOperation", &SampleGraphics::CanvasSaveOperation}); + this->drawFunctionMap_.insert({"SaveLayerOperation", &SampleGraphics::CanvasSaveLayerOperation}); + this->drawFunctionMap_.insert({"ConcatMatrix", &SampleGraphics::DrawCanvasConcatMatrix}); + this->drawFunctionMap_.insert({"DrawRegion", &SampleGraphics::DrawRegion}); + + this->drawFunctionMap_.insert({"LocalPixelMap", &SampleGraphics::DrawPixelMapRect}); + this->drawFunctionMap_.insert({"CustomPixelMap", &SampleGraphics::DrawCustomPixelMap}); + this->drawFunctionMap_.insert({"DrawBitmap", &SampleGraphics::DrawBitmap}); + this->drawFunctionMap_.insert({"DrawImage", &SampleGraphics::DrawImage}); +} + +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; +} + +napi_value SampleGraphics::DrawImage(napi_env env, napi_callback_info info) +{ + SAMPLE_LOGI("DrawImage"); + if ((env == nullptr) || (info == nullptr)) { + SAMPLE_LOGE("NapiRegister: env or info is null"); + return nullptr; + } + + napi_value thisArg; + size_t argc = 3; + napi_value args[3]; + 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); + + NativePixelMap *nativePixelMap = OH_PixelMap_InitNativePixelMap(env, args[2]); + SampleGraphics *render = SampleGraphics().GetInstance(id); + if (render != nullptr) { + render->nativePixelMap_ = nativePixelMap; + 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}, + {"drawImage", nullptr, SampleGraphics::DrawImage, 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/NdkDrawingApiSamples/entry/src/main/cpp/samples/sample_graphics.h b/NdkDrawingApiSamples/entry/src/main/cpp/samples/sample_graphics.h new file mode 100644 index 0000000000000000000000000000000000000000..34fcd1c5d102d9aa9c0960d637c2379c57b71e1b --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/cpp/samples/sample_graphics.h @@ -0,0 +1,166 @@ +/* + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "napi/native_api.h" +#include + + +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 napi_value DrawImage(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); + + // brush + void DrawBrushBasic(OH_Drawing_Canvas *canvas); + void DrawMixedMode(OH_Drawing_Canvas *canvas); + void DrawShaderEffect(OH_Drawing_Canvas *canvas); + void DrawColorFilter(OH_Drawing_Canvas *canvas); + void DrawMaskFilterBrush(OH_Drawing_Canvas *canvas); + + // pen + void DrawPenBasic(OH_Drawing_Canvas *canvas); + void DrawPenLinearGradient(OH_Drawing_Canvas *canvas); + void DrawMiterLimit(OH_Drawing_Canvas *canvas); + void DrawStroke(OH_Drawing_Canvas *canvas); + void DrawPathEffect(OH_Drawing_Canvas *canvas); + void DrawImageFilter(OH_Drawing_Canvas *canvas); + void DrawMaskFilterPen(OH_Drawing_Canvas *canvas); + + // rect + void DrawRectBasic(OH_Drawing_Canvas *canvas); + void DrawRectIntersect(OH_Drawing_Canvas *canvas); + void DrawRectJoin(OH_Drawing_Canvas *canvas); + void DrawRoundRect(OH_Drawing_Canvas *canvas); + + // path + void DrawPathBasic(OH_Drawing_Canvas *canvas); + void DrawPathAdd(OH_Drawing_Canvas *canvas); + void DrawPathTo(OH_Drawing_Canvas *canvas); + void DrawStar(OH_Drawing_Canvas *canvas); + void BuildFromSvgString(OH_Drawing_Canvas *canvas); + + // matrix + void DrawMatrixBasic(OH_Drawing_Canvas *canvas); + void DrawTranslationOperation(OH_Drawing_Canvas *canvas); + void DrawPreTranslationOperation(OH_Drawing_Canvas *canvas); + void DrawPostTranslationOperation(OH_Drawing_Canvas *canvas); + void DrawRotationOperation(OH_Drawing_Canvas *canvas); + void DrawPreRotationOperation(OH_Drawing_Canvas *canvas); + void DrawPostRotationOperation(OH_Drawing_Canvas *canvas); + void DrawScaleOperation(OH_Drawing_Canvas *canvas); + void DrawPreScaleOperation(OH_Drawing_Canvas *canvas); + void DrawPostScaleOperation(OH_Drawing_Canvas *canvas); + void DrawConcatOperation(OH_Drawing_Canvas *canvas); + + // Canvas + void DrawCreateCanvas(OH_Drawing_Canvas *canvas); + void DrawClipOperation(OH_Drawing_Canvas *canvas); + void CanvasSaveOperation(OH_Drawing_Canvas *canvas); + void CanvasSaveLayerOperation(OH_Drawing_Canvas *canvas); + void DrawCanvasConcatMatrix(OH_Drawing_Canvas *canvas); + void DrawRegion(OH_Drawing_Canvas *canvas); + void DrawCustomPixelMap(OH_Drawing_Canvas *canvas); + void DrawPixelMapRect(OH_Drawing_Canvas *canvas); + void DrawBitmap(OH_Drawing_Canvas *canvas); + void DrawImage(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 value1100_; + static float value1200_; + bool desc = false; + + EGLDisplay EGLDisplay_ = EGL_NO_DISPLAY; + EGLConfig EGLConfig_ = nullptr; + EGLContext EGLContext_ = EGL_NO_CONTEXT; + EGLSurface EGLSurface_ = nullptr; + + 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; + NativePixelMap *nativePixelMap_ = 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/NdkDrawingApiSamples/entry/src/main/cpp/types/libentry/Index.d.ts b/NdkDrawingApiSamples/entry/src/main/cpp/types/libentry/Index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..6c07bc3e6ca89c2cf37df36794d286dff08f7e2f --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/cpp/types/libentry/oh-package.json5 b/NdkDrawingApiSamples/entry/src/main/cpp/types/libentry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2fba3bb65f84559a125158fcdd2816076bdd7379 --- /dev/null +++ b/NdkDrawingApiSamples/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": "12", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/cpp/utils/adaptation_util.cpp b/NdkDrawingApiSamples/entry/src/main/cpp/utils/adaptation_util.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cea2d962e9f2f5c3d495f2c0b5e7b5c5ce02e88d --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/cpp/utils/adaptation_util.h b/NdkDrawingApiSamples/entry/src/main/cpp/utils/adaptation_util.h new file mode 100644 index 0000000000000000000000000000000000000000..7c449b601910fd4966e94ab7f213d677ba21529b --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/BitmapDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/BitmapDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..8ba47c25209536ada692e168ec2a570fd28deee6 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/BitmapDrawing.ets @@ -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. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct BitmapDrawing { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'basicEffectXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + this.xComponentContext.draw('CanvasGet', 'DrawBitmap'); + }) + .backgroundColor(Color.White) + .width('100%') + .height('100%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/BrushDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/BrushDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..eff6118cfca8dfa1574424af1fd753a440394f15 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/BrushDrawing.ets @@ -0,0 +1,78 @@ +/* + * 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 BrushDrawing { + 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%') + Flex({ + direction: FlexDirection.Row, + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Start, + alignItems: ItemAlign.Start + }) { + Button('Basic Brush') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'BrushBasic'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('BlendMode') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'MixedMode'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('ColorFilter') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ColorFilter'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('ShaderEffect') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'LinearGradient'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('MaskFilter') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'MaskFilterBrush'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + } + .width('100%') + .height('30%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/CanvasDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/CanvasDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..262d93d99e99de72dcb58486f08233ec06e061fb --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/CanvasDrawing.ets @@ -0,0 +1,92 @@ +/* + * 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 CanvasDrawing { + 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%') + Flex({ + direction: FlexDirection.Row, + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Start, + alignItems: ItemAlign.Start + }) { + Button('CreateCanvas') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGetByCPU', 'CanvasCreate'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('Clip') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ClipOperation'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('Save') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'SaveOperation'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('SaveLayer') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'SaveLayerOperation'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('ConcatMatrix') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ConcatMatrix'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('DrawPixelMap') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'CustomPixelMap'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('DrawRegion') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'DrawRegion'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + } + .width('100%') + .height('30%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/ImageDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/ImageDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..fb07ab8bb20e316f272c043e5f147afeefb466a0 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/ImageDrawing.ets @@ -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. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct ImageDrawing { + private xComponentContext: XComponentContext | undefined = undefined; + + build() { + Column() { + XComponent({ id: 'basicEffectXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + this.xComponentContext.draw('CanvasGet', 'DrawImage'); + }) + .backgroundColor(Color.White) + .width('100%') + .height('100%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/MatrixDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/MatrixDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..b00b0023ddb2aa1fd508d4bd64c8d121c18574ce --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/MatrixDrawing.ets @@ -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. + */ + +import XComponentContext from '../../interface/XComponentContext'; + +@Entry +@Component +struct MatrixDrawing { + 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%') + Flex({ + direction: FlexDirection.Row, + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Start, + alignItems: ItemAlign.Start + }) { + Button('MatrixBasic') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'MatrixBasic'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('Translation') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'TranslationOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('PreTranslation') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PreTranslationOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('PostTranslation') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PostTranslationOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('Rotation') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'RotationOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('PreRotation') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PreRotationOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('PostRotation') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PostRotationOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('Scale') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ScaleOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('PreScale') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PreScaleOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('PostScale') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PostScaleOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + Button('Concat') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ConcatOperation'); + } + }) + .margin({ top: 5, bottom: 5, left: 5, right: 5 }) + } + .width('100%') + .height('30%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PathDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PathDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..c8253cd9d73edf87ac96e6f35ce4bae8a2b22f11 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PathDrawing.ets @@ -0,0 +1,78 @@ +/* + * 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 PathDrawing { + 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%') + Flex({ + direction: FlexDirection.Row, + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Start, + alignItems: ItemAlign.Start + }) { + Button('PathBasic') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PathBasic'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('PathAdd*') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PathAdd'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('Path*To') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PathTo'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('PathStar') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PathStar'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('BuildFromSvgString') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'BuildFromSvgString'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + } + .width('100%') + .height('30%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PenDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PenDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..109c2fb6b430eaf089bf571927c19b82439aa748 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PenDrawing.ets @@ -0,0 +1,92 @@ +/* + * 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 PenDrawing { + 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%') + Flex({ + direction: FlexDirection.Row, + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Start, + alignItems: ItemAlign.Start + }) { + Button('Basic Pen') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PenBasic'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('Cap & Join') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'Stroke'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('MiterLimit') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'MiterLimit'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('ImageFilter') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'ImageFilter'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('PathEffect') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PathEffect'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('ShaderEffect') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'PenLinearGradient'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('MaskFilter') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'MaskFilterPen'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + } + .width('100%') + .height('30%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PixelMapDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PixelMapDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..8cfbb2e7be27de1c3505e3b7aa648e5454cdbbef --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/PixelMapDrawing.ets @@ -0,0 +1,77 @@ +/* + * 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'; +import { image } from '@kit.ImageKit'; +import { resourceManager } from '@kit.LocalizationKit'; +import { BusinessError } from '@kit.BasicServicesKit'; + +@Entry +@Component +struct PixelMapDrawing { + private xComponentContext: XComponentContext | undefined = undefined; + private pMap: image.PixelMap | undefined = undefined; + aboutToAppear() { + const context: Context = getContext(this); + const resourceMgr: resourceManager.ResourceManager = context.resourceManager; + resourceMgr.getRawFileContent('startIcon.png').then((fileData: Uint8Array) => { + console.log('Succeeded in getting RawFileContent'); + const buffer = fileData.buffer.slice(0); + const imageSource: image.ImageSource = image.createImageSource(buffer); + imageSource.createPixelMap().then((pMap: image.PixelMap) => { + this.pMap = pMap; + }).catch((err: BusinessError) => { + console.error('Failed to creating PixelMap'); + }); + }).catch((err: BusinessError) => { + console.error('Failed to get RawFileContent'); + }); + } + + build() { + Column() { + XComponent({ id: 'basicEffectXComponent', type: XComponentType.SURFACE, libraryname: 'entry' }) + .onLoad((xComponentContext) => { + this.xComponentContext = xComponentContext as XComponentContext; + }) + .backgroundColor(Color.White) + .width('100%') + .height('70%') + Flex({ + direction: FlexDirection.Row, + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Start, + alignItems: ItemAlign.Start + }) { + Button('LocalPixelMap') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.drawImage('CanvasGet', 'LocalPixelMap', this.pMap); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('CustomPixelMap') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'CustomPixelMap'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + } + .width('100%') + .height('30%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/RectDrawing.ets b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/RectDrawing.ets new file mode 100644 index 0000000000000000000000000000000000000000..802e2a689f031379a10d76ea782c2aba2234ae8c --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/drawing/pages/RectDrawing.ets @@ -0,0 +1,71 @@ +/* + * 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 RectDrawing { + 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%') + Flex({ + direction: FlexDirection.Row, + wrap: FlexWrap.Wrap, + justifyContent: FlexAlign.Start, + alignItems: ItemAlign.Start + }) { + Button('Basic Rect') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'RectBasic'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('Intersect') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'RectIntersect'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('Join') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'RectJoin'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + Button('RoundRect') + .onClick((): void => { + if (this.xComponentContext) { + this.xComponentContext.draw('CanvasGet', 'RoundRect'); + } + }) + .margin({ top: 10, bottom: 10, left: 10, right: 10 }) + } + .width('100%') + .height('30%') + } + } +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/ets/entryability/EntryAbility.ets b/NdkDrawingApiSamples/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..965554bb3a331e2418180b86da1993baf5e8d536 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets b/NdkDrawingApiSamples/entry/src/main/ets/entrybackupability/EntryBackupAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..b1e212947256c5533c7b06285a597c94f840a6e3 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/ets/interface/XComponentContext.ts b/NdkDrawingApiSamples/entry/src/main/ets/interface/XComponentContext.ts new file mode 100644 index 0000000000000000000000000000000000000000..00e14e462fbefcc4838478cf0846dc6a54ee4b97 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/interface/XComponentContext.ts @@ -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 { image } from '@kit.ImageKit'; + +export default interface XComponentContext { + draw(canvasType:string, shapeType: string):void; + drawImage(canvasType:string, shapeType: string, pixelmap: image.PixelMap):void; +}; diff --git a/NdkDrawingApiSamples/entry/src/main/ets/pages/Index.ets b/NdkDrawingApiSamples/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..ec98ac6fbc1e1dc55dfdd818385dc3045d64ab15 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,89 @@ +/* + * 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/BrushDrawing', + 'drawing/pages/PenDrawing', + 'drawing/pages/RectDrawing', + 'drawing/pages/PathDrawing', + 'drawing/pages/MatrixDrawing', + 'drawing/pages/CanvasDrawing', + 'drawing/pages/PixelMapDrawing', + 'drawing/pages/BitmapDrawing', + 'drawing/pages/ImageDrawing' +]; + +@Entry +@Component +struct Index { + ResourceToString(resource: Resource): string { + return getContext(this).resourceManager.getStringSync(resource); + } + + @State listItem: Item[] = [ + { text: 'drawing_brush' }, + { text: 'drawing_pen' }, + { text: 'drawing_rect' }, + { text: 'drawing_path' }, + { text: 'drawing_matrix' }, + { text: 'drawing_canvas' }, + { text: 'drawing_pixelmap' }, + { text: 'drawing_bitmap' }, + { text: 'drawing_image' } + ] + + 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/NdkDrawingApiSamples/entry/src/main/module.json5 b/NdkDrawingApiSamples/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..1cf10bcbee31beca865cd0e3f142c7b258335421 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/module.json5 @@ -0,0 +1,52 @@ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "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/NdkDrawingApiSamples/entry/src/main/resources/base/element/color.json b/NdkDrawingApiSamples/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/resources/base/element/string.json b/NdkDrawingApiSamples/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..9a89005ff0071537f56ae01f009959576ccdd255 --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "NDKGraphicsDraw" + } + ] +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/resources/base/media/background.png b/NdkDrawingApiSamples/entry/src/main/resources/base/media/background.png new file mode 100644 index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d Binary files /dev/null and b/NdkDrawingApiSamples/entry/src/main/resources/base/media/background.png differ diff --git a/NdkDrawingApiSamples/entry/src/main/resources/base/media/foreground.png b/NdkDrawingApiSamples/entry/src/main/resources/base/media/foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902 Binary files /dev/null and b/NdkDrawingApiSamples/entry/src/main/resources/base/media/foreground.png differ diff --git a/NdkDrawingApiSamples/entry/src/main/resources/base/media/layered_image.json b/NdkDrawingApiSamples/entry/src/main/resources/base/media/layered_image.json new file mode 100644 index 0000000000000000000000000000000000000000..fb49920440fb4d246c82f9ada275e26123a2136a --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/resources/base/media/right.png b/NdkDrawingApiSamples/entry/src/main/resources/base/media/right.png new file mode 100644 index 0000000000000000000000000000000000000000..812a7bd2dc2efcb999d962575b43139077cb7d16 Binary files /dev/null and b/NdkDrawingApiSamples/entry/src/main/resources/base/media/right.png differ diff --git a/NdkDrawingApiSamples/entry/src/main/resources/base/media/startIcon.png b/NdkDrawingApiSamples/entry/src/main/resources/base/media/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b Binary files /dev/null and b/NdkDrawingApiSamples/entry/src/main/resources/base/media/startIcon.png differ diff --git a/NdkDrawingApiSamples/entry/src/main/resources/base/profile/backup_config.json b/NdkDrawingApiSamples/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 0000000000000000000000000000000000000000..78f40ae7c494d71e2482278f359ec790ca73471a --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/NdkDrawingApiSamples/entry/src/main/resources/base/profile/main_pages.json b/NdkDrawingApiSamples/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..111170b4d4c4ddfddd896f7811ea14e73813406e --- /dev/null +++ b/NdkDrawingApiSamples/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,14 @@ +{ + "src": [ + "pages/Index", + "drawing/pages/BitmapDrawing", + "drawing/pages/BrushDrawing", + "drawing/pages/PenDrawing", + "drawing/pages/RectDrawing", + "drawing/pages/PathDrawing", + "drawing/pages/MatrixDrawing", + "drawing/pages/CanvasDrawing", + "drawing/pages/PixelMapDrawing", + "drawing/pages/ImageDrawing" + ] +} diff --git a/NdkDrawingApiSamples/entry/src/main/resources/dark/element/color.json b/NdkDrawingApiSamples/entry/src/main/resources/dark/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..79b11c2747aec33e710fd3a7b2b3c94dd9965499 --- /dev/null +++ b/NdkDrawingApiSamples/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/NdkDrawingApiSamples/entry/src/main/resources/rawfile/startIcon.png b/NdkDrawingApiSamples/entry/src/main/resources/rawfile/startIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/NdkDrawingApiSamples/entry/src/main/resources/rawfile/startIcon.png differ diff --git a/NdkDrawingApiSamples/hvigor/hvigor-config.json5 b/NdkDrawingApiSamples/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e0bd0d82696bcd6337fc106180834b6a9ac56a5d --- /dev/null +++ b/NdkDrawingApiSamples/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +{ + "modelVersion": "5.0.0", + "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/NdkDrawingApiSamples/hvigorfile.ts b/NdkDrawingApiSamples/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..f3cb9f1a87a81687554a76283af8df27d8bda775 --- /dev/null +++ b/NdkDrawingApiSamples/hvigorfile.ts @@ -0,0 +1,6 @@ +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/NdkDrawingApiSamples/oh-package.json5 b/NdkDrawingApiSamples/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..dd6b0d408799801607b2f5b3256b2a4969d90e02 --- /dev/null +++ b/NdkDrawingApiSamples/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.0", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.19", + "@ohos/hamock": "1.0.0" + } +} diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418143325437.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418143325437.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..42d3305267673ced262c60b0d976f8954fb0ce4e Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418143325437.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150845623.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150845623.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..9b4fdbfbc2cd70eb5058ab0931424150ce2e42a8 Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150845623.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150909597.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150909597.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..f112efa6f93543e945f7efac335dab9a5fa5e3e6 Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150909597.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150925879.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150925879.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..8b8e47adbd81a3b3b3d06217226d817f1ed676e1 Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150925879.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150945891.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150945891.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..7552be473407708535f468a6c9e4368fa716c19c Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418150945891.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151048183.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151048183.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..fa5c7af31d15817f123b18e78055146a93e903e1 Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151048183.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151107524.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151107524.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1bf4d2fe401faf6467def354d6111dc4d5793bb7 Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151107524.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151125603.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151125603.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..bd9f20c7af5f9a8a64a7776e303267cb3b47b7e1 Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151125603.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151143671.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151143671.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..5f94d223fc3d06e0337d7eee389c512e3794b5b9 Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151143671.jpeg differ diff --git a/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151155313.jpeg b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151155313.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..ef734a974a1915af55b2c1df4ab9f37ea60bbd5d Binary files /dev/null and b/NdkDrawingApiSamples/screenshots/device/Screenshot_20250418151155313.jpeg differ diff --git a/README.md b/README.md index 7155519c9aed0542ef47d87a79096a07ff6a6fc2..674ee0d4657b28338a017cc867cc534fe6a0c120 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ * [ArkTsDrawingGuideSamples: 图形绘制与显示的示例(ArkTS)](ArkTsDrawingGuideSamples) * [NdkDrawingSamples: 使用Drawing实现图形绘制与显示的示例(C/C++)](NdkDrawingSamples) * [NdkDrawingGuideSamples: 图形绘制与显示的示例(drawing C/C++)](NdkDrawingGuideSamples) +* [NdkDrawingApiSamples: Drawing API示例(C/C++)](NdkDrawingApiSamples) ## 使用说明