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

c)ijgxDm}8EsRXFt3h@+Ufr7@DN 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 literal 0 HcmV?d00001 diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/backup_config.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/backup_config.json new file mode 100644 index 000000000..78f40ae7c --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/backup_config.json @@ -0,0 +1,3 @@ +{ + "allowToBackupRestore": true +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/main_pages.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 000000000..30c4bf1b2 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,12 @@ +{ + "src": [ + "pages/Index", + "drawing/pages/CanvasGetResult", + "drawing/pages/CanvasOperationState", + "drawing/pages/BasicEffect", + "drawing/pages/ComplexEffect", + "drawing/pages/ShapeDrawing", + "drawing/pages/PixelMapDrawing", + "drawing/pages/TextBlockDrawing" + ] +} diff --git a/Drawing/NDKGraphicsDraw/entry/src/main/resources/dark/element/color.json b/Drawing/NDKGraphicsDraw/entry/src/main/resources/dark/element/color.json new file mode 100644 index 000000000..79b11c274 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/main/resources/dark/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#000000" + } + ] +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/mock/Libentry.mock.ets b/Drawing/NDKGraphicsDraw/entry/src/mock/Libentry.mock.ets new file mode 100644 index 000000000..133fac902 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/mock/Libentry.mock.ets @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const nativeMock: Record = { + 'add': (a: number, b: number) => { + return a + b; + }, +}; + +export default nativeMock; \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/mock/mock-config.json5 b/Drawing/NDKGraphicsDraw/entry/src/mock/mock-config.json5 new file mode 100644 index 000000000..2c7d2ba82 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/mock/mock-config.json5 @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "libentry.so": { + "source": "src/mock/Libentry.mock.ets" + } +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/Ability.test.ets b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 000000000..dd422eaf5 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { describe, it, expect } from '@ohos/hypium'; +import { Driver, ON } from '@ohos.UiTest'; +import Logger from '../utils/Logger'; +import { abilityDelegatorRegistry } from '@kit.TestKit'; +import { UIAbility, Want } from '@kit.AbilityKit'; + +const TAG = '[Sample_NDKGraphicsDraw]'; +const DELAY_SHORT = 400; +const DELAY_LONG = 1000; + +const delegator = abilityDelegatorRegistry.getAbilityDelegator(); +const bundleName = abilityDelegatorRegistry.getArguments().bundleName; + +function getString(resourceData: Resource): string { + let manage = delegator.getAppContext().resourceManager; + return manage.getStringSync(resourceData); +} + +export default function abilityTest() { + describe('ActsAbilityTest', () => { + /** + * @tc.number StartAbility_001 + * @tc.name StartAbility_001 + * @tc.desc 启动Ability + */ + it('NDKGraphicsDraw_StartAbility_001',0, async (done: Function) => { + console.info('uitest: StartAbility_001 begin'); + //start tested ability + const want: Want = { + bundleName: bundleName, + abilityName: 'EntryAbility' + }; + await delegator.startAbility(want); + let driver = Driver.create(); + await driver.delayMs(DELAY_LONG); + //check top display ability + const ability: UIAbility = await delegator.getCurrentTopAbility(); + console.info('get top ability'); + expect(ability.context.abilityInfo.name).assertEqual('EntryAbility'); + done(); + console.info('uitest: StartAbility_001 end'); + }) + + /** + * @tc.number:CanvasGetResult_001 + * @tc.name:CanvasGetResult_001 + * @tc.desc:画布的获取与绘制结果测试 + */ + it('NDKGraphicsDraw_CanvasGetResult_001', 0, async (done: Function) => { + Logger.info(TAG, 'CanvasGetResult_001 begin'); + let driver = Driver.create(); + let canvasGetResultStr = getString($r('app.string.CanvasGetResult')); + await driver.assertComponentExist(ON.text(canvasGetResultStr)); + let canvasButton = await driver.findComponent(ON.text(canvasGetResultStr)); + await canvasButton.click(); + await driver.delayMs(DELAY_SHORT); + + let canvasGetStr = getString($r('app.string.CanvasGet')); + await driver.assertComponentExist(ON.text(canvasGetStr)); + let canvasGetButton = await driver.findComponent(ON.text(canvasGetStr)); + await canvasGetButton.click(); + await driver.delayMs(DELAY_SHORT); + + let getStringByCPUStr = getString($r('app.string.CanvasGetByCPU')); + await driver.assertComponentExist(ON.text(getStringByCPUStr)); + let canvasGetByCPUButton = await driver.findComponent(ON.text(getStringByCPUStr)); + await canvasGetByCPUButton.click(); + await driver.delayMs(DELAY_SHORT); + + let getStringByGPUStr = getString($r('app.string.CanvasGetByGPU')); + await driver.assertComponentExist(ON.text(getStringByGPUStr)); + let canvasGetByGPUButton = await driver.findComponent(ON.text(getStringByGPUStr)); + await canvasGetByGPUButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'CanvasGetResult_001 end'); + }); + + /** + * @tc.number:CanvasOperationState_001 + * @tc.name:CanvasOperationState_001 + * @tc.desc:画布操作与状态操作结果测试 + */ + it('NDKGraphicsDraw_CanvasOperationState_001', 0, async (done: Function) => { + Logger.info(TAG, 'CanvasGet_001 begin'); + let driver = Driver.create(); + let canvasOperationStr = getString($r('app.string.CanvasOperationState')); + await driver.assertComponentExist(ON.text(canvasOperationStr)); + let canvasOperationButton = await driver.findComponent(ON.text(canvasOperationStr)); + await canvasOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let clipOperationStr = getString($r('app.string.ClipOperation')); + await driver.assertComponentExist(ON.text(clipOperationStr)); + let clipOperationButton = await driver.findComponent(ON.text(clipOperationStr)); + await clipOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let translationOperationStr = getString($r('app.string.TranslationOperation')); + await driver.assertComponentExist(ON.text(translationOperationStr)); + let translationOperationButton = await driver.findComponent(ON.text(translationOperationStr)); + await translationOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let rotationOperationStr = getString($r('app.string.RotationOperation')); + await driver.assertComponentExist(ON.text(rotationOperationStr)); + let rotationOperationButton = await driver.findComponent(ON.text(rotationOperationStr)); + await rotationOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let scaleOperationStr = getString($r('app.string.ScaleOperation')); + await driver.assertComponentExist(ON.text(scaleOperationStr)); + let scaleOperationButton = await driver.findComponent(ON.text(scaleOperationStr)); + await scaleOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + let stateOperationStr = getString($r('app.string.StateOperation')); + await driver.assertComponentExist(ON.text(stateOperationStr)); + let stateOperationButton = await driver.findComponent(ON.text(stateOperationStr)); + await stateOperationButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'CanvasGet_001 end'); + }); + + /** + * @tc.number:BasicEffect_001 + * @tc.name:BasicEffect_001 + * @tc.desc:基础绘制效果结果测试 + */ + it('NDKGraphicsDraw_BasicEffect_001', 0, async (done: Function) => { + Logger.info(TAG, 'BasicEffect_001 begin'); + let driver = Driver.create(); + let basicEffectStr = getString($r('app.string.BasicEffect')); + await driver.assertComponentExist(ON.text(basicEffectStr)); + let basicEffectButton = await driver.findComponent(ON.text(basicEffectStr)); + await basicEffectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let fillingStr = getString($r('app.string.Filling')); + await driver.assertComponentExist(ON.text(fillingStr)); + let fillingButton = await driver.findComponent(ON.text(fillingStr)); + await fillingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let strokeStr = getString($r('app.string.Stroke')); + await driver.assertComponentExist(ON.text(strokeStr)); + let strokeButton = await driver.findComponent(ON.text(strokeStr)); + await strokeButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'BasicEffect_001 end'); + }); + + /** + * @tc.number:ComplexEffect_001 + * @tc.name:ComplexEffect_001 + * @tc.desc:复杂绘制效果结果测试 + */ + it('NDKGraphicsDraw_ComplexEffect_001', 0, async (done: Function) => { + Logger.info(TAG, 'ComplexEffect_001 begin'); + let driver = Driver.create(); + let complexEffectStr = getString($r('app.string.ComplexEffect')); + await driver.assertComponentExist(ON.text(complexEffectStr)); + let complexEffectButton = await driver.findComponent(ON.text(complexEffectStr)); + await complexEffectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let mixedModeStr = getString($r('app.string.MixedMode')); + await driver.assertComponentExist(ON.text(mixedModeStr)); + let mixedModeButton = await driver.findComponent(ON.text(mixedModeStr)); + await mixedModeButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pathEffectStr = getString($r('app.string.PathEffect')); + await driver.assertComponentExist(ON.text(pathEffectStr)); + let pathEffectButton = await driver.findComponent(ON.text(pathEffectStr)); + await pathEffectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let linearGradientStr = getString($r('app.string.LinearGradient')); + await driver.assertComponentExist(ON.text(linearGradientStr)); + let linearGradientButton = await driver.findComponent(ON.text(linearGradientStr)); + await linearGradientButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pathGradientStr = getString($r('app.string.PathGradient')); + await driver.assertComponentExist(ON.text(pathGradientStr)); + let pathGradientButton = await driver.findComponent(ON.text(pathGradientStr)); + await pathGradientButton.click(); + await driver.delayMs(DELAY_SHORT); + + let sectorGradientStr = getString($r('app.string.SectorGradient')); + await driver.assertComponentExist(ON.text(sectorGradientStr)); + let sectorGradientButton = await driver.findComponent(ON.text(sectorGradientStr)); + await sectorGradientButton.click(); + await driver.delayMs(DELAY_SHORT); + + let colorFilterStr = getString($r('app.string.ColorFilter')); + await driver.assertComponentExist(ON.text(colorFilterStr)); + let colorFilterButton = await driver.findComponent(ON.text(colorFilterStr)); + await colorFilterButton.click(); + await driver.delayMs(DELAY_SHORT); + + let imageFilterStr = getString($r('app.string.ImageFilter')); + await driver.assertComponentExist(ON.text(imageFilterStr)); + let imageFilterStrButton = await driver.findComponent(ON.text(imageFilterStr)); + await imageFilterStrButton.click(); + await driver.delayMs(DELAY_SHORT); + + let maskFilterStr = getString($r('app.string.MaskFilter')); + await driver.assertComponentExist(ON.text(maskFilterStr)); + let maskFilterButton = await driver.findComponent(ON.text(maskFilterStr)); + await maskFilterButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'ComplexEffect_001 end'); + }); + + /** + * @tc.number:ShapeDrawing_001 + * @tc.name:ShapeDrawing_001 + * @tc.desc:几何形状绘制结果测试 + */ + it('NDKGraphicsDraw_ShapeDrawing_001', 0, async (done: Function) => { + Logger.info(TAG, 'ShapeDrawing_001 begin'); + let driver = Driver.create(); + let shapeDrawingStr = getString($r('app.string.Shape_Drawing')); + await driver.assertComponentExist(ON.text(shapeDrawingStr)); + let shapeDrawingButton = await driver.findComponent(ON.text(shapeDrawingStr)); + await shapeDrawingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pointStr = getString($r('app.string.Point')); + await driver.assertComponentExist(ON.text(pointStr)); + let pointButton = await driver.findComponent(ON.text(pointStr)); + await pointButton.click(); + await driver.delayMs(DELAY_SHORT); + + let arcStr = getString($r('app.string.Arc')); + await driver.assertComponentExist(ON.text(arcStr)); + let arcButton = await driver.findComponent(ON.text(arcStr)); + await arcButton.click(); + await driver.delayMs(DELAY_SHORT); + + let circleStr = getString($r('app.string.Circle')); + await driver.assertComponentExist(ON.text(circleStr)); + let circleButton = await driver.findComponent(ON.text(circleStr)); + await circleButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pathStr = getString($r('app.string.Path')); + await driver.assertComponentExist(ON.text(pathStr)); + let pathButton = await driver.findComponent(ON.text(pathStr)); + await pathButton.click(); + await driver.delayMs(DELAY_SHORT); + + let regionStr = getString($r('app.string.Region')); + await driver.assertComponentExist(ON.text(regionStr)); + let regionButton = await driver.findComponent(ON.text(regionStr)); + await regionButton.click(); + await driver.delayMs(DELAY_SHORT); + + let rectStr = getString($r('app.string.Rect')); + await driver.assertComponentExist(ON.text(rectStr)); + let rectButton = await driver.findComponent(ON.text(rectStr)); + await rectButton.click(); + await driver.delayMs(DELAY_SHORT); + + let roundRectStr = getString($r('app.string.RoundRect')); + await driver.assertComponentExist(ON.text(roundRectStr)); + let roundRectButton = await driver.findComponent(ON.text(roundRectStr)); + await roundRectButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'ShapeDrawing_001 end'); + }); + + it('NDKGraphicsDraw_PixelMapDrawing_001', 0, async (done: Function) => { + Logger.info(TAG, 'PixelMapDrawing_001 begin'); + let driver = Driver.create(); + let pixelMapDrawingStr = getString($r('app.string.PixelMap_Drawing')); + await driver.assertComponentExist(ON.text(pixelMapDrawingStr)); + let pixelMapDrawingButton = await driver.findComponent(ON.text(pixelMapDrawingStr)); + await pixelMapDrawingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let pixelMapStr = getString($r('app.string.PixelMap')); + await driver.assertComponentExist(ON.text(pixelMapStr)); + let pixelMapButton = await driver.findComponent(ON.text(pixelMapStr)); + await pixelMapButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'PixelMapDrawing_001 end'); + }); + + it('NDKGraphicsDraw_TextBlockDrawing_001', 0, async (done: Function) => { + Logger.info(TAG, 'TextBlockDrawing_001 begin'); + let driver = Driver.create(); + let textBlockDrawingStr = getString($r('app.string.TextBlock_Drawing')); + await driver.assertComponentExist(ON.text(textBlockDrawingStr)); + let textBlockDrawingButton = await driver.findComponent(ON.text(textBlockDrawingStr)); + await textBlockDrawingButton.click(); + await driver.delayMs(DELAY_SHORT); + + let baseTextStr = getString($r('app.string.BaseText')); + await driver.assertComponentExist(ON.text(baseTextStr)); + let baseTextButton = await driver.findComponent(ON.text(baseTextStr)); + await baseTextButton.click(); + await driver.delayMs(DELAY_SHORT); + + let strokeTextStr = getString($r('app.string.StrokeText')); + await driver.assertComponentExist(ON.text(strokeTextStr)); + let strokeTextButton = await driver.findComponent(ON.text(strokeTextStr)); + await strokeTextButton.click(); + await driver.delayMs(DELAY_SHORT); + + let gradientTextStr = getString($r('app.string.GradientText')); + await driver.assertComponentExist(ON.text(gradientTextStr)); + let gradientTextButton = await driver.findComponent(ON.text(gradientTextStr)); + await gradientTextButton.click(); + await driver.delayMs(DELAY_SHORT); + + await driver.pressBack(); + done(); + Logger.info(TAG, 'TextBlockDrawing_001 end'); + }); + }) +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/List.test.ets b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 000000000..1eac52fce --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/utils/Logger.ets b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/utils/Logger.ets new file mode 100644 index 000000000..61ed537de --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/ets/utils/Logger.ets @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import hilog from '@ohos.hilog'; + +class Logger { + private domain: number = 0xF811; + private prefix: string = ''; + private format: string = '%{public}s, %{public}s'; + + constructor(prefix: string) { + this.prefix = prefix; + this.domain = 0xF811; + } + + debug(...args: string[]): void { + hilog.debug(this.domain, this.prefix, this.format, args); + } + + info(...args: string[]): void { + hilog.info(this.domain, this.prefix, this.format, args); + } + + warn(...args: string[]): void { + hilog.warn(this.domain, this.prefix, this.format, args); + } + + error(...args: string[]): void { + hilog.error(this.domain, this.prefix, this.format, args); + } +} + +export default new Logger('[Sample_NDKGraphicsDraw]'); \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/entry/src/ohosTest/module.json5 b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/module.json5 new file mode 100644 index 000000000..c3fd9dda3 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/entry/src/ohosTest/module.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "deviceTypes": [ + "default", + "tablet" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} diff --git a/Drawing/NDKGraphicsDraw/hvigor/hvigor-config.json5 b/Drawing/NDKGraphicsDraw/hvigor/hvigor-config.json5 new file mode 100644 index 000000000..d584c19c2 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/hvigor/hvigor-config.json5 @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "modelVersion": "5.0.1", + "dependencies": { + }, + "execution": { + // "analyze": "normal", /* Define the build analyze mode. Value: [ "normal" | "advanced" | false ]. Default: "normal" */ + // "daemon": true, /* Enable daemon compilation. Value: [ true | false ]. Default: true */ + // "incremental": true, /* Enable incremental compilation. Value: [ true | false ]. Default: true */ + // "parallel": true, /* Enable parallel compilation. Value: [ true | false ]. Default: true */ + // "typeCheck": false, /* Enable typeCheck. Value: [ true | false ]. Default: false */ + }, + "logging": { + // "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */ + }, + "debugging": { + // "stacktrace": false /* Disable stacktrace compilation. Value: [ true | false ]. Default: false */ + }, + "nodeOptions": { + // "maxOldSpaceSize": 8192 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process. Default: 8192*/ + // "exposeGC": true /* Enable to trigger garbage collection explicitly. Default: true*/ + } +} diff --git a/Drawing/NDKGraphicsDraw/hvigorfile.ts b/Drawing/NDKGraphicsDraw/hvigorfile.ts new file mode 100644 index 000000000..2a5e543f1 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/hvigorfile.ts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { appTasks } from '@ohos/hvigor-ohos-plugin'; + +export default { + system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins:[] /* Custom plugin to extend the functionality of Hvigor. */ +} diff --git a/Drawing/NDKGraphicsDraw/oh-package.json5 b/Drawing/NDKGraphicsDraw/oh-package.json5 new file mode 100644 index 000000000..e41bae026 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/oh-package.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "modelVersion": "5.0.1", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.19", + "@ohos/hamock": "1.0.0" + } +} diff --git a/Drawing/NDKGraphicsDraw/ohosTest.md b/Drawing/NDKGraphicsDraw/ohosTest.md new file mode 100644 index 000000000..7b49fd8c6 --- /dev/null +++ b/Drawing/NDKGraphicsDraw/ohosTest.md @@ -0,0 +1,14 @@ +# NDKGraphicDraw测试用例归档 + +## 用例表 + +| 测试功能 | 预置条件 | 输入 | 预期输出 | 是否自动 | 测试结果 | +| ---------------------- | ------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------ | -------- | -------- | +| 拉起应用 | 设备正常运行 | | 成功拉起应用 | 是 | Pass | +| 画布获取功能 | 进入“画布的获取与绘制结果的显示”页面 | | 页面显示“获取直接绘图结果”与“获取离屏画布绘图结果” | 是 | Pass | +| 画布操作及状态处理功能 | 进入“画布操作及状态处理”界面 | 依次点击裁剪操作、平移操作、旋转操作、缩放操作、画布状态操作五个按钮 | 在每个按钮点击后,绘制出对应的操作结果图案 | 是 | Pass | +| 基础绘制效果功能 | 进入“基础绘制效果”界面 | 依次点击填充效果、描边效果两个按钮 | 页面显示填充效果图案、描边效果图案 | 是 | Pass | +| 复杂绘制效果功能 | 进入“复杂绘制效果”界面 | 依次点击混合模式、路径效果、线性渐变、径向渐变、扇形渐变、颜色滤波器、图像滤波器、蒙版滤波器八个按钮 | 在每个按钮点击后,绘制出对应的绘制效果图案 | 是 | Pass | +| 几何图形绘制功能 | 进入“几何图形绘制”界面 | 依次点击点、圆弧、圆、路径、区域、矩形、圆角矩形七个按钮 | 在每个按钮点击后,绘制出对应的图案 | 是 | Pass | +| 图片绘制功能 | 进入“图片绘制”界面 | 依次点击绘制图片、编辑中间像素两个按钮 | 先绘制出一幅矩形像素图,而后像素图中间的像素变为黑白色 | 是 | Pass | +| 字块绘制功能 | 进入“字块绘制”界面 | 依次点击基本文字、文字描边、文字渐变三个按钮 | 依次绘制出基本文字图案、描边文字图案和渐变文字图案 | 是 | Pass | \ No newline at end of file diff --git a/Drawing/NDKGraphicsDraw/screenshot/Shape.jpeg b/Drawing/NDKGraphicsDraw/screenshot/Shape.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..9aa3382108acca02184a7681b93cffb66e5461d4 GIT binary patch literal 49108 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±_)`{@jn;#@^pSUHkP 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%0DXk`Oo^k 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 literal 0 HcmV?d00001 diff --git a/Drawing/NDKGraphicsDraw/screenshot/effect.jpeg b/Drawing/NDKGraphicsDraw/screenshot/effect.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..be41d49159d3f4ca9f58a161732faeb3ee877dd3 GIT binary patch literal 51232 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 B%z^*_ literal 0 HcmV?d00001 diff --git a/Drawing/NDKGraphicsDraw/screenshot/index.jpeg b/Drawing/NDKGraphicsDraw/screenshot/index.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..1b85aa811a34c8b9ac67bd5bfcd16ed88d062a20 GIT binary patch literal 39945 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 literal 0 HcmV?d00001 -- Gitee