add drawing sample

Signed-off-by: Yingtong Hu <huyingtong1@huawei.com>
This commit is contained in:
Yingtong Hu 2024-02-29 10:19:29 +08:00
parent ff68785af9
commit 8b854158f2
55 changed files with 2232 additions and 0 deletions

View File

@ -66,6 +66,11 @@ Note: If the text contains special characters, please escape them according to t
<filteritem type="filename" name="icon.png" desc="png for hap"/>
<filteritem type="filename" name="bootpic.zip" desc="bootanimation"/>
<filteritem type="filename" name="cursor.raw" desc="cursor"/>
<filteritem type="filename" name="startIcon.png" desc="app start icon"/>
<filteritem type="filename" name="DrawPath.jpg" desc="sample renderings"/>
<filteritem type="filename" name="Index.jpg" desc="sample renderings"/>
<filteritem type="filename" name="DrawText.jpg" desc="sample renderings"/>
<filteritem type="filename" name="app_icon.png" desc="app icon"/>
</filefilter>
</filefilterlist>
</oatconfig>

View File

@ -0,0 +1,11 @@
/node_modules
/oh_modules
/local.properties
/.idea
**/build
/.hvigor
.cxx
/.clangd
/.clang-format
/.clang-tidy
**/.test

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 2023 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.nativedrawing",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}

View File

@ -0,0 +1,8 @@
{
"string": [
{
"name": "app_name",
"value": "NativeDrawing"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,111 @@
# Native Drawing
### 介绍
本示例中主要介绍开发者在利用Native XComponent来获取NativeWindow实例、获取布局/事件信息、注册事件回调并通过Drawing API实现在页面上绘制形状。功能主要包括点击按钮绘制几何图形颜色文字图片渐变填充描边。
使用说明
1. 安装编译生成的hap包并打开应用。
2. 点击页面底部“Draw Path”按钮页面将绘制路径的描边填充几何图形和图片
3. 点击页面底部“Draw Text”按钮页面将绘制“Hello World”。
### 效果预览
| 主页 | 绘制路径 | 绘制文字 |
| ------------------------------------ |-----------------------------------------------| --------------------------------------------------- |
| ![main](screenshots/device/Index.jpg) | ![Draw Path](screenshots/device/DrawPath.jpg) | ![change color](screenshots/device/DrawText.jpg) |
### 工程目录
```
├──entry/src/main
│ ├──cpp // C++代码区
│ │ ├──CMakeLists.txt // CMake配置文件
│ │ ├──hello.cpp // Napi模块注册
│ │ ├──common
│ │ │ └──log_common.h // 日志封装定义文件
│ │ ├──plugin // 生命周期管理模块
│ │ │ ├──plugin_manager.cpp
│ │ │ └──plugin_manager.h
│ │ ├──samples // samples渲染模块
│ │ │ ├──sample_bitmap.cpp
│ │ │ └──sample_bitmap.h
│ ├──ets // ets代码区
│ │ ├──entryability
│ │ │ ├──EntryAbility.ts // 程序入口类
| | | └──EntryAbility.ets
| | ├──interface
│ │ │ └──XComponentContext.ts // XComponentContext
│ │ └──pages // 页面文件
│ │ └──Index.ets // 主界面
| ├──resources // 资源文件目录
```
### 具体实现
通过在IDE中创建Native c++ 工程在c++代码中定义对外接口为drawPattern和drawText在js侧调用该接口可在页面上绘制出路径样式、图片和“Hello World”文字。
在XComponent的OnSurfaceCreated回调中获取NativeWindow实例并初始化NativeWindow环境。调用OH_NativeXComponent_GetXComponentSize接口获取XComponent的宽高并以此为输入调用Drawing相关的绘制接口在NativeWindow上绘制出图形和文字。
源码参考:[samples目录](entry/src/main/cpp/samples)下的文件。
涉及到的相关接口:
| 接口名 | 描述 |
| -------- | -------- |
| OH_Drawing_BitmapCreate (void) | 创建一个位图对象。 |
| OH_Drawing_BitmapBuild (OH_Drawing_Bitmap *, const uint32_t width, const uint32_t height, const OH_Drawing_BitmapFormat *) | 初始化位图对象的宽度和高度,并且为该位图设置像素格式。 |
| OH_Drawing_CanvasCreate (void) | 创建一个画布对象。 |
| OH_Drawing_CanvasBind (OH_Drawing_Canvas *, OH_Drawing_Bitmap *) | 将一个位图对象绑定到画布中使得画布绘制的内容输出到位图中即CPU渲染。 |
| OH_Drawing_CanvasAttachBrush (OH_Drawing_Canvas *, const OH_Drawing_Brush *) | 设置画刷给画布,画布将会使用设置的画刷样式和颜色去填充绘制的图形形状。 |
| OH_Drawing_CanvasAttachPen (OH_Drawing_Canvas *, const OH_Drawing_Pen *) | 设置画笔给画布,画布将会使用设置画笔的样式和颜色去绘制图形形状的轮廓。 |
| OH_Drawing_CanvasDrawPath (OH_Drawing_Canvas *, const OH_Drawing_Path *) | 画一个自定义路径。 |
| OH_Drawing_PathCreate (void) | 创建一个路径对象。 |
| OH_Drawing_PathMoveTo (OH_Drawing_Path *, float x, float y) | 设置自定义路径的起始点位置。 |
| OH_Drawing_PathLineTo (OH_Drawing_Path *, float x, float y) | 添加一条到目标点的线段。 |
| OH_Drawing_PenCreate (void) | 创建一个画笔对象。 |
| OH_Drawing_PenSetAntiAlias (OH_Drawing_Pen *, bool) | 设置抗锯齿属性,如果为真则说明画笔会启用抗锯齿功能,在绘制图形时会对图形的边缘像素进行半透明的模糊处理。 |
| OH_Drawing_PenSetWidth (OH_Drawing_Pen *, float width) | 设置画笔的厚度属性,厚度属性描述了画笔绘制图形轮廓的宽度。 |
| OH_Drawing_BrushCreate (void) | 创建一个画刷对象。 |
| OH_Drawing_BrushSetColor (OH_Drawing_Brush *, uint32_t color) | 设置画刷的颜色属性颜色属性描述了画刷填充图形时使用的颜色用一个32位ARGB的变量表示。 |
| OH_Drawing_CreateTypographyStyle (void) | 创建一个排版对象,用于定义排版样式。 |
| OH_Drawing_CreateTextStyle (void) | 创建一个文本对象,用于定义文本样式。 |
| OH_Drawing_TypographyHandlerAddText (OH_Drawing_TypographyCreate *, const char *) | 设置文本内容。 |
| OH_Drawing_TypographyPaint (OH_Drawing_Typography *, OH_Drawing_Canvas *, double, double) | 显示文本。 |
| OH_Drawing_CanvasDrawLine (OH_Drawing_Canvas* , float x1, float y1, float x2, float y2 ) | 用于画一条直线段。 |
| OH_Drawing_PointCreate (float x, float y ) | 用于创建一个坐标点对象。 |
| OH_Drawing_CanvasDrawCircle (OH_Drawing_Canvas* , const OH_Drawing_Point* , float radius ) | 用于画一个圆形。 |
| OH_Drawing_PathCubicTo (OH_Drawing_Path* , float ctrlX1, float ctrlY1, float ctrlX2, float ctrlY2, float endX, float endY ) | 用于添加一条从路径最后点位置到目标点位置的三阶贝塞尔圆滑曲线。 |
| OH_Drawing_PathReset (OH_Drawing_Path* ) | 用于重置自定义路径数据。 |
| OH_Drawing_PathQuadTo (OH_Drawing_Path* , float ctrlX, float ctrlY, float endX, float endY ) | 用于添加一条从路径最后点位置到目标点位置的二阶贝塞尔圆滑曲线。 |
| OH_Drawing_CanvasDetachPen (OH_Drawing_Canvas* ) | 用于去除掉画布中的画笔,使用后画布将不去绘制图形形状的轮廓。 |
| OH_Drawing_ShaderEffectCreateLinearGradient (const OH_Drawing_Point* startPt, const OH_Drawing_Point* endPt, const uint32_t* colors, const float* pos, uint32_t size, OH_Drawing_TileMode ) | 创建着色器,在两个指定点之间生成线性渐变。 |
| OH_Drawing_BrushSetShaderEffect (OH_Drawing_Brush* , OH_Drawing_ShaderEffect* ) | 为画刷设置着色器效果。 |
| OH_Drawing_RectCreate (float left, float top, float right, float bottom ) | 用于创建一个矩形对象。 |
| OH_Drawing_RoundRectCreate (const OH_Drawing_Rect* , float xRad, float yRad ) | 用于创建一个圆角矩形对象。 |
| OH_Drawing_PathAddRoundRect (OH_Drawing_Path* , const OH_Drawing_RoundRect* roundRect, OH_Drawing_PathDirection ) | 按指定方向,向路径添加圆角矩形轮廓。 |
| OH_Drawing_ImageCreate (void ) | 创建一个图片对象,描述了要绘制的二维像素数组。 |
| OH_Drawing_ImageBuildFromBitmap (OH_Drawing_Image* , OH_Drawing_Bitmap* ) | 从位图构造图片对象内容,共享或复制位图像素。如果位图被标记为不可变状态, 像素内存是共享的,不是复制。 |
| OH_Drawing_SamplingOptionsCreate (OH_Drawing_FilterMode , OH_Drawing_MipmapMode ) | 创建一个采样选项对象。 |
| OH_Drawing_CanvasDrawImageRect (OH_Drawing_Canvas* , OH_Drawing_Image* , OH_Drawing_Rect* dst, OH_Drawing_SamplingOptions* ) | 将图片绘制到画布的指定区域上。 |
| OH_Drawing_CanvasDetachBrush (OH_Drawing_Canvas* ) | 用于去除掉画布中的画刷,使用后画布将不去填充图形形状。 |
详细的接口说明请参考[Drawing](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis-arkgraphics2d/_drawing.md)。
### 相关权限
不涉及。
### 依赖
XComponent NativeWindow。
### 约束与限制
1. 本示例仅支持标准系统上运行。
2. 本示例为Stage模型已适配API version 10版本SDKSDK版本号(API Version 10 Release),镜像版本号(4.0 Release);
3. 本示例需要使用DevEco Studio 版本号(4.0 Release)及以上版本才可编译运行。

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2023 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": {
"signingConfigs": [],
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": 10,
//指定OpenHarmony应用/服务编译时的版本
"compatibleSdkVersion": 10,
//指定OpenHarmony应用/服务兼容的最低版本。
"targetSdkVersion": 10,
//指定OpenHarmony应用/服务目标版本。若没有设置默认为compatibleSdkVersion
"runtimeOS": "OpenHarmony",
//指定为OpenHarmony
}
],
"buildModeSet": [
{
"name": "debug",
},
{
"name": "release"
}
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}

View File

@ -0,0 +1,6 @@
/node_modules
/oh_modules
/.preview
/build
/.cxx
/.test

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2023 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": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": "",
}
},
"targets": [
{
"name": "default",
},
{
"name": "ohosTest",
}
]
}

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2023 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.
*/
// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
export { hapTasks } from '@ohos/hvigor-ohos-plugin';

View File

@ -0,0 +1,18 @@
# 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://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# 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

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2023 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.
*/
{
"license": "",
"devDependencies": {},
"author": "",
"name": "entry",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dependencies": {
"libentry.so": "file:./src/main/cpp/types/libentry"
}
}

View File

@ -0,0 +1,26 @@
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(drawing_test)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include)
add_library(entry SHARED
hello.cpp
samples/sample_bitmap.cpp
plugin/plugin_manager.cpp
)
find_library(
# Sets the name of the path variable.
hilog-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
hilog_ndk.z
)
target_link_libraries(entry PUBLIC ${hilog-lib})
target_link_libraries(entry PUBLIC libace_napi.z.so)
target_link_libraries(entry PUBLIC libace_ndk.z.so)
target_link_libraries(entry PUBLIC libnative_window.so)
target_link_libraries(entry PUBLIC libnative_drawing.so)

View File

@ -0,0 +1,26 @@
/*
* Copyright (c) 2023 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 <hilog/log.h>
#define LOG_PRINT_DOMAIN 0xFF00
#define APP_LOG_DOMAIN 0x0001
constexpr const char *APP_LOG_TAG = "DrawingSample";
#define DRAWING_LOGI(...) ((void)OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
#define DRAWING_LOGD(...) ((void)OH_LOG_Print(LOG_APP, LOG_DEBUG, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
#define DRAWING_LOGW(...) ((void)OH_LOG_Print(LOG_APP, LOG_WARN, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
#define DRAWING_LOGE(...) ((void)OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, APP_LOG_TAG, __VA_ARGS__))
#endif // LOG_COMMON_H

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2023 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 <hilog/log.h>
#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)
{
DRAWING_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);
}

View File

@ -0,0 +1,116 @@
/*
* Copyright (c) 2023 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 <ace/xcomponent/native_interface_xcomponent.h>
#include <cstdint>
#include <hilog/log.h>
#include <string>
#include "common/log_common.h"
#include "plugin_manager.h"
PluginManager *PluginManager::GetInstance()
{
static PluginManager pluginManager;
return &pluginManager;
}
PluginManager::~PluginManager()
{
DRAWING_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)
{
if ((env == nullptr) || (exports == nullptr)) {
DRAWING_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) {
DRAWING_LOGE("Export: napi_get_named_property fail");
return;
}
OH_NativeXComponent *nativeXComponent = nullptr;
if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
DRAWING_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) {
DRAWING_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 {
DRAWING_LOGE("render is nullptr");
}
}
}
void PluginManager::SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent)
{
DRAWING_LOGI("set native xComponent, ID = %{public}s.", id.c_str());
if (nativeXComponent == nullptr) {
DRAWING_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;
}
}
SampleBitMap *PluginManager::GetRender(std::string &id)
{
if (pluginRenderMap_.find(id) == pluginRenderMap_.end()) {
SampleBitMap *instance = SampleBitMap::GetInstance(id);
pluginRenderMap_[id] = instance;
return instance;
}
return pluginRenderMap_[id];
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2023 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 <ace/xcomponent/native_interface_xcomponent.h>
#include <js_native_api.h>
#include <js_native_api_types.h>
#include <string>
#include <unordered_map>
#include "samples/sample_bitmap.h"
class PluginManager {
public:
~PluginManager();
static PluginManager *GetInstance();
void SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent);
SampleBitMap *GetRender(std::string &id);
void Export(napi_env env, napi_value exports);
private:
std::unordered_map<std::string, OH_NativeXComponent *> nativeXComponentMap_;
std::unordered_map<std::string, SampleBitMap *> pluginRenderMap_;
};
#endif // PLUGIN_MANAGER_H

View File

@ -0,0 +1,563 @@
/*
* Copyright (c) 2023 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 <bits/alltypes.h>
#include <native_drawing/drawing_font_collection.h>
#include <native_drawing/drawing_image.h>
#include <native_drawing/drawing_point.h>
#include <native_drawing/drawing_rect.h>
#include <native_drawing/drawing_round_rect.h>
#include <native_drawing/drawing_sampling_options.h>
#include <native_drawing/drawing_shader_effect.h>
#include <native_drawing/drawing_text_typography.h>
#include "common/log_common.h"
#include "sample_bitmap.h"
static void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window)
{
DRAWING_LOGI("OnSurfaceCreatedCB");
if ((component == nullptr) || (window == nullptr)) {
DRAWING_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) {
DRAWING_LOGE("OnSurfaceCreatedCB: Unable to get XComponent id");
return;
}
std::string id(idStr);
auto render = SampleBitMap::GetInstance(id);
OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(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);
DRAWING_LOGI("xComponent width = %{public}llu, height = %{public}llu", width, height);
}
}
static void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window)
{
DRAWING_LOGI("OnSurfaceDestroyedCB");
if ((component == nullptr) || (window == nullptr)) {
DRAWING_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) {
DRAWING_LOGE("OnSurfaceDestroyedCB: Unable to get XComponent id");
return;
}
std::string id(idStr);
SampleBitMap::Release(id);
}
static std::unordered_map<std::string, SampleBitMap *> g_instance;
void SampleBitMap::SetWidth(uint64_t width)
{
width_ = width;
}
void SampleBitMap::SetHeight(uint64_t height)
{
height_ = height;
}
void SampleBitMap::SetNativeWindow(OHNativeWindow *nativeWindow)
{
nativeWindow_ = nativeWindow;
}
void SampleBitMap::Prepare()
{
if (nativeWindow_ == nullptr) {
DRAWING_LOGE("nativeWindow_ is nullptr");
return;
}
// 这里的nativeWindow是从上一步骤中的回调函数中获得的
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
int ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer_, &fenceFd_);
DRAWING_LOGI("request buffer ret = %{public}d", ret);
// 通过 OH_NativeWindow_GetBufferHandleFromNative 获取 buffer 的 handle
bufferHandle_ = OH_NativeWindow_GetBufferHandleFromNative(buffer_);
// 使用系统mmap接口拿到bufferHandle的内存虚拟地址
mappedAddr_ = static_cast<uint32_t *>(
mmap(bufferHandle_->virAddr, bufferHandle_->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle_->fd, 0));
if (mappedAddr_ == MAP_FAILED) {
DRAWING_LOGE("mmap failed");
}
}
void SampleBitMap::DisPlay()
{
// 画完后获取像素地址,地址指向的内存包含画布画的像素数据
void *bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap_);
uint32_t *value = static_cast<uint32_t *>(bitmapAddr);
uint32_t *pixel = static_cast<uint32_t *>(mappedAddr_); // 使用mmap获取到的地址来访问内存
if (pixel == nullptr) {
DRAWING_LOGE("pixel is null");
return;
}
if (value == nullptr) {
DRAWING_LOGE("value is null");
return;
}
uint32_t width = static_cast<uint32_t>(bufferHandle_->stride / 4);
for (uint32_t x = 0; x < width; x++) {
for (uint32_t y = 0; y < height_; y++) {
*pixel++ = *value++;
}
}
// 设置刷新区域如果Region中的Rect为nullptr,或者rectNumber为0则认为OHNativeWindowBuffer全部有内容更改。
Region region {nullptr, 0};
// 通过OH_NativeWindow_NativeWindowFlushBuffer 提交给消费者使用,例如:显示在屏幕上。
OH_NativeWindow_NativeWindowFlushBuffer(nativeWindow_, buffer_, fenceFd_, region);
// 内存使用完记得去掉内存映射
int result = munmap(mappedAddr_, bufferHandle_->size);
if (result == -1) {
DRAWING_LOGE("munmap failed!");
}
}
void SampleBitMap::Create()
{
uint32_t width = static_cast<uint32_t>(bufferHandle_->stride / 4);
// 创建一个bitmap对象
cBitmap_ = OH_Drawing_BitmapCreate();
// 定义bitmap的像素格式
OH_Drawing_BitmapFormat cFormat {COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
// 构造对应格式的bitmap
OH_Drawing_BitmapBuild(cBitmap_, width, height_, &cFormat);
// 创建一个canvas对象
cCanvas_ = OH_Drawing_CanvasCreate();
// 将画布与bitmap绑定画布画的内容会输出到绑定的bitmap内存中
OH_Drawing_CanvasBind(cCanvas_, cBitmap_);
// 使用白色清除画布内容
OH_Drawing_CanvasClear(cCanvas_, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
}
void SampleBitMap::DrawPathHelper()
{
// 创建一个画刷Brush对象Brush对象用于形状的填充
cBrush_ = OH_Drawing_BrushCreate();
float startX = width_ / 5; // divide w by 5 to get start x
int distance = 50; // distance between earch point
float startY = height_ / 4 + 2 * distance; // divide h by 4 and 2 times the distance to get start y
startPt_ = OH_Drawing_PointCreate(startX, startY);
float endX = width_ / 2; // divide w by 2 to get end x
float endY = height_ / 4 + 6 * distance; // divide h by 4 and 6 times the distance to get end y
endPt_ = OH_Drawing_PointCreate(endX, endY);
uint32_t color[] = {0xffff0000, 0xff00ff00};
float pos[] = {0., 1.0};
// 创建并设置Brush的渐变效果
uint32_t size = 2; // shader size 2
shaderEffect_ =
OH_Drawing_ShaderEffectCreateLinearGradient(startPt_, endPt_, color, pos, size, OH_Drawing_TileMode::CLAMP);
OH_Drawing_BrushSetShaderEffect(cBrush_, shaderEffect_);
// 将Brush画刷设置到canvas中
OH_Drawing_CanvasAttachBrush(cCanvas_, cBrush_);
// 绘制圆角矩形
int x1 = 50; // x-axis point 1 50
float rectY1 = height_ / 4 + 2 * distance; // divide h by 4 and 2 times the distance to get rect y1
float rectY2 = height_ / 4 + 6 * distance; // divide h by 4 and 6 times the distance to get rect y2
cRect_ = OH_Drawing_RectCreate(x1, rectY1, distance + width_ / 3, rectY2); // divide w by 3 to get rect x2
int angle = 20; // round rect angle 20
cRRect_ = OH_Drawing_RoundRectCreate(cRect_, angle, angle);
OH_Drawing_PathReset(cPath_);
OH_Drawing_PathAddRoundRect(cPath_, cRRect_, PATH_DIRECTION_CW);
OH_Drawing_CanvasDrawPath(cCanvas_, cPath_);
// 绘制黑色背景图片
rectY1 = height_ / 2 + 2 * distance; // divide h by 2 and 2 times the distance to get rect y1
rectY2 = height_ / 2 + 6 * distance; // divide h by 2 and 6 times the distance to get rect y2
cRect2_ = OH_Drawing_RectCreate(x1, rectY1, distance + width_ / 3, rectY2); // divide w by 3 to get rect x2
cImage_ = OH_Drawing_ImageCreate();
cBitmap2_ = OH_Drawing_BitmapCreate();
OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
int imageY = 200; // image Y point 200
OH_Drawing_BitmapBuild(cBitmap2_, width_ / 3, imageY, &cFormat); // divide w by 3 to get image x
OH_Drawing_ImageBuildFromBitmap(cImage_, cBitmap2_);
cOptions_ = OH_Drawing_SamplingOptionsCreate(OH_Drawing_FilterMode::FILTER_MODE_NEAREST,
OH_Drawing_MipmapMode::MIPMAP_MODE_NEAREST);
OH_Drawing_CanvasDrawImageRect(cCanvas_, cImage_, cRect2_, cOptions_);
}
void SampleBitMap::DrawPath()
{
constexpr float penWidth = 10.0f; // pen width 10
// 创建一个画笔Pen对象Pen对象用于形状的边框线绘制
cPen_ = OH_Drawing_PenCreate();
OH_Drawing_PenSetAntiAlias(cPen_, true);
OH_Drawing_PenSetColor(cPen_, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xA5, 0x00));
OH_Drawing_PenSetWidth(cPen_, penWidth);
OH_Drawing_PenSetJoin(cPen_, LINE_ROUND_JOIN);
// 将Pen画笔设置到canvas中
OH_Drawing_CanvasAttachPen(cCanvas_, cPen_);
// 绘制直线
int x1 = 50; // x-axis point 1 50
int lineLen = 50; // line length 50
float y1 = height_ / 10; // divide h by 10 to get y-axis point 1
float x2 = width_ / 4; // divide w by 4 to get x-axis point 2
OH_Drawing_CanvasDrawLine(cCanvas_, x1, y1, x2 + lineLen, y1);
OH_Drawing_CanvasDrawLine(cCanvas_, x2 + lineLen, y1, x1, y1 + lineLen);
// 绘制圆形
float centerX = width_ / 2; // divide w by 2 to get x-axis of center of the circle
float centerY = height_ / 10; // divide h by 10 to get y-axis of center of the circle
cCenter_ = OH_Drawing_PointCreate(centerX, centerY);
float radius = width_ / 8; // divide w by 8 to get radius of the circle
OH_Drawing_CanvasDrawCircle(cCanvas_, cCenter_, radius);
// 绘制三阶贝塞尔圆滑曲线
cPath_ = OH_Drawing_PathCreate();
float startX = width_ / 4 * 3; // get 3 out of 4 width to get start x1
float startY = height_ / 15; // divide h by 15 to get start y1
OH_Drawing_PathMoveTo(cPath_, startX, startY);
int distance = 50; // distance between earch point
float ctrlX1 = startX + distance;
float ctrlY1 = startY - distance;
float ctrlX2 = startX + 2 * distance; // 2 means twice the distance
float ctrlY2 = startY + distance;
float endX = startX + 3 * distance; // 3 means three times the distance
float endY = startY;
OH_Drawing_PathCubicTo(cPath_, ctrlX1, ctrlY1, ctrlX2, ctrlY2, endX, endY);
OH_Drawing_CanvasDrawPath(cCanvas_, cPath_);
// 绘制二阶贝塞尔圆滑曲线
OH_Drawing_PathReset(cPath_);
startY = height_ / 10; // divide h by 10 to get start y1
OH_Drawing_PathMoveTo(cPath_, startX, startY);
ctrlX1 = startX + distance;
ctrlY1 = startY * 2; // 2 means twice the start y1
endX = startX + 2 * distance; // 2 means twice the distance
endY = startY;
OH_Drawing_PathQuadTo(cPath_, ctrlX1, ctrlY1, endX, endY);
OH_Drawing_CanvasDrawPath(cCanvas_, cPath_);
// 取消描边
OH_Drawing_CanvasDetachPen(cCanvas_);
this->DrawPathHelper();
}
void SampleBitMap::DrawTextInPath()
{
// 取消描边和填充
OH_Drawing_CanvasDetachPen(cCanvas_);
OH_Drawing_CanvasDetachBrush(cCanvas_);
// 选择从左到右/左对齐等排版属性
OH_Drawing_TypographyStyle *typoStyle = OH_Drawing_CreateTypographyStyle();
OH_Drawing_SetTypographyTextDirection(typoStyle, TEXT_DIRECTION_LTR);
OH_Drawing_SetTypographyTextAlign(typoStyle, TEXT_ALIGN_JUSTIFY);
// TEXT_ALIGN_JUSTIFY
// 设置文字颜色,例如黑色
OH_Drawing_TextStyle *txtStyle = OH_Drawing_CreateTextStyle();
OH_Drawing_SetTextStyleColor(txtStyle, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));
// 设置文字大小、字重等属性
double fontSize = width_ / 25;
OH_Drawing_SetTextStyleFontSize(txtStyle, fontSize);
OH_Drawing_SetTextStyleFontWeight(txtStyle, FONT_WEIGHT_400);
OH_Drawing_SetTextStyleBaseLine(txtStyle, TEXT_BASELINE_ALPHABETIC);
OH_Drawing_SetTextStyleFontHeight(txtStyle, 1);
// 设置字体类型等
const char *fontFamilies[] = {"Roboto"};
OH_Drawing_SetTextStyleFontFamilies(txtStyle, 1, fontFamilies);
OH_Drawing_SetTextStyleFontStyle(txtStyle, FONT_STYLE_NORMAL);
OH_Drawing_SetTextStyleLocale(txtStyle, "zh");
OH_Drawing_TypographyCreate *handler =
OH_Drawing_CreateTypographyHandler(typoStyle, OH_Drawing_CreateFontCollection());
OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle);
// 设置文字内容
const char *text = "路径描边\n";
OH_Drawing_TypographyHandlerAddText(handler, text);
OH_Drawing_TypographyHandlerPopTextStyle(handler);
OH_Drawing_Typography *typography = OH_Drawing_CreateTypography(handler);
// 设置页面最大宽度
double maxWidth = width_;
OH_Drawing_TypographyLayout(typography, maxWidth);
// 设置文本在画布上绘制的起始位置
double position[2] = {10, 10};
// 将文本绘制到画布上
OH_Drawing_TypographyPaint(typography, cCanvas_, position[0], position[1]);
OH_Drawing_TypographyCreate *handler1 =
OH_Drawing_CreateTypographyHandler(typoStyle, OH_Drawing_CreateFontCollection());
OH_Drawing_TypographyHandlerPushTextStyle(handler1, txtStyle);
// 设置文字内容
const char *text1 = "路径填充\n";
OH_Drawing_TypographyHandlerAddText(handler1, text1);
OH_Drawing_TypographyHandlerPopTextStyle(handler1);
OH_Drawing_Typography *typography1 = OH_Drawing_CreateTypography(handler1);
// 设置页面最大宽度
OH_Drawing_TypographyLayout(typography1, width_);
// 将文本绘制到画布上
int x1 = 10; // x1 10
int y1 = height_ / 4; // divide h by 4 to get y1
OH_Drawing_TypographyPaint(typography1, cCanvas_, x1, y1);
OH_Drawing_TypographyCreate *handler2 =
OH_Drawing_CreateTypographyHandler(typoStyle, OH_Drawing_CreateFontCollection());
OH_Drawing_TypographyHandlerPushTextStyle(handler2, txtStyle);
// 设置文字内容
const char *text2 = "绘制图片\n";
OH_Drawing_TypographyHandlerAddText(handler2, text2);
OH_Drawing_TypographyHandlerPopTextStyle(handler2);
OH_Drawing_Typography *typography2 = OH_Drawing_CreateTypography(handler2);
// 设置页面最大宽度
OH_Drawing_TypographyLayout(typography2, width_);
// 将文本绘制到画布上
y1 = height_ / 2; // divide h by 2 to get y1
OH_Drawing_TypographyPaint(typography2, cCanvas_, x1, y1);
}
void SampleBitMap::DrawText()
{
constexpr float penWidth = 5.0f; // pen width 5
// 创建一个画笔Pen对象Pen对象用于形状的边框线绘制
cPen_ = OH_Drawing_PenCreate();
OH_Drawing_PenSetAntiAlias(cPen_, true);
OH_Drawing_PenSetColor(cPen_, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0x00, 0x00));
OH_Drawing_PenSetWidth(cPen_, penWidth);
OH_Drawing_PenSetJoin(cPen_, LINE_ROUND_JOIN);
// 将Pen画笔设置到canvas中
OH_Drawing_CanvasAttachPen(cCanvas_, cPen_);
// 选择从左到右/左对齐等排版属性
OH_Drawing_TypographyStyle *typoStyle = OH_Drawing_CreateTypographyStyle();
OH_Drawing_SetTypographyTextDirection(typoStyle, TEXT_DIRECTION_LTR);
OH_Drawing_SetTypographyTextAlign(typoStyle, TEXT_ALIGN_JUSTIFY);
// TEXT_ALIGN_JUSTIFY
// 设置文字颜色,例如黑色
OH_Drawing_TextStyle *txtStyle = OH_Drawing_CreateTextStyle();
OH_Drawing_SetTextStyleColor(txtStyle, OH_Drawing_ColorSetArgb(0xFF, 0x66, 0x00, 0x00));
// 设置文字大小、字重等属性
double fontSize = width_ / 5;
OH_Drawing_SetTextStyleFontSize(txtStyle, fontSize);
OH_Drawing_SetTextStyleFontWeight(txtStyle, FONT_WEIGHT_400);
OH_Drawing_SetTextStyleBaseLine(txtStyle, TEXT_BASELINE_ALPHABETIC);
OH_Drawing_SetTextStyleFontHeight(txtStyle, 1);
// 设置字体类型等
const char *fontFamilies[] = {"Roboto"};
OH_Drawing_SetTextStyleFontFamilies(txtStyle, 1, fontFamilies);
OH_Drawing_SetTextStyleFontStyle(txtStyle, FONT_STYLE_NORMAL);
OH_Drawing_SetTextStyleLocale(txtStyle, "en");
OH_Drawing_TypographyCreate *handler =
OH_Drawing_CreateTypographyHandler(typoStyle, OH_Drawing_CreateFontCollection());
OH_Drawing_TypographyHandlerPushTextStyle(handler, txtStyle);
// 设置文字内容
const char *text = "Hello World\n";
OH_Drawing_TypographyHandlerAddText(handler, text);
OH_Drawing_TypographyHandlerPopTextStyle(handler);
OH_Drawing_Typography *typography = OH_Drawing_CreateTypography(handler);
// 设置页面最大宽度
double maxWidth = width_;
OH_Drawing_TypographyLayout(typography, maxWidth);
// 设置文本在画布上绘制的起始位置
double position[2] = {width_ / 5.0, height_ / 2.0};
// 将文本绘制到画布上
OH_Drawing_TypographyPaint(typography, cCanvas_, position[0], position[1]);
}
napi_value SampleBitMap::NapiDrawPattern(napi_env env, napi_callback_info info)
{
DRAWING_LOGI("NapiDrawPattern");
if ((env == nullptr) || (info == nullptr)) {
DRAWING_LOGE("NapiDrawPattern: env or info is null");
return nullptr;
}
napi_value thisArg;
if (napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr) != napi_ok) {
DRAWING_LOGE("NapiDrawPattern: napi_get_cb_info fail");
return nullptr;
}
napi_value exportInstance;
if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
DRAWING_LOGE("NapiDrawPattern: napi_get_named_property fail");
return nullptr;
}
OH_NativeXComponent *nativeXComponent = nullptr;
if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
DRAWING_LOGE("NapiDrawPattern: 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) {
DRAWING_LOGE("NapiDrawPattern: Unable to get XComponent id");
return nullptr;
}
DRAWING_LOGI("ID = %{public}s", idStr);
std::string id(idStr);
SampleBitMap *render = SampleBitMap().GetInstance(id);
if (render != nullptr) {
render->Prepare();
render->Create();
render->DrawPath();
render->DrawTextInPath();
render->DisPlay();
DRAWING_LOGI("DrawPath executed");
} else {
DRAWING_LOGE("render is nullptr");
}
return nullptr;
}
napi_value SampleBitMap::NapiDrawText(napi_env env, napi_callback_info info)
{
DRAWING_LOGI("NapiDrawText");
if ((env == nullptr) || (info == nullptr)) {
DRAWING_LOGE("NapiDrawPattern: env or info is null");
return nullptr;
}
napi_value thisArg;
if (napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr) != napi_ok) {
DRAWING_LOGE("NapiDrawPattern: napi_get_cb_info fail");
return nullptr;
}
napi_value exportInstance;
if (napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) {
DRAWING_LOGE("NapiDrawPattern: napi_get_named_property fail");
return nullptr;
}
OH_NativeXComponent *nativeXComponent = nullptr;
if (napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent)) != napi_ok) {
DRAWING_LOGE("NapiDrawPattern: 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) {
DRAWING_LOGE("NapiDrawPattern: Unable to get XComponent id");
return nullptr;
}
DRAWING_LOGI("ID = %{public}s", idStr);
std::string id(idStr);
SampleBitMap *render = SampleBitMap().GetInstance(id);
if (render != nullptr) {
render->Prepare();
render->Create();
render->DrawText();
render->DisPlay();
DRAWING_LOGI("DrawText executed");
} else {
DRAWING_LOGE("render is nullptr");
}
return nullptr;
}
SampleBitMap::~SampleBitMap()
{
// 销毁创建的对象
OH_Drawing_BrushDestroy(cBrush_);
cBrush_ = nullptr;
OH_Drawing_PenDestroy(cPen_);
cPen_ = nullptr;
OH_Drawing_PathDestroy(cPath_);
cPath_ = nullptr;
// 销毁canvas对象
OH_Drawing_CanvasDestroy(cCanvas_);
cCanvas_ = nullptr;
// 销毁bitmap对象
OH_Drawing_BitmapDestroy(cBitmap_);
cBitmap_ = nullptr;
OH_Drawing_BitmapDestroy(cBitmap2_);
cBitmap2_ = nullptr;
OH_Drawing_RectDestroy(cRect_);
cRect_ = nullptr;
OH_Drawing_RectDestroy(cRect2_);
cRect2_ = nullptr;
OH_Drawing_ShaderEffectDestroy(shaderEffect_);
shaderEffect_ = nullptr;
OH_Drawing_PointDestroy(startPt_);
startPt_ = nullptr;
OH_Drawing_PointDestroy(endPt_);
endPt_ = nullptr;
OH_Drawing_PointDestroy(cCenter_);
cCenter_ = nullptr;
OH_Drawing_ImageDestroy(cImage_);
cImage_ = nullptr;
OH_Drawing_SamplingOptionsDestroy(cOptions_);
cOptions_ = nullptr;
OH_Drawing_RoundRectDestroy(cRRect_);
cRRect_ = nullptr;
buffer_ = nullptr;
bufferHandle_ = nullptr;
nativeWindow_ = nullptr;
mappedAddr_ = nullptr;
}
void SampleBitMap::Release(std::string &id)
{
SampleBitMap *render = SampleBitMap::GetInstance(id);
if (render != nullptr) {
delete render;
render = nullptr;
g_instance.erase(g_instance.find(id));
}
}
void SampleBitMap::Export(napi_env env, napi_value exports)
{
if ((env == nullptr) || (exports == nullptr)) {
DRAWING_LOGE("Export: env or exports is null");
return;
}
napi_property_descriptor desc[] = {
{"drawPattern", nullptr, SampleBitMap::NapiDrawPattern, nullptr, nullptr, nullptr, napi_default, nullptr},
{"drawText", nullptr, SampleBitMap::NapiDrawText, 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) {
DRAWING_LOGE("Export: napi_define_properties failed");
}
}
void SampleBitMap::RegisterCallback(OH_NativeXComponent *nativeXComponent)
{
DRAWING_LOGI("register callback");
renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
// Callback must be initialized
renderCallback_.DispatchTouchEvent = nullptr;
renderCallback_.OnSurfaceChanged = nullptr;
OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback_);
}
SampleBitMap *SampleBitMap::GetInstance(std::string &id)
{
if (g_instance.find(id) == g_instance.end()) {
SampleBitMap *render = new SampleBitMap(id);
g_instance[id] = render;
return render;
} else {
return g_instance[id];
}
}

View File

@ -0,0 +1,85 @@
/*
* Copyright (c) 2023 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_BITMAP_H
#define SAMPLE_BITMAP_H
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <arpa/nameser.h>
#include <bits/alltypes.h>
#include <native_window/external_window.h>
#include <native_drawing/drawing_bitmap.h>
#include <native_drawing/drawing_color.h>
#include <native_drawing/drawing_canvas.h>
#include <native_drawing/drawing_pen.h>
#include <native_drawing/drawing_brush.h>
#include <native_drawing/drawing_path.h>
#include <cstdint>
#include <map>
#include <sys/mman.h>
#include <string>
#include "napi/native_api.h"
class SampleBitMap {
public:
SampleBitMap() = default;
~SampleBitMap();
explicit SampleBitMap(std::string id) : id_(id) {}
static napi_value NapiDrawPattern(napi_env env, napi_callback_info info);
static napi_value NapiDrawText(napi_env env, napi_callback_info info);
static void Release(std::string &id);
void DrawTextInPath();
void DrawText();
void SetWidth(uint64_t width);
void SetHeight(uint64_t height);
void SetNativeWindow(OHNativeWindow *nativeWindow);
void Prepare();
void Create();
void DisPlay();
void DrawPath();
void DrawPathHelper();
void Export(napi_env env, napi_value exports);
void RegisterCallback(OH_NativeXComponent *nativeXComponent);
static SampleBitMap *GetInstance(std::string &id);
std::string id_;
private:
OH_NativeXComponent_Callback renderCallback_;
uint64_t width_ = 0;
uint64_t height_ = 0;
OH_Drawing_Bitmap *cBitmap_ = nullptr;
OH_Drawing_Canvas *cCanvas_ = nullptr;
OH_Drawing_Path *cPath_ = nullptr;
OH_Drawing_Brush *cBrush_ = nullptr;
OH_Drawing_Pen *cPen_ = nullptr;
OHNativeWindow *nativeWindow_ = nullptr;
uint32_t *mappedAddr_ = nullptr;
BufferHandle *bufferHandle_ = nullptr;
struct NativeWindowBuffer *buffer_ = nullptr;
int fenceFd_ = 0;
OH_Drawing_ShaderEffect *shaderEffect_ = nullptr;
OH_Drawing_Rect *cRect_ = nullptr;
OH_Drawing_Point *startPt_ = nullptr;
OH_Drawing_Point *endPt_ = nullptr;
OH_Drawing_Rect *cRect2_ = nullptr;
OH_Drawing_Image *cImage_ = nullptr;
OH_Drawing_Bitmap *cBitmap2_ = nullptr;
OH_Drawing_SamplingOptions *cOptions_ = nullptr;
OH_Drawing_Point *cCenter_ = nullptr;
OH_Drawing_RoundRect *cRRect_ = nullptr;
};
#endif

View File

@ -0,0 +1,14 @@
/*
* Copyright (c) 2023 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.
*/

View File

@ -0,0 +1,21 @@
/*
* Copyright (c) 2023 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": "",
"description": "Please describe the basic information."
}

View File

@ -0,0 +1,58 @@
/*
* Copyright (c) 2023 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 from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
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, data) => {
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. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
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');
}
};

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2023 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 UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => {
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. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground() {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground() {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
};

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2023 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 {
drawPattern(): void;
drawText(): void;
};

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2023 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";
const TAG = '[Sample_DrawingAPI]';
@Entry
@Component
struct Index {
private xComponentContext: XComponentContext | undefined = undefined;
build() {
Column() {
Row() {
XComponent({ id: 'xcomponentId', type: 'surface', libraryname: 'entry' })
.onLoad((xComponentContext) => {
this.xComponentContext = xComponentContext as XComponentContext;
}).width('100%') // Multiples of 64
}.height('100%')
Row() {
Button('Draw Path')
.fontSize('16fp')
.fontWeight(500)
.margin({ bottom: 24, right: 12 })
.onClick(() => {
console.log(TAG, "Draw Path click");
if (this.xComponentContext) {
console.log(TAG, "Draw Path");
this.xComponentContext.drawPattern();
}
})
.width('33.6%')
.height(40)
.shadow(ShadowStyle.OUTER_DEFAULT_LG)
Button('Draw Text')
.fontSize('16fp')
.fontWeight(500)
.margin({ bottom: 24, left: 12 })
.onClick(() => {
console.log(TAG, "draw text click");
if (this.xComponentContext) {
console.log(TAG, "draw text");
this.xComponentContext.drawText();
}
})
.width('33.6%')
.height(40)
.shadow(ShadowStyle.OUTER_DEFAULT_LG)
}
.width('100%')
.justifyContent(FlexAlign.Center)
.shadow(ShadowStyle.OUTER_DEFAULT_SM)
.alignItems(VerticalAlign.Bottom)
.layoutWeight(1)
}
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2023 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:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}

View File

@ -0,0 +1,8 @@
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -0,0 +1,5 @@
{
"src": [
"pages/Index"
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "module description"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_desc",
"value": "模块描述"
},
{
"name": "EntryAbility_desc",
"value": "description"
},
{
"name": "EntryAbility_label",
"value": "label"
}
]
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (c) 2023 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 AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import { describe, it, expect } from '@ohos/hypium';
import { Driver, ON } from '@ohos.UiTest';
const TAG = '[Sample_DrawingAPI]';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
/**
* 打开应用
*/
it('StartAbility_001', 0, async (done: Function) => {
console.info(TAG, 'StartAbility_001 begin');
let driver = Driver.create();
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
try {
await abilityDelegator.startAbility({
bundleName: 'com.samples.nativedrawing',
abilityName: 'EntryAbility'
});
} catch (exception) {
console.info(TAG, `StartAbility_001 exception = ${JSON.stringify(exception)}`);
expect().assertFail();
}
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('Draw Path'));
done();
console.info(TAG, 'StartAbility_001 end');
})
/**
* 点击按钮,绘制图形
*/
it('DrawPath_001', 2, async () => {
console.info(TAG, 'DrawPath_001 begin');
let driver = Driver.create();
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
try {
await abilityDelegator.startAbility({
bundleName: 'com.samples.nativedrawing',
abilityName: 'EntryAbility'
});
} catch (exception) {
console.info(TAG, `DrawPath_001 exception = ${JSON.stringify(exception)}`);
expect().assertFail();
}
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('Draw Path'));
let drawPathBtn = await driver.findComponent(ON.text('Draw Path'));
// 点击'Draw Path'按钮
await drawPathBtn.click();
await driver.delayMs(1000);
console.info(TAG, 'DrawPath_001 end');
})
})
}

View File

@ -0,0 +1,20 @@
/*
* Copyright (c) 2023 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 './DrawingAbility.test';
export default function testsuite() {
abilityTest();
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (c) 2023 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 UIAbility from '@ohos.app.ability.UIAbility';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import hilog from '@ohos.hilog';
import { Hypium } from '@ohos/hypium';
import testsuite from '../test/List.test';
import window from '@ohos.window';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
export default class TestAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator;
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs;
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
windowStage.loadContent('testability/pages/Index', (err, data) => {
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. Data: %{public}s',
JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
}
onForeground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
}
onBackground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
}
}

View File

@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 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.
*/
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2023 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';
import TestRunner from '@ohos.application.testRunner';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import Want from '@ohos.app.ability.Want';
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator | undefined = undefined
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs | undefined = undefined
async function onAbilityCreateCallback() {
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
}
async function addAbilityMonitorCallback(err : Error) {
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
}
export default class OpenHarmonyTestRunner implements TestRunner {
constructor() {
}
onPrepare() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
}
async onRun() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
const bundleName = abilityDelegatorArguments.bundleName;
const testAbilityName = 'TestAbility';
let lMonitor: AbilityDelegatorRegistry.AbilityMonitor = {
abilityName: testAbilityName,
onAbilityCreate: onAbilityCreateCallback,
};
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
const want: Want = {
bundleName: bundleName,
abilityName: testAbilityName
};
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
abilityDelegator.startAbility(want, (err, data) => {
hilog.info(0x0000, 'testTag', 'startAbility : err : %{public}s', JSON.stringify(err) ?? '');
hilog.info(0x0000, 'testTag', 'startAbility : data : %{public}s',JSON.stringify(data) ?? '');
})
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
}
}

View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2023 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';
import TestRunner from '@ohos.application.testRunner';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
var abilityDelegator = undefined
var abilityDelegatorArguments = undefined
async function onAbilityCreateCallback() {
hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback');
}
async function addAbilityMonitorCallback(err: any) {
hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? '');
}
export default class OpenHarmonyTestRunner implements TestRunner {
constructor() {
}
onPrepare() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare ');
}
async onRun() {
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run');
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility'
let lMonitor = {
abilityName: testAbilityName,
onAbilityCreate: onAbilityCreateCallback,
};
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName
var debug = abilityDelegatorArguments.parameters['-D']
if (debug == 'true')
{
cmd += ' -D'
}
hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd);
abilityDelegator.executeShellCommand(cmd,
(err: any, d: any) => {
hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? '');
hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? '');
hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? '');
})
hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end');
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2023 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",
"description": "$string:module_test_desc",
"mainElement": "TestAbility",
"deviceTypes": [
"default",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:test_pages",
"abilities": [
{
"name": "TestAbility",
"srcEntry": "./ets/testability/TestAbility.ets",
"description": "$string:TestAbility_desc",
"icon": "$media:icon",
"label": "$string:TestAbility_label",
"exported": true,
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"skills": [
{
"actions": [
"action.system.home"
],
"entities": [
"entity.system.home"
]
}
]
}
]
}
}

View File

@ -0,0 +1,8 @@
{
"color": [
{
"name": "start_window_background",
"value": "#FFFFFF"
}
]
}

View File

@ -0,0 +1,16 @@
{
"string": [
{
"name": "module_test_desc",
"value": "test ability description"
},
{
"name": "TestAbility_desc",
"value": "the test ability"
},
{
"name": "TestAbility_label",
"value": "test label"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -0,0 +1,5 @@
{
"src": [
"testability/pages/Index"
]
}

View File

@ -0,0 +1,33 @@
/*
* Copyright (c) 2023 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.
*/
{
"hvigorVersion": "3.0.2",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "3.0.2"
},
"execution": {
// "daemon": true, /* Enable daemon compilation. Default: true */
// "incremental": true, /* Enable incremental compilation. Default: true */
// "parallel": true, /* Enable parallel compilation. Default: true */
// "typeCheck": false, /* Enable typeCheck. Default: false */
},
"logging": {
// "level": "info" /* Define the log level. Value: [ "debug" | "info" | "warn" | "error" ]. Default: "info" */
},
"debugging": {
// "stacktrace": false /* Disable stacktrace compilation. Default: false */
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,17 @@
/*
* Copyright (c) 2023 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.
*/
// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
export { appTasks } from '@ohos/hvigor-ohos-plugin';

View File

@ -0,0 +1,61 @@
# Copyright (c) 2023 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.
#!/bin/bash
# ----------------------------------------------------------------------------
# Hvigor startup script, version 1.0.0
#
# Required ENV vars:
# ------------------
# NODE_HOME - location of a Node home dir
# or
# Add /usr/local/nodejs/bin to the PATH environment variable
# ----------------------------------------------------------------------------
HVIGOR_APP_HOME=$(dirname $(readlink -f $0))
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
warn() {
echo ""
echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
}
error() {
echo ""
echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m"
}
fail() {
error "$@"
exit 1
}
# Determine node to start hvigor wrapper script
if [ -n "${NODE_HOME}" ];then
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
if [ ! -x "$EXECUTABLE_NODE" ];then
fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed"
fi
else
EXECUTABLE_NODE="node"
which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path"
fi
# Check hvigor wrapper script
if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then
fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}"
fi
# start hvigor-wrapper script
exec "${EXECUTABLE_NODE}" \
"${HVIGOR_WRAPPER_SCRIPT}" "$@"

View File

@ -0,0 +1,77 @@
@rem Copyright (c) 2023 Huawei Device Co., Ltd.
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem http://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Hvigor startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
set NODE_EXE=node.exe
goto start
:start
@rem Find node.exe
if defined NODE_HOME goto findNodeFromNodeHome
%NODE_EXE% --version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
echo.
echo Please set the NODE_HOME variable in your environment to match the
echo location of your NodeJs installation.
goto fail
:findNodeFromNodeHome
set NODE_HOME=%NODE_HOME:"=%
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
if exist "%NODE_EXE_PATH%" goto execute
echo.
echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH.
echo.
echo Please set the NODE_HOME variable in your environment to match the
echo location of your NodeJs installation.
goto fail
:execute
@rem Execute hvigor
"%NODE_EXE%" %WRAPPER_MODULE_PATH% %*
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
:fail
exit /b 1
:hvigorwEnd
if "%OS%" == "Windows_NT" endlocal
:end

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2023 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.
*/
{
"lockfileVersion": 1,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6"
},
"packages": {
"@ohos/hypium@1.0.6": {
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz",
"integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ=="
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2023 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.
*/
{
"license": "",
"devDependencies": {
"@ohos/hypium": "1.0.6"
},
"author": "",
"name": "drawing",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dependencies": {}
}

View File

@ -0,0 +1,8 @@
# PathDrawingSample 测试用例归档
## 用例表
|测试功能|预置条件|输入|预期输出|是否自动|测试结果|
|--------------------------------|--------------------------------|--------------------------------|--------------------------------|--------------------------------|--------------------------------|
| 拉起应用 | 设备正常运行 | |成功拉起应用|是| Pass |
| 绘制图形 | 位于首页 | 1、点击**Draw Path** | 1、页面显示路径描边、填充和图片 | 是 | Pass |

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB