[sample] Drawing新增CRenderNode Sample

Signed-off-by: l00844999 <lizhan12@huawei.com>
This commit is contained in:
l00844999 2024-04-08 10:08:58 +08:00
parent cd4421d6e8
commit 17150cee2f
76 changed files with 925 additions and 1530 deletions

View File

@ -172,6 +172,14 @@ Note:If the text contains special characters, please escape them according to th
<filteritem type="filepath" name="code/BasicFeature/Native/NdkDrawing/screenshots/device/Index.jpg" desc="Provided by code/BasicFeature/Native/NdkDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkDrawing/screenshots/device/DrawPath.jpg" desc="Provided by code/BasicFeature/Native/NdkDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkDrawing/screenshots/device/DrawText.jpg" desc="Provided by code/BasicFeature/Native/NdkDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/screenshots/Index.jpeg" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/screenshots/DrawPath.jpeg" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/screenshots/DrawRect.jpeg" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/screenshots/DrawText.jpeg" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/entry/src/ohosTest/resources/base/media/icon.png" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/entry/src/main/resources/base/media/icon.png" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/entry/src/main/resources/base/media/startIcon.png" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkRenderNodeDrawing/AppScope/resources/base/media/app_icon.png" desc="Provided by code/BasicFeature/Native/NdkRenderNodeDrawing"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkNativeWindow/screenshots/device/ChangeColor.jpg" desc="Provided by code/BasicFeature/Native/NdkNativeWindow"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkNativeWindow/screenshots/device/GetAvailableCount.jpg" desc="Provided by code/BasicFeature/Native/NdkNativeWindow"/>
<filteritem type="filepath" name="code/BasicFeature/Native/NdkNativeWindow/screenshots/device/Main.jpg" desc="Provided by code/BasicFeature/Native/NdkNativeWindow"/>

View File

@ -245,7 +245,7 @@
<tr height="18" style='height:13.50pt;'>
<td x:str><a href="code/BasicFeature/Native/NdkNativeWindow">Native Window</a></td>
<td x:str><a href="code/BasicFeature/Native/XComponent3D">XComponent3D</a></td>
<td ></td>
<td x:str><a href="code/BasicFeature/Native/NdkRenderNodeDrawing">Native RenderNode Drawing</a></td>
<td ></td>
<td ></td>
</tr>

View File

@ -8,4 +8,5 @@
/.clangd
/.clang-format
/.clang-tidy
**/.test
**/.test
oh-package-lock.json5

View File

@ -1,10 +1,10 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
* 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,
@ -15,7 +15,7 @@
{
"app": {
"bundleName": "com.samples.nativedrawing",
"bundleName": "com.samples.ndknodedrawing",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",

View File

@ -0,0 +1,106 @@
# Native RenderNode Drawing
### 介绍
本示例中主要介绍开发者在利用自绘制渲染节点RenderNode通过Drawing API实现在页面上完成自定义绘制需求。功能主要包括点击按钮绘制一个五角星一个矩形和“Hello World Drawing”文字。
使用说明
1. 安装编译生成的hap包并打开应用。
2. 点击页面底部“Draw Path”按钮页面将绘制一个五角星
3. 点击页面底部“Draw Rect”按钮页面将绘制一个矩形
4. 点击页面底部“Draw Text”按钮页面将绘制“Hello World Drawing”。
### 效果预览
| 主页 | 绘制五角星 | 绘制矩形 |绘制文字 |
| ------------------------------------ |------------------------------------| ------------------------------------ | ------------------------------------ |
| ![main](screenshots/Index.jpeg) | ![Draw Path](screenshots/DrawPath.jpeg) | ![change color](screenshots/DrawRect.jpeg) | ![change color](screenshots/DrawText.jpeg) |
### 工程目录
```
├──entry/src/main
│ ├──cpp // C++代码区
│ │ ├──CMakeLists.txt // CMake配置文件
│ │ ├──hello.cpp // Napi模块注册
│ │ ├──native_bridge.cpp // C自定义绘制接口实现
│ │ ├──common
│ │ │ └──log_common.h // 日志封装定义文件
│ │ ├──types/libentry
│ │ │ └──index.d.ts // native侧暴露给ArkTS侧接口的声明
│ ├──ets // ets代码区
│ │ ├──entryability
│ │ │ └──EntryAbility.ts // 程序入口类
│ │ └──pages // 页面文件
│ │ └──Index.ets // 主界面
| ├──resources // 资源文件目录
```
### 具体实现
通过在IDE中创建Native c++ 工程在c++代码中定义对外接口为nativeOnDraw在js侧调用该接口并传入相应绘制参数可在页面上绘制出一个五角星矩形和“Hello World Drawing”文字。
RenderNode提供自绘制渲染节点在c++代码侧通过Drawing接口完成绘制代码编写并定义相关对外接口ts侧即可通过RenderNode和NodeController调用自定义绘制接口进而调用Drawing相关的绘制接口绘制出一个五角星矩形和文字。
源码参考:[cpp目录](entry/src/main/cpp)下的文件。
涉及到的相关接口:
| 接口名 | 描述 |
| -------- | -------- |
| OH_Drawing_CanvasAttachBrush (OH_Drawing_Canvas *, const OH_Drawing_Brush *) | 设置画刷给画布,画布将会使用设置的画刷样式和颜色去填充绘制的图形形状。 |
| OH_Drawing_CanvasAttachPen (OH_Drawing_Canvas *, const OH_Drawing_Pen *) | 设置画笔给画布,画布将会使用设置画笔的样式和颜色去绘制图形形状的轮廓。 |
| OH_Drawing_CanvasDetachBrush (const const OH_Drawing_Brush *) | 清空画布上已设置的画刷效果。 |
| OH_Drawing_CanvasDetachPen (const const OH_Drawing_Pen *) | 清空画布上已设置的画笔效果。 |
| OH_Drawing_CanvasDrawPath (OH_Drawing_Canvas *, const OH_Drawing_Path *) | 画一个自定义路径。 |
| OH_Drawing_CanvasDrawPath (OH_Drawing_Canvas *, const OH_Drawing_Rect *) | 画一个矩形。 |
| 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_PathClose (OH_Drawing_Path *) | 闭合路径,会添加一条到路径起点位置的线段。 |
| OH_Drawing_PathDestroy (OH_Drawing_Path *) | 销毁路径对象。 |
| OH_Drawing_RectCreate (float left, float top, float right, float bottom) | 创建一个矩形对象。 |
| OH_Drawing_RectDestroy (const OH_Drawing_Rect *) | 销毁矩形对象。 |
| OH_Drawing_PenCreate (void) | 创建一个画笔对象。 |
| OH_Drawing_PenSetAntiAlias (OH_Drawing_Pen *, bool) | 设置抗锯齿属性,如果为真则说明画笔会启用抗锯齿功能,在绘制图形时会对图形的边缘像素进行半透明的模糊处理。 |
| OH_Drawing_PenSetWidth (OH_Drawing_Pen *, float width) | 设置画笔的厚度属性,厚度属性描述了画笔绘制图形轮廓的宽度。 |
| OH_Drawing_PenDestroy (const OH_Drawing_Pen *) | 销毁画笔对象。 |
| OH_Drawing_BrushCreate (void) | 创建一个画刷对象。 |
| OH_Drawing_BrushSetColor (OH_Drawing_Brush *, uint32_t color) | 设置画刷的颜色属性颜色属性描述了画刷填充图形时使用的颜色用一个32位ARGB的变量表示。 |
| OH_Drawing_BrushDestroy (const OH_Drawing_Brush *) | 销毁画刷对象。 |
| 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) | 显示文本。 |
详细的接口说明请参考[Drawing](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/native-apis/_drawing.md)。
### 相关权限
不涉及。
### 依赖
RenderNode。
### 约束与限制
1. 本示例仅支持标准系统上运行。
2. 本示例为Stage模型已适配API version 11版本SDKSDK版本号(API Version 11 Release),镜像版本号(4.1 Release);
3. 本示例需要使用DevEco Studio 版本号(4.1 Release)及以上版本才可编译运行。
### 下载
如需单独下载本工程,执行如下命令:
```
git init
git config core.sparsecheckout true
echo code/BasicFeature/Native/NdkRenderNodeDrawing/ > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master
```

View File

@ -12,7 +12,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
{
"app": {
"signingConfigs": [],

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -14,17 +14,39 @@
*/
{
"apiType": 'stageMode',
"apiType": "stageMode",
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": "",
"abiFilters": ["arm64-v8a", "armeabi-v7a", "x86_64"],
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
},
"nativeLib": {
"debugSymbol": {
"strip": true,
"exclude": []
}
}
},
],
"targets": [
{
"name": "default",
"name": "default"
},
{
"name": "ohosTest",

View File

@ -0,0 +1,6 @@
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: hapTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

View File

@ -0,0 +1,11 @@
{
"name": "entry",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
"libentry.so": "file:./src/main/cpp/types/libentry"
}
}

View File

@ -8,9 +8,7 @@ include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include)
add_library(entry SHARED
hello.cpp
samples/sample_bitmap.cpp
plugin/plugin_manager.cpp
native_bridge.cpp
)
find_library(
# Sets the name of the path variable.
@ -21,6 +19,5 @@ find_library(
)
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

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -13,16 +13,40 @@
* limitations under the License.
*/
#include <hilog/log.h>
#include "napi/native_api.h"
#include "common/log_common.h"
#include "plugin/plugin_manager.h"
static napi_value Add(napi_env env, napi_callback_info info)
{
size_t requireArgc = 2;
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
napi_valuetype valuetype0;
napi_typeof(env, args[0], &valuetype0);
napi_valuetype valuetype1;
napi_typeof(env, args[1], &valuetype1);
double value0;
napi_get_value_double(env, args[0], &value0);
double value1;
napi_get_value_double(env, args[1], &value1);
napi_value sum;
napi_create_double(env, value0 + value1, &sum);
return sum;
}
EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports)
{
DRAWING_LOGI("napi init");
PluginManager::GetInstance()->Export(env, exports);
napi_property_descriptor desc[] = {
{ "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
};
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
return exports;
}
EXTERN_C_END
@ -33,8 +57,8 @@ static napi_module demoModule = {
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "entry",
.nm_priv = ((void *)0),
.reserved = {0},
.nm_priv = ((void*)0),
.reserved = { 0 },
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void)

View File

@ -0,0 +1,208 @@
/*
* Copyright (c) 2024 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 <cmath>
#include <string>
#include "napi/native_api.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 <native_drawing/drawing_rect.h>
#include <native_drawing/drawing_font_collection.h>
#include <native_drawing/drawing_text_typography.h>
#include "common/log_common.h"
enum DrawType {
NONE,
PATH,
RECT,
TEXT
};
static void NativeOnDrawPath(OH_Drawing_Canvas *canvas, int32_t width, int32_t height)
{
// native node draw function
int len = height / 8;
float aX = width / 4;
float aY = height / 8;
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;
// 创建一个path对象然后使用接口连接成一个五角星形状
OH_Drawing_Path *cPath = OH_Drawing_PathCreate();
// 指定path的起始位置
OH_Drawing_PathMoveTo(cPath, aX, aY);
// 用直线连接到目标点
OH_Drawing_PathLineTo(cPath, bX, bY);
OH_Drawing_PathLineTo(cPath, cX, cY);
OH_Drawing_PathLineTo(cPath, dX, dY);
OH_Drawing_PathLineTo(cPath, eX, eY);
// 闭合形状path绘制完毕
OH_Drawing_PathClose(cPath);
constexpr float penWidth = 10.0f; // pen width 10
// 创建一个画笔Pen对象Pen对象用于形状的边框线绘制
OH_Drawing_Pen *cPen = OH_Drawing_PenCreate();
OH_Drawing_PenSetAntiAlias(cPen, true);
OH_Drawing_PenSetColor(cPen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
OH_Drawing_PenSetWidth(cPen, penWidth);
OH_Drawing_PenSetJoin(cPen, LINE_ROUND_JOIN);
// 将Pen画笔设置到canvas中
OH_Drawing_CanvasAttachPen(canvas, cPen);
// 创建一个画刷Brush对象Brush对象用于形状的填充
OH_Drawing_Brush *cBrush = OH_Drawing_BrushCreate();
OH_Drawing_BrushSetColor(cBrush, OH_Drawing_ColorSetArgb(0xFF, 0x00, 0xFF, 0x00));
// 将Brush画刷设置到canvas中
OH_Drawing_CanvasAttachBrush(canvas, cBrush);
// 在画布上画path的形状五角星的边框样式为pen设置颜色填充为Brush设置
OH_Drawing_CanvasDrawPath(canvas, cPath);
// 绘制完成后将画笔和画刷从画布上清空并销毁
OH_Drawing_CanvasDetachPen(canvas);
OH_Drawing_CanvasDetachBrush(canvas);
OH_Drawing_PenDestroy(cPen);
OH_Drawing_BrushDestroy(cBrush);
OH_Drawing_PathDestroy(cPath);
}
static void NativeOnDrawRect(OH_Drawing_Canvas *canvas)
{
// 创建一个左上角坐标为(150, 200),右下角坐标为(400, 700)的矩形
OH_Drawing_Rect *cRect = OH_Drawing_RectCreate(150, 200, 400, 700);
// 创建一个画笔Pen对象Pen对象用于形状的边框线绘制
OH_Drawing_Pen *cPen = OH_Drawing_PenCreate();
OH_Drawing_PenSetColor(cPen, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0x00, 0x00));
OH_Drawing_PenSetWidth(cPen, 10.0f); // pen width 10
// 将Pen画笔设置到canvas中
OH_Drawing_CanvasAttachPen(canvas, cPen);
OH_Drawing_CanvasDrawRect(canvas, cRect);
OH_Drawing_CanvasDetachPen(canvas);
OH_Drawing_PenDestroy(cPen);
OH_Drawing_RectDestroy(cRect);
}
static void NativeOnDrawText(OH_Drawing_Canvas *canvas, int32_t width, int32_t height)
{
// 选择从左到右/左对齐等排版属性
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 / 30;
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 Drawing\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 / 10.0, height / 4.0};
// 将文本绘制到画布上
OH_Drawing_TypographyPaint(typography, canvas, position[0], position[1]);
}
// 开发者提供的native方法入参有且仅有如下两个开发者不需进行变更。
// napi_env 为当前运行的上下文
// napi_callback_info 记录了一些信息包括从ArkTS侧传递过来参数等。
static napi_value OnDraw(napi_env env, napi_callback_info info)
{
size_t argc = 5;
napi_value args[5] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
int32_t id;
napi_get_value_int32(env, args[0], &id);
void *temp = nullptr;
napi_unwrap(env, args[1], &temp);
OH_Drawing_Canvas *canvas = reinterpret_cast<OH_Drawing_Canvas *>(temp);
int32_t width;
napi_get_value_int32(env, args[2], &width); // 2 means the second argument
int32_t height;
napi_get_value_int32(env, args[3], &height); // 3 means the third argument
int32_t drawOption;
napi_get_value_int32(env, args[4], &drawOption); // 4 means the forth argument
if (drawOption == PATH) {
NativeOnDrawPath(canvas, width, height);
} else if (drawOption == RECT) {
NativeOnDrawRect(canvas);
} else if (drawOption == TEXT) {
NativeOnDrawText(canvas, width, height);
}
return nullptr;
}
static napi_value GetNodeDescriptors(napi_env env, napi_callback_info info) { return nullptr; }
EXTERN_C_START
// Init将在exports上挂上Add/NativeCallArkTS这些native方法此处的exports就是开发者import之后获取到的ArkTS对象。
static napi_value Init(napi_env env, napi_value exports)
{
napi_property_descriptor desc[] = {
{"nativeGetNodeDescriptors", nullptr, GetNodeDescriptors, nullptr, nullptr, nullptr, napi_default, nullptr},
{"nativeOnDraw", nullptr, OnDraw, nullptr, nullptr, nullptr, napi_default, nullptr},
};
// 在exports这个ArkTs对象上挂载native方法
napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
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

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -13,8 +13,6 @@
* limitations under the License.
*/
export default interface XComponentContext {
drawPattern(): void;
import { DrawContext } from "@ohos.arkui.node";
drawText(): void;
};
export const nativeOnDraw: (id: number, context: DrawContext, width: number, height: number, drawType: number) => void

View File

@ -0,0 +1,6 @@
{
"name": "libentry.so",
"types": "./index.d.ts",
"version": "",
"description": "Please describe the basic information."
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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

View File

@ -0,0 +1,108 @@
/*
* Copyright (c) 2024 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 { NodeController, FrameNode, RenderNode, DrawContext } from "@ohos.arkui.node";
import { UIContext } from '@ohos.arkui.UIContext';
import bridge from "libentry.so";
enum drawType {
none,
path,
rect,
text
}
class MyRenderNode extends RenderNode {
private type: drawType = drawType.none
draw(context: DrawContext) {
bridge.nativeOnDraw(666, context, vp2px(this.size.width), vp2px(this.size.height), this.type)
}
resetType(t: drawType) {
this.type = t
}
}
// 创建一个MyRenderNode对象
const newNode = new MyRenderNode()
// 定义newNode的大小和位置
newNode.frame = { x: 0, y: 0, width: 750, height: 800 }
class MyNodeController extends NodeController {
private rootNode: FrameNode | null = null;
makeNode(uiContext: UIContext): FrameNode {
this.rootNode = new FrameNode(uiContext)
if (this.rootNode === null) {
return this.rootNode
}
const renderNode = this.rootNode.getRenderNode()
if (renderNode !== null) {
renderNode.frame = { x: 0, y: 0, width: 10, height: 500 }
renderNode.pivot = { x: 50, y: 50 }
renderNode.appendChild(newNode)
}
return this.rootNode
}
addNode(node: RenderNode): void {
if (this.rootNode === null) {
return
}
const renderNode = this.rootNode.getRenderNode()
if (renderNode !== null) {
renderNode.appendChild(node)
}
}
}
@Entry
@Component
struct RenderTest {
private myNodeController: MyNodeController = new MyNodeController()
build() {
Column() {
Row() {
NodeContainer(this.myNodeController)
.height('100%')
Button("Draw Path")
.margin({ bottom: 200, right: 12 })
.onClick(() => {
newNode.resetType(drawType.path)
newNode.invalidate()
})
Button("Draw Rect")
.margin({ bottom: 200, right: 12 })
.onClick(() => {
newNode.resetType(drawType.rect)
newNode.invalidate()
})
Button("Draw Text")
.margin({ bottom: 200, right: 12 })
.onClick(() => {
newNode.resetType(drawType.text)
newNode.invalidate()
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
.shadow(ShadowStyle.OUTER_DEFAULT_SM)
.alignItems(VerticalAlign.Bottom)
.layoutWeight(1)
}
}
}

View File

@ -1,10 +1,10 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
* 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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -12,6 +12,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
const NativeMock: Record<string, Object> = {
'add': (a: number, b: number) => {
return a + b;
},
};
// 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';
export default NativeMock;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -14,8 +14,7 @@
*/
{
"name": "libentry.so",
"types": "./index.d.ts",
"version": "",
"description": "Please describe the basic information."
"libentry.so": {
"source": "src/mock/libentry.mock.ets"
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -20,18 +20,17 @@ 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');
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',
bundleName: 'com.samples.ndknodedrawing',
abilityName: 'EntryAbility'
});
} catch (exception) {
@ -45,7 +44,7 @@ export default function abilityTest() {
})
/**
* 点击按钮,绘制图形
* 点击按钮,绘制路径
*/
it('DrawPath_001', 2, async () => {
console.info(TAG, 'DrawPath_001 begin');
@ -53,7 +52,7 @@ export default function abilityTest() {
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
try {
await abilityDelegator.startAbility({
bundleName: 'com.samples.nativedrawing',
bundleName: 'com.samples.ndknodedrawing',
abilityName: 'EntryAbility'
});
} catch (exception) {
@ -68,5 +67,55 @@ export default function abilityTest() {
await driver.delayMs(1000);
console.info(TAG, 'DrawPath_001 end');
})
/**
* 点击按钮,绘制矩形
*/
it('DrawRect_001', 2, async () => {
console.info(TAG, 'DrawRect_001 begin');
let driver = Driver.create();
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
try {
await abilityDelegator.startAbility({
bundleName: 'com.samples.ndknodedrawing',
abilityName: 'EntryAbility'
});
} catch (exception) {
console.info(TAG, `DrawRect_001 exception = ${JSON.stringify(exception)}`);
expect().assertFail();
}
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('Draw Rect'));
let drawPathBtn = await driver.findComponent(ON.text('Draw Rect'));
// 点击'Draw Rect'按钮
await drawPathBtn.click();
await driver.delayMs(1000);
console.info(TAG, 'DrawRect_001 end');
})
/**
* 点击按钮,绘制文字
*/
it('DrawText_001', 2, async () => {
console.info(TAG, 'DrawText_001 begin');
let driver = Driver.create();
let abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
try {
await abilityDelegator.startAbility({
bundleName: 'com.samples.ndknodedrawing',
abilityName: 'EntryAbility'
});
} catch (exception) {
console.info(TAG, `DrawText_001 exception = ${JSON.stringify(exception)}`);
expect().assertFail();
}
await driver.delayMs(1000);
await driver.assertComponentExist(ON.text('Draw Text'));
let drawPathBtn = await driver.findComponent(ON.text('Draw Text'));
// 点击'Draw Text'按钮
await drawPathBtn.click();
await driver.delayMs(1000);
console.info(TAG, 'DrawPath_001 end');
})
})
}

View File

@ -1,10 +1,10 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
* 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,
@ -13,7 +13,7 @@
* limitations under the License.
*/
import abilityTest from './DrawingAbility.test';
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();

View File

@ -1,10 +1,10 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
* 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,
@ -13,24 +13,22 @@
* limitations under the License.
*/
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import hilog from '@ohos.hilog';
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { abilityDelegatorRegistry } from '@kit.TestKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
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();
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);
}

View File

@ -1,10 +1,10 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
* 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,

View File

@ -0,0 +1,105 @@
/*
* Copyright (c) 2024 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, TestRunner } from '@kit.TestKit';
import { UIAbility, Want } from '@kit.AbilityKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { resourceManager } from '@kit.LocalizationKit';
import { util } from '@kit.ArkTS';
let abilityDelegator: abilityDelegatorRegistry.AbilityDelegator;
let abilityDelegatorArguments: abilityDelegatorRegistry.AbilityDelegatorArgs;
let jsonPath: string = 'mock/mock-config.json';
let tag: string = 'testTag';
async function onAbilityCreateCallback(data: UIAbility) {
hilog.info(0x0000, 'testTag', 'onAbilityCreateCallback, data: ${}', JSON.stringify(data));
}
async function addAbilityMonitorCallback(err: BusinessError) {
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() {
let tag = 'testTag';
hilog.info(0x0000, tag, '%{public}s', 'OpenHarmonyTestRunner onRun run');
abilityDelegatorArguments = abilityDelegatorRegistry.getArguments()
abilityDelegator = abilityDelegatorRegistry.getAbilityDelegator()
let moduleName = abilityDelegatorArguments.parameters['-m'];
let context = abilityDelegator.getAppContext().getApplicationContext().createModuleContext(moduleName);
let mResourceManager = context.resourceManager;
await checkMock(abilityDelegator, mResourceManager);
const bundleName = abilityDelegatorArguments.bundleName;
const testAbilityName: string = 'TestAbility';
let lMonitor: abilityDelegatorRegistry.AbilityMonitor = {
abilityName: testAbilityName,
onAbilityCreate: onAbilityCreateCallback,
moduleName: moduleName
};
abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback)
const want: Want = {
bundleName: bundleName,
abilityName: testAbilityName,
moduleName: moduleName
};
abilityDelegator.startAbility(want, (err: BusinessError, data: void) => {
hilog.info(0x0000, tag, 'startAbility : err : %{public}s', JSON.stringify(err) ?? '');
hilog.info(0x0000, tag, 'startAbility : data : %{public}s', JSON.stringify(data) ?? '');
})
hilog.info(0x0000, tag, '%{public}s', 'OpenHarmonyTestRunner onRun end');
}
}
async function checkMock(abilityDelegator: abilityDelegatorRegistry.AbilityDelegator, resourceManager: resourceManager.ResourceManager) {
let rawFile: Uint8Array;
try {
rawFile = resourceManager.getRawFileContentSync(jsonPath);
hilog.info(0x0000, tag, 'MockList file exists');
let mockStr: string = util.TextDecoder.create("utf-8", { ignoreBOM: true }).decodeWithStream(rawFile);
let mockMap: Record<string, string> = getMockList(mockStr);
try {
abilityDelegator.setMockList(mockMap)
} catch (error) {
let code = (error as BusinessError).code;
let message = (error as BusinessError).message;
hilog.error(0x0000, tag, `abilityDelegator.setMockList failed, error code: ${code}, message: ${message}.`);
}
} catch (error) {
let code = (error as BusinessError).code;
let message = (error as BusinessError).message;
hilog.error(0x0000, tag, `ResourceManager:callback getRawFileContent failed, error code: ${code}, message: ${message}.`);
}
}
function getMockList(jsonStr: string) {
let jsonObj: Record<string, Object> = JSON.parse(jsonStr);
let map: Map<string, object> = new Map<string, object>(Object.entries(jsonObj));
let mockList: Record<string, string> = {};
map.forEach((value: object, key: string) => {
let realValue: string = value['source'].toString();
mockList[key] = realValue;
});
hilog.info(0x0000, tag, '%{public}s', 'mock-json value:' + JSON.stringify(mockList) ?? '');
return mockList;
}

View File

@ -1,10 +1,10 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
* 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,
@ -21,8 +21,7 @@
"mainElement": "TestAbility",
"deviceTypes": [
"default",
"tablet",
"2in1"
"tablet"
],
"deliveryWithInstall": true,
"installationFree": false,

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2023 Huawei Device Co., Ltd.
* Copyright (c) 2024 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
@ -13,5 +13,8 @@
* 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';
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2024 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, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function localUnitTest() {
describe('localUnitTest',() => {
// Defines a test suite. Two parameters are supported: test suite name and test suite function.
beforeAll(() => {
// Presets an action, which is performed only once before all test cases of the test suite start.
// This API supports only one parameter: preset action function.
});
beforeEach(() => {
// Presets an action, which is performed before each unit test case starts.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: preset action function.
});
afterEach(() => {
// Presets a clear action, which is performed after each unit test case ends.
// The number of execution times is the same as the number of test cases defined by **it**.
// This API supports only one parameter: clear action function.
});
afterAll(() => {
// Presets a clear action, which is performed after all test cases of the test suite end.
// This API supports only one parameter: clear action function.
});
it('assertContain', 0, () => {
// Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
let a = 'abc';
let b = 'b';
// Defines a variety of assertion methods, which are used to declare expected boolean conditions.
expect(a).assertContain(b);
expect(a).assertEqual(a);
});
});
}

View File

@ -0,0 +1,22 @@
{
"hvigorVersion": "4.0.2",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "4.0.2"
},
"execution": {
// "analyze": "default", /* Define the build analyze mode. Value: [ "default" | "verbose" | false ]. Default: "default" */
// "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": 4096 /* Enable nodeOptions maxOldSpaceSize compilation. Unit M. Used for the daemon process */
}
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
import { appTasks } from '@ohos/hvigor-ohos-plugin';
export default {
system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */
plugins:[] /* Custom plugin to extend the functionality of Hvigor. */
}

View File

@ -0,0 +1,54 @@
#!/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="`pwd -P`"
HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js
#NODE_OPTS="--max-old-space-size=4096"
fail() {
echo "$*"
exit 1
}
set_executable_node() {
EXECUTABLE_NODE="${NODE_HOME}/bin/node"
if [ -x "$EXECUTABLE_NODE" ]; then
return
fi
EXECUTABLE_NODE="${NODE_HOME}/node"
if [ -x "$EXECUTABLE_NODE" ]; then
return
fi
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"
}
# Determine node to start hvigor wrapper script
if [ -n "${NODE_HOME}" ]; then
set_executable_node
else
EXECUTABLE_NODE="node"
command -v ${EXECUTABLE_NODE} &> /dev/null || fail "ERROR: NODE_HOME not set and 'node' command not found"
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
if [ -z "${NODE_OPTS}" ]; then
NODE_OPTS="--"
fi
# start hvigor-wrapper script
exec "${EXECUTABLE_NODE}" "${NODE_OPTS}" \
"${HVIGOR_WRAPPER_SCRIPT}" "$@"

View File

@ -0,0 +1,54 @@
@rem
@rem ----------------------------------------------------------------------------
@rem Hvigor startup script for Windows, version 1.0.0
@rem
@rem Required ENV vars:
@rem ------------------
@rem NODE_HOME - location of a Node home dir
@rem or
@rem Add %NODE_HOME%/bin to the PATH environment variable
@rem ----------------------------------------------------------------------------
@rem
@echo off
@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%
set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js
set NODE_EXE=node.exe
@rem set NODE_OPTS="--max-old-space-size=4096"
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
if not defined NODE_OPTS set NODE_OPTS="--"
@rem Find node.exe
if defined NODE_HOME (
set NODE_HOME=%NODE_HOME:"=%
set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE%
)
%NODE_EXE% --version >NUL 2>&1
if "%ERRORLEVEL%" == "0" (
"%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %*
) else if exist "%NODE_EXE_PATH%" (
"%NODE_EXE%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %*
) else (
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.
)
if "%ERRORLEVEL%" == "0" (
if "%OS%" == "Windows_NT" endlocal
) else (
exit /b %ERRORLEVEL%
)

View File

@ -0,0 +1,14 @@
{
"name": "drawingxnode",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "",
"author": "",
"license": "",
"dependencies": {
},
"devDependencies": {
"@ohos/hypium": "1.0.15",
"@ohos/hamock": "1.0.0-rc"
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,120 +0,0 @@
# 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_PenCreate (void) | 创建一个画笔对象。 |
| OH_Drawing_PenSetAntiAlias (OH_Drawing_Pen *, bool) | 设置抗锯齿属性,如果为真则说明画笔会启用抗锯齿功能,在绘制图形时会对图形的边缘像素进行半透明的模糊处理。 |
| OH_Drawing_PenSetWidth (OH_Drawing_Pen *, float width) | 设置画笔的厚度属性,厚度属性描述了画笔绘制图形轮廓的宽度。 |
| OH_Drawing_BrushCreate (void) | 创建一个画刷对象。 |
| 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 11版本SDKSDK版本号(API Version 11 Release),镜像版本号(4.1 Release);
3. 本示例需要使用DevEco Studio 版本号(4.1 Release)及以上版本才可编译运行。
### 下载
如需单独下载本工程,执行如下命令:
```
git init
git config core.sparsecheckout true
echo code/BasicFeature/Native/PathDrawingSample/ > .git/info/sparse-checkout
git remote add origin https://gitee.com/openharmony/applications_app_samples.git
git pull origin master
```

View File

@ -1,27 +0,0 @@
/*
* 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

@ -1,116 +0,0 @@
/*
* 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

@ -1,39 +0,0 @@
/*
* 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

@ -1,563 +0,0 @@
/*
* 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

@ -1,85 +0,0 @@
/*
* 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

@ -1,14 +0,0 @@
/*
* 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

@ -1,56 +0,0 @@
/*
* 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

@ -1,70 +0,0 @@
/*
* 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

@ -1,62 +0,0 @@
/*
* 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

@ -1,64 +0,0 @@
/*
* 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');
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -1,33 +0,0 @@
/*
* 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

@ -1,61 +0,0 @@
# 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

@ -1,77 +0,0 @@
@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

@ -1,28 +0,0 @@
/*
* 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

@ -1,27 +0,0 @@
/*
* 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": {}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB