feat: finish drawing

This commit is contained in:
clz 2023-12-29 22:36:31 +08:00
commit 7f9ae9cb3b
71 changed files with 1627 additions and 0 deletions

11
.gitignore vendored Normal file
View File

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

10
AppScope/app.json5 Normal file
View File

@ -0,0 +1,10 @@
{
"app": {
"bundleName": "com.example.harmony_demo_napi_drawing",
"vendor": "example",
"versionCode": 1000000,
"versionName": "1.0.0",
"icon": "$media:app_icon",
"label": "$string:app_name"
}
}

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

62
build-profile.json5 Normal file
View File

@ -0,0 +1,62 @@
{
"app": {
"signingConfigs": [
{
"name": "default",
"type": "HarmonyOS",
"material": {
"certpath": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_drawing_com.example.harmony_demo_napi_drawing_70086000144137060.cer",
"storePassword": "0000001BE3753910899E0BBB6ECF202A75EEFB89D3A07523759EE64981C319C97D66402C494CE432BBF304",
"keyAlias": "debugKey",
"keyPassword": "0000001BAC241F099392989D533D4D4FF463DB473AD97FFE782F55EAD43F81EB506344AFD09877228BDBB3",
"profile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_drawing_com.example.harmony_demo_napi_drawing_70086000144137060.p7b",
"signAlg": "SHA256withECDSA",
"storeFile": "C:\\Users\\Administrator\\.ohos\\config\\auto_debug_harmony_demo_napi_drawing_com.example.harmony_demo_napi_drawing_70086000144137060.p12"
}
}
],
"products": [
{
"name": "default",
"signingConfig": "default",
"compileSdkVersion": "4.1.0(11)",
"compatibleSdkVersion": "4.0.0(10)",
"runtimeOS": "HarmonyOS"
}
],
"buildModeSet": [
{
"name": "debug",
},
{
"name": "release"
}
]
},
"modules": [
{
"name": "entry",
"srcPath": "./entry",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
},
{
"name": "drawing",
"srcPath": "./drawing",
"targets": [
{
"name": "default",
"applyToProducts": [
"default"
]
}
]
}
]
}

BIN
dependencies/fast-xml-parser-4.3.2.tgz vendored Normal file

Binary file not shown.

BIN
dependencies/hvigor-3.1.0-s.tgz vendored Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
dependencies/rollup.tgz vendored Normal file

Binary file not shown.

6
drawing/.gitignore vendored Normal file
View File

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

3
drawing/Index.ets Normal file
View File

@ -0,0 +1,3 @@
export { DrawingDemo } from './src/main/ets/pages/Index'
export { XComponentContext } from './src/main/ets/interface/XComponentContext'

View File

@ -0,0 +1,33 @@
{
"apiType": "stageMode",
"buildOption": {
"externalNativeOptions": {
"path": "./src/main/cpp/CMakeLists.txt",
"arguments": "",
"cppFlags": ""
},
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
}
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
}
]
}

6
drawing/hvigorfile.ts Normal file
View File

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

View File

@ -0,0 +1,18 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope

12
drawing/oh-package.json5 Normal file
View File

@ -0,0 +1,12 @@
{
"name": "drawing",
"version": "1.0.0",
"description": "Please describe the basic information.",
"main": "Index.ets",
"author": "",
"license": "Apache-2.0",
"packageType": "InterfaceHar",
"dependencies": {
"libdrawing.so": "file:./src/main/cpp/types/libdrawing"
}
}

View File

@ -0,0 +1,24 @@
# the minimum version of CMake.
cmake_minimum_required(VERSION 3.4.1)
project(harmony_demo_napi_drawing)
set(NATIVERENDER_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include
${NATIVERENDER_ROOT_PATH}/plugin)
add_library(drawing SHARED
napi_init.cpp
plugin/plugin_manager.cpp
plugin/plugin_render.cpp
plugin/sample_bitMap.cpp
)
target_link_libraries(drawing PUBLIC
libace_napi.z.so
libace_ndk.z.so
libnative_window.so
libnative_drawing.so
hilog_ndk.z.so
)

View File

@ -0,0 +1,61 @@
#include "napi/native_api.h"
#include "plugin/plugin_manager.h"
#include "sample_bitMap.h"
#include <hilog/log.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) {
napi_property_descriptor desc[] = {
{"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
// {"getContext", nullptr, PluginManager::GetContext, nullptr, nullptr, nullptr, napi_default, nullptr},
};
if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
OH_LOG_ERROR(LOG_APP, "Init", "napi_define_properties failed");
return nullptr;
}
PluginManager::GetInstance()->Export(env, exports);
SampleBitMap::Export(env, exports);
return exports;
}
EXTERN_C_END
static napi_module drawing = {
.nm_version = 1,
.nm_flags = 0,
.nm_filename = nullptr,
.nm_register_func = Init,
.nm_modname = "drawing",
.nm_priv = ((void *)0),
.reserved = {0},
};
extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { napi_module_register(&drawing); }

View File

@ -0,0 +1,88 @@
//
// Created on 2023/12/22.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "plugin_manager.h"
#include "plugin_render.h"
#include <hilog/log.h>
const auto TAG = "PluginManager";
PluginManager PluginManager::pluginManager_;
PluginManager::~PluginManager() { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "~PluginManager"); }
void PluginManager::Export(napi_env env, napi_value exports) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "Export: begin");
if ((env == nullptr) || (exports == nullptr)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: env or exports is null");
return;
}
napi_value exportsInstance = nullptr;
if ((napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportsInstance)) != napi_ok) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: napi_get_named_property failed");
return;
}
OH_NativeXComponent *nativeXComponent = nullptr;
if ((napi_unwrap(env, exportsInstance, reinterpret_cast<void **>(&nativeXComponent))) != napi_ok) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: napi_unwrap failed");
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) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: OH_NativeXComponent_GetXComponentId fail");
return;
}
std::string id(idStr);
auto context = PluginManager::GetInstance();
if (context != nullptr && nativeXComponent != nullptr) {
context->SetNativeXComponent(id, nativeXComponent);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "id is %s", id.c_str());
auto render = context->GetRender(id);
if (render != nullptr) {
render->RegisterCallback(nativeXComponent);
render->Export(env, exports);
}
} else {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "Export: render is nullptr");
}
}
void PluginManager::SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent) {
if (nativeXComponent == nullptr) {
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;
}
}
PluginRender *PluginManager::GetRender(std::string &id) {
if (pluginRenderMap_.find(id) == pluginRenderMap_.end()) {
PluginRender *instance = PluginRender::GetInstance(id);
pluginRenderMap_[id] = instance;
return instance;
}
return pluginRenderMap_[id];
}

View File

@ -0,0 +1,51 @@
//
// Created on 2023/12/22.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef HARMONY_DEMO_NAPI_DRAWING_PLUGIN_MANAGER_H
#define HARMONY_DEMO_NAPI_DRAWING_PLUGIN_MANAGER_H
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <unordered_map>
#include "napi/native_api.h"
#include "plugin_render.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 <cmath>
#include <algorithm>
#include <stdint.h>
#include <sys/mman.h>
#include <unordered_map>
#include <string>
class PluginManager {
public:
~PluginManager();
static PluginManager *GetInstance() { return &PluginManager::pluginManager_; }
static napi_value GetContext(napi_env env, napi_callback_info info);
void SetNativeXComponent(std::string &id, OH_NativeXComponent *nativeXComponent);
PluginRender *GetRender(std::string &id);
void Export(napi_env env, napi_value exports);
private:
static PluginManager pluginManager_;
OH_NativeXComponent_Callback mRenderCallback;
OH_NativeXComponent_MouseEvent_Callback mMouseCallback;
std::unordered_map<std::string, OH_NativeXComponent *> nativeXComponentMap_;
std::unordered_map<std::string, PluginRender *> pluginRenderMap_;
// void RegisterCallback(OH_NativeXComponent *nativeXComponent);
};
#endif // HARMONY_DEMO_NAPI_DRAWING_PLUGIN_MANAGER_H

View File

@ -0,0 +1,95 @@
//
// Created on 2023/12/25.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "plugin_render.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include "napi/native_api.h"
#include <hilog/log.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 <cmath>
#include <algorithm>
#include <stdint.h>
#include <sys/mman.h>
#include "sample_bitMap.h"
const auto TAG = "PluginRender";
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "OnSurfaceCreated");
// 可获取 OHNativeWindow 实例
OHNativeWindow *nativeWindow = static_cast<OHNativeWindow *>(window);
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) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "OnSurfaceCreatedCB: Unable to get XComponent id");
return;
}
std::string id(idStr);
auto render = SampleBitMap::GetInstance(id);
// auto render = new SampleBitMap();
render->SetNativeWindow(nativeWindow); // 设置OHNativeWindow实例
uint64_t width;
uint64_t height;
int32_t size_res = OH_NativeXComponent_GetXComponentSize(component, window, &width, &height);
// 设置画布宽高
if ((size_res == OH_NATIVEXCOMPONENT_RESULT_SUCCESS) && (render != nullptr)) {
render->SetHeight(height);
render->SetWidth(width);
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "xComponent render width = %{public}d, height = %{public}d",
render->GetWidth(), render->GetHeight());
}
}
void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "OnSurfaceChanged");
}
void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "OnSurfaceDestroyed");
}
void DispatchTouchEventCB(OH_NativeXComponent *component, void *window) {
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, TAG, "DispatchTouchEvent");
}
std::unordered_map<std::string, PluginRender *> PluginRender::instance_;
PluginRender::~PluginRender() {}
PluginRender *PluginRender::GetInstance(std::string &id) {
if (PluginRender::instance_.find(id) == PluginRender::instance_.end()) {
PluginRender render;
PluginRender::instance_[id] = &render;
}
return PluginRender::instance_[id];
}
void PluginRender::Export(napi_env env, napi_value value) {}
void PluginRender::RegisterCallback(OH_NativeXComponent *nativeXComponent) {
this->renderCallback_.DispatchTouchEvent = DispatchTouchEventCB;
this->renderCallback_.OnSurfaceChanged = OnSurfaceChangedCB;
this->renderCallback_.OnSurfaceCreated = OnSurfaceCreatedCB;
this->renderCallback_.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
// 将 callback 注册给 NativeXComponent
OH_NativeXComponent_RegisterCallback(nativeXComponent, &this->renderCallback_);
}

View File

@ -0,0 +1,42 @@
//
// Created on 2023/12/25.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include <ace/xcomponent/native_interface_xcomponent.h>
#include "napi/native_api.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 <cmath>
#include <algorithm>
#include <stdint.h>
#include <sys/mman.h>
#include <unordered_map>
#include <string>
#ifndef HARMONY_DEMO_NAPI_DRAWING_PLUGIN_RENDER_H
#define HARMONY_DEMO_NAPI_DRAWING_PLUGIN_RENDER_H
class PluginRender {
private:
~PluginRender();
OH_NativeXComponent_Callback renderCallback_;
public:
static std::unordered_map<std::string, PluginRender *> instance_;
static PluginRender *GetInstance(std::string &id);
void Export(napi_env env, napi_value);
// 注册监听XComponent组件的回调包括生命周期函数手势监听函数等。
void RegisterCallback(OH_NativeXComponent *nativeXComponent);
};
#endif // HARMONY_DEMO_NAPI_DRAWING_PLUGIN_RENDER_H

View File

@ -0,0 +1,246 @@
//
// Created on 2023/12/27.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "sample_bitMap.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <asm/setup.h>
#include <hilog/log.h>
#include <ace/xcomponent/native_interface_xcomponent.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 <cmath>
#include <algorithm>
#include <stdint.h>
#include <sys/mman.h>
const auto TAG = "SampleBitMap";
const unsigned int LOG_PRINT_DOMAIN = 0xFF00;
SampleBitMap::~SampleBitMap() {}
std::unordered_map<std::string, SampleBitMap *> SampleBitMap::instance_;
SampleBitMap *SampleBitMap::GetInstance(std::string &id) {
if (SampleBitMap::instance_.find(id) == SampleBitMap::instance_.end()) {
SampleBitMap::instance_[id] = new SampleBitMap();
}
return SampleBitMap::instance_[id];
}
napi_value SampleBitMap::NapiDrawPattern(napi_env env, napi_callback_info info) {
// 获取XComponentId 和 NativeWindows
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern");
if ((nullptr == env) || (nullptr == info)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: env or info is null");
return nullptr;
}
napi_value thisArg;
if (napi_ok != napi_get_cb_info(env, info, nullptr, nullptr, &thisArg, nullptr)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: napi_get_cb_info fail");
return nullptr;
}
napi_value exportInstance;
if (napi_ok != napi_get_named_property(env, thisArg, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: napi_get_named_property fail");
return nullptr;
}
OH_NativeXComponent *nativeXComponent = nullptr;
if (napi_ok != napi_unwrap(env, exportInstance, reinterpret_cast<void **>(&nativeXComponent))) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "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_RESULT_SUCCESS != OH_NativeXComponent_GetXComponentId(nativeXComponent, idStr, &idSize)) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, TAG, "NapiDrawPattern: Unable to get XComponent id");
return nullptr;
}
std::string id(idStr); // XComponent id
// 根据XComponent Id 获取SampleBitMap对象绘制图形
auto bitMap = SampleBitMap::GetInstance(id);
bitMap->DrawPattern();
return nullptr;
}
void SampleBitMap::DrawPattern() {
/**
* 1. BitMap实例
*/
// 创建一个bitmap对象
OH_Drawing_Bitmap *cBitmap = OH_Drawing_BitmapCreate();
// 定义bitmap的像素格式
OH_Drawing_BitmapFormat cFormat{COLOR_FORMAT_RGBA_8888, ALPHA_FORMAT_OPAQUE};
// 构造对应格式的bitmapwidth的值必须为 bufferHandle->stride / 4
OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, TAG, "DrawingPattern: width=%{public}d, height=%{public}d",
width_, height_);
OH_Drawing_BitmapBuild(cBitmap, width_, height_, &cFormat);
/**
* 2.
*/
// 创建一个canvas对象
OH_Drawing_Canvas *cCanvas = OH_Drawing_CanvasCreate();
// 将画布与bitmap绑定画布画的内容会输出到绑定的bitmap内存中
OH_Drawing_CanvasBind(cCanvas, cBitmap);
// 使用白色清除画布内容
OH_Drawing_CanvasClear(cCanvas, OH_Drawing_ColorSetArgb(0xFF, 0xFF, 0xFF, 0xFF));
/**
* 3. Path形状
*/
int len = height_ / 4;
float aX = width_ / 2;
float aY = height_ / 4;
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);
/**
* 4.
*/
// 创建一个画笔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, 10.0);
OH_Drawing_PenSetJoin(cPen, LINE_ROUND_JOIN);
// 将Pen画笔设置到canvas中
OH_Drawing_CanvasAttachPen(cCanvas, 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(cCanvas, cBrush);
/**
* 5. Path形状
*/
// 在画布上画path的形状五角星的边框样式为pen设置颜色填充为Brush设置
OH_Drawing_CanvasDrawPath(cCanvas, cPath);
/**
* 6.
*/
this->Draw(cBitmap);
/**
* 7.
*/
// 销毁创建的对象
OH_Drawing_BrushDestroy(cBrush);
cBrush = nullptr;
OH_Drawing_PenDestroy(cPen);
cPen = nullptr;
OH_Drawing_PathDestroy(cPath);
cPath = nullptr;
OH_Drawing_CanvasDestroy(cCanvas);
cCanvas = nullptr;
OH_Drawing_BitmapDestroy(cBitmap);
cBitmap = nullptr;
}
void SampleBitMap::Clear() {}
void SampleBitMap::Draw(OH_Drawing_Bitmap *cBitmap) {
OHNativeWindowBuffer *buffer_ = NULL;
// 通过 OH_NativeWindow_NativeWindowRequestBuffer 获取 OHNativeWindowBuffer 实例
int32_t ret = OH_NativeWindow_NativeWindowRequestBuffer(nativeWindow_, &buffer_, &fenceFd_);
BufferHandle *bufferHandle_ = OH_NativeWindow_GetBufferHandleFromNative(buffer_);
uint32_t *mappedAddr_ = static_cast<uint32_t *>(
// 使用系统接口mmap将bufferHandle对应的共享内存映射到用户空间可以通过映射出来的虚拟地址向bufferHandle中写入图像数据
// bufferHandle->virAddr是bufferHandle在共享内存中的起始地址bufferHandle->size是bufferHandle在共享内存中的内存占用大小
mmap(bufferHandle_->virAddr, bufferHandle_->size, PROT_READ | PROT_WRITE, MAP_SHARED, bufferHandle_->fd, 0));
if (mappedAddr_ == MAP_FAILED) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "mmap failed");
}
// 画完后获取像素地址,地址指向的内存包含画布画的像素数据
void *bitmapAddr = OH_Drawing_BitmapGetPixels(cBitmap);
uint32_t *value = static_cast<uint32_t *>(bitmapAddr);
// 使用mmap获取到的地址来访问内存
uint32_t *pixel = static_cast<uint32_t *>(mappedAddr_);
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) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, TAG, "munmap failed!");
}
}
napi_value SampleBitMap::NapiClear(napi_env env, napi_callback_info info) { return nullptr; }
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},
{"clearPattern", nullptr, SampleBitMap::NapiClear, nullptr, nullptr, nullptr, napi_default, nullptr},
};
if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
// DRAWING_LOGE("Export: napi_define_properties failed");
}
}

View File

@ -0,0 +1,52 @@
//
// Created on 2023/12/27.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef HARMONY_DEMO_NAPI_DRAWING_SAMPLE_BITMAP_H
#define HARMONY_DEMO_NAPI_DRAWING_SAMPLE_BITMAP_H
#include <bits/alltypes.h>
#include <hilog/log.h>
#include <native_drawing/drawing_types.h>
#include <native_window/external_window.h>
#include <stdint.h>
#include <unordered_map>
#include <string>
#include <js_native_api.h>
#include <js_native_api_types.h>
class SampleBitMap {
public:
~SampleBitMap();
static SampleBitMap *GetInstance(std::string &id);
void SetNativeWindow(OHNativeWindow *native_window) { this->nativeWindow_ = native_window; }
void SetHeight(int height) { this->height_ = height; }
void SetWidth(int width) { this->width_ = width; }
int GetHeight() const { return this->height_; }
int GetWidth() const { return this->width_; }
void Draw(OH_Drawing_Bitmap *cBitmap);
void DrawPattern();
void Clear();
static napi_value NapiDrawPattern(napi_env env, napi_callback_info info);
static napi_value NapiClear(napi_env env, napi_callback_info info);
static void Export(napi_env env, napi_value exports);
private:
static std::unordered_map<std::string, SampleBitMap *> instance_;
OHNativeWindow *nativeWindow_;
int fenceFd_;
int height_ = 0;
int width_ = 0;
};
#endif // HARMONY_DEMO_NAPI_DRAWING_SAMPLE_BITMAP_H

View File

@ -0,0 +1,3 @@
export const add: (a: number, b: number) => number;
export const drawPattern: () => void;

View File

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

View File

@ -0,0 +1,4 @@
export interface XComponentContext {
add: (a: number, b: number) => number;
drawPattern: () => void;
}

View File

@ -0,0 +1,50 @@
import hilog from '@ohos.hilog';
import { XComponentContext } from '../interface/XComponentContext';
const TAG = 'DrawingDemo'
@Entry
@Component
export struct DrawingDemo {
private xComponentAttrs: XComponentAttrs = {
id: 'xcomponentId',
type: XComponentType.SURFACE,
libraryname: 'drawing'
}
@State xComponentContext: XComponentContext | undefined = undefined;
build() {
Column({ space: 10 }) {
Row() {
XComponent(this.xComponentAttrs)// .focusable(true)// 可响应键盘事件
.onLoad((xComponentContext: XComponentContext) => {
this.xComponentContext = xComponentContext
const res = xComponentContext.add(2, 3)
hilog.info(0xffff, TAG, `xComponentContext.add: 2 + 3 = ${res}`)
})
.onDestroy(() => {
console.log("onDestroy");
})
.width('100%')
.height('80%')
}
.width('100%')
.justifyContent(FlexAlign.Center)
Row() {
Button('绘制')
.onClick(() => {
this.xComponentContext?.drawPattern()
})
}
.width('100%')
.justifyContent(FlexAlign.Center)
}
}
}
interface XComponentAttrs {
id: string;
type: number;
libraryname: string;
}

View File

@ -0,0 +1,3 @@
export function add(a:number, b:number) {
return a + b;
}

View File

@ -0,0 +1,14 @@
{
"module": {
"name": "drawing",
"type": "shared",
"description": "$string:shared_desc",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"pages": "$profile:main_pages"
}
}

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

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

View File

@ -0,0 +1,5 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}

View File

@ -0,0 +1,33 @@
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);
});
});
}

6
entry/.gitignore vendored Normal file
View File

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

31
entry/build-profile.json5 Normal file
View File

@ -0,0 +1,31 @@
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
// "apPath": "./modules.ap" /* Profile used for profile-guided optimization (PGO), a compiler optimization technique to improve app runtime performance. */
},
},
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
},
],
"targets": [
{
"name": "default"
},
{
"name": "ohosTest",
}
]
}

6
entry/hvigorfile.ts Normal file
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,18 @@
# Define project specific obfuscation rules here.
# You can include the obfuscation configuration files in the current module's build-profile.json5.
#
# For more details, see
# https://gitee.com/openharmony/arkcompiler_ets_frontend/blob/master/arkguard/README.md
# Obfuscation options:
# -disable-obfuscation: disable all obfuscations
# -enable-property-obfuscation: obfuscate the property names
# -enable-toplevel-obfuscation: obfuscate the names in the global scope
# -compact: remove unnecessary blank spaces and all line feeds
# -remove-log: remove all console.* statements
# -print-namecache: print the name cache that contains the mapping from the old names to new names
# -apply-namecache: reuse the given cache file
# Keep options:
# -keep-property-name: specifies property names that you want to keep
# -keep-global-name: specifies names that you want to keep in the global scope

13
entry/oh-package.json5 Normal file
View File

@ -0,0 +1,13 @@
{
"license": "",
"devDependencies": {},
"author": "",
"name": "entry",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dynamicDependencies": {},
"dependencies": {
"drawing": 'file:../drawing',
}
}

View File

@ -0,0 +1,43 @@
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
import hilog from '@ohos.hilog';
import UIAbility from '@ohos.app.ability.UIAbility';
import Want from '@ohos.app.ability.Want';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
}
onDestroy(): void {
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage): void {
// Main window is created, set main page for this ability
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy(): void {
// Main window is destroyed, release UI related resources
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
}
onForeground(): void {
// Ability has brought to foreground
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
}
onBackground(): void {
// Ability has back to background
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
}
};

View File

@ -0,0 +1,22 @@
import hilog from '@ohos.hilog';
import testNapi from 'libentry.so';
import { DrawingDemo } from 'drawing'
const TAG = '[Sample_DrawingAPI]'
@Entry
@Component
struct Index {
build() {
Column() {
DrawingDemo()
}
}
}
interface XComponentAttrs {
id: string;
type: number;
libraryname: string;
}

View File

@ -0,0 +1,38 @@
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:main_pages",
"abilities": [
{
"name": "EntryAbility",
"srcEntry": "./ets/entryability/EntryAbility.ets",
"description": "$string:EntryAbility_desc",
"icon": "$media:icon",
"label": "$string:EntryAbility_label",
"startWindowIcon": "$media:startIcon",
"startWindowBackground": "$color:start_window_background",
"exported": true,
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
]
}
]
}
}

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

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

View File

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

View File

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

View File

@ -0,0 +1,35 @@
import hilog from '@ohos.hilog';
import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
export default function abilityTest() {
describe('ActsAbilityTest', () => {
// 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.
hilog.info(0x0000, 'testTag', '%{public}s', 'it begin');
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,5 @@
import abilityTest from './Ability.test';
export default function testsuite() {
abilityTest();
}

View File

@ -0,0 +1,50 @@
import UIAbility from '@ohos.app.ability.UIAbility';
import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry';
import hilog from '@ohos.hilog';
import { Hypium } from '@ohos/hypium';
import testsuite from '../test/List.test';
import window from '@ohos.window';
import Want from '@ohos.app.ability.Want';
import AbilityConstant from '@ohos.app.ability.AbilityConstant';
export default class TestAbility extends UIAbility {
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate');
hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? '');
hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:' + JSON.stringify(launchParam) ?? '');
let abilityDelegator: AbilityDelegatorRegistry.AbilityDelegator;
abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator();
let abilityDelegatorArguments: AbilityDelegatorRegistry.AbilityDelegatorArgs;
abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments();
hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!');
Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite);
}
onDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy');
}
onWindowStageCreate(windowStage: window.WindowStage) {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate');
windowStage.loadContent('testability/pages/Index', (err, data) => {
if (err.code) {
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
return;
}
hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s',
JSON.stringify(data) ?? '');
});
}
onWindowStageDestroy() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy');
}
onForeground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground');
}
onBackground() {
hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground');
}
}

View File

@ -0,0 +1,17 @@
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}

View File

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

View File

@ -0,0 +1,38 @@
{
"module": {
"name": "entry_test",
"type": "feature",
"description": "$string:module_test_desc",
"mainElement": "TestAbility",
"deviceTypes": [
"phone",
"tablet",
"2in1"
],
"deliveryWithInstall": true,
"installationFree": false,
"pages": "$profile:test_pages",
"abilities": [
{
"name": "TestAbility",
"srcEntry": "./ets/testability/TestAbility.ets",
"description": "$string:TestAbility_desc",
"icon": "$media:icon",
"label": "$string:TestAbility_label",
"exported": true,
"startWindowIcon": "$media:icon",
"startWindowBackground": "$color:start_window_background",
"skills": [
{
"actions": [
"action.system.home"
],
"entities": [
"entity.system.home"
]
}
]
}
]
}
}

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

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

View File

@ -0,0 +1,5 @@
import localUnitTest from './LocalUnit.test';
export default function testsuite() {
localUnitTest();
}

View File

@ -0,0 +1,33 @@
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,8 @@
{
"hvigorVersion": "file:../dependencies/hvigor-3.1.0-s.tgz",
"dependencies": {
"@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-3.1.0-s.tgz",
"rollup": "file:../dependencies/rollup.tgz",
"fast-xml-parser": "file:../dependencies/fast-xml-parser-4.3.2.tgz"
}
}

2
hvigor/hvigor-wrapper.js Normal file

File diff suppressed because one or more lines are too long

6
hvigorfile.ts Normal file
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. */
}

54
hvigorw Normal file
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}" "$@"

67
hvigorw.bat Normal file
View File

@ -0,0 +1,67 @@
@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
@rem set NODE_OPTS="--max-old-space-size=4096"
goto start
:start
if not defined NODE_OPTS set NODE_OPTS="--"
@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%" "%NODE_OPTS%" "%WRAPPER_MODULE_PATH%" %*
if "%ERRORLEVEL%" == "0" goto hvigorwEnd
:fail
exit /b 1
:hvigorwEnd
if "%OS%" == "Windows_NT" endlocal
:end

13
oh-package-lock.json5 Normal file
View File

@ -0,0 +1,13 @@
{
"lockfileVersion": 1,
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
"specifiers": {
"@ohos/hypium@1.0.11": "@ohos/hypium@1.0.11"
},
"packages": {
"@ohos/hypium@1.0.11": {
"resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.11.tgz",
"integrity": "sha512-KawcLnv43C3QIYv1UbDnKCFX3MohtDxGuFvzlUxT/qf2DBilR56Ws6zrj90LdH6PjloJQwOPESuBQIHBACAK7w=="
}
}
}

13
oh-package.json5 Normal file
View File

@ -0,0 +1,13 @@
{
"license": "",
"devDependencies": {
"@ohos/hypium": "1.0.11"
},
"author": "",
"name": "harmony_demo_napi_drawing",
"description": "Please describe the basic information.",
"main": "",
"version": "1.0.0",
"dynamicDependencies": {},
"dependencies": {}
}