From ec57f692c13009fc2d9777b168d3adae565f431f Mon Sep 17 00:00:00 2001 From: Hparty <420024556@qq.com> Date: Tue, 6 Aug 2024 18:43:29 +0800 Subject: [PATCH 1/5] Support for OHOS interfaces --- CMakeLists.txt | 5 +- ohos/.gitignore | 12 + ohos/AppScope/app.json5 | 10 + .../resources/base/element/string.json | 8 + .../resources/base/media/app_icon.png | 3 + ohos/build-profile.json5 | 48 ++ ohos/entry/.gitignore | 6 + ohos/entry/build-profile.json5 | 34 + ohos/entry/hvigorfile.ts | 2 + ohos/entry/oh-package-lock.json5 | 29 + ohos/entry/oh-package.json5 | 12 + .../src/main/ets/entryability/EntryAbility.ts | 56 ++ ohos/entry/src/main/ets/pages/Index.ets | 68 ++ ohos/entry/src/main/module.json5 | 51 ++ .../main/resources/base/element/color.json | 8 + .../main/resources/base/element/string.json | 16 + .../src/main/resources/base/media/icon.png | 3 + .../resources/base/profile/main_pages.json | 5 + .../main/resources/en_US/element/string.json | 16 + .../src/main/resources/rawfile/PAG_LOGO.pag | 3 + .../main/resources/zh_CN/element/string.json | 16 + ohos/hvigor/hvigor-config.json5 | 5 + ohos/hvigorfile.ts | 2 + ohos/libpag/.gitignore | 6 + ohos/libpag/Index.ets | 29 + ohos/libpag/build-profile.json5 | 39 ++ ohos/libpag/hvigorfile.ts | 6 + ohos/libpag/obfuscation-rules.txt | 18 + ohos/libpag/oh-package-lock.json5 | 18 + ohos/libpag/oh-package.json5 | 12 + .../src/main/cpp/types/libpag/Index.d.ts | 388 ++++++++++++ .../main/cpp/types/libpag/oh-package.json5 | 6 + ohos/libpag/src/main/ets/PAG.ets | 10 + ohos/libpag/src/main/ets/PAGComposition.ets | 178 ++++++ ohos/libpag/src/main/ets/PAGFile.ets | 216 +++++++ ohos/libpag/src/main/ets/PAGFont.ets | 35 ++ ohos/libpag/src/main/ets/PAGImage.ets | 115 ++++ ohos/libpag/src/main/ets/PAGImageLayer.ets | 41 ++ ohos/libpag/src/main/ets/PAGInit.ets | 32 + ohos/libpag/src/main/ets/PAGLayer.ets | 219 +++++++ ohos/libpag/src/main/ets/PAGMarker.ets | 8 + ohos/libpag/src/main/ets/PAGPlayer.ets | 243 +++++++ ohos/libpag/src/main/ets/PAGScaleMode.ets | 20 + ohos/libpag/src/main/ets/PAGShapeLayer.ets | 8 + ohos/libpag/src/main/ets/PAGSolidLayer.ets | 20 + ohos/libpag/src/main/ets/PAGSurface.ets | 57 ++ ohos/libpag/src/main/ets/PAGText.ets | 100 +++ ohos/libpag/src/main/ets/PAGTextLayer.ets | 92 +++ ohos/libpag/src/main/ets/PAGVideoRange.ets | 22 + ohos/libpag/src/main/ets/PAGView.ets | 329 ++++++++++ ohos/libpag/src/main/ets/private/PAGUtils.ets | 135 ++++ ohos/libpag/src/main/module.json5 | 13 + .../main/resources/base/element/string.json | 8 + .../resources/base/profile/main_pages.json | 2 + .../src/ohosTest/ets/test/Ability.test.ets | 35 ++ .../src/ohosTest/ets/test/List.test.ets | 5 + ohos/libpag/src/ohosTest/module.json5 | 13 + ohos/libpag/src/test/List.test.ets | 5 + ohos/libpag/src/test/LocalUnit.test.ets | 33 + ohos/oh-package-lock.json5 | 27 + ohos/oh-package.json5 | 10 + src/platform/ohos/HardwareDecoder.cpp | 8 +- src/platform/ohos/HardwareDecoder.h | 5 +- src/platform/ohos/JPAG.cpp | 80 +++ src/platform/ohos/JPAG.h | 35 ++ src/platform/ohos/JPAGComposition.cpp | 432 +++++++++++++ src/platform/ohos/JPAGFile.cpp | 357 +++++++++++ src/platform/ohos/JPAGFont.cpp | 189 ++++++ src/platform/ohos/JPAGFont.h | 37 ++ src/platform/ohos/JPAGImage.cpp | 231 +++++++ src/platform/ohos/JPAGImage.h | 44 ++ src/platform/ohos/JPAGImageLayer.cpp | 117 ++++ src/platform/ohos/JPAGLayer.cpp | 507 +++++++++++++++ src/platform/ohos/JPAGLayerHandle.h | 53 ++ src/platform/ohos/JPAGPlayer.cpp | 592 ++++++++++++++++++ src/platform/ohos/JPAGPlayer.h | 44 ++ src/platform/ohos/JPAGShapeLayer.cpp | 31 + src/platform/ohos/JPAGSolidLayer.cpp | 75 +++ src/platform/ohos/JPAGSurface.cpp | 172 +++++ src/platform/ohos/JPAGSurface.h | 48 ++ src/platform/ohos/JPAGText.cpp | 276 ++++++++ src/platform/ohos/JPAGText.h | 36 ++ src/platform/ohos/JPAGTextLayer.cpp | 210 +++++++ src/platform/ohos/JPAGView.cpp | 574 +++++++++++++++++ src/platform/ohos/JPAGView.h | 58 ++ src/platform/ohos/JsHelper.cpp | 439 +++++++++++++ src/platform/ohos/JsHelper.h | 58 ++ src/platform/ohos/NativeDisplayLink.cpp | 51 ++ src/platform/ohos/NativeDisplayLink.h | 40 ++ src/platform/ohos/NativePlatform.cpp | 12 +- src/platform/ohos/NativePlatform.h | 1 + 91 files changed, 7772 insertions(+), 11 deletions(-) create mode 100644 ohos/.gitignore create mode 100644 ohos/AppScope/app.json5 create mode 100644 ohos/AppScope/resources/base/element/string.json create mode 100644 ohos/AppScope/resources/base/media/app_icon.png create mode 100644 ohos/build-profile.json5 create mode 100755 ohos/entry/.gitignore create mode 100755 ohos/entry/build-profile.json5 create mode 100755 ohos/entry/hvigorfile.ts create mode 100644 ohos/entry/oh-package-lock.json5 create mode 100755 ohos/entry/oh-package.json5 create mode 100755 ohos/entry/src/main/ets/entryability/EntryAbility.ts create mode 100755 ohos/entry/src/main/ets/pages/Index.ets create mode 100755 ohos/entry/src/main/module.json5 create mode 100755 ohos/entry/src/main/resources/base/element/color.json create mode 100755 ohos/entry/src/main/resources/base/element/string.json create mode 100644 ohos/entry/src/main/resources/base/media/icon.png create mode 100755 ohos/entry/src/main/resources/base/profile/main_pages.json create mode 100755 ohos/entry/src/main/resources/en_US/element/string.json create mode 100644 ohos/entry/src/main/resources/rawfile/PAG_LOGO.pag create mode 100755 ohos/entry/src/main/resources/zh_CN/element/string.json create mode 100644 ohos/hvigor/hvigor-config.json5 create mode 100644 ohos/hvigorfile.ts create mode 100644 ohos/libpag/.gitignore create mode 100644 ohos/libpag/Index.ets create mode 100644 ohos/libpag/build-profile.json5 create mode 100644 ohos/libpag/hvigorfile.ts create mode 100644 ohos/libpag/obfuscation-rules.txt create mode 100644 ohos/libpag/oh-package-lock.json5 create mode 100644 ohos/libpag/oh-package.json5 create mode 100644 ohos/libpag/src/main/cpp/types/libpag/Index.d.ts create mode 100644 ohos/libpag/src/main/cpp/types/libpag/oh-package.json5 create mode 100644 ohos/libpag/src/main/ets/PAG.ets create mode 100644 ohos/libpag/src/main/ets/PAGComposition.ets create mode 100644 ohos/libpag/src/main/ets/PAGFile.ets create mode 100644 ohos/libpag/src/main/ets/PAGFont.ets create mode 100644 ohos/libpag/src/main/ets/PAGImage.ets create mode 100644 ohos/libpag/src/main/ets/PAGImageLayer.ets create mode 100644 ohos/libpag/src/main/ets/PAGInit.ets create mode 100644 ohos/libpag/src/main/ets/PAGLayer.ets create mode 100644 ohos/libpag/src/main/ets/PAGMarker.ets create mode 100644 ohos/libpag/src/main/ets/PAGPlayer.ets create mode 100644 ohos/libpag/src/main/ets/PAGScaleMode.ets create mode 100644 ohos/libpag/src/main/ets/PAGShapeLayer.ets create mode 100644 ohos/libpag/src/main/ets/PAGSolidLayer.ets create mode 100644 ohos/libpag/src/main/ets/PAGSurface.ets create mode 100644 ohos/libpag/src/main/ets/PAGText.ets create mode 100644 ohos/libpag/src/main/ets/PAGTextLayer.ets create mode 100644 ohos/libpag/src/main/ets/PAGVideoRange.ets create mode 100644 ohos/libpag/src/main/ets/PAGView.ets create mode 100644 ohos/libpag/src/main/ets/private/PAGUtils.ets create mode 100644 ohos/libpag/src/main/module.json5 create mode 100644 ohos/libpag/src/main/resources/base/element/string.json create mode 100644 ohos/libpag/src/main/resources/base/profile/main_pages.json create mode 100644 ohos/libpag/src/ohosTest/ets/test/Ability.test.ets create mode 100644 ohos/libpag/src/ohosTest/ets/test/List.test.ets create mode 100644 ohos/libpag/src/ohosTest/module.json5 create mode 100644 ohos/libpag/src/test/List.test.ets create mode 100644 ohos/libpag/src/test/LocalUnit.test.ets create mode 100644 ohos/oh-package-lock.json5 create mode 100644 ohos/oh-package.json5 create mode 100644 src/platform/ohos/JPAG.cpp create mode 100644 src/platform/ohos/JPAG.h create mode 100644 src/platform/ohos/JPAGComposition.cpp create mode 100644 src/platform/ohos/JPAGFile.cpp create mode 100644 src/platform/ohos/JPAGFont.cpp create mode 100644 src/platform/ohos/JPAGFont.h create mode 100644 src/platform/ohos/JPAGImage.cpp create mode 100644 src/platform/ohos/JPAGImage.h create mode 100644 src/platform/ohos/JPAGImageLayer.cpp create mode 100644 src/platform/ohos/JPAGLayer.cpp create mode 100644 src/platform/ohos/JPAGLayerHandle.h create mode 100644 src/platform/ohos/JPAGPlayer.cpp create mode 100644 src/platform/ohos/JPAGPlayer.h create mode 100644 src/platform/ohos/JPAGShapeLayer.cpp create mode 100644 src/platform/ohos/JPAGSolidLayer.cpp create mode 100644 src/platform/ohos/JPAGSurface.cpp create mode 100644 src/platform/ohos/JPAGSurface.h create mode 100644 src/platform/ohos/JPAGText.cpp create mode 100644 src/platform/ohos/JPAGText.h create mode 100644 src/platform/ohos/JPAGTextLayer.cpp create mode 100644 src/platform/ohos/JPAGView.cpp create mode 100644 src/platform/ohos/JPAGView.h create mode 100644 src/platform/ohos/JsHelper.cpp create mode 100644 src/platform/ohos/JsHelper.h create mode 100644 src/platform/ohos/NativeDisplayLink.cpp create mode 100644 src/platform/ohos/NativeDisplayLink.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cda7a234c..9802b82faa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -380,13 +380,16 @@ elseif (OHOS) find_library(NATIVE_BUFFER_LIB native_buffer) find_library(NATIVE_WINDOW_LIB native_window) find_library(NATIVE_IMAGE_LIB native_image) + find_library(NATIVE_VSYNC_LIB native_vsync) find_library(NATIVE_MEDIA_CODECBASE_LIB native_media_codecbase) find_library(NATIVE_MEDIA_CORE_LIB native_media_core) find_library(NATIVE_MEDIA_VDEC_LIB native_media_vdec) + find_library(NATIVE_RAWFILE_Z_LIB rawfile.z) list(APPEND PAG_SHARED_LIBS ${PIXELMAP_NDK_LIB} ${IMAGE_SOURCE_NDK_LIB} ${PIXELMAP_LIB} ${IMAGE_SOURCE_LIB} ${ACE_NDK_LIB} ${HILOG_NDK_LIB} ${ACE_NAPI_LIB} ${NATIVE_BUFFER_LIB} ${NATIVE_WINDOW_LIB} ${NATIVE_IMAGE_LIB} - ${NATIVE_MEDIA_CODECBASE_LIB} ${NATIVE_MEDIA_CORE_LIB} ${NATIVE_MEDIA_VDEC_LIB}) + ${NATIVE_MEDIA_CODECBASE_LIB} ${NATIVE_MEDIA_CORE_LIB} ${NATIVE_MEDIA_VDEC_LIB} + ${NATIVE_VSYNC_LIB} ${NATIVE_RAWFILE_Z_LIB}) file(GLOB_RECURSE PLATFORM_FILES src/platform/ohos/*.*) list(APPEND PAG_FILES ${PLATFORM_FILES}) diff --git a/ohos/.gitignore b/ohos/.gitignore new file mode 100644 index 0000000000..d2ff20141c --- /dev/null +++ b/ohos/.gitignore @@ -0,0 +1,12 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test +/.appanalyzer \ No newline at end of file diff --git a/ohos/AppScope/app.json5 b/ohos/AppScope/app.json5 new file mode 100644 index 0000000000..8ce2aefacb --- /dev/null +++ b/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "org.libpag.PAGViewer", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/AppScope/resources/base/element/string.json b/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000..17ef74dfa6 --- /dev/null +++ b/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "PAGViewer" + } + ] +} diff --git a/ohos/AppScope/resources/base/media/app_icon.png b/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000..924274f1a4 --- /dev/null +++ b/ohos/AppScope/resources/base/media/app_icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79c27214e49332c1e5bcbbe9badeac547c13ee38f597658de313b907fdf2a4e6 +size 2777 diff --git a/ohos/build-profile.json5 b/ohos/build-profile.json5 new file mode 100644 index 0000000000..f4bbc7f584 --- /dev/null +++ b/ohos/build-profile.json5 @@ -0,0 +1,48 @@ +{ + "app": { + "signingConfigs": [ + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compatibleSdkVersion": "5.0.0(12)", + "runtimeOS": "HarmonyOS", + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + }, + { + "name": "libpag", + "srcPath": "./libpag", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/entry/.gitignore b/ohos/entry/.gitignore new file mode 100755 index 0000000000..e2713a2779 --- /dev/null +++ b/ohos/entry/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/entry/build-profile.json5 b/ohos/entry/build-profile.json5 new file mode 100755 index 0000000000..d7bb3d441e --- /dev/null +++ b/ohos/entry/build-profile.json5 @@ -0,0 +1,34 @@ +{ + "apiType": "stageMode", + "buildOption": { + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + }, + "nativeLib": { + "debugSymbol": { + "strip": true, + "exclude": [] + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/entry/hvigorfile.ts b/ohos/entry/hvigorfile.ts new file mode 100755 index 0000000000..80e4ec5b81 --- /dev/null +++ b/ohos/entry/hvigorfile.ts @@ -0,0 +1,2 @@ +// 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'; diff --git a/ohos/entry/oh-package-lock.json5 b/ohos/entry/oh-package-lock.json5 new file mode 100644 index 0000000000..7056613b42 --- /dev/null +++ b/ohos/entry/oh-package-lock.json5 @@ -0,0 +1,29 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "libpag.so@../libpag/src/main/cpp/types/libpag": "libpag.so@../libpag/src/main/cpp/types/libpag", + "libpag@../libpag": "libpag@../libpag" + }, + "packages": { + "libpag.so@../libpag/src/main/cpp/types/libpag": { + "name": "libpag.so", + "version": "1.0.0", + "resolved": "../libpag/src/main/cpp/types/libpag", + "registryType": "local" + }, + "libpag@../libpag": { + "name": "libpag", + "version": "1.0.0", + "resolved": "../libpag", + "registryType": "local", + "dependencies": { + "libpag.so": "file:./src/main/cpp/types/libpag" + }, + "packageType": "InterfaceHar" + } + } +} \ No newline at end of file diff --git a/ohos/entry/oh-package.json5 b/ohos/entry/oh-package.json5 new file mode 100755 index 0000000000..ef4eb35dfa --- /dev/null +++ b/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "libpag": "../libpag" + } +} diff --git a/ohos/entry/src/main/ets/entryability/EntryAbility.ts b/ohos/entry/src/main/ets/entryability/EntryAbility.ts new file mode 100755 index 0000000000..aefdd5b7b8 --- /dev/null +++ b/ohos/entry/src/main/ets/entryability/EntryAbility.ts @@ -0,0 +1,56 @@ +/* + * 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 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'); + } +}; diff --git a/ohos/entry/src/main/ets/pages/Index.ets b/ohos/entry/src/main/ets/pages/Index.ets new file mode 100755 index 0000000000..8d628ccc5f --- /dev/null +++ b/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,68 @@ +import * as pag from 'libpag'; + +@Entry +@Component +struct Index { + @State message: string = ""; + @State @Watch("updateMessage") stateString: string = ""; + @State composition: pag.PAGComposition | null = null; + @State @Watch("updateMessage") progress: number = 0; + @State isPlaying: boolean = false; + @State repeatCount: number = 1; + + aboutToAppear(): void { + let manager = getContext(this).resourceManager; + let file = pag.PAGFile.LoadFromAssets(manager, "PAG_LOGO.pag"); + this.composition = file as pag.PAGComposition; + this.isPlaying = true; + } + + onAnimationStart = (view: pag.PAGView) => { + this.stateString = 'PAG start'; + } + onAnimationEnd = (view: pag.PAGView) => { + this.stateString = `PAG end`; + } + onAnimationRepeat = (view: pag.PAGView) => { + this.stateString = `PAG repeat`; + } + onAnimationCancel = (view: pag.PAGView) => { + this.stateString = `PAG cancel`; + } + onAnimationUpdate = (view: pag.PAGView) => { + } + + updateMessage() { + this.message = this.stateString + ` progress ${this.progress.toFixed(2)}`; + } + + build() { + Row() { + Column() { + pag.PAGView({ + composition: this.composition, + progress: this.progress, + isPlaying: this.isPlaying, + repeatCount: this.repeatCount, + listeners: [new WeakRef(this)] + }) + .height('50%') + .onClick(() => { + this.isPlaying = !this.isPlaying + }) + + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + .onClick(() => { + this.progress = 0.5; + this.repeatCount = 0; + }) + .height('50%') + } + .width('100%') + + } + .height('100%') + } +} diff --git a/ohos/entry/src/main/module.json5 b/ohos/entry/src/main/module.json5 new file mode 100755 index 0000000000..bac72d9592 --- /dev/null +++ b/ohos/entry/src/main/module.json5 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "default" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ts", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ] + } +} \ No newline at end of file diff --git a/ohos/entry/src/main/resources/base/element/color.json b/ohos/entry/src/main/resources/base/element/color.json new file mode 100755 index 0000000000..3c712962da --- /dev/null +++ b/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/entry/src/main/resources/base/element/string.json b/ohos/entry/src/main/resources/base/element/string.json new file mode 100755 index 0000000000..799199a5d9 --- /dev/null +++ b/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "PAGDemo" + } + ] +} \ No newline at end of file diff --git a/ohos/entry/src/main/resources/base/media/icon.png b/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000..3331ee22f2 --- /dev/null +++ b/ohos/entry/src/main/resources/base/media/icon.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4adf600f4737768ca3e71a1350b1dab64cec1b65dc9f9c7edf8af1f2765c751e +size 17005 diff --git a/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100755 index 0000000000..1898d94f58 --- /dev/null +++ b/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100755 index 0000000000..799199a5d9 --- /dev/null +++ b/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "PAGDemo" + } + ] +} \ No newline at end of file diff --git a/ohos/entry/src/main/resources/rawfile/PAG_LOGO.pag b/ohos/entry/src/main/resources/rawfile/PAG_LOGO.pag new file mode 100644 index 0000000000..1426f31121 --- /dev/null +++ b/ohos/entry/src/main/resources/rawfile/PAG_LOGO.pag @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:63d66f64839672ac8e177ea6342021f9de03a0f6ee267e16792536e232504749 +size 11052 diff --git a/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100755 index 0000000000..a8eb3a6116 --- /dev/null +++ b/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "PAGDemo" + } + ] +} \ No newline at end of file diff --git a/ohos/hvigor/hvigor-config.json5 b/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000..f70ecd4112 --- /dev/null +++ b/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,5 @@ +{ + "modelVersion": "5.0.0", + "dependencies": { + } +} \ No newline at end of file diff --git a/ohos/hvigorfile.ts b/ohos/hvigorfile.ts new file mode 100644 index 0000000000..6478186902 --- /dev/null +++ b/ohos/hvigorfile.ts @@ -0,0 +1,2 @@ +// 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'; \ No newline at end of file diff --git a/ohos/libpag/.gitignore b/ohos/libpag/.gitignore new file mode 100644 index 0000000000..e2713a2779 --- /dev/null +++ b/ohos/libpag/.gitignore @@ -0,0 +1,6 @@ +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/libpag/Index.ets b/ohos/libpag/Index.ets new file mode 100644 index 0000000000..50ca9b0c80 --- /dev/null +++ b/ohos/libpag/Index.ets @@ -0,0 +1,29 @@ +export { PAGView, PAGViewListener } from './src/main/ets/PAGView' + +export { PAGPlayer } from './src/main/ets/PAGPlayer' + +export { PAGSurface } from './src/main/ets/PAGSurface' + +export { PAGLayer, PAGLayerType } from './src/main/ets/PAGLayer' + +export { PAGComposition } from './src/main/ets/PAGComposition' + +export { PAGFile } from './src/main/ets/PAGFile' + +export { PAGFont } from './src/main/ets/PAGFont' + +export { PAGImage } from './src/main/ets/PAGImage' + +export { PAGImageLayer } from './src/main/ets/PAGImageLayer' + +export { PAGMarker } from './src/main/ets/PAGMarker' + +export { PAGShapeLayer } from './src/main/ets/PAGShapeLayer' + +export { PAGSolidLayer } from './src/main/ets/PAGSolidLayer' + +export { PAGTextLayer } from './src/main/ets/PAGTextLayer' + +export { PAGVideoRange } from './src/main/ets/PAGVideoRange' + +export { PAG } from './src/main/ets/PAG' diff --git a/ohos/libpag/build-profile.json5 b/ohos/libpag/build-profile.json5 new file mode 100644 index 0000000000..c683de76b3 --- /dev/null +++ b/ohos/libpag/build-profile.json5 @@ -0,0 +1,39 @@ +{ + "apiType": "stageMode", + "buildOption": { + "externalNativeOptions": { + "path": "../../CMakeLists.txt", + "arguments": "", + "cppFlags": "" + } + }, + "buildOptionSet": [ + { + "name": "release", + "arkOptions": { + "obfuscation": { + "ruleOptions": { + "enable": true, + "files": [ + "./obfuscation-rules.txt" + ] + } + } + }, + "nativeLib": { + "debugSymbol": { + "strip": true, + "exclude": [] + } + } + }, + ], + "targets": [ + { + "name": "default" + }, + { + "name": "ohosTest" + } + ] +} \ No newline at end of file diff --git a/ohos/libpag/hvigorfile.ts b/ohos/libpag/hvigorfile.ts new file mode 100644 index 0000000000..d993120bd7 --- /dev/null +++ b/ohos/libpag/hvigorfile.ts @@ -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. */ +} diff --git a/ohos/libpag/obfuscation-rules.txt b/ohos/libpag/obfuscation-rules.txt new file mode 100644 index 0000000000..69c4d6a8a5 --- /dev/null +++ b/ohos/libpag/obfuscation-rules.txt @@ -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://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/source-obfuscation-V5 + +# Obfuscation options: +# -disable-obfuscation: disable all obfuscations +# -enable-property-obfuscation: obfuscate the property names +# -enable-toplevel-obfuscation: obfuscate the names in the global scope +# -compact: remove unnecessary blank spaces and all line feeds +# -remove-log: remove all console.* statements +# -print-namecache: print the name cache that contains the mapping from the old names to new names +# -apply-namecache: reuse the given cache file + +# Keep options: +# -keep-property-name: specifies property names that you want to keep +# -keep-global-name: specifies names that you want to keep in the global scope \ No newline at end of file diff --git a/ohos/libpag/oh-package-lock.json5 b/ohos/libpag/oh-package-lock.json5 new file mode 100644 index 0000000000..12356e22dd --- /dev/null +++ b/ohos/libpag/oh-package-lock.json5 @@ -0,0 +1,18 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "libpag.so@src/main/cpp/types/libpag": "libpag.so@src/main/cpp/types/libpag" + }, + "packages": { + "libpag.so@src/main/cpp/types/libpag": { + "name": "libpag.so", + "version": "1.0.0", + "resolved": "src/main/cpp/types/libpag", + "registryType": "local" + } + } +} \ No newline at end of file diff --git a/ohos/libpag/oh-package.json5 b/ohos/libpag/oh-package.json5 new file mode 100644 index 0000000000..2724d5f215 --- /dev/null +++ b/ohos/libpag/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "name": "libpag", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "Index.ets", + "author": "", + "license": "Apache-2.0", + "packageType": "InterfaceHar", + "dependencies": { + "libpag.so": "file:./src/main/cpp/types/libpag" + }, +} \ No newline at end of file diff --git a/ohos/libpag/src/main/cpp/types/libpag/Index.d.ts b/ohos/libpag/src/main/cpp/types/libpag/Index.d.ts new file mode 100644 index 0000000000..bfc7591e3c --- /dev/null +++ b/ohos/libpag/src/main/cpp/types/libpag/Index.d.ts @@ -0,0 +1,388 @@ +import resourceManager from "@ohos.resourceManager"; +import { image } from "@kit.ImageKit"; + +export declare class JPAGImage { + static FromPath(path: string): JPAGImage | null; + + static FromBytes(data: Int8Array): JPAGImage | null; + + static FromPixelMap(pixelMap: image.PixelMap): JPAGImage | null; + + static LoadFromAssets(manager: resourceManager.ResourceManager, name: string): JPAGImage | null; + + width(): number; + + height(): number; + + matrix(): Array; + + setMatrix(matrix: Array); + + scaleMode(): number; + + setScaleMode(mode: number) +} + +export declare class JPAGLayer { + layerType(): number; + + layerName(): string; + + isPAGFile(): boolean; + + matrix(): Array; + + setMatrix(matrix: Array); + + resetMatrix(); + + getTotalMatrix(): Array; + + visible(): boolean; + + setVisible(value: boolean); + + editableIndex(): number; + + parent(): JPAGComposition | null; + + markers(): Array; + + localTimeToGlobal(localTime: number): number; + + globalToLocalTime(globalTime: number): number; + + duration(): number; + + frameRate(): number; + + startTime(): number; + + setStartTime(time: number): void; + + currentTime(): number; + + setCurrentTime(time: number): void; + + getProgress(): number; + + setProgress(value: number): void; + + trackMatteLayer(): JPAGLayer | null; + + getBounds(): Array; + + excludedFromTimeline(): boolean; + + setExcludedFromTimeline(value: boolean); +} + +export declare class JPAGSolidLayer extends JPAGLayer { + solidColor(): number; + + setSolidColor(solidColor: number); +} + +export declare class JPAGImageLayer extends JPAGLayer { + static Make(width: number, height: number, duration: number): JPAGImageLayer | null; + + contentDuration(): number; + + getVideoRanges(): Array; + + setImage(image: JPAGImage); + + imageBytes(): ArrayBuffer | null; +} + +export declare class JPAGTextLayer extends JPAGLayer { + fillColor(): number; + + setFillColor(color: number): void; + + font(): JPAGFont; + + setFont(font: JPAGFont); + + fontSize(): number; + + setFontSize(fontSize: number): void; + + strokeColor(): number; + + setStrokeColor(color: number): void; + + text(): string; + + setText(text: string): void; + + reset(): void; +} + +export declare class JPAGShapeLayer extends JPAGLayer { +} + +export declare class JPAGComposition extends JPAGLayer { + static Make(width: number, height: number): JPAGComposition | null; + + width(): number; + + height(): number; + + setContentSize(width: number, height: number): void; + + numChildren(): number; + + getLayerAt(index: number): JPAGLayer; + + getLayerIndex(layer: JPAGLayer): number; + + setLayerIndex(layer: JPAGLayer, index: number): void; + + addLayer(pagLayer: JPAGLayer): void; + + addLayerAt(pagLayer: JPAGLayer, index: number): void; + + contains(pagLayer: JPAGLayer): boolean; + + removeLayer(pagLayer: JPAGLayer): JPAGLayer | null; + + removeLayerAt(index: number): JPAGLayer | null; + + removeAllLayers(): void; + + swapLayer(pagLayer1: JPAGLayer, pagLayer2: JPAGLayer): void; + + swapLayerAt(index1: number, index2: number); + + audioBytes(): ArrayBuffer | null; + + audioStartTime(): number; + + audioMarkers(): Array; + + getLayersByName(layerName: string): Array; + + getLayersUnderPoint(localX: number, localY: number): Array +} + +export declare class JPAGFile extends JPAGComposition { + static MaxSupportedTagLevel(): number; + + static LoadFromPath(filePath: string): JPAGFile | null; + + static LoadFromBytes(data: Int8Array, filePath?: string): JPAGFile | null; + + static LoadFromAssets(manager: resourceManager.ResourceManager, name: string): JPAGFile | null; + + tagLevel(): number; + + numTexts(): number; + + numImages(): number; + + numVideos(): number; + + path(): string; + + getTextData(index: number): JPAGText | null; + + replaceText(editableTextIndex: number, textData: JPAGText | null); + + replaceImage(editableImageIndex: number, image: JPAGImage | null); + + replaceImageByName(layerName: string, image: JPAGImage | null); + + getLayersByEditableIndex(editableIndex: number, layerType: number): Array; + + getEditableIndices(layerType: number): Array; + + timeStretchMode(): number; + + setTimeStretchMode(value: number); + + setDuration(duration: number); + + copyOriginal(): JPAGFile; +} + +export declare class JPAGPlayer { + setComposition(composition: JPAGComposition | null): void; + + getComposition(): JPAGComposition | null; + + getSurface(): JPAGSurface | null; + + setSurface(surface: JPAGSurface | null): void; + + setProgress(progress: number): void; + + videoEnabled(): boolean; + + setVideoEnabled(value: boolean): void; + + cacheEnabled(): boolean; + + setCacheEnabled(value: boolean); + + useDiskCache(): boolean; + + setUseDiskCache(value: boolean); + + cacheScale(): number; + + setCacheScale(value: number); + + maxFrameRate(): number; + + setMaxFrameRate(value: number); + + scaleMode(): number; + + setScaleMode(mode: number) + + matrix(): Array; + + setMatrix(matrix: Array); + + duration(): number; + + getProgress(): number; + + setProgress(progress: number): void; + + currentFrame(): number; + + prepare(): void; + + flush(): void; + + getBounds(pagLayer: JPAGLayer): Array; + + getLayersUnderPoint(surfaceX: number, surfaceY: number): Array; + + hitTestPoint(pagLayer: JPAGLayer, surfaceX: number, + surfaceY: number, pixelHitTest: boolean): boolean; +} + +export declare class JPAGSurface { + static MakeOffscreen(width: number, height: number): JPAGSurface | null; + + width(): number; + + height(): number; + + clearAll(): boolean; + + freeCache(): void; + + makeSnapshot(): image.PixelMap | null; +} + +export declare class JPAGView { + flush(): void; + + setProgress(progress: number): void; + + setComposition(composition: JPAGComposition | null): void; + + setRepeatCount(repeatCount: number): void; + + play(): void; + + pause(): void; + + setStateChangeCallback(callback: (number) => void): void; + + setProgressUpdateCallback(callback: (double) => void): void; + + uniqueID(): string; + + setSync(isSync: boolean): void; + + setVideoEnabled(videoEnabled: boolean): void; + + setCacheEnabled(cacheEnabled: boolean): void; + + setCacheScale(cacheScale: number): void; + + setMaxFrameRate(maxFrameRate: number): void; + + setScaleMode(scaleMode: number): void; + + setMatrix(matrix: Array); + + currentFrame(): number; + + getLayersUnderPoint(x: number, y: number): Array; + + freeCache(); + + makeSnapshot(): image.PixelMap | null; +} + +export declare class JPAGFont { + static RegisterFontFromPath(fontPath: string, ttcIndex?: number, + fontFamily?: string, fontStyle?: string): JPAGFont; + + static RegisterFontFromAsset(manager: resourceManager.ResourceManager, fileName: string, ttcIndex?: number, + fontFamily?: string, fontStyle?: string): JPAGFont; + + static UnregisterFont(font: JPAGFont); + + static SetFallbackFontPaths(fontPath: Array): void; + + constructor(fontFamily?: string, fontStyle?: string); + + fontFamily: string; + + fontStyle: string; +} + +export declare class JPAGText { + applyFill: boolean; + + applyStroke: boolean; + + baselineShift: number; + + boxText: boolean; + + boxTextRect: Array; + + firstBaseLine: number; + + fauxBold: boolean; + + fauxItalic: boolean; + + fillColor: number; + + fontFamily: string; + + fontStyle: string; + + fontSize: number; + + strokeColor: number; + + strokeOverFill: boolean; + + strokeWidth: number; + + text: string; + + justification: number; + + leading: number; + + tracking: number; + + backgroundColor: number; + + backgroundAlpha: number; +} + +export declare class JPAG { + static SDKVersion(): string; +} \ No newline at end of file diff --git a/ohos/libpag/src/main/cpp/types/libpag/oh-package.json5 b/ohos/libpag/src/main/cpp/types/libpag/oh-package.json5 new file mode 100644 index 0000000000..c84a8255fb --- /dev/null +++ b/ohos/libpag/src/main/cpp/types/libpag/oh-package.json5 @@ -0,0 +1,6 @@ +{ + "name": "libpag.so", + "types": "./Index.d.ts", + "version": "1.0.0", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAG.ets b/ohos/libpag/src/main/ets/PAG.ets new file mode 100644 index 0000000000..f8eac6c363 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAG.ets @@ -0,0 +1,10 @@ +import { JPAG } from 'libpag.so'; + +export class PAG { + /** + * Get SDK version information. + */ + static SDKVersion(): string { + return JPAG.SDKVersion(); + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGComposition.ets b/ohos/libpag/src/main/ets/PAGComposition.ets new file mode 100644 index 0000000000..0010c2ca24 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGComposition.ets @@ -0,0 +1,178 @@ +import { PAGLayer } from "./PAGLayer" +import { JPAGLayer, JPAGComposition } from "libpag.so" +import { PAGMarker } from './PAGMarker'; +import { PAGUtils } from './private/PAGUtils'; + +export class PAGComposition extends PAGLayer { + static Make(width: number, height: number): PAGComposition | null { + let native = JPAGComposition.Make(width, height); + if (native == null) { + return null; + } + return new PAGComposition(native); + } + + constructor(nativeLayer: JPAGLayer) { + super(nativeLayer); + } + + /** + * The width of Composition. + */ + width(): number { + return this.getNativeComposition().width(); + } + + /** + * Returns the height of Composition. + */ + height(): number { + return this.getNativeComposition().height(); + } + + /** + * Set the size of the Composition. + */ + setContentSize(width: number, height: number): void { + this.getNativeComposition().setContentSize(width, height); + } + + /** + * Returns the number of child layers of this composition. + */ + numChildren(): number { + return this.getNativeComposition().numChildren(); + } + + /** + * Returns the child layer that exists at the specified index. + * @param index The index position of the child layer. + * @return The child layer at the specified index position. + */ + getLayerAt(index: number): PAGLayer { + return PAGUtils.WarpJPAGLayer(this.getNativeComposition().getLayerAt(index)); + } + + /** + * Returns the index position of a child layer. + * @param layer The layer instance to identify. + * @return The index position of the child layer to identify. + */ + getLayerIndex(layer: PAGLayer): number { + return this.getNativeComposition().getLayerIndex(layer.nativeLayer); + } + + /** + * Changes the position of an existing child in the container. This affects the layering of child layers. + * @param layer The child layer for which you want to change the index number. + * @param index The resulting index number for the child layer. + */ + setLayerIndex(layer: PAGLayer, index: number): void { + this.getNativeComposition().setLayerIndex(layer.nativeLayer, index); + } + + /** + * Add PAGLayer to current PAGComposition at the top. + */ + addLayer(pagLayer: PAGLayer): void { + this.getNativeComposition().addLayer(pagLayer.nativeLayer); + } + + /** + * Add PAGLayer to current PAGComposition at the specified index. + */ + addLayerAt(pagLayer: PAGLayer, index: number): void { + this.getNativeComposition().addLayerAt(pagLayer.nativeLayer, index); + } + + /** + * Check whether current PAGComposition contains the specified pagLayer. + */ + contains(pagLayer: PAGLayer): boolean { + return this.getNativeComposition().contains(pagLayer.nativeLayer); + } + + /** + * Remove the specified PAGLayer from current PAGComposition. + */ + removeLayer(pagLayer: PAGLayer): PAGLayer | null { + let result = this.getNativeComposition().removeLayer(pagLayer.nativeLayer); + if (result == null) { + return null; + } + return PAGUtils.WarpJPAGLayer(result); + } + + /** + * Remove the PAGLayer at specified index from current PAGComposition. + */ + removeLayerAt(index: number): PAGLayer | null { + let result = this.getNativeComposition().removeLayerAt(index); + if (result == null) { + return null; + } + return PAGUtils.WarpJPAGLayer(result); + } + + /** + * Remove all PAGLayers from current PAGComposition. + */ + removeAllLayers(): void { + this.getNativeComposition().removeAllLayers(); + } + + /** + * Swap the layers. + */ + swapLayer(pagLayer1: PAGLayer, pagLayer2: PAGLayer): void { + this.getNativeComposition().swapLayer(pagLayer1.nativeLayer, pagLayer2.nativeLayer); + } + + /** + * Swap the layers at the specified index. + */ + swapLayerAt(index1: number, index2: number) { + this.getNativeComposition().swapLayerAt(index1, index2); + } + + /** + * The audio data of this composition, which is an AAC audio in an MPEG-4 container. + */ + audioBytes(): ArrayBuffer | null { + return this.getNativeComposition().audioBytes(); + } + + /** + * Indicates when the first frame of the audio plays in the composition's timeline. + */ + audioStartTime(): number { + return this.getNativeComposition().audioStartTime(); + } + + /** + * Returns the audio markers of this composition. + */ + audioMarkers(): Array { + return this.getNativeComposition().audioMarkers() as Array; + } + + /** + * Returns an array of layers that match the specified layer name. + */ + getLayersByName(layerName: string): Array { + return PAGUtils.WarpJPAGLayers(this.getNativeComposition().getLayersByName(layerName)); + } + + /** + * Returns an array of layers that lie under the specified point. The point is in pixels and from this + * PAGComposition's local coordinates. + */ + getLayersUnderPoint(localX: number, localY: number): Array { + return PAGUtils.WarpJPAGLayers(this.getNativeComposition().getLayersUnderPoint(localX, localY)); + } + + + getNativeComposition(): JPAGComposition { + return this.nativeLayer as JPAGComposition; + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGFile.ets b/ohos/libpag/src/main/ets/PAGFile.ets new file mode 100644 index 0000000000..4969fc8617 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGFile.ets @@ -0,0 +1,216 @@ +import { JPAGFile, JPAGLayer } from 'libpag.so' +import { PAGComposition } from './PAGComposition' +import { resourceManager } from '@kit.LocalizationKit'; +import { PAGLayer, PAGLayerType } from './PAGLayer'; +import { PAGText } from './PAGText'; +import { PAGImage } from './PAGImage'; +import { PAGUtils } from './private/PAGUtils'; + +/** + * Defines the rules on how to stretch the timeline of content to fit the specified duration. + */ +export enum PAGTimeStretchMode { + /** + * Keep the original playing speed, and display the last frame if the content's duration is less + * than target duration. + */ + None = 0, + /* + * Change the playing speed of the content to fit target duration. + */ + Scale = 1, + /** + * Keep the original playing speed, but repeat the content if the content's duration is less than + * target duration. This is the default mode. + */ + Repeat = 2, + /** + * Keep the original playing speed, but repeat the content in reversed if the content's duration + * is less than target duration. + */ + RepeatInverted = 3 +} + +export class PAGFile extends PAGComposition { + constructor(nativeLayer: JPAGLayer) { + super(nativeLayer); + } + + /** + * The maximum tag level current SDK supports. + */ + static MaxSupportedTagLevel(): number { + return JPAGFile.MaxSupportedTagLevel(); + }; + + /** + * Load a pag file from the specified path, returns null if the file does not exist or the + * data is not a pag file. + * Note: All PAGFiles loaded by the same path share the same internal cache. The internal + * cache is alive until all PAGFiles are released. Use 'PAGFile.Load(byte[])' instead + * if you don't want to load a PAGFile from the intenal caches. + */ + static LoadFromPath(filePath: string): PAGFile | null { + let native = JPAGFile.LoadFromPath(filePath); + if (native == null) { + return null; + } + return new PAGFile(native); + } + + static LoadFromBytes(data: Int8Array, filePath?: string): PAGFile | null { + let native = JPAGFile.LoadFromBytes(data, filePath); + if (native == null) { + return null; + } + return new PAGFile(native); + } + + /** + * Load a pag file from assets, returns null if the file does not exist or the data is not a + * pag file. + * Note: The same path shares resource in memory untill the file is released. If the file + * may be changed, please use 'Load(byte[])' instead + */ + static LoadFromAssets(manager: resourceManager.ResourceManager, name: string): PAGFile | null { + let native = JPAGFile.LoadFromAssets(manager, name); + if (native == null) { + return null; + } + return new PAGFile(native); + } + + /** + * The tag level this pag file requires. + */ + tagLevel(): number { + return this.getNativeFile().tagLevel(); + } + + /** + * The number of editable texts. + */ + numTexts(): number { + return this.getNativeFile().numTexts(); + } + + /** + * The number of replaceable images. + */ + numImages(): number { + return this.getNativeFile().numImages(); + } + + /** + * The number of video compositions. + */ + numVideos(): number { + return this.getNativeFile().numVideos(); + } + + + /** + * The path string of this file, returns empty string if the file is loaded from byte stream. + */ + path(): string { + return this.getNativeFile().path(); + } + + /** + * Get a text data of the specified index. The index ranges from 0 to numTexts - 1. + * Note: It always returns the default text data. + */ + getTextData(index: number): PAGText | null { + let nativeFile = this.getNativeFile(); + let result = nativeFile.getTextData(index); + if (result == null) { + return null; + } + return PAGUtils.ToPAGText(result); + } + + /** + * Replace the text data of the specified index. The index ranges from 0 to PAGFile.numTexts - 1. Passing in null + * for the textData parameter will reset it to default text data. + */ + replaceText(editableTextIndex: number, textData: PAGText | null) { + if (textData == null) { + this.getNativeFile().replaceText(editableTextIndex, null); + } else { + this.getNativeFile().replaceText(editableTextIndex, PAGUtils.ToJPAGText(textData)); + } + } + + /** + * Replace the image data of the specified index. The index ranges from 0 to PAGFile.numImages - 1. Passing in null + * for the image parameter will reset it to default image data. + */ + replaceImage(editableImageIndex: number, image: PAGImage | null) { + if (image == null) { + this.getNativeFile().replaceImage(editableImageIndex, null); + } else { + this.getNativeFile().replaceImage(editableImageIndex, image.nativeImage); + } + } + + /** + * Replace the image data of the specified layer name. Passing in null + * for the image parameter will reset it to default image data. + */ + replaceImageByName(layerName: string, image: PAGImage | null) { + if (image == null) { + this.getNativeFile().replaceImageByName(layerName, null); + } else { + this.getNativeFile().replaceImageByName(layerName, image.nativeImage); + } + } + + /** + * Return an array of layers by specified editable index and layer type. + */ + getLayersByEditableIndex(editableIndex: number, layerType: PAGLayerType): Array { + return PAGUtils.WarpJPAGLayers(this.getNativeFile().getLayersByEditableIndex(editableIndex, layerType)); + } + + /** + * Returns the indices of the editable layers in this PAGFile. + * If the editableIndex of a PAGLayer is not present in the returned indices, the PAGLayer should + * not be treated as editable. + */ + getEditableIndices(layerType: PAGLayerType): Array { + return this.getNativeFile().getEditableIndices(layerType); + } + + /** + * Indicate how to stretch the original duration to fit target duration when file's duration is changed. + * The default value is PAGTimeStretchMode::Repeat. + */ + timeStretchMode(): PAGTimeStretchMode { + return this.getNativeFile().timeStretchMode(); + } + + /** + * Set the timeStretchMode of this file. + */ + setTimeStretchMode(value: PAGTimeStretchMode) { + this.getNativeFile().setTimeStretchMode(value); + } + + /** + * Set the duration of this PAGFile. Passing a value less than or equal to 0 resets the duration to its default value. + */ + setDuration(duration: number) { + this.getNativeFile().setDuration(duration); + } + + /** + * Make a copy of the original file, any modification to current file has no effect on the result file. + */ + copyOriginal(): PAGFile { + return new PAGFile(this.getNativeFile().copyOriginal()); + } + + private getNativeFile(): JPAGFile { + return this.nativeLayer as JPAGFile; + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGFont.ets b/ohos/libpag/src/main/ets/PAGFont.ets new file mode 100644 index 0000000000..2ec2d5bdc9 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGFont.ets @@ -0,0 +1,35 @@ +import { resourceManager } from '@kit.LocalizationKit'; +import { JPAGFont } from 'libpag.so'; +import { PAGUtils } from './private/PAGUtils'; + +export class PAGFont { + static RegisterFontFromPath(fontPath: string, ttcIndex?: number, + fontFamily?: string, fontStyle?: string): PAGFont { + let jFont = JPAGFont.RegisterFontFromPath(fontPath, ttcIndex, fontFamily, fontStyle); + return PAGUtils.ToPAGFont(jFont); + } + + static RegisterFontFromAsset(manager: resourceManager.ResourceManager, fileName: string, ttcIndex?: number, + fontFamily?: string, fontStyle?: string): PAGFont { + let jFont = JPAGFont.RegisterFontFromAsset(manager, fileName, ttcIndex, fontFamily, fontStyle); + return PAGUtils.ToPAGFont(jFont); + } + + static UnregisterFont(font: PAGFont): void { + JPAGFont.UnregisterFont(new JPAGFont(font.fontFamily, font.fontStyle)); + } + + constructor(fontFamily?: string, fontStyle?: string) { + this.fontFamily = fontFamily ? fontFamily : ""; + this.fontStyle = fontStyle ? fontStyle : ""; + } + + /** + * A string with the name of the font family. + **/ + fontFamily: string; + /** + * A string with the style information — e.g., “bold”, “italic”. + **/ + fontStyle: string; +} diff --git a/ohos/libpag/src/main/ets/PAGImage.ets b/ohos/libpag/src/main/ets/PAGImage.ets new file mode 100644 index 0000000000..c706ce957f --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGImage.ets @@ -0,0 +1,115 @@ +import { resourceManager } from '@kit.LocalizationKit'; +import { PAGUtils } from './private/PAGUtils'; +import { Matrix4 } from '@kit.ArkUI'; +import { PAGScaleMode } from './PAGScaleMode'; +import { PAGInit } from './PAGInit'; +import { JPAGImage } from 'libpag.so' + + +export class PAGImage { + private constructor(nativeImage: JPAGImage) { + PAGInit.Init(); + this.nativeImage = nativeImage; + } + + /** + * Creates a PAGImage object from a path of a image file, return null if the file does not exist or it's not a valid image file. + * @param path + * @returns + */ + static FromPath(path: string): PAGImage | null { + let nativeImage = JPAGImage.FromPath(path); + if (nativeImage == null) { + return null; + } else { + return new PAGImage(nativeImage); + } + } + + /** + * Creates a PAGImage object from the specified byte data, return null if the bytes is empty or it's not a valid image file. + * @param data + * @returns + */ + static FromBytes(data: Int8Array): PAGImage | null { + let nativeImage = JPAGImage.FromBytes(data); + if (nativeImage == null) { + return null; + } else { + return new PAGImage(nativeImage); + } + } + + /** + * Creates a PAGImage object from pixelMap, return null if the pixelMap is empty or it's not valid. + * @param pixelMap + * @returns + */ + static FromPixelMap(pixelMap: PixelMap): PAGImage | null { + let nativeImage = JPAGImage.FromPixelMap(pixelMap); + if (nativeImage == null) { + return null; + } else { + return new PAGImage(nativeImage); + } + } + + /** + * Load a pag file from assets, returns null if the file does not exist or the data is not a valid image file. + * @param manager + * @param name + * @returns + */ + static LoadFromAssets(manager: resourceManager.ResourceManager, name: string): PAGImage | null { + let nativeImage = JPAGImage.LoadFromAssets(manager, name); + if (nativeImage == null) { + return null; + } else { + return new PAGImage(nativeImage); + } + } + + /** + * Returns the width in pixels of the image. + */ + width(): number { + return this.nativeImage.width(); + } + + /** + * Returns the height in pixels of the image. + */ + height(): number { + return this.nativeImage.height(); + } + + /** + * Returns the current scale mode. + */ + scaleMode(): PAGScaleMode { + return this.nativeImage.scaleMode(); + } + + /** + * Specifies the rule of how to scale the image content to fit the original image size. + */ + setScaleMode(mode: PAGScaleMode) { + this.nativeImage.setScaleMode(mode); + } + + /** + * Returns a copy of current matrix. + */ + matrix(): Matrix4 { + return PAGUtils.ToTsMatrix(this.nativeImage.matrix()); + } + + /** + * Set the transformation which will be applied to the image content. + */ + public setMatrix(matrix: Matrix4) { + this.nativeImage.setMatrix(PAGUtils.ToNativeMatrix(matrix)); + } + + readonly nativeImage: JPAGImage; +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGImageLayer.ets b/ohos/libpag/src/main/ets/PAGImageLayer.ets new file mode 100644 index 0000000000..3fab65a17a --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGImageLayer.ets @@ -0,0 +1,41 @@ +import { JPAGImageLayer, JPAGLayer } from 'libpag.so'; +import { PAGImage } from './PAGImage'; +import { PAGLayer } from './PAGLayer'; +import { PAGVideoRange } from './PAGVideoRange'; + +export class PAGImageLayer extends PAGLayer { + constructor(nativeLayer: JPAGLayer) { + super(nativeLayer); + } + + static Make(width: number, height: number, duration: number): PAGImageLayer | null { + let nativeImageLayer = JPAGImageLayer.Make(width, height, duration); + if (nativeImageLayer == null) { + return null; + } else { + return new PAGImageLayer(nativeImageLayer); + } + } + + contentDuration(): number { + return this.getNativeImageLayer().contentDuration(); + } + + getVideoRanges(): Array { + return this.getNativeImageLayer().getVideoRanges() as Array; + } + + setImage(image: PAGImage) { + this.getNativeImageLayer().setImage(image.nativeImage); + } + + imageBytes(): ArrayBuffer | null { + return this.getNativeImageLayer().imageBytes(); + } + + getNativeImageLayer(): JPAGImageLayer { + return this.nativeLayer as JPAGImageLayer; + } + + +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGInit.ets b/ohos/libpag/src/main/ets/PAGInit.ets new file mode 100644 index 0000000000..1403317570 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGInit.ets @@ -0,0 +1,32 @@ +import { font } from '@kit.ArkUI'; +import { JPAGFont } from 'libpag.so'; + +export class PAGInit { + static Init() { + if (PAGInit.hasInit) { + return; + } + PAGInit.InitFontFallback(); + PAGInit.hasInit = true; + } + + private static hasInit: boolean = false; + + private static InitFontFallback() { + let fontConfig = font.getUIFontConfig(); + for (let index = 0; index < fontConfig.fallbackGroups.length; index++) { + const element = fontConfig.fallbackGroups[index]; + let paths = new Array(); + for (let j = 0; j < element.fallback.length; j++) { + let fontInfo = font.getFontByName(element.fallback[j].family) + if (fontInfo == null) { + fontInfo = font.getFontByName(element.fallback[j].family + " Regular") + } + if (fontInfo != null) { + paths.push(fontInfo.path); + } + } + JPAGFont.SetFallbackFontPaths(paths); + } + } +} diff --git a/ohos/libpag/src/main/ets/PAGLayer.ets b/ohos/libpag/src/main/ets/PAGLayer.ets new file mode 100644 index 0000000000..7fc1bda265 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGLayer.ets @@ -0,0 +1,219 @@ +import { JPAGLayer } from 'libpag.so' +import { PAGComposition } from './PAGComposition'; +import { PAGMarker } from './PAGMarker'; +import { Matrix4, Rect } from '@ohos.arkui.node'; +import { PAGUtils } from './private/PAGUtils'; + +/** + * Layers are always one of the following types. + */ +export enum PAGLayerType { + Unknown = 0, + Null, + Solid, + Text, + Shape, + Image, + PreCompose +} + +export class PAGLayer { + constructor(nativeLayer: JPAGLayer) { + this.nativeLayer = nativeLayer; + } + + /** + * Returns the type of layer. + */ + layerType(): PAGLayerType { + return this.nativeLayer.layerType(); + } + + /** + * Returns the name of the layer. + */ + layerName(): string { + return this.nativeLayer.layerName(); + } + + /** + * A matrix object containing values that alter the scaling, rotation, and translation of the layer. + * Altering it does not change the animation matrix, and it will be concatenated to current animation matrix for + * displaying. + */ + matrix(): Matrix4 { + return PAGUtils.ToTsMatrix(this.nativeLayer.matrix()); + } + + /** + * A matrix object containing values that alter the scaling, rotation, and translation of the layer. + * Altering it does not change the animation matrix, and it will be concatenated to current animation matrix for + * displaying. + */ + setMatrix(matrix: Matrix4) { + this.nativeLayer.setMatrix(PAGUtils.ToNativeMatrix(matrix)); + } + + /** + * Resets the matrix to its default value. + */ + resetMatrix() { + this.nativeLayer.resetMatrix(); + } + + /** + * The final matrix for displaying, it is the combination of the matrix property and current matrix from animation. + */ + getTotalMatrix(): Matrix4 { + return PAGUtils.ToTsMatrix(this.nativeLayer.getTotalMatrix()); + } + + /** + * Whether or not the layer is visible. + */ + visible(): boolean { + return this.nativeLayer.visible(); + } + + setVisible(value: boolean) { + this.nativeLayer.setVisible(value); + } + + /** + * Ranges from 0 to PAGFile.numTexts - 1 if the layer type is text, or from 0 to PAGFile.numImages -1 if the + * layer type is image, otherwise returns -1. + */ + editableIndex(): number { + return this.nativeLayer.editableIndex(); + } + + /** + * Indicates the Container instance that contains this Node instance. + */ + parent(): PAGComposition | null { + let native = this.nativeLayer.parent(); + if (native) { + return new PAGComposition(native); + } else { + return null; + } + } + + /** + * Returns the markers of this layer. + */ + markers(): Array { + return this.nativeLayer.markers() as Array; + } + + /** + * Converts the time from the PAGLayer's (local) timeline to the PAGSurface (global) timeline. The time is in + * microseconds. + */ + localTimeToGlobal(localTime: number): number { + return this.nativeLayer.localTimeToGlobal(localTime); + } + + /** + * Converts the time from the PAGSurface (global) to the PAGLayer's (local) timeline timeline. The time is in + * microseconds. + */ + globalToLocalTime(globalTime: number): number { + return this.nativeLayer.globalToLocalTime(globalTime); + } + + /** + * The duration of the layer in microseconds, indicates the length of the visible range. + */ + duration(): number { + return this.nativeLayer.duration(); + } + + /** + * Returns the frame rate of this layer. + */ + frameRate(): number { + return this.nativeLayer.frameRate(); + } + + /** + * The start time of the layer in microseconds, indicates the start position of the visible range. It could be a negative value. + */ + startTime(): number { + return this.nativeLayer.startTime(); + } + + /** + * Set the start time of the layer, in microseconds. + */ + setStartTime(time: number) { + this.nativeLayer.setStartTime(time); + } + + /** + * The current time of the layer in microseconds, the layer is invisible if currentTime is not in the visible range + * {@code (startTime <= currentTime < startTime + duration)}. + */ + currentTime(): number { + return this.nativeLayer.currentTime(); + } + + /** + * Set the current time of the layer in microseconds. + */ + setCurrentTime(time: number) { + this.nativeLayer.setCurrentTime(time); + } + + /** + * Returns the current progress of play position, the value is from 0.0 to 1.0. + */ + getProgress(): number { + return this.nativeLayer.getProgress(); + } + + /** + * Set the progress of play position, the value ranges from 0.0 to 1.0. A value of 0.0 represents the + * frame at startTime. A value of 1.0 represents the frame at the end of duration. + */ + setProgress(value: number) { + this.nativeLayer.setProgress(value); + } + + /** + * Returns trackMatte layer of this layer. + */ + trackMatteLayer(): PAGLayer | null { + let native = this.nativeLayer.trackMatteLayer(); + if (native) { + return PAGUtils.WarpJPAGLayer(native); + } else { + return null; + } + } + + /** + * Returns a rectangle in pixels that defines the original area of the layer, which is not + * transformed by the matrix. + */ + getBounds(): Rect { + return PAGUtils.ToTsRect(this.nativeLayer.getBounds()); + } + + /** + * Indicate whether this layer is excluded from parent's timeline. If set to true, this layer's current time + * will not change when parent's current time changes. + */ + excludedFromTimeline(): boolean { + return this.nativeLayer.excludedFromTimeline(); + } + + /** + * Set the excludedFromTimeline flag of this layer. + */ + setExcludedFromTimeline(value: boolean) { + this.nativeLayer.setExcludedFromTimeline(value); + } + + readonly nativeLayer: JPAGLayer; +} diff --git a/ohos/libpag/src/main/ets/PAGMarker.ets b/ohos/libpag/src/main/ets/PAGMarker.ets new file mode 100644 index 0000000000..2506b85ff1 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGMarker.ets @@ -0,0 +1,8 @@ +/** + * Marker stores comments and other metadata and mark important times in a composition or layer. + */ +export interface PAGMarker { + startTime: number + duration: number + comment: string +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGPlayer.ets b/ohos/libpag/src/main/ets/PAGPlayer.ets new file mode 100644 index 0000000000..6f7fdd7116 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGPlayer.ets @@ -0,0 +1,243 @@ +import { Matrix4, Rect } from '@ohos.arkui.node'; +import { JPAGPlayer } from 'libpag.so' +import { PAGComposition } from './PAGComposition'; +import { PAGInit } from './PAGInit'; +import { PAGSurface } from './PAGSurface'; +import { PAGLayer } from './PAGLayer'; +import { PAGUtils } from './private/PAGUtils'; +import { PAGScaleMode } from './PAGScaleMode'; + +export class PAGPlayer { + constructor(nativePlayer: JPAGPlayer | null = null) { + PAGInit.Init(); + if (nativePlayer == null) { + this.nativePlayer = new JPAGPlayer(); + } else { + this.nativePlayer = nativePlayer; + } + } + + /** + * Returns the current PAGComposition for PAGPlayer to render as content. + */ + getComposition(): PAGComposition | null { + return this.composition; + } + + /** + * Sets a new PAGComposition for PAGPlayer to render as content. + * Note: If the composition is already added to another PAGPlayer, it will be removed from the + * previous PAGPlayer. + */ + setComposition(composition: PAGComposition | null) { + this.composition = composition; + if (composition == null) { + this.nativePlayer.setComposition(null); + } else { + this.nativePlayer.setComposition(composition.getNativeComposition()); + } + } + + /** + * Returns the PAGSurface object for PAGPlayer to render onto. + */ + getSurface(): PAGSurface | null { + return this.surface; + } + + /** + * Set the PAGSurface object for PAGPlayer to render onto. + */ + setSurface(surface: PAGSurface | null): void { + this.surface = surface; + if (surface == null) { + this.nativePlayer.setSurface(null); + } else { + this.nativePlayer.setSurface(surface.nativeSurface); + } + } + + /** + * If set to false, the player skips rendering for video composition. + */ + videoEnabled(): boolean { + return this.nativePlayer.videoEnabled(); + } + + /** + * Set the value of videoEnabled property. + */ + setVideoEnabled(value: boolean) { + return this.nativePlayer.setVideoEnabled(value); + } + + /** + * If set to true, PAGPlayer caches an internal bitmap representation of the static content for + * each layer. This caching can increase performance for layers that contain complex vector + * content. The execution speed can be significantly faster depending on the complexity of the + * content, but it requires extra graphics memory. The default value is true. + */ + cacheEnabled(): boolean { + return this.nativePlayer.cacheEnabled(); + } + + /** + * Set the value of cacheEnabled property. + */ + setCacheEnabled(value: boolean) { + this.nativePlayer.setCacheEnabled(value); + } + + /** + * If set to true, PAG will cache the associated rendering data into a disk file, such as the + * decoded image frames of video compositions. This can help reduce memory usage and improve + * rendering performance. + */ + public useDiskCache(): boolean { + return this.nativePlayer.useDiskCache(); + } + + /** + * Set the value of useDiskCache property. + */ + public setUseDiskCache(value: boolean) { + this.nativePlayer.setUseDiskCache(value); + } + + /** + * This value defines the scale factor for internal graphics caches, ranges from 0.0 to 1.0. The + * scale factors less than 1.0 may result in blurred output, but it can reduce the usage of + * graphics memory which leads to better performance. The default value is 1.0. + */ + public cacheScale(): number { + return this.nativePlayer.cacheScale(); + } + + /** + * Set the value of cacheScale property. + */ + public setCacheScale(value: number) { + this.nativePlayer.setCacheScale(value); + } + + /** + * The maximum frame rate for rendering, ranges from 1 to 60. If set to a value less than the + * actual frame rate from composition, it drops frames but increases performance. Otherwise, it + * has no effect. The default value is 60. + */ + public maxFrameRate(): number { + return this.nativePlayer.maxFrameRate(); + } + + /** + * Set the maximum frame rate for rendering. + */ + public setMaxFrameRate(value: number) { + this.nativePlayer.setMaxFrameRate(value); + } + + /** + * Returns the current scale mode. + */ + scaleMode(): PAGScaleMode { + return this.nativePlayer.scaleMode(); + } + + /** + * Specifies the rule of how to scale the pag content to fit the surface size. The matrix + * changes when this method is called. + */ + setScaleMode(mode: PAGScaleMode) { + this.nativePlayer.setScaleMode(mode); + } + + /** + * Returns a copy of current matrix. + */ + matrix(): Matrix4 { + return PAGUtils.ToTsMatrix(this.nativePlayer.matrix()); + } + + /** + * Sets the transformation which will be applied to the composition. The scaleMode property + * will be set to PAGScaleMode::None when this method is called. + */ + public setMatrix(matrix: Matrix4) { + this.nativePlayer.setMatrix(PAGUtils.ToNativeMatrix(matrix)); + } + + /** + * The duration of current composition in microseconds. + */ + public duration(): number { + return this.nativePlayer.duration(); + } + + /** + * Returns the current progress of play position, the value is from 0.0 to 1.0. + */ + public getProgress(): number { + return this.nativePlayer.getProgress(); + } + + /** + * Sets the progress of play position, the value ranges from 0.0 to 1.0. It is applied only when + * the composition is not null. + */ + setProgress(progress: number): void { + this.nativePlayer.setProgress(progress); + } + + /** + * Returns the current frame. + */ + public currentFrame(): number { + return this.nativePlayer.currentFrame(); + } + + /** + * Prepares the player for the next flush() call. It collects all CPU tasks from the current + * progress of the composition and runs them asynchronously in parallel. It is usually used for + * speeding up the first frame rendering. + */ + prepare() { + this.nativePlayer.prepare(); + } + + flush() { + this.nativePlayer.flush(); + } + + /** + * Returns a rectangle in pixels that defines the displaying area of the specified layer, which + * is in the coordinate of the PAGSurface. + */ + getBounds(pagLayer: PAGLayer): Rect { + return PAGUtils.ToTsRect(this.nativePlayer.getBounds(pagLayer.nativeLayer)) + } + + /** + * Returns an array of layers that lie under the specified point. The point is in pixels and + * from the surface's coordinates. + */ + public getLayersUnderPoint(surfaceX: number, surfaceY: number): Array { + return PAGUtils.WarpJPAGLayers(this.nativePlayer.getLayersUnderPoint(surfaceX, surfaceY)); + } + + /** + * Evaluates the PAGLayer to see if it overlaps or intersects with the specified point. The point + * is in the coordinate space of the PAGSurface, not the PAGComposition that contains the + * PAGLayer. It always returns false if the PAGLayer or its parent (or parent's parent...) has not + * been added to this PAGPlayer. The pixelHitTest parameter indicates whether or not to check + * against the actual pixels of the object (true) or the bounding box (false). Returns true if the + * PAGLayer overlaps or intersects with the specified point. + */ + hitTestPoint(pagLayer: PAGLayer, surfaceX: number, + surfaceY: number, pixelHitTest: boolean): boolean { + return this.nativePlayer.hitTestPoint(pagLayer.nativeLayer, surfaceX, surfaceY, pixelHitTest); + } + + readonly nativePlayer: JPAGPlayer; + private composition: PAGComposition | null = null; + private surface: PAGSurface | null = null; +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGScaleMode.ets b/ohos/libpag/src/main/ets/PAGScaleMode.ets new file mode 100644 index 0000000000..a0d49ededd --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGScaleMode.ets @@ -0,0 +1,20 @@ +export enum PAGScaleMode { + /** + * The content is not scaled. + */ + None = 0, + /** + * The content is stretched to fit. + */ + Stretch = 1, + /** + * The content is scaled with respect to the original unscaled image's aspect ratio. + * This is the default value. + */ + LetterBox = 2, + /** + * The content is scaled to fit with respect to the original unscaled image's aspect ratio. + * This results in cropping on one axis. + */ + Zoom = 3 +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGShapeLayer.ets b/ohos/libpag/src/main/ets/PAGShapeLayer.ets new file mode 100644 index 0000000000..97344d6e40 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGShapeLayer.ets @@ -0,0 +1,8 @@ +import { JPAGLayer } from 'libpag.so'; +import { PAGLayer } from './PAGLayer'; + +export class PAGShapeLayer extends PAGLayer { + constructor(nativeLayer: JPAGLayer) { + super(nativeLayer); + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGSolidLayer.ets b/ohos/libpag/src/main/ets/PAGSolidLayer.ets new file mode 100644 index 0000000000..b89d14e1bf --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGSolidLayer.ets @@ -0,0 +1,20 @@ +import { JPAGLayer, JPAGSolidLayer } from 'libpag.so'; +import { PAGLayer } from './PAGLayer'; + +export class PAGSolidLayer extends PAGLayer { + constructor(nativeLayer: JPAGLayer) { + super(nativeLayer); + } + + solidColor(): number { + return this.getNativeSolidColor().solidColor(); + } + + setSolidColor(color: number) { + this.getNativeSolidColor().setSolidColor(color); + } + + getNativeSolidColor(): JPAGSolidLayer { + return this.nativeLayer as JPAGSolidLayer; + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGSurface.ets b/ohos/libpag/src/main/ets/PAGSurface.ets new file mode 100644 index 0000000000..1f72cdba9f --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGSurface.ets @@ -0,0 +1,57 @@ +import { JPAGSurface } from 'libpag.so' +import { PAGInit } from './PAGInit'; +import { image } from '@kit.ImageKit'; + +export class PAGSurface { + private constructor(nativeSurface: JPAGSurface) { + PAGInit.Init(); + this.nativeSurface = nativeSurface; + } + + static MakeOffscreen(width: number, height: number): PAGSurface | null { + let nativeSurface = JPAGSurface.MakeOffscreen(width, height); + if (nativeSurface == null) { + return null; + } else { + return new PAGSurface(nativeSurface); + } + } + + /** + * The width of surface in pixels. + */ + width(): number { + return this.nativeSurface.width(); + } + + /** + * The height of surface in pixels. + */ + height(): number { + return this.nativeSurface.height(); + } + + /** + * Erases all pixels of this surface with transparent color. Returns true if the content has changed. + */ + clearAll(): boolean { + return this.nativeSurface.clearAll(); + } + + /** + * Free the cache created by the surface immediately. Call this method can reduce memory pressure. + */ + freeCache(): void { + return this.nativeSurface.freeCache(); + } + + /** + * Returns a bitmap capturing the contents of the PAGSurface. Subsequent rendering of the + * PAGSurface will not be captured. + */ + public makeSnapshot(): image.PixelMap | null { + return this.nativeSurface.makeSnapshot(); + } + + readonly nativeSurface: JPAGSurface; +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGText.ets b/ohos/libpag/src/main/ets/PAGText.ets new file mode 100644 index 0000000000..41af707c7b --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGText.ets @@ -0,0 +1,100 @@ +import { Rect } from '@ohos.arkui.node'; + +export enum PAGTextJustification { + Left = 0, + Center = 1, + Right = 2, + FullJustifyLastLineLeft = 3, + FullJustifyLastLineRight = 4, + FullJustifyLastLineCenter = 5, + FullJustifyLastLineFull = 6 +} + +export class PAGText { + /** + * When true, the text layer shows a fill. + */ + applyFill: boolean = true; + /** + * When true, the text layer shows a stroke. + */ + applyStroke: boolean = false; + /** + * Readonly, external modifications are not valid. + */ + baselineShift: number = 0; + /** + * When true, the text layer is paragraph (bounded) text. + * Readonly, external modifications are not valid. + */ + boxText: boolean = false; + /** + * For box text, the pixel boundary for the text bounds. + * Readonly, external modifications are not valid. + */ + boxTextRect: Rect = { + left: 0, + top: 0, + right: 0, + bottom: 0 + }; + /** + * Readonly, external modifications are not valid. + */ + firstBaseLine: number = 0; + fauxBold: boolean = false; + fauxItalic: boolean = false; + /** + * The text layer’s fill color. + */ + fillColor: number = 0; + /** + * A string with the name of the font family. + **/ + fontFamily: string = ""; + /** + * A string with the style information — e.g., “bold”, “italic”. + **/ + fontStyle: string = ""; + /** + * The text layer’s font size in pixels. + */ + fontSize: number = 24; + /** + * The text layer’s stroke color. + */ + strokeColor: number = 0; + /** + * Indicates the rendering order for the fill and stroke of a text layer. + * Readonly, external modifications are not valid. + */ + strokeOverFill: boolean = true; + /** + * The text layer’s stroke thickness. + */ + strokeWidth: number = 1; + /** + * The text layer’s Source Text value. + */ + text: string = ""; + /** + * The paragraph justification for the text layer. Such as : PAGJustificationLeftJustify, PAGJustificationCenterJustify... + */ + justification: PAGTextJustification = PAGTextJustification.Left; + /** + * The space between lines, 0 indicates 'auto', which is fontSize * 1.2 + */ + leading: number = 0; + /** + * The text layer’s spacing between characters. + */ + tracking: number = 0; + /** + * The text layer’s background color. + */ + backgroundColor: number = 0; + /** + * The text layer’s background alpha. 0 = 100% transparent, 255 = 100% opaque. + */ + backgroundAlpha: number = 255; +} diff --git a/ohos/libpag/src/main/ets/PAGTextLayer.ets b/ohos/libpag/src/main/ets/PAGTextLayer.ets new file mode 100644 index 0000000000..fd3998f9c0 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGTextLayer.ets @@ -0,0 +1,92 @@ +import { JPAGLayer, JPAGTextLayer } from 'libpag.so'; +import { PAGLayer } from './PAGLayer'; +import { PAGFont } from './PAGFont'; +import { PAGUtils } from './private/PAGUtils'; + +export class PAGTextLayer extends PAGLayer { + constructor(nativeLayer: JPAGLayer) { + super(nativeLayer); + } + + /** + * Returns the text layer’s fill color. + */ + fillColor(): number { + return this.getNativeTextLayer().fillColor(); + } + + /** + * Set the text layer’s fill color. + */ + setFillColor(color: number): void { + this.getNativeTextLayer().setFillColor(color); + } + + /** + * Returns the text layer's font. + */ + font(): PAGFont { + return PAGUtils.ToPAGFont(this.getNativeTextLayer().font()); + } + + /** + * Set the text layer's font. + */ + setFont(font: PAGFont) { + this.getNativeTextLayer().setFont(PAGUtils.ToJPAGFont(font)); + } + + /** + * Returns the text layer's font size. + */ + fontSize(): number { + return this.getNativeTextLayer().fontSize(); + } + + /** + * Set the text layer's font size. + */ + setFontSize(fontSize: number): void { + this.getNativeTextLayer().setFontSize(fontSize); + } + + /** + * Returns the text layer's stroke color. + */ + strokeColor(): number { + return this.getNativeTextLayer().strokeColor(); + } + + /** + * Set the text layer's stroke color. + */ + + setStrokeColor(color: number): void { + this.getNativeTextLayer().setStrokeColor(color); + } + + /** + * Returns the text layer's text. + */ + text(): string { + return this.getNativeTextLayer().text(); + } + + /** + * Set the text layer's text. + */ + setText(text: string): void { + this.getNativeTextLayer().setText(text); + } + + /** + * Reset the text layer to its default text data. + */ + reset(): void { + this.getNativeTextLayer().reset(); + } + + private getNativeTextLayer(): JPAGTextLayer { + return this.nativeLayer as JPAGTextLayer; + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGVideoRange.ets b/ohos/libpag/src/main/ets/PAGVideoRange.ets new file mode 100644 index 0000000000..07038bf974 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGVideoRange.ets @@ -0,0 +1,22 @@ +/** + * Represents a time range from the content of PAGImageLayer. + */ + +export interface PAGVideoRange { + /** + * The start time of the source video, in microseconds. + */ + startTime: number; + /** + * The end time of the source video (not included), in microseconds. + */ + endTime: number; + /** + * The duration for playing after applying speed. + */ + playDuration: number; + /** + * Indicates whether the video should play backward. + */ + reversed: boolean; +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/PAGView.ets b/ohos/libpag/src/main/ets/PAGView.ets new file mode 100644 index 0000000000..d47f80cd97 --- /dev/null +++ b/ohos/libpag/src/main/ets/PAGView.ets @@ -0,0 +1,329 @@ +import { JPAGView } from 'libpag.so' +import { PAGComposition } from './PAGComposition'; +import { PAGInit } from "./PAGInit" +import { PAGScaleMode } from './PAGScaleMode'; +import { PAGLayer } from './PAGLayer'; +import { image } from '@kit.ImageKit'; +import { PAGUtils } from './private/PAGUtils'; +import { Matrix4 } from '@ohos.arkui.node'; + +export interface PAGViewListener { + /** + * Notifies the beginning of the animation. It can be called from either the UI thread or the thread + * that calls the play method. + */ + onAnimationStart?: (view: PAGView) => void; + + /** + * Notifies the end of the animation. It can only be called from the UI thread. + */ + onAnimationEnd?: (view: PAGView) => void; + + /** + * Notifies the repetition of the animation. It can only be called from the UI thread. + */ + onAnimationRepeat?: (view: PAGView) => void; + + /** + * Notifies the cancellation of the animation. It can be called from either the UI thread or the + * thread that calls the stop method. + */ + onAnimationCancel?: (view: PAGView) => void; + + /** + * Notifies another frame of the animation has occurred. It may be called from an arbitrary + * thread if the animation is running asynchronously. + */ + onAnimationUpdate?: (view: PAGView) => void; +} + +@Component +export struct PAGView { + /** + * PAGComposition is the content of PAGView. + * Note: If the composition is already added to another PAGView, it will be removed from the + * previous PAGView. + */ + @Link @Watch("onCompositionChange") composition: PAGComposition | null; + /** + * Indicates whether this pag view is playing. + */ + @Link @Watch("onPlayStateChange") isPlaying: boolean; + /** + * The current progress of play position, the value is from 0.0 to 1.0. It is applied only + * when the composition is not null. + */ + @Link @Watch("onProgressChange") progress: number; + /** + * The total number of times the animation is set to play. The default is 1, which means the + * animation will play only once. If the repeat count is set to 0 or a negative value, the + * animation will play infinity times. + */ + @Prop @Watch("onRepeatCountChange") repeatCount: number = 0; + /** + * Set true to make PAGView playing in the main thread. The default value is false. + */ + @Prop @Watch("OnSyncChange") isSync: boolean = false; + /** + * If set to false, PAGView skips rendering for video composition. + */ + @Prop @Watch("OnVideoEnabledChange") videoEnabled: boolean = true; + /** + * If set to true, PAG renderer caches an internal bitmap representation of the static content + * for each layer. This caching can increase performance for layers that contain complex vector + * content. The execution speed can be significantly faster depending on the complexity of the + * content, but it requires extra graphics memory. The default value is true. + */ + @Prop @Watch("OnCacheEnabledChange") cacheEnabled: boolean = true; + /** + * This value defines the scale factor for internal graphics caches, ranges from 0.0 to 1.0. The + * scale factors less than 1.0 may result in blurred output, but it can reduce the usage of + * graphics memory which leads to better performance. The default value is 1.0. + */ + @Prop @Watch("OnCacheScaleChange") cacheScale: number = 1.0; + /** + * The maximum frame rate for rendering. If set to a value less than the actual frame rate from + * PAGFile, it drops frames but increases performance. Otherwise, it has no effect. The default + * value is 60. + */ + @Prop @Watch("OnMaxFrameRateChange") maxFrameRate: number = 60.0; + /** + * Specifies the rule of how to scale the pag content to fit the surface size. The matrix + * changes when this method is called. + */ + @Prop @Watch("OnScaleModeChange") scaleMode: PAGScaleMode = PAGScaleMode.LetterBox; + /** + * Sets the transformation which will be applied to the composition. The scaleMode property + * will be set to PAGScaleMode::None when this method is called. + */ + @Prop @Watch("OnMatrixChange") matrix: Matrix4 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + /** + * listener will be sent events through the life of an animation, + * such as start, repeat, and end. PAGView only holds a weak reference to the listener. + */ + @State listeners: Array> = []; + + build() { + XComponent({ + id: this.controller.uniqueID(), + type: "surface", + libraryname: "pag", + }) + .onLoad(() => { + this.initView(); + }) + .backgroundColor(Color.Transparent) + } + + flush(): void { + this.controller.flush(); + } + + /** + * Adds a listener to the set of listeners that are sent events through the life of an + * animation, such as start, repeat, and end. + */ + addListener(listener: WeakRef) { + this.listeners.push(listener); + } + + /** + * Removes a listener from the set listening to this animation. + */ + removeListener(listener: WeakRef) { + const index = this.listeners.indexOf(listener); + if (index > -1) { + this.listeners.splice(index, 1); + } + } + + /** + * Returns the current frame. + */ + currentFrame(): number { + return this.composition ? this.composition.currentTime() : 0; + } + + /** + * Returns an array of layers that lie under the specified point. + * The point is in pixels not dp. + */ + getLayersUnderPoint(x: number, y: number): Array { + return PAGUtils.WarpJPAGLayers(this.controller.getLayersUnderPoint(x, y)); + } + + /** + * Free the cache created by the pag view immediately. Can be called to reduce memory pressure. + */ + freeCache(): void { + this.controller.freeCache(); + } + + /** + * Returns a bitmap capturing the contents of the PAGView. Subsequent rendering of the + * PAGView will not be captured. Returns null if the PAGView hasn't been presented yet. + */ + makeSnapshot(): image.PixelMap | null { + return this.controller.makeSnapshot(); + } + + onPageShow(): void { + if (super.onPageShow) { + super.onPageShow(); + } + this.flush(); + } + + private initView() { + PAGInit.Init(); + this.controller.setStateChangeCallback(this.onAnimatorStateChange); + this.controller.setProgressUpdateCallback(this.onAnimatorProgressUpdate); + + this.controller.setComposition(this.composition?.getNativeComposition()); + this.controller.setProgress(this.progress); + this.controller.setRepeatCount(this.repeatCount) + this.controller.setSync(this.isSync); + this.controller.setVideoEnabled(this.videoEnabled); + this.controller.setCacheEnabled(this.cacheEnabled); + this.controller.setCacheScale(this.cacheScale); + this.controller.setMaxFrameRate(this.maxFrameRate); + if (PAGUtils.IsEmptyMatrix(this.matrix)) { + this.controller.setScaleMode(this.scaleMode); + } else { + this.controller.setMatrix(PAGUtils.ToNativeMatrix(this.matrix)); + } + if (this.isPlaying) { + this.controller.play(); + } else { + this.controller.flush(); + } + } + + private onCompositionChange() { + this.controller.setComposition(this.composition?.getNativeComposition()); + if (!this.isPlaying) { + this.flush() + } + } + + private onPlayStateChange() { + if (this.isPlaying) { + this.controller.play(); + } else { + this.controller.pause(); + } + } + + private onRepeatCountChange() { + this.controller.setRepeatCount(this.repeatCount); + } + + private onProgressChange() { + if (this.progress == this.nativeProgress) { + return; + } + this.controller.setProgress(this.progress); + if (!this.isPlaying) { + this.flush() + } + } + + private OnSyncChange() { + this.controller.setSync(this.isSync); + } + + private OnVideoEnabledChange() { + this.controller.setVideoEnabled(this.videoEnabled); + } + + private OnCacheEnabledChange() { + this.controller.setCacheEnabled(this.cacheEnabled); + } + + private OnCacheScaleChange() { + this.controller.setCacheScale(this.cacheScale); + } + + private OnMaxFrameRateChange() { + this.controller.setMaxFrameRate(this.maxFrameRate); + } + + private OnScaleModeChange() { + this.controller.setScaleMode(this.scaleMode); + } + + private OnMatrixChange() { + this.controller.setMatrix(PAGUtils.ToNativeMatrix(this.matrix)) + } + + private onAnimationStart() { + this.isPlaying = true; + for (const weakListener of this.listeners) { + const listener = weakListener.deref(); + if (listener && listener.onAnimationStart) { + listener.onAnimationStart(this); + } + } + } + + private onAnimationEnd() { + this.isPlaying = false; + for (const weakListener of this.listeners) { + const listener = weakListener.deref(); + if (listener && listener.onAnimationEnd) { + listener.onAnimationEnd(this); + } + } + } + + private onAnimationCancel() { + this.isPlaying = false; + for (const weakListener of this.listeners) { + const listener = weakListener.deref(); + if (listener && listener.onAnimationCancel) { + listener.onAnimationCancel(this); + } + } + } + + private onAnimationRepeat() { + for (const weakListener of this.listeners) { + const listener = weakListener.deref(); + if (listener && listener.onAnimationRepeat) { + listener.onAnimationRepeat(this); + } + } + } + + private nativeProgress: number = 0.0; + private controller: JPAGView = new JPAGView(); + private onAnimatorStateChange = (state: number): void => { + switch (state) { + case PAGAnimatorState.Start: + return this.onAnimationStart(); + case PAGAnimatorState.Cancel: + return this.onAnimationCancel(); + case PAGAnimatorState.End: + return this.onAnimationEnd(); + case PAGAnimatorState.Repeat: + return this.onAnimationRepeat(); + } + } + private onAnimatorProgressUpdate = (progress: number): void => { + this.nativeProgress = progress; + this.progress = progress; + for (const weakListener of this.listeners) { + const listener = weakListener.deref(); + if (listener && listener.onAnimationUpdate) { + listener.onAnimationUpdate(this); + } + } + } +} + +enum PAGAnimatorState { + Start = 0, + Cancel = 1, + End = 2, + Repeat = 3 +} \ No newline at end of file diff --git a/ohos/libpag/src/main/ets/private/PAGUtils.ets b/ohos/libpag/src/main/ets/private/PAGUtils.ets new file mode 100644 index 0000000000..32fe74ee38 --- /dev/null +++ b/ohos/libpag/src/main/ets/private/PAGUtils.ets @@ -0,0 +1,135 @@ +import { Matrix4, Rect } from '@ohos.arkui.node'; +import { JPAGFont, JPAGLayer, JPAGText } from 'libpag.so'; +import { PAGComposition } from '../PAGComposition'; +import { PAGFile } from '../PAGFile'; +import { PAGFont } from '../PAGFont'; +import { PAGImageLayer } from '../PAGImageLayer'; +import { PAGLayer, PAGLayerType } from '../PAGLayer'; +import { PAGShapeLayer } from '../PAGShapeLayer'; +import { PAGSolidLayer } from '../PAGSolidLayer'; +import { PAGText } from '../PAGText'; +import { PAGTextLayer } from '../PAGTextLayer'; + +export namespace PAGUtils { + export function ToTsMatrix(matrix: Array): Matrix4 { + + return [matrix[0], matrix[1], matrix[2], 0, + matrix[3], matrix[4], matrix[5], 0, + matrix[6], matrix[7], matrix[8], 0, + 0, 0, 0, 1]; + } + + export function ToNativeMatrix(matrix: Matrix4): Array { + return Array.of(matrix[0], matrix[1], matrix[2], matrix[4], matrix[5], matrix[6], matrix[8], matrix[9], + matrix[10]); + } + + export function ToTsRect(rect: Array): Rect { + return { + left: rect[0], + top: rect[1], + right: rect[2], + bottom: rect[3] + }; + } + + export function ToNativeRect(rect: Rect): Array { + return Array.of(rect.left, rect.top, rect.right, rect.bottom); + } + + export function WarpJPAGLayer(nativeLayer: JPAGLayer): PAGLayer { + if (nativeLayer.isPAGFile()) { + return new PAGFile(nativeLayer); + } + switch (nativeLayer.layerType()) { + case PAGLayerType.Solid: + return new PAGSolidLayer(nativeLayer); + case PAGLayerType.Text: + return new PAGTextLayer(nativeLayer); + case PAGLayerType.Shape: + return new PAGShapeLayer(nativeLayer); + case PAGLayerType.Image: + return new PAGImageLayer(nativeLayer); + case PAGLayerType.PreCompose: + return new PAGComposition(nativeLayer); + } + return new PAGLayer(nativeLayer); + } + + export function WarpJPAGLayers(nativeLayers: Array): Array { + let result = new Array(nativeLayers.length); + for (let i = 0; i < nativeLayers.length; i++) { + result[i] = PAGUtils.WarpJPAGLayer(nativeLayers[i]); + } + return result; + } + + export function ToJPAGFont(font: PAGFont): JPAGFont { + return new JPAGFont(font.fontFamily, font.fontStyle); + } + + export function ToPAGFont(font: JPAGFont): PAGFont { + return new PAGFont(font.fontFamily, font.fontStyle); + } + + export function IsEmptyMatrix(matrix: Matrix4) { + for (let index = 0; index < 16; index++) { + if (matrix[index] != 0) { + return false; + } + } + return true; + } + + export function ToPAGText(text: JPAGText): PAGText { + let result = new PAGText(); + result.applyFill = text.applyFill; + result.applyStroke = text.applyStroke; + result.baselineShift = text.baselineShift; + result.boxText = text.boxText; + result.boxTextRect = ToTsRect(text.boxTextRect); + result.firstBaseLine = text.firstBaseLine; + result.fauxBold = text.fauxBold; + result.fauxItalic = text.fauxItalic; + result.fillColor = text.fillColor; + result.fontFamily = text.fontFamily; + result.fontStyle = text.fontStyle; + result.fontSize = text.fontSize; + result.strokeColor = text.strokeColor; + result.strokeOverFill = text.strokeOverFill; + result.strokeWidth = text.strokeWidth; + result.text = text.text; + result.justification = text.justification; + result.leading = text.leading; + result.tracking = text.tracking; + result.backgroundColor = text.backgroundColor; + result.backgroundAlpha = text.backgroundAlpha; + return result; + } + + export function ToJPAGText(text: PAGText): JPAGText { + let result = new JPAGText(); + result.applyFill = text.applyFill; + result.applyStroke = text.applyStroke; + result.baselineShift = text.baselineShift; + result.boxText = text.boxText; + result.boxTextRect = ToNativeRect(text.boxTextRect); + result.firstBaseLine = text.firstBaseLine; + result.fauxBold = text.fauxBold; + result.fauxItalic = text.fauxItalic; + result.fillColor = text.fillColor; + result.fontFamily = text.fontFamily; + result.fontStyle = text.fontStyle; + result.fontSize = text.fontSize; + result.strokeColor = text.strokeColor; + result.strokeOverFill = text.strokeOverFill; + result.strokeWidth = text.strokeWidth; + result.text = text.text; + result.justification = text.justification; + result.leading = text.leading; + result.tracking = text.tracking; + result.backgroundColor = text.backgroundColor; + result.backgroundAlpha = text.backgroundAlpha; + return result; + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/module.json5 b/ohos/libpag/src/main/module.json5 new file mode 100644 index 0000000000..909fe72546 --- /dev/null +++ b/ohos/libpag/src/main/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "libpag", + "type": "shared", + "description": "$string:shared_desc", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true + } +} \ No newline at end of file diff --git a/ohos/libpag/src/main/resources/base/element/string.json b/ohos/libpag/src/main/resources/base/element/string.json new file mode 100644 index 0000000000..98e1d8a84b --- /dev/null +++ b/ohos/libpag/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "shared_desc", + "value": "description" + } + ] +} \ No newline at end of file diff --git a/ohos/libpag/src/main/resources/base/profile/main_pages.json b/ohos/libpag/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000..2c63c08510 --- /dev/null +++ b/ohos/libpag/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,2 @@ +{ +} diff --git a/ohos/libpag/src/ohosTest/ets/test/Ability.test.ets b/ohos/libpag/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000..85c78f6757 --- /dev/null +++ b/ohos/libpag/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,35 @@ +import { hilog } from '@kit.PerformanceAnalysisKit'; +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); + }) + }) +} \ No newline at end of file diff --git a/ohos/libpag/src/ohosTest/ets/test/List.test.ets b/ohos/libpag/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000..794c7dc4ed --- /dev/null +++ b/ohos/libpag/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,5 @@ +import abilityTest from './Ability.test'; + +export default function testsuite() { + abilityTest(); +} \ No newline at end of file diff --git a/ohos/libpag/src/ohosTest/module.json5 b/ohos/libpag/src/ohosTest/module.json5 new file mode 100644 index 0000000000..cbd9c51720 --- /dev/null +++ b/ohos/libpag/src/ohosTest/module.json5 @@ -0,0 +1,13 @@ +{ + "module": { + "name": "libpag_test", + "type": "feature", + "deviceTypes": [ + "phone", + "tablet", + "2in1" + ], + "deliveryWithInstall": true, + "installationFree": false + } +} \ No newline at end of file diff --git a/ohos/libpag/src/test/List.test.ets b/ohos/libpag/src/test/List.test.ets new file mode 100644 index 0000000000..bb5b5c3731 --- /dev/null +++ b/ohos/libpag/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest(); +} \ No newline at end of file diff --git a/ohos/libpag/src/test/LocalUnit.test.ets b/ohos/libpag/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000..165fc1615e --- /dev/null +++ b/ohos/libpag/src/test/LocalUnit.test.ets @@ -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); + }); + }); +} \ No newline at end of file diff --git a/ohos/oh-package-lock.json5 b/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000..98a0290587 --- /dev/null +++ b/ohos/oh-package-lock.json5 @@ -0,0 +1,27 @@ +{ + "meta": { + "stableOrder": true + }, + "lockfileVersion": 3, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hamock@1.0.0": "@ohos/hamock@1.0.0", + "@ohos/hypium@1.0.18": "@ohos/hypium@1.0.18" + }, + "packages": { + "@ohos/hamock@1.0.0": { + "name": "@ohos/hamock", + "version": "1.0.0", + "integrity": "sha512-K6lDPYc6VkKe6ZBNQa9aoG+ZZMiwqfcR/7yAVFSUGIuOAhPvCJAo9+t1fZnpe0dBRBPxj2bxPPbKh69VuyAtDg==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hamock/-/hamock-1.0.0.har", + "registryType": "ohpm" + }, + "@ohos/hypium@1.0.18": { + "name": "@ohos/hypium", + "version": "1.0.18", + "integrity": "sha512-RGe/iLGdeywdQilMWZsHKUoiE9OJ+9QxQsorF92R2ImLNVHVhbpSePNITGpW7TnvLgOIP/jscOqfIOhk6X7XRQ==", + "resolved": "https://ohpm.openharmony.cn/ohpm/@ohos/hypium/-/hypium-1.0.18.har", + "registryType": "ohpm" + } + } +} \ No newline at end of file diff --git a/ohos/oh-package.json5 b/ohos/oh-package.json5 new file mode 100644 index 0000000000..ebdda7e54d --- /dev/null +++ b/ohos/oh-package.json5 @@ -0,0 +1,10 @@ +{ + "modelVersion": "5.0.0", + "description": "Please describe the basic information.", + "dependencies": { + }, + "devDependencies": { + "@ohos/hypium": "1.0.18", + "@ohos/hamock": "1.0.0" + } +} diff --git a/src/platform/ohos/HardwareDecoder.cpp b/src/platform/ohos/HardwareDecoder.cpp index ea2d565e62..e24a5641d9 100644 --- a/src/platform/ohos/HardwareDecoder.cpp +++ b/src/platform/ohos/HardwareDecoder.cpp @@ -14,6 +14,7 @@ // either express or implied. see the license for the specific language governing permissions // and limitations under the license. // +///////////////////////////////////////////////////////////////////////////////////////////////// #include "HardwareDecoder.h" #include @@ -182,7 +183,7 @@ DecodingResult HardwareDecoder::onDecodeFrame() { pendingFrames.remove(codecBufferInfo.attr.pts); } else { lock.unlock(); - return DecodingResult::TryAgainLater; + return DecodingResult::Success; } int ret = OH_VideoDecoder_FreeOutputBuffer(videoCodec, codecBufferInfo.bufferIndex); if (ret != AV_ERR_OK) { @@ -218,7 +219,10 @@ bool HardwareDecoder::start() { } int64_t HardwareDecoder::presentationTime() { - return codecBufferInfo.attr.pts; + if (codecBufferInfo.buffer) { + return codecBufferInfo.attr.pts; + } + return -1; } std::shared_ptr HardwareDecoder::onRenderFrame() { diff --git a/src/platform/ohos/HardwareDecoder.h b/src/platform/ohos/HardwareDecoder.h index 7540313d3c..5fc7b33e57 100644 --- a/src/platform/ohos/HardwareDecoder.h +++ b/src/platform/ohos/HardwareDecoder.h @@ -14,6 +14,7 @@ // either express or implied. see the license for the specific language governing permissions // and limitations under the license. // +///////////////////////////////////////////////////////////////////////////////////////////////// #pragma once @@ -88,8 +89,8 @@ class HardwareDecoder : public VideoDecoder { OH_AVCodecCategory codecCategory = HARDWARE; int videoStride = 0; int videoSliceHeight = 0; - int yBufferSize = 0; - int uvBufferSize = 0; + int64_t yBufferSize = 0; + int64_t uvBufferSize = 0; YUVBuffer yuvBuffer{}; explicit HardwareDecoder(const VideoFormat& format); bool initDecoder(const OH_AVCodecCategory avCodecCategory); diff --git a/src/platform/ohos/JPAG.cpp b/src/platform/ohos/JPAG.cpp new file mode 100644 index 0000000000..84415d86ac --- /dev/null +++ b/src/platform/ohos/JPAG.cpp @@ -0,0 +1,80 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAG.h" +#include "base/utils/Log.h" +#include "pag/pag.h" +#include "platform/ohos/JPAG.h" +#include "platform/ohos/JPAGFont.h" +#include "platform/ohos/JPAGImage.h" +#include "platform/ohos/JPAGText.h" +#include "platform/ohos/JPAGView.h" +#include "platform/ohos/JPAGLayerHandle.h" +#include "platform/ohos/JPAGPlayer.h" +#include "platform/ohos/JPAGSurface.h" +#include "platform/ohos/JsHelper.h" + +namespace pag { +static napi_value SDKVersion(napi_env env, napi_callback_info) { + napi_value value; + auto version = PAG::SDKVersion(); + napi_create_string_utf8(env, version.c_str(), version.length(), &value); + return value; +} + +napi_value JPAG::Constructor(napi_env env, napi_callback_info info) { + napi_value result = nullptr; + size_t argc = 1; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &result, nullptr); + if (argc == 0) { + return nullptr; + } + return result; +} + +bool JPAG::Init(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = {PAG_STATIC_METHOD_ENTRY(SDKVersion, SDKVersion)}; + auto status = DefineClass(env, exports, ClassName(), sizeof(classProp) / sizeof(classProp[0]), + classProp, Constructor, ""); + return status == napi_ok; +} +} // namespace pag + +EXTERN_C_START + +static napi_value Init(napi_env env, napi_value exports) { + bool result = pag::JPAG::Init(env, exports) && pag::JPAGLayerHandle::Init(env, exports) && + pag::JPAGImage::Init(env, exports) && pag::JPAGPlayer::Init(env, exports) && + pag::JPAGSurface::Init(env, exports) && pag::JPAGFont::Init(env, exports) && + pag::JPAGText::Init(env, exports) && pag::JPAGImage::Init(env, exports) && + pag::JPAGView::Init(env, exports); + if (!result) { + LOGE("PAG InitFailed"); + } + return exports; +} +EXTERN_C_END + +static napi_module demoModule = { + 1, 0, nullptr, Init, "pag", ((void*)0), {0}, +}; + +extern "C" __attribute__((constructor)) void RegisterEntryModule(void) { + napi_module_register(&demoModule); +} \ No newline at end of file diff --git a/src/platform/ohos/JPAG.h b/src/platform/ohos/JPAG.h new file mode 100644 index 0000000000..db82e9bbd1 --- /dev/null +++ b/src/platform/ohos/JPAG.h @@ -0,0 +1,35 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include +#include "napi/native_api.h" + +namespace pag { +class JPAG { + public: + static bool Init(napi_env env, napi_value exports); + static std::string ClassName() { + return "JPAG"; + } + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); +}; +} // namespace pag diff --git a/src/platform/ohos/JPAGComposition.cpp b/src/platform/ohos/JPAGComposition.cpp new file mode 100644 index 0000000000..bd71def043 --- /dev/null +++ b/src/platform/ohos/JPAGComposition.cpp @@ -0,0 +1,432 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include "JPAGLayerHandle.h" +#include "JsHelper.h" + +namespace pag { + +static std::shared_ptr FromJs(napi_env env, napi_value value) { + auto layer = JPAGLayerHandle::FromJs(env, value); + if (layer && layer->layerType() == LayerType::PreCompose) { + return std::static_pointer_cast(layer); + } + return nullptr; +} + +static napi_value Make(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + int width = 0; + int height = 0; + napi_get_value_int32(env, args[0], &width); + napi_get_value_int32(env, args[1], &height); + return JPAGLayerHandle::ToJs(env, PAGComposition::Make(width, height)); +} + +static napi_value Width(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + napi_value value; + napi_create_int32(env, 0, &value); + return value; + } + napi_value value; + napi_create_int32(env, composition->width(), &value); + return value; +} + +static napi_value Height(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + napi_value value; + napi_create_int32(env, composition->height(), &value); + return value; +} + +static napi_value SetContentSize(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 2; + napi_value args[2] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + int32_t width = 0; + napi_get_value_int32(env, args[0], &width); + int32_t height = 0; + napi_get_value_int32(env, args[1], &height); + composition->setContentSize(width, height); + return nullptr; +} + +static napi_value NumChildren(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + napi_value value; + napi_create_int32(env, composition->numChildren(), &value); + return value; +} + +static napi_value GetLayerAt(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + int32_t index = -1; + napi_get_value_int32(env, args[0], &index); + return JPAGLayerHandle::ToJs(env, composition->getLayerAt(index)); +} + +static napi_value GetLayerIndex(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + napi_value value; + napi_create_int32(env, composition->getLayerIndex(layer), &value); + return value; +} + +static napi_value SetLayerIndex(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 2; + napi_value args[2] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + if (!layer) { + return nullptr; + } + int32_t index = -1; + napi_get_value_int32(env, args[1], &index); + if (index < 0) { + return nullptr; + } + composition->setLayerIndex(layer, index); + return nullptr; +} + +static napi_value AddLayer(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + napi_value value; + if (!composition) { + napi_get_boolean(env, false, &value); + return value; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + if (!layer) { + napi_get_boolean(env, false, &value); + } else { + napi_get_boolean(env, composition->addLayer(layer), &value); + } + return value; +} + +static napi_value AddLayerAt(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 2; + napi_value args[2] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + napi_value value; + if (!composition) { + napi_get_boolean(env, false, &value); + return value; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + if (!layer) { + napi_get_boolean(env, false, &value); + return value; + } + int32_t index = -1; + napi_get_value_int32(env, args[1], &index); + if (index < 0) { + napi_get_boolean(env, false, &value); + } else { + napi_get_boolean(env, composition->addLayerAt(layer, index), &value); + } + return value; +} + +static napi_value Contains(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + napi_value value; + if (!composition) { + napi_get_boolean(env, false, &value); + return value; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + if (!layer) { + napi_get_boolean(env, false, &value); + return value; + } + napi_get_boolean(env, composition->contains(layer), &value); + return value; +} + +static napi_value RemoveLayer(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + if (!layer) { + return nullptr; + } + return JPAGLayerHandle::ToJs(env, composition->removeLayer(layer)); +} + +static napi_value RemoveLayerAt(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + int32_t index = -1; + napi_get_value_int32(env, args[0], &index); + if (index < 0) { + return nullptr; + } + return JPAGLayerHandle::ToJs(env, composition->removeLayerAt(index)); +} + +static napi_value RemoveAllLayers(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + composition->removeAllLayers(); + return nullptr; +} + +static napi_value SwapLayer(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 2; + napi_value args[2] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + auto layer1 = JPAGLayerHandle::FromJs(env, args[0]); + if (!layer1) { + return nullptr; + } + auto layer2 = JPAGLayerHandle::FromJs(env, args[1]); + if (!layer2) { + return nullptr; + } + composition->swapLayer(layer1, layer2); + return nullptr; +} + +static napi_value SwapLayerAt(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 2; + napi_value args[2] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + int32_t index1 = -1; + napi_get_value_int32(env, args[0], &index1); + if (index1 < 0) { + return nullptr; + } + int32_t index2 = -1; + napi_get_value_int32(env, args[1], &index2); + if (index2 < 0) { + return nullptr; + } + composition->swapLayerAt(index1, index2); + return nullptr; +} + +static napi_value AudioBytes(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + napi_value arraybuffer; + void* data = nullptr; + auto audio = composition->audioBytes(); + napi_create_arraybuffer(env, audio->length(), &data, &arraybuffer); + memcpy(data, audio->data(), audio->length()); + return arraybuffer; +} + +static napi_value AudioMarkers(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + return CreateMarkers(env, composition->audioMarkers()); +} + +static napi_value AudioStartTime(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + napi_value value; + napi_create_int32(env, 0, &value); + return value; + } + napi_value value; + napi_create_int32(env, composition->audioStartTime(), &value); + return value; +} + +static napi_value GetLayersByName(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + char name[1024] = {0}; + size_t length = 0; + napi_get_value_string_utf8(env, args[0], name, 1024, &length); + auto layers = composition->getLayersByName(std::string(name, length)); + napi_value array; + napi_create_array_with_length(env, layers.size(), &array); + for (size_t i = 0; i < layers.size(); i++) { + napi_set_element(env, array, i, JPAGLayerHandle::ToJs(env, layers[i])); + } + return array; +} + +static napi_value GetLayersUnderPoint(napi_env env, napi_callback_info info) { + napi_value jsComposition = nullptr; + size_t argc = 2; + napi_value args[2] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsComposition, nullptr); + auto composition = FromJs(env, jsComposition); + if (!composition) { + return nullptr; + } + double x = 0; + napi_get_value_double(env, args[0], &x); + double y = 0; + napi_get_value_double(env, args[1], &y); + auto layers = composition->getLayersUnderPoint(x, y); + napi_value array; + napi_create_array_with_length(env, layers.size(), &array); + for (size_t i = 0; i < layers.size(); i++) { + napi_set_element(env, array, i, JPAGLayerHandle::ToJs(env, layers[i])); + } + return array; +} + +bool JPAGLayerHandle::InitPAGCompositionLayerEnv(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = { + PAG_STATIC_METHOD_ENTRY(Make, Make), + + PAG_DEFAULT_METHOD_ENTRY(width, Width), + PAG_DEFAULT_METHOD_ENTRY(height, Height), + PAG_DEFAULT_METHOD_ENTRY(setContentSize, SetContentSize), + PAG_DEFAULT_METHOD_ENTRY(numChildren, NumChildren), + PAG_DEFAULT_METHOD_ENTRY(getLayerAt, GetLayerAt), + PAG_DEFAULT_METHOD_ENTRY(getLayerIndex, GetLayerIndex), + PAG_DEFAULT_METHOD_ENTRY(setLayerIndex, SetLayerIndex), + PAG_DEFAULT_METHOD_ENTRY(addLayer, AddLayer), + PAG_DEFAULT_METHOD_ENTRY(addLayerAt, AddLayerAt), + PAG_DEFAULT_METHOD_ENTRY(contains, Contains), + PAG_DEFAULT_METHOD_ENTRY(removeLayer, RemoveLayer), + PAG_DEFAULT_METHOD_ENTRY(removeLayerAt, RemoveLayerAt), + PAG_DEFAULT_METHOD_ENTRY(removeAllLayers, RemoveAllLayers), + PAG_DEFAULT_METHOD_ENTRY(swapLayer, SwapLayer), + PAG_DEFAULT_METHOD_ENTRY(swapLayerAt, SwapLayerAt), + PAG_DEFAULT_METHOD_ENTRY(audioBytes, AudioBytes), + PAG_DEFAULT_METHOD_ENTRY(audioMarkers, AudioMarkers), + PAG_DEFAULT_METHOD_ENTRY(audioStartTime, AudioStartTime), + PAG_DEFAULT_METHOD_ENTRY(getLayersByName, GetLayersByName), + PAG_DEFAULT_METHOD_ENTRY(getLayersUnderPoint, GetLayersUnderPoint)}; + + auto status = DefineClass(env, exports, GetLayerClassName(LayerType::PreCompose), + sizeof(classProp) / sizeof(classProp[0]), classProp, Constructor, + GetBaseClassName()); + return status == napi_status::napi_ok; +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGFile.cpp b/src/platform/ohos/JPAGFile.cpp new file mode 100644 index 0000000000..4ccd18d7f6 --- /dev/null +++ b/src/platform/ohos/JPAGFile.cpp @@ -0,0 +1,357 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include "JPAGLayerHandle.h" +#include "JsHelper.h" +#include "platform/ohos/JPAGImage.h" +#include "platform/ohos/JPAGText.h" + +namespace pag { + +static std::shared_ptr FromJs(napi_env env, napi_value value) { + auto layer = JPAGLayerHandle::FromJs(env, value); + if (layer && layer->isPAGFile()) { + return std::static_pointer_cast(layer); + } + return nullptr; +} + +static napi_value MaxSupportedTagLevel(napi_env env, napi_callback_info) { + napi_value result; + napi_create_uint32(env, PAGFile::MaxSupportedTagLevel(), &result); + return result; +} + +static napi_value LoadFromPath(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + char filePath[1024] = {0}; + size_t length = 0; + napi_get_value_string_utf8(env, args[0], filePath, 1024, &length); + return JPAGLayerHandle::ToJs(env, PAGFile::Load(std::string(filePath, length))); +} + +static napi_value LoadFromBytes(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + size_t length; + void* data; + auto code = napi_get_arraybuffer_info(env, args[1], &data, &length); + if (code != napi_ok) { + return nullptr; + } + std::string path = ""; + if (argc == 2) { + char filePath[1024] = {0}; + size_t pathLength = 0; + napi_get_value_string_utf8(env, args[0], filePath, 1024, &pathLength); + path = std::string(filePath, length); + } + return JPAGLayerHandle::ToJs(env, PAGFile::Load(data, length, path)); +} + +static napi_value LoadFromAssets(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + NativeResourceManager* mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]); + size_t strSize; + char srcBuf[1024]; + napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize); + std::string fileName(srcBuf, strSize); + RawFile* rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf); + if (rawFile != NULL) { + long len = OH_ResourceManager_GetRawFileSize(rawFile); + auto data = ByteData::Make(len); + if (!data) { + return nullptr; + } + OH_ResourceManager_ReadRawFile(rawFile, data->data(), len); + return JPAGLayerHandle::ToJs(env, PAGFile::Load(data->data(), len, "asset://" + fileName)); + } + return nullptr; +} + +static napi_value TagLevel(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + napi_value result; + napi_create_int32(env, file->tagLevel(), &result); + return result; +} + +static napi_value NumTexts(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + napi_value result; + napi_create_int32(env, file->numTexts(), &result); + return result; +} + +static napi_value NumImages(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + napi_value result; + napi_create_int32(env, file->numImages(), &result); + return result; +} + +static napi_value NumVideos(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + napi_value result; + napi_create_int32(env, file->numVideos(), &result); + return result; +} + +static napi_value Path(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + napi_value result; + auto path = file->path(); + napi_create_string_utf8(env, path.c_str(), path.length(), &result); + return result; +} + +static napi_value GetTextData(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + int index = 0; + napi_get_value_int32(env, args[0], &index); + return JPAGText::ToJs(env, file->getTextData(index)); +} + +static napi_value ReplaceText(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + int index = 0; + napi_get_value_int32(env, args[0], &index); + auto textData = JPAGText::FromJs(env, args[1]); + file->replaceText(index, textData); + return nullptr; +} + +static napi_value ReplaceImage(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + int index = 0; + napi_get_value_int32(env, args[0], &index); + auto image = JPAGImage::FromJs(env, args[1]); + file->replaceImage(index, image); + return nullptr; +} + +static napi_value ReplaceImageByName(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + char str[2048]; + size_t length = 0; + napi_get_value_string_utf8(env, args[0], str, 2048, &length); + auto image = JPAGImage::FromJs(env, args[1]); + file->replaceImageByName({str, length}, image); + return nullptr; +} + +static napi_value GetLayersByEditableIndex(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + int editableIndex = 0; + napi_get_value_int32(env, args[0], &editableIndex); + int layerType = 0; + napi_get_value_int32(env, args[1], &layerType); + auto layers = file->getLayersByEditableIndex(editableIndex, static_cast(layerType)); + napi_value array; + napi_create_array_with_length(env, layers.size(), &array); + for (size_t i = 0; i < layers.size(); i++) { + napi_set_element(env, array, i, JPAGLayerHandle::ToJs(env, layers[i])); + } + return array; +} + +static napi_value GetEditableIndices(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + int layerType = 0; + napi_get_value_int32(env, args[0], &layerType); + auto editableIndices = file->getEditableIndices(static_cast(layerType)); + napi_value array; + napi_create_array_with_length(env, editableIndices.size(), &array); + for (size_t i = 0; i < editableIndices.size(); i++) { + napi_value value; + napi_create_int32(env, editableIndices[i], &value); + napi_set_element(env, array, i, value); + } + return array; +} +static napi_value TimeStretchMode(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + napi_value value; + napi_create_int32(env, file->timeStretchMode(), &value); + return value; +} + +static napi_value SetTimeStretchMode(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + int mode = 0; + napi_get_value_int32(env, args[0], &mode); + file->setTimeStretchMode(mode); + return nullptr; +} +static napi_value SetDuration(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + int64_t duration = 0; + napi_get_value_int64(env, args[0], &duration); + file->setDuration(duration); + return nullptr; +} + +static napi_value CopyOriginal(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsFile; + napi_get_cb_info(env, info, &argc, args, &jsFile, nullptr); + auto file = FromJs(env, jsFile); + if (file == nullptr) { + return nullptr; + } + return JPAGLayerHandle::ToJs(env, file->copyOriginal()); +} + +bool JPAGLayerHandle::InitPAGFileEnv(napi_env env, napi_value exports) { + + napi_property_descriptor classProp[] = { + PAG_STATIC_METHOD_ENTRY(MaxSupportedTagLevel, MaxSupportedTagLevel), + PAG_STATIC_METHOD_ENTRY(LoadFromPath, LoadFromPath), + PAG_STATIC_METHOD_ENTRY(LoadFromBytes, LoadFromBytes), + PAG_STATIC_METHOD_ENTRY(LoadFromAssets, LoadFromAssets), + + PAG_DEFAULT_METHOD_ENTRY(tagLevel, TagLevel), + PAG_DEFAULT_METHOD_ENTRY(numTexts, NumTexts), + PAG_DEFAULT_METHOD_ENTRY(numImages, NumImages), + PAG_DEFAULT_METHOD_ENTRY(numVideos, NumVideos), + PAG_DEFAULT_METHOD_ENTRY(path, Path), + PAG_DEFAULT_METHOD_ENTRY(getTextData, GetTextData), + PAG_DEFAULT_METHOD_ENTRY(replaceText, ReplaceText), + PAG_DEFAULT_METHOD_ENTRY(replaceImage, ReplaceImage), + PAG_DEFAULT_METHOD_ENTRY(replaceImageByName, ReplaceImageByName), + PAG_DEFAULT_METHOD_ENTRY(getLayersByEditableIndex, GetLayersByEditableIndex), + PAG_DEFAULT_METHOD_ENTRY(getEditableIndices, GetEditableIndices), + PAG_DEFAULT_METHOD_ENTRY(timeStretchMode, TimeStretchMode), + PAG_DEFAULT_METHOD_ENTRY(setTimeStretchMode, SetTimeStretchMode), + PAG_DEFAULT_METHOD_ENTRY(setDuration, SetDuration), + PAG_DEFAULT_METHOD_ENTRY(copyOriginal, CopyOriginal)}; + auto status = + DefineClass(env, exports, GetFileClassName(), sizeof(classProp) / sizeof(classProp[0]), + classProp, Constructor, GetLayerClassName(LayerType::PreCompose)); + return status == napi_ok; +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGFont.cpp b/src/platform/ohos/JPAGFont.cpp new file mode 100644 index 0000000000..01573088bf --- /dev/null +++ b/src/platform/ohos/JPAGFont.cpp @@ -0,0 +1,189 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAGFont.h" +#include +#include +#include "base/utils/Log.h" +#include "platform/ohos/JsHelper.h" + +#define JPAGFONT_FONT_FAMILY "fontFamily" +#define JPAGFONT_FONT_STYLE "fontStyle" + +namespace pag { + +static napi_value RegisterFontFromPath(napi_env env, napi_callback_info info) { + size_t argc = 4; + napi_value args[4] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + char fontPath[1024]; + size_t pathLength = 0; + napi_get_value_string_utf8(env, args[0], fontPath, 1024, &pathLength); + + int index = 0; + if (argc > 1) { + napi_get_value_int32(env, args[1], &index); + } + + char fontFamily[1024]; + size_t familyLength = 0; + if (argc > 2) { + napi_get_value_string_utf8(env, args[2], fontFamily, 1024, &familyLength); + } + + char fontStyle[1024]; + size_t styleLength = 0; + if (argc > 3) { + napi_get_value_string_utf8(env, args[3], fontStyle, 1024, &styleLength); + } + + auto font = PAGFont::RegisterFont({fontPath, pathLength}, index, {fontFamily, familyLength}, + {fontStyle, styleLength}); + return JPAGFont::ToJs(env, font); +} + +static napi_value RegisterFontFromAsset(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); + + NativeResourceManager* mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]); + + size_t nameLength; + char name[1024]; + napi_get_value_string_utf8(env, args[1], name, sizeof(name), &nameLength); + RawFile* rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, name); + if (rawFile == NULL) { + return nullptr; + } + + long len = OH_ResourceManager_GetRawFileSize(rawFile); + auto data = ByteData::Make(len); + if (data == nullptr) { + return nullptr; + } + OH_ResourceManager_ReadRawFile(rawFile, data->data(), len); + + int index = 0; + if (argc > 2) { + napi_get_value_int32(env, args[2], &index); + } + + char fontFamily[1024]; + size_t familyLength = 0; + if (argc > 3) { + napi_get_value_string_utf8(env, args[3], fontFamily, 1024, &familyLength); + } + + char fontStyle[1024]; + size_t styleLength = 0; + if (argc > 4) { + napi_get_value_string_utf8(env, args[4], fontStyle, 1024, &styleLength); + } + + auto font = PAGFont::RegisterFont(data->data(), data->length(), index, {fontFamily, familyLength}, + {fontStyle, styleLength}); + return JPAGFont::ToJs(env, font); +} + +static napi_value UnregisterFont(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + PAGFont::UnregisterFont(JPAGFont::FromJs(env, args[0])); + return nullptr; +} + +static napi_value SetFallbackFontPaths(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + + uint32_t length = 0; + napi_get_array_length(env, args[0], &length); + std::vector fontPaths; + std::vector ttcIndices; + for (uint32_t i = 0; i < length; i++) { + napi_value pathValue; + napi_get_element(env, args[0], i, &pathValue); + char path[1024]; + size_t pathLength = 0; + napi_get_value_string_utf8(env, pathValue, path, 1024, &pathLength); + fontPaths.push_back({path, pathLength}); + ttcIndices.push_back(0); + } + PAGFont::SetFallbackFontPaths(fontPaths, ttcIndices); + return nullptr; +} + +bool JPAGFont::Init(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = { + PAG_STATIC_METHOD_ENTRY(RegisterFontFromPath, RegisterFontFromPath), + PAG_STATIC_METHOD_ENTRY(RegisterFontFromAsset, RegisterFontFromAsset), + PAG_STATIC_METHOD_ENTRY(UnregisterFont, UnregisterFont), + PAG_STATIC_METHOD_ENTRY(SetFallbackFontPaths, SetFallbackFontPaths)}; + auto status = DefineClass(env, exports, ClassName(), sizeof(classProp) / sizeof(classProp[0]), + classProp, Constructor, ""); + return status == napi_ok; +} + +napi_value JPAGFont::ToJs(napi_env env, const PAGFont& font) { + napi_value fontFamily; + napi_create_string_utf8(env, font.fontFamily.c_str(), font.fontFamily.length(), &fontFamily); + + napi_value fontStyle; + napi_create_string_utf8(env, font.fontStyle.c_str(), font.fontStyle.length(), &fontStyle); + + napi_value arg[] = {fontFamily, fontStyle}; + + napi_value result; + auto status = napi_new_instance(env, GetConstructor(env, ClassName()), 2, arg, &result); + if (status != napi_ok) { + LOGE("JPAGFont::ToJs napi_new_instance failed :%d", status); + return nullptr; + } + return result; +} + +PAGFont JPAGFont::FromJs(napi_env env, napi_value value) { + napi_value fontFamily; + napi_get_named_property(env, value, JPAGFONT_FONT_FAMILY, &fontFamily); + char fontFamilyBuf[1024]; + size_t familyLength = 0; + napi_get_value_string_utf8(env, fontFamily, fontFamilyBuf, 1024, &familyLength); + + napi_value fontStyle; + napi_get_named_property(env, value, JPAGFONT_FONT_STYLE, &fontStyle); + char fontStyleBuf[1024]; + size_t styleLength = 0; + napi_get_value_string_utf8(env, fontStyle, fontStyleBuf, 1024, &styleLength); + + return PAGFont{{fontFamilyBuf, familyLength}, {fontStyleBuf, styleLength}}; +} + +napi_value JPAGFont::Constructor(napi_env env, napi_callback_info info) { + napi_value result = nullptr; + size_t argc = 2; + napi_value args[2]; + napi_get_cb_info(env, info, &argc, args, &result, nullptr); + napi_set_named_property(env, result, JPAGFONT_FONT_FAMILY, args[0]); + napi_set_named_property(env, result, JPAGFONT_FONT_STYLE, args[1]); + return result; +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGFont.h b/src/platform/ohos/JPAGFont.h new file mode 100644 index 0000000000..afc6ecc573 --- /dev/null +++ b/src/platform/ohos/JPAGFont.h @@ -0,0 +1,37 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include +#include "pag/pag.h" + +namespace pag { +class JPAGFont { + public: + static bool Init(napi_env env, napi_value exports); + static napi_value ToJs(napi_env env, const PAGFont& font); + static PAGFont FromJs(napi_env env, napi_value value); + static std::string ClassName() { + return "JPAGFont"; + } + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); +}; +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGImage.cpp b/src/platform/ohos/JPAGImage.cpp new file mode 100644 index 0000000000..501389225d --- /dev/null +++ b/src/platform/ohos/JPAGImage.cpp @@ -0,0 +1,231 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// + +#include "JPAGImage.h" +#include +#include +#include +#include +#include "JsHelper.h" +#include "rendering/editing/StillImage.h" + +namespace pag { + +static napi_value FromPath(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + char path[1024]; + size_t pathLength = 0; + napi_get_value_string_utf8(env, args[0], path, 1024, &pathLength); + return JPAGImage::ToJs(env, PAGImage::FromPath(path)); +} + +static napi_value FromBytes(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + size_t length; + void* data; + auto code = napi_get_arraybuffer_info(env, args[1], &data, &length); + if (code != napi_ok) { + return nullptr; + } + return JPAGImage::ToJs(env, PAGImage::FromBytes(data, length)); + ; +} + +static napi_value FromPixelMap(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + auto bitmap = tgfx::OHOSPixelMap::CopyBitmap(env, args[0]); + auto image = tgfx::Image::MakeFrom(bitmap); + if (image == nullptr) { + return nullptr; + } + auto pagImage = pag::StillImage::MakeFrom(std::move(image)); + return JPAGImage::ToJs(env, pagImage); +} + +static napi_value LoadFromAssets(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + NativeResourceManager* mNativeResMgr = OH_ResourceManager_InitNativeResourceManager(env, args[0]); + size_t strSize; + char srcBuf[1024]; + napi_get_value_string_utf8(env, args[1], srcBuf, sizeof(srcBuf), &strSize); + RawFile* rawFile = OH_ResourceManager_OpenRawFile(mNativeResMgr, srcBuf); + if (rawFile != NULL) { + long len = OH_ResourceManager_GetRawFileSize(rawFile); + auto data = ByteData::Make(len); + if (!data) { + return nullptr; + } + OH_ResourceManager_ReadRawFile(rawFile, data->data(), len); + return JPAGImage::ToJs(env, PAGImage::FromBytes(data->data(), data->length())); + } + return nullptr; +} + +static napi_value Width(napi_env env, napi_callback_info info) { + napi_value jsPAGImage = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsPAGImage, nullptr); + auto pagImage = JPAGImage::FromJs(env, jsPAGImage); + if (!pagImage) { + napi_value value; + napi_create_int32(env, 0, &value); + return value; + } + napi_value value; + napi_create_int32(env, pagImage->width(), &value); + return value; +} + +static napi_value Height(napi_env env, napi_callback_info info) { + napi_value jsPAGImage = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsPAGImage, nullptr); + auto pagImage = JPAGImage::FromJs(env, jsPAGImage); + if (!pagImage) { + napi_value value; + napi_create_int32(env, 0, &value); + return value; + } + napi_value value; + napi_create_int32(env, pagImage->height(), &value); + return value; +} + +static napi_value Matrix(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPAGImage = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPAGImage, nullptr); + auto pagImage = JPAGImage::FromJs(env, jsPAGImage); + if (!pagImage) { + return nullptr; + } + return CreateMatrix(env, pagImage->matrix()); +} + +static napi_value SetMatrix(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPAGImage = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPAGImage, nullptr); + auto pagImage = JPAGImage::FromJs(env, jsPAGImage); + if (!pagImage) { + return nullptr; + } + pagImage->setMatrix(GetMatrix(env, args[0])); + return nullptr; +} + +static napi_value ScaleMode(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPAGImage = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPAGImage, nullptr); + auto pagImage = JPAGImage::FromJs(env, jsPAGImage); + if (!pagImage) { + return nullptr; + } + napi_value result; + napi_create_int32(env, pagImage->scaleMode(), &result); + return result; +} + +static napi_value SetScaleMode(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPAGImage = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPAGImage, nullptr); + auto pagImage = JPAGImage::FromJs(env, jsPAGImage); + if (!pagImage) { + return nullptr; + } + int value = 0; + auto status = napi_get_value_int32(env, args[0], &value); + if (status == napi_status::napi_ok) { + pagImage->setScaleMode(value); + } + return nullptr; +} + +napi_value JPAGImage::Constructor(napi_env env, napi_callback_info info) { + napi_value result = nullptr; + size_t argc = 1; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &result, nullptr); + if (argc == 0) { + return nullptr; + } + void* image = nullptr; + napi_get_value_external(env, args[0], &image); + napi_wrap( + env, result, image, + [](napi_env, void* finalize_data, void*) { + JPAGImage* pagImage = static_cast(finalize_data); + delete pagImage; + }, + nullptr, nullptr); + return result; +} + +bool JPAGImage::Init(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = {PAG_STATIC_METHOD_ENTRY(FromPath, FromPath), + PAG_STATIC_METHOD_ENTRY(FromBytes, FromBytes), + PAG_STATIC_METHOD_ENTRY(FromPixelMap, FromPixelMap), + PAG_STATIC_METHOD_ENTRY(LoadFromAssets, LoadFromAssets), + PAG_DEFAULT_METHOD_ENTRY(width, Width), + PAG_DEFAULT_METHOD_ENTRY(height, Height), + PAG_DEFAULT_METHOD_ENTRY(matrix, Matrix), + PAG_DEFAULT_METHOD_ENTRY(setMatrix, SetMatrix), + PAG_DEFAULT_METHOD_ENTRY(scaleMode, ScaleMode), + PAG_DEFAULT_METHOD_ENTRY(setScaleMode, SetScaleMode)}; + auto status = DefineClass(env, exports, ClassName(), sizeof(classProp) / sizeof(classProp[0]), + classProp, Constructor, ""); + return status == napi_ok; +} + +std::shared_ptr JPAGImage::FromJs(napi_env env, napi_value value) { + JPAGImage* image = nullptr; + auto status = napi_unwrap(env, value, (void**)&image); + if (status == napi_ok) { + return image->get(); + } else { + return nullptr; + } +} + +napi_value JPAGImage::ToJs(napi_env env, std::shared_ptr pagImage) { + if (!pagImage) { + return nullptr; + } + JPAGImage* handler = new JPAGImage(pagImage); + napi_value result = NewInstance(env, ClassName(), handler); + if (result == nullptr) { + delete handler; + } + return result; +} +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGImage.h b/src/platform/ohos/JPAGImage.h new file mode 100644 index 0000000000..ef6a16a631 --- /dev/null +++ b/src/platform/ohos/JPAGImage.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include +#include +#include "pag/pag.h" + +namespace pag { +class JPAGImage { + public: + explicit JPAGImage(std::shared_ptr pagImage) : pagImage(pagImage) { + } + static bool Init(napi_env env, napi_value exports); + static napi_value ToJs(napi_env env, std::shared_ptr pagImage); + static std::shared_ptr FromJs(napi_env env, napi_value value); + static std::string ClassName() { + return "JPAGImage"; + } + + std::shared_ptr get() { + return pagImage; + } + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); + std::shared_ptr pagImage; +}; +} // namespace pag diff --git a/src/platform/ohos/JPAGImageLayer.cpp b/src/platform/ohos/JPAGImageLayer.cpp new file mode 100644 index 0000000000..1ad707f98c --- /dev/null +++ b/src/platform/ohos/JPAGImageLayer.cpp @@ -0,0 +1,117 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAGImage.h" +#include "JPAGLayerHandle.h" +#include "JsHelper.h" +#include "pag/pag.h" + +namespace pag { +static std::shared_ptr FromJs(napi_env env, napi_value value) { + auto layer = JPAGLayerHandle::FromJs(env, value); + if (layer && layer->layerType() == LayerType::Image) { + return std::static_pointer_cast(layer); + } + return nullptr; +} + +static napi_value Make(napi_env env, napi_callback_info info) { + size_t argc = 3; + napi_value args[3]; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + int32_t width = 0; + napi_get_value_int32(env, args[0], &width); + int32_t height = 0; + napi_get_value_int32(env, args[1], &height); + int32_t duration = 0; + napi_get_value_int32(env, args[2], &duration); + return JPAGLayerHandle::ToJs(env, PAGImageLayer::Make(width, height, duration)); +} + +static napi_value GetVideoRanges(napi_env env, napi_callback_info info) { + napi_value jsLayer = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto pagImageLayer = FromJs(env, jsLayer); + if (!pagImageLayer) { + return nullptr; + } + return CreateVideoRanges(env, pagImageLayer->getVideoRanges()); +} + +static napi_value SetImage(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto pagImageLayer = FromJs(env, jsLayer); + if (pagImageLayer == nullptr) { + return nullptr; + } + auto image = JPAGImage::FromJs(env, args[0]); + pagImageLayer->setImage(image); + return nullptr; +} + +static napi_value ContentDuration(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto pagImageLayer = FromJs(env, jsLayer); + if (pagImageLayer == nullptr) { + return nullptr; + } + napi_value result; + napi_create_int64(env, pagImageLayer->contentDuration(), &result); + return result; +} + +static napi_value ImageBytes(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto pagImageLayer = FromJs(env, jsLayer); + if (pagImageLayer == nullptr) { + return nullptr; + } + napi_value arraybuffer; + void* data = nullptr; + auto imageBytes = pagImageLayer->imageBytes(); + napi_create_arraybuffer(env, imageBytes->length(), &data, &arraybuffer); + memcpy(data, imageBytes->data(), imageBytes->length()); + return arraybuffer; +} + +bool JPAGLayerHandle::InitPAGImageLayerEnv(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = { + PAG_DEFAULT_METHOD_ENTRY(Make, Make), + PAG_DEFAULT_METHOD_ENTRY(getVideoRanges, GetVideoRanges), + PAG_DEFAULT_METHOD_ENTRY(setImage, SetImage), + PAG_DEFAULT_METHOD_ENTRY(contentDuration, ContentDuration), + PAG_DEFAULT_METHOD_ENTRY(imageBytes, ImageBytes)}; + + auto status = DefineClass(env, exports, GetLayerClassName(LayerType::Image), + sizeof(classProp) / sizeof(classProp[0]), classProp, Constructor, + GetBaseClassName()); + return status == napi_status::napi_ok; +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGLayer.cpp b/src/platform/ohos/JPAGLayer.cpp new file mode 100644 index 0000000000..9d8953971c --- /dev/null +++ b/src/platform/ohos/JPAGLayer.cpp @@ -0,0 +1,507 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include +#include "JPAGLayerHandle.h" +#include "JsHelper.h" +#include "base/utils/Log.h" +#include "pag/file.h" + +namespace pag { + +static napi_value LayerType(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + napi_create_int32(env, static_cast(layer->layerType()), &result); + return result; +} + +static napi_value IsPAGFile(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + napi_get_boolean(env, layer->isPAGFile(), &result); + return result; +} + +static napi_value LayerName(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + auto name = layer->layerName(); + napi_create_string_utf8(env, name.c_str(), name.length(), &result); + return result; +} + +static napi_value Matrix(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + return CreateMatrix(env, layer->matrix()); +} + +static napi_value SetMatrix(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + layer->setMatrix(GetMatrix(env, args[0])); + return nullptr; +} + +static napi_value ResetMatrix(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + layer->resetMatrix(); + return nullptr; +} + +static napi_value GetTotalMatrix(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + return CreateMatrix(env, layer->getTotalMatrix()); +} + +static napi_value Visible(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + napi_value result; + if (!layer) { + napi_get_boolean(env, false, &result); + } else { + napi_get_boolean(env, layer->visible(), &result); + } + return result; +} + +static napi_value SetVisible(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + bool visible = false; + if (napi_get_value_bool(env, args[0], &visible) != napi_ok) { + return nullptr; + } + layer->setVisible(visible); + return nullptr; +} + +static napi_value EditableIndex(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + if (napi_create_int32(env, layer->editableIndex(), &result) != napi_ok) { + return nullptr; + } + return result; +} + +static napi_value Parent(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + return JPAGLayerHandle::ToJs(env, layer->parent()); +} + +static napi_value Markers(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + return CreateMarkers(env, layer->markers()); +} + +static napi_value LocalTimeToGlobal(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + int64_t localTime = 0; + napi_get_value_int64(env, args[0], &localTime); + napi_value result; + napi_create_int64(env, layer->localTimeToGlobal(localTime), &result); + return result; +} + +static napi_value GlobalToLocalTime(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + int64_t globalTime = 0; + napi_get_value_int64(env, args[0], &globalTime); + napi_value result; + napi_create_int64(env, layer->globalToLocalTime(globalTime), &result); + return result; +} + +static napi_value Duration(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + napi_create_int64(env, layer->duration(), &result); + return result; +} + +static napi_value FrameRate(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + napi_create_double(env, layer->frameRate(), &result); + return result; +} + +static napi_value StartTime(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + napi_create_int64(env, layer->startTime(), &result); + return result; +} + +static napi_value SetStartTime(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + int64_t startTime = 0; + napi_get_value_int64(env, args[0], &startTime); + layer->setStartTime(startTime); + return nullptr; +} + +static napi_value CurrentTime(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + napi_create_int64(env, layer->currentTime(), &result); + return result; +} + +static napi_value SetCurrentTime(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + int64_t currentTime = 0; + napi_get_value_int64(env, args[0], ¤tTime); + layer->setCurrentTime(currentTime); + return nullptr; +} + +static napi_value GetProgress(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + + napi_value result; + napi_create_double(env, layer->getProgress(), &result); + return result; +} + +static napi_value SetProgress(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + double progress = 0; + napi_get_value_double(env, args[0], &progress); + layer->setProgress(progress); + return nullptr; +} + +static napi_value TrackMatteLayer(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + return JPAGLayerHandle::ToJs(env, layer->trackMatteLayer()); +} + +static napi_value GetBounds(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + return CreateRect(env, layer->getBounds()); +} + +static napi_value ExcludedFromTimeline(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + napi_value result; + napi_get_boolean(env, layer->excludedFromTimeline(), &result); + return result; +} + +static napi_value SetExcludedFromTimeline(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + bool excludedFromTimeline = 0; + napi_get_value_bool(env, args[0], &excludedFromTimeline); + layer->setExcludedFromTimeline(excludedFromTimeline); + return nullptr; +} + +std::shared_ptr JPAGLayerHandle::FromJs(napi_env env, napi_value value) { + JPAGLayerHandle* cLayerHandler = nullptr; + auto status = napi_unwrap(env, value, (void**)&cLayerHandler); + if (status == napi_ok && cLayerHandler) { + return cLayerHandler->get(); + } else { + return nullptr; + } +} + +napi_value JPAGLayerHandle::ToJs(napi_env env, std::shared_ptr layer) { + if (env == nullptr || layer == nullptr) { + return nullptr; + } + std::string className = ""; + if (layer->isPAGFile()) { + className = GetFileClassName(); + } else { + className = GetLayerClassName(layer->layerType()); + } + auto handler = new JPAGLayerHandle(layer); + auto result = NewInstance(env, className, handler); + if (result == nullptr) { + delete handler; + } + return result; +} + +std::string JPAGLayerHandle::GetLayerClassName(enum LayerType layerType) { + switch (layerType) { + case LayerType::PreCompose: + return "JPAGComposition"; + case LayerType::Image: + return "JPAGImageLayer"; + case LayerType::Text: + return "JPAGTextLayer"; + case LayerType::Shape: + return "JPAGShapeLayer"; + case LayerType::Solid: + return "JPAGSolidLayer"; + default: + return GetBaseClassName(); + } +} + +std::string JPAGLayerHandle::GetFileClassName() { + return "JPAGFile"; +} + +std::string JPAGLayerHandle::GetBaseClassName() { + return "JPAGLayer"; +} + +napi_value JPAGLayerHandle::Constructor(napi_env env, napi_callback_info info) { + napi_value result = nullptr; + size_t argc = 1; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &result, nullptr); + if (argc == 0) { + return nullptr; + } + void* handle = nullptr; + napi_get_value_external(env, args[0], &handle); + napi_wrap( + env, result, handle, + [](napi_env, void* finalize_data, void*) { + JPAGLayerHandle* handler = static_cast(finalize_data); + delete handler; + }, + nullptr, nullptr); + return result; +} + +bool JPAGLayerHandle::InitPAGLayerEnv(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = { + PAG_DEFAULT_METHOD_ENTRY(layerType, LayerType), + PAG_DEFAULT_METHOD_ENTRY(layerName, LayerName), + PAG_DEFAULT_METHOD_ENTRY(isPAGFile, IsPAGFile), + PAG_DEFAULT_METHOD_ENTRY(matrix, Matrix), + PAG_DEFAULT_METHOD_ENTRY(setMatrix, SetMatrix), + PAG_DEFAULT_METHOD_ENTRY(resetMatrix, ResetMatrix), + PAG_DEFAULT_METHOD_ENTRY(getTotalMatrix, GetTotalMatrix), + PAG_DEFAULT_METHOD_ENTRY(visible, Visible), + PAG_DEFAULT_METHOD_ENTRY(setVisible, SetVisible), + PAG_DEFAULT_METHOD_ENTRY(editableIndex, EditableIndex), + PAG_DEFAULT_METHOD_ENTRY(parent, Parent), + PAG_DEFAULT_METHOD_ENTRY(markers, Markers), + PAG_DEFAULT_METHOD_ENTRY(localTimeToGlobal, LocalTimeToGlobal), + PAG_DEFAULT_METHOD_ENTRY(globalToLocalTime, GlobalToLocalTime), + PAG_DEFAULT_METHOD_ENTRY(duration, Duration), + PAG_DEFAULT_METHOD_ENTRY(frameRate, FrameRate), + PAG_DEFAULT_METHOD_ENTRY(startTime, StartTime), + PAG_DEFAULT_METHOD_ENTRY(setStartTime, SetStartTime), + PAG_DEFAULT_METHOD_ENTRY(currentTime, CurrentTime), + PAG_DEFAULT_METHOD_ENTRY(setCurrentTime, SetCurrentTime), + PAG_DEFAULT_METHOD_ENTRY(getProgress, GetProgress), + PAG_DEFAULT_METHOD_ENTRY(setProgress, SetProgress), + PAG_DEFAULT_METHOD_ENTRY(trackMatteLayer, TrackMatteLayer), + PAG_DEFAULT_METHOD_ENTRY(getBounds, GetBounds), + PAG_DEFAULT_METHOD_ENTRY(excludedFromTimeline, ExcludedFromTimeline), + PAG_DEFAULT_METHOD_ENTRY(setExcludedFromTimeline, SetExcludedFromTimeline), + }; + auto status = DefineClass(env, exports, GetBaseClassName(), + sizeof(classProp) / sizeof(classProp[0]), classProp, Constructor, ""); + return status == napi_ok; +} + +bool JPAGLayerHandle::Init(napi_env env, napi_value exports) { + return InitPAGLayerEnv(env, exports) && InitPAGImageLayerEnv(env, exports) && + InitPAGTextLayerEnv(env, exports) && InitPAGSolidLayerEnv(env, exports) && + InitPAGShapeLayerEnv(env, exports) && InitPAGCompositionLayerEnv(env, exports) && + InitPAGFileEnv(env, exports); +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGLayerHandle.h b/src/platform/ohos/JPAGLayerHandle.h new file mode 100644 index 0000000000..0161ebffd9 --- /dev/null +++ b/src/platform/ohos/JPAGLayerHandle.h @@ -0,0 +1,53 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include + +namespace pag { +class JPAGLayerHandle { + public: + static bool Init(napi_env env, napi_value exports); + static std::shared_ptr FromJs(napi_env env, napi_value); + static napi_value ToJs(napi_env env, std::shared_ptr layer); + static std::string GetLayerClassName(LayerType layer); + static std::string GetFileClassName(); + static std::string GetBaseClassName(); + + explicit JPAGLayerHandle(std::shared_ptr layer) : layer(layer) { + } + + std::shared_ptr get() { + return layer; + } + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); + static bool InitPAGLayerEnv(napi_env env, napi_value exports); + static bool InitPAGImageLayerEnv(napi_env env, napi_value exports); + static bool InitPAGTextLayerEnv(napi_env env, napi_value exports); + static bool InitPAGShapeLayerEnv(napi_env env, napi_value exports); + static bool InitPAGSolidLayerEnv(napi_env env, napi_value exports); + static bool InitPAGCompositionLayerEnv(napi_env env, napi_value exports); + static bool InitPAGFileEnv(napi_env env, napi_value exports); + + std::shared_ptr layer; +}; + +} // namespace pag diff --git a/src/platform/ohos/JPAGPlayer.cpp b/src/platform/ohos/JPAGPlayer.cpp new file mode 100644 index 0000000000..16bc445670 --- /dev/null +++ b/src/platform/ohos/JPAGPlayer.cpp @@ -0,0 +1,592 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAGPlayer.h" +#include +#include "JPAGLayerHandle.h" +#include "JsHelper.h" +#include "JPAGSurface.h" + +namespace pag { + +static napi_value GetComposition(napi_env env, napi_callback_info info) { + napi_value jsPlayer = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + return JPAGLayerHandle::ToJs(env, player->getComposition()); +} + +static napi_value SetComposition(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + auto composition = JPAGLayerHandle::FromJs(env, args[0]); + if (!composition || composition->layerType() != LayerType::PreCompose) { + return nullptr; + } + player->setComposition(std::static_pointer_cast(composition)); + return nullptr; +} + +/** + * Returns the PAGSurface object for PAGPlayer to render onto. + */ +static napi_value GetSurface(napi_env env, napi_callback_info info) { + napi_value jsPlayer = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + return JPAGSurface::ToJs(env, player->getSurface()); +} + +static napi_value SetSurface(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + player->setSurface(JPAGSurface::FromJs(env, args[0])); + return nullptr; +} + +static napi_value VideoEnabled(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + bool videoEnable = player->videoEnabled(); + napi_value result; + napi_get_boolean(env, videoEnable, &result); + return result; +} + +static napi_value SetVideoEnabled(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + bool videoEnabled = false; + auto status = napi_get_value_bool(env, args[0], &videoEnabled); + if (status == napi_status::napi_ok) { + player->setVideoEnabled(videoEnabled); + } + return nullptr; +} + +static napi_value CacheEnabled(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + bool cacheEnabled = player->cacheEnabled(); + napi_value result; + napi_get_boolean(env, cacheEnabled, &result); + return result; +} + +static napi_value SetCacheEnabled(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + bool value = false; + auto status = napi_get_value_bool(env, args[0], &value); + if (status == napi_status::napi_ok) { + player->setCacheEnabled(value); + } + return nullptr; +} + +static napi_value UseDiskCache(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + bool useDiskCache = player->useDiskCache(); + napi_value result; + napi_get_boolean(env, useDiskCache, &result); + return result; +} + +static napi_value SetUseDiskCache(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + bool value = false; + auto status = napi_get_value_bool(env, args[0], &value); + if (status == napi_status::napi_ok) { + player->setUseDiskCache(value); + } + return nullptr; +} + +static napi_value CacheScale(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value result; + napi_create_double(env, player->cacheScale(), &result); + return result; +} + +static napi_value SetCacheScale(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + double value = 0.0; + auto status = napi_get_value_double(env, args[0], &value); + if (status == napi_status::napi_ok) { + player->setCacheScale(value); + } + return nullptr; +} + +static napi_value MaxFrameRate(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value result; + napi_create_double(env, player->maxFrameRate(), &result); + return result; +} + +static napi_value SetMaxFrameRate(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + double value = 0.0; + auto status = napi_get_value_double(env, args[0], &value); + if (status == napi_status::napi_ok) { + player->setMaxFrameRate(value); + } + return nullptr; +} + +static napi_value ScaleMode(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value result; + napi_create_int32(env, player->scaleMode(), &result); + return result; +} + +static napi_value SetScaleMode(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + int value = 0; + auto status = napi_get_value_int32(env, args[0], &value); + if (status == napi_status::napi_ok) { + player->setScaleMode(value); + } + return nullptr; +} + +static napi_value GetMatrix(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + return CreateMatrix(env, player->matrix()); +} + +static napi_value SetMatrix(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + player->setMatrix(GetMatrix(env, args[0])); + return nullptr; +} + +static napi_value Duration(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value value; + napi_create_double(env, player->duration(), &value); + return value; +} + +static napi_value NextFrame(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + player->nextFrame(); + return nullptr; +} + +static napi_value PreFrame(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + player->preFrame(); + return nullptr; +} + +static napi_value GetProgress(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value value; + napi_create_double(env, player->getProgress(), &value); + return value; +} + +static napi_value SetProgress(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + double value = 0; + auto status = napi_get_value_double(env, args[0], &value); + if (status == napi_status::napi_ok) { + player->setProgress(value); + } + return nullptr; +} + +static napi_value CurrentFrame(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value value; + napi_create_int64(env, player->currentFrame(), &value); + return value; +} + +static napi_value AutoClear(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value value; + napi_get_boolean(env, player->autoClear(), &value); + return value; +} + +static napi_value SetAutoClear(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + bool value = false; + auto status = napi_get_value_bool(env, args[0], &value); + if (status == napi_status::napi_ok) { + player->setAutoClear(value); + } + return nullptr; +} + +static napi_value Prepare(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + player->prepare(); + return nullptr; +} + +static napi_value Flush(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + napi_value value; + napi_get_boolean(env, player->flush(), &value); + return value; +} + +static napi_value GetBounds(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + if (layer == nullptr) { + return nullptr; + } + auto rect = player->getBounds(layer); + return CreateRect(env, rect); +} + +static napi_value GetLayersUnderPoint(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + return nullptr; + } + double surfaceX = 0; + napi_get_value_double(env, args[0], &surfaceX); + double surfaceY = 0; + napi_get_value_double(env, args[1], &surfaceY); + auto layers = player->getLayersUnderPoint(surfaceX, surfaceY); + napi_value result; + napi_create_array_with_length(env, layers.size(), &result); + for (uint32_t i = 0; i < layers.size(); i++) { + auto layer = JPAGLayerHandle::ToJs(env, layers[i]); + if (!layer) { + break; + } + napi_set_element(env, result, i, layer); + } + return result; +} + +static napi_value HitTestPoint(napi_env env, napi_callback_info info) { + size_t argc = 3; + napi_value args[3] = {nullptr}; + napi_value jsPlayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + auto player = JPAGPlayer::FromJs(env, jsPlayer); + if (!player) { + napi_value jsResult; + napi_get_boolean(env, false, &jsResult); + return jsResult; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + if (layer == nullptr) { + napi_value jsResult; + napi_get_boolean(env, false, &jsResult); + return jsResult; + } + double surfaceX = 0; + napi_get_value_double(env, args[1], &surfaceX); + double surfaceY = 0; + napi_get_value_double(env, args[2], &surfaceY); + bool result = player->hitTestPoint(layer, surfaceX, surfaceY); + napi_value jsResult; + napi_get_boolean(env, result, &jsResult); + return jsResult; +} + +napi_value JPAGPlayer::Constructor(napi_env env, napi_callback_info info) { + napi_value jsPlayer = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsPlayer, nullptr); + void* cPlayer = nullptr; + if (argc == 0) { + cPlayer = new JPAGPlayer(std::make_shared()); + } else { + napi_get_value_external(env, args[0], &cPlayer); + } + napi_wrap( + env, jsPlayer, cPlayer, + [](napi_env, void* finalize_data, void*) { + JPAGPlayer* player = static_cast(finalize_data); + delete player; + }, + nullptr, nullptr); + return jsPlayer; +} + +bool JPAGPlayer::Init(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = { + PAG_DEFAULT_METHOD_ENTRY(getComposition, GetComposition), + PAG_DEFAULT_METHOD_ENTRY(setComposition, SetComposition), + PAG_DEFAULT_METHOD_ENTRY(getSurface, GetSurface), + PAG_DEFAULT_METHOD_ENTRY(setSurface, SetSurface), + PAG_DEFAULT_METHOD_ENTRY(videoEnabled, VideoEnabled), + PAG_DEFAULT_METHOD_ENTRY(setVideoEnabled, SetVideoEnabled), + PAG_DEFAULT_METHOD_ENTRY(cacheEnabled, CacheEnabled), + PAG_DEFAULT_METHOD_ENTRY(setCacheEnabled, SetCacheEnabled), + PAG_DEFAULT_METHOD_ENTRY(useDiskCache, UseDiskCache), + PAG_DEFAULT_METHOD_ENTRY(setUseDiskCache, SetUseDiskCache), + PAG_DEFAULT_METHOD_ENTRY(cacheScale, CacheScale), + PAG_DEFAULT_METHOD_ENTRY(setCacheScale, SetCacheScale), + PAG_DEFAULT_METHOD_ENTRY(maxFrameRate, MaxFrameRate), + PAG_DEFAULT_METHOD_ENTRY(setMaxFrameRate, SetMaxFrameRate), + PAG_DEFAULT_METHOD_ENTRY(scaleMode, ScaleMode), + PAG_DEFAULT_METHOD_ENTRY(setScaleMode, SetScaleMode), + PAG_DEFAULT_METHOD_ENTRY(matrix, GetMatrix), + PAG_DEFAULT_METHOD_ENTRY(setMatrix, SetMatrix), + PAG_DEFAULT_METHOD_ENTRY(duration, Duration), + PAG_DEFAULT_METHOD_ENTRY(nextFrame, NextFrame), + PAG_DEFAULT_METHOD_ENTRY(preFrame, PreFrame), + PAG_DEFAULT_METHOD_ENTRY(getProgress, GetProgress), + PAG_DEFAULT_METHOD_ENTRY(setProgress, SetProgress), + PAG_DEFAULT_METHOD_ENTRY(currentFrame, CurrentFrame), + PAG_DEFAULT_METHOD_ENTRY(autoClear, AutoClear), + PAG_DEFAULT_METHOD_ENTRY(setAutoClear, SetAutoClear), + PAG_DEFAULT_METHOD_ENTRY(prepare, Prepare), + PAG_DEFAULT_METHOD_ENTRY(flush, Flush), + PAG_DEFAULT_METHOD_ENTRY(getBounds, GetBounds), + PAG_DEFAULT_METHOD_ENTRY(getLayersUnderPoint, GetLayersUnderPoint), + PAG_DEFAULT_METHOD_ENTRY(hitTestPoint, HitTestPoint)}; + + auto status = DefineClass(env, exports, ClassName(), sizeof(classProp) / sizeof(classProp[0]), + classProp, Constructor, ""); + return status == napi_ok; +} + +std::shared_ptr JPAGPlayer::FromJs(napi_env env, napi_value value) { + JPAGPlayer* cPlayer = nullptr; + auto status = napi_unwrap(env, value, (void**)&cPlayer); + if (status == napi_ok) { + return cPlayer->get(); + } else { + return nullptr; + } +} + +napi_value JPAGPlayer::ToJs(napi_env env, std::shared_ptr player) { + if (!player) { + return nullptr; + } + JPAGPlayer* handler = new JPAGPlayer(player); + napi_value result = NewInstance(env, ClassName(), handler); + if (result == nullptr) { + delete handler; + } + return result; +} +} // namespace pag diff --git a/src/platform/ohos/JPAGPlayer.h b/src/platform/ohos/JPAGPlayer.h new file mode 100644 index 0000000000..bd1d56cc16 --- /dev/null +++ b/src/platform/ohos/JPAGPlayer.h @@ -0,0 +1,44 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include + +#include "pag/pag.h" + +namespace pag { + +class JPAGPlayer { + public: + explicit JPAGPlayer(std::shared_ptr pagPlayer) : pagPlayer(pagPlayer) { + } + static bool Init(napi_env env, napi_value exports); + static std::shared_ptr FromJs(napi_env env, napi_value value); + static napi_value ToJs(napi_env env, std::shared_ptr player); + static std::string ClassName() { + return "JPAGPlayer"; + } + std::shared_ptr get() { + return pagPlayer; + } + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); + std::shared_ptr pagPlayer; +}; +} // namespace pag diff --git a/src/platform/ohos/JPAGShapeLayer.cpp b/src/platform/ohos/JPAGShapeLayer.cpp new file mode 100644 index 0000000000..26eab6ea52 --- /dev/null +++ b/src/platform/ohos/JPAGShapeLayer.cpp @@ -0,0 +1,31 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "pag/pag.h" +#include "JPAGLayerHandle.h" +#include "JsHelper.h" + +namespace pag { +bool JPAGLayerHandle::InitPAGShapeLayerEnv(napi_env env, napi_value exports) { + auto status = DefineClass(env, exports, GetLayerClassName(LayerType::Shape), + 0, nullptr, Constructor, + GetBaseClassName()); + return status == napi_status::napi_ok; +} + +} // namespace pag diff --git a/src/platform/ohos/JPAGSolidLayer.cpp b/src/platform/ohos/JPAGSolidLayer.cpp new file mode 100644 index 0000000000..3303760fab --- /dev/null +++ b/src/platform/ohos/JPAGSolidLayer.cpp @@ -0,0 +1,75 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "pag/pag.h" +#include "JPAGLayerHandle.h" +#include "JsHelper.h" + +namespace pag { +static std::shared_ptr FromJs(napi_env env, napi_value value) { + auto layer = JPAGLayerHandle::FromJs(env, value); + if (layer && layer->layerType() == LayerType::Solid) { + return std::static_pointer_cast(layer); + } + return nullptr; +} + +static napi_value SolidColor(napi_env env, napi_callback_info info) { + napi_value jsLayer = nullptr; + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto solidLayer = FromJs(env, jsLayer); + if (!solidLayer) { + return 0; + } + + napi_value result; + Color color = solidLayer->solidColor(); + napi_create_int32(env, MakeColorInt(color.red, color.green, color.blue), &result); + return result; +} + +static napi_value SetSolidColor(napi_env env, napi_callback_info info) { + napi_value jsLayer = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto solidLayer = FromJs(env, jsLayer); + if (!solidLayer) { + return nullptr; + } + int32_t color = 0; + napi_get_value_int32(env, args[0], &color); + solidLayer->setSolidColor(ToColor(color)); + return nullptr; +} + +bool JPAGLayerHandle::InitPAGSolidLayerEnv(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = { + PAG_DEFAULT_METHOD_ENTRY(solidColor, SolidColor), + PAG_DEFAULT_METHOD_ENTRY(setSolidColor, SetSolidColor) + }; + + auto status = DefineClass(env, exports, GetLayerClassName(LayerType::Solid), + sizeof(classProp) / sizeof(classProp[0]), classProp, Constructor, + GetBaseClassName()); + return status == napi_status::napi_ok; +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGSurface.cpp b/src/platform/ohos/JPAGSurface.cpp new file mode 100644 index 0000000000..e5e8ab27cd --- /dev/null +++ b/src/platform/ohos/JPAGSurface.cpp @@ -0,0 +1,172 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAGSurface.h" + +#include +#include "JsHelper.h" + +namespace pag { + +static napi_value Width(napi_env env, napi_callback_info info) { + napi_value jSurface = nullptr; + size_t argc = 0; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &jSurface, nullptr); + auto surface = JPAGSurface::FromJs(env, jSurface); + int width = 0; + if (surface) { + width = surface->width(); + } + napi_value result; + napi_create_int32(env, width, &result); + return result; +} + +static napi_value Height(napi_env env, napi_callback_info info) { + napi_value jSurface = nullptr; + size_t argc = 0; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &jSurface, nullptr); + auto surface = JPAGSurface::FromJs(env, jSurface); + int height = 0; + if (surface) { + height = surface->height(); + } + napi_value result; + napi_create_int32(env, height, &result); + return result; +} + +static napi_value UpdateSize(napi_env env, napi_callback_info info) { + napi_value jSurface = nullptr; + size_t argc = 0; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &jSurface, nullptr); + auto surface = JPAGSurface::FromJs(env, jSurface); + if (surface) { + surface->updateSize(); + } + return nullptr; +} + +static napi_value ClearAll(napi_env env, napi_callback_info info) { + napi_value jSurface = nullptr; + size_t argc = 0; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &jSurface, nullptr); + auto surface = JPAGSurface::FromJs(env, jSurface); + bool success = false; + if (surface) { + success = surface->clearAll(); + } + napi_value result; + napi_get_boolean(env, success, &result); + return result; +} + +static napi_value FreeCache(napi_env env, napi_callback_info info) { + napi_value jSurface = nullptr; + size_t argc = 0; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &jSurface, nullptr); + auto surface = JPAGSurface::FromJs(env, jSurface); + if (surface) { + surface->freeCache(); + } + return nullptr; +} + +static napi_value MakeOffscreen(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2]; + napi_get_cb_info(env, info, &argc, args, nullptr, nullptr); + int32_t x = 0; + napi_get_value_int32(env, args[0], &x); + int32_t y = 0; + napi_get_value_int32(env, args[1], &y); + return JPAGSurface::ToJs(env, PAGSurface::MakeOffscreen(x, y)); +} + +static napi_value MakeSnapshot(napi_env env, napi_callback_info info) { + napi_value jSurface = nullptr; + size_t argc = 0; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &jSurface, nullptr); + auto surface = JPAGSurface::FromJs(env, jSurface); + return MakeSnapshot(env, surface.get()); +} + +napi_value JPAGSurface::Constructor(napi_env env, napi_callback_info info) { + napi_value result = nullptr; + size_t argc = 1; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &result, nullptr); + if (argc == 0) { + return nullptr; + } + void* surface = nullptr; + napi_get_value_external(env, args[0], &surface); + napi_wrap( + env, result, surface, + [](napi_env, void* finalize_data, void*) { + JPAGSurface* surface = static_cast(finalize_data); + delete surface; + }, + nullptr, nullptr); + return result; +} + +bool JPAGSurface::Init(napi_env env, napi_value exports) { + static const napi_property_descriptor classProp[] = { + PAG_STATIC_METHOD_ENTRY(MakeOffscreen, MakeOffscreen), + PAG_DEFAULT_METHOD_ENTRY(width, Width), + PAG_DEFAULT_METHOD_ENTRY(height, Height), + PAG_DEFAULT_METHOD_ENTRY(updateSize, UpdateSize), + PAG_DEFAULT_METHOD_ENTRY(clearAll, ClearAll), + PAG_DEFAULT_METHOD_ENTRY(freeCache, FreeCache), + PAG_DEFAULT_METHOD_ENTRY(makeSnapshot, MakeSnapshot)}; + + auto status = DefineClass(env, exports, ClassName(), sizeof(classProp) / sizeof(classProp[0]), + classProp, Constructor, ""); + + return status == napi_ok; +} + +napi_value JPAGSurface::ToJs(napi_env env, std::shared_ptr surface) { + if (!surface) { + return nullptr; + } + JPAGSurface* handler = new JPAGSurface(surface); + napi_value result = NewInstance(env, ClassName(), handler); + if (result == nullptr) { + delete handler; + } + return result; +} + +std::shared_ptr JPAGSurface::FromJs(napi_env env, napi_value value) { + JPAGSurface* cSurface = nullptr; + auto status = napi_unwrap(env, value, (void**)&cSurface); + if (status == napi_ok) { + return cSurface->get(); + } else { + return nullptr; + } +} +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGSurface.h b/src/platform/ohos/JPAGSurface.h new file mode 100644 index 0000000000..fbf0380824 --- /dev/null +++ b/src/platform/ohos/JPAGSurface.h @@ -0,0 +1,48 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include +#include +#include +#include "pag/pag.h" + +namespace pag { + +class JPAGSurface { + public: + explicit JPAGSurface(std::shared_ptr pagSurface) : pagSurface(pagSurface) { + } + static bool Init(napi_env env, napi_value exports); + static std::shared_ptr FromJs(napi_env env, napi_value value); + static napi_value ToJs(napi_env env, std::shared_ptr surface); + static std::string ClassName() { + return "JPAGSurface"; + } + + std::shared_ptr get() { + return pagSurface; + } + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); + std::shared_ptr pagSurface; +}; + +} // namespace pag diff --git a/src/platform/ohos/JPAGText.cpp b/src/platform/ohos/JPAGText.cpp new file mode 100644 index 0000000000..112258a8a4 --- /dev/null +++ b/src/platform/ohos/JPAGText.cpp @@ -0,0 +1,276 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAGText.h" +#include "base/utils/Log.h" +#include "platform/ohos/JsHelper.h" + +#define JPAGTEXT_APPLY_FILL "applyFill" +#define JPAGTEXT_APPLY_STROKE "applyStroke" +#define JPAGTEXT_BASELINE_SHIFT "baselineShift" +#define JPAGTEXT_BOX_TEXT "boxText" +#define JPAGTEXT_BOX_TEXT_RECT "boxTextRect" +#define JPAGTEXT_FIRST_BASE_LINE "firstBaseLine" +#define JPAGTEXT_FAUX_BOLD "fauxBold" +#define JPAGTEXT_FAUX_ITALIC "fauxItalic" +#define JPAGTEXT_FILL_COLOR "fillColor" +#define JPAGTEXT_FONT_FAMILY "fontFamily" +#define JPAGTEXT_FONT_STYLE "fontStyle" +#define JPAGTEXT_FONT_SIZE "fontSize" +#define JPAGTEXT_STROKE_COLOR "strokeColor" +#define JPAGTEXT_STROKE_OVER_FILL "strokeOverFill" +#define JPAGTEXT_STROKE_WIDTH "strokeWidth" +#define JPAGTEXT_TEXT "text" +#define JPAGTEXT_JUSTIFICATION "justification" +#define JPAGTEXT_LEADING "leading" +#define JPAGTEXT_TRACKING "tracking" +#define JPAGTEXT_BACKGROUND_COLOR "backgroundColor" +#define JPAGTEXT_BACKGROUND_ALPHA "backgroundAlpha" + +namespace pag { +bool JPAGText::Init(napi_env env, napi_value exports) { + auto status = DefineClass(env, exports, ClassName(), 0, nullptr, Constructor, ""); + return status == napi_ok; +} + +std::shared_ptr JPAGText::FromJs(napi_env env, napi_value value) { + auto text = std::make_shared(); + napi_value applyFill; + napi_get_named_property(env, value, JPAGTEXT_APPLY_FILL, &applyFill); + napi_get_value_bool(env, applyFill, &text->applyFill); + + napi_value applyStroke; + napi_get_named_property(env, value, JPAGTEXT_APPLY_STROKE, &applyStroke); + napi_get_value_bool(env, applyStroke, &text->applyStroke); + + napi_value baselineShift; + napi_get_named_property(env, value, JPAGTEXT_BASELINE_SHIFT, &baselineShift); + double temp = 0; + napi_get_value_double(env, baselineShift, &temp); + text->baselineShift = temp; + + napi_value boxText; + napi_get_named_property(env, value, JPAGTEXT_BOX_TEXT, &boxText); + napi_get_value_bool(env, boxText, &text->boxText); + + napi_value boxTextRect; + napi_get_named_property(env, value, JPAGTEXT_BOX_TEXT_RECT, &boxTextRect); + Rect rect = GetRect(env, boxTextRect); + text->boxTextPos = {rect.x(), rect.y()}; + text->boxTextSize = {rect.width(), rect.height()}; + + napi_value firstBaseLine; + napi_get_named_property(env, value, JPAGTEXT_FIRST_BASE_LINE, &firstBaseLine); + temp = 0; + napi_get_value_double(env, firstBaseLine, &temp); + text->firstBaseLine = temp; + + napi_value fauxBold; + napi_get_named_property(env, value, JPAGTEXT_FAUX_BOLD, &fauxBold); + napi_get_value_bool(env, fauxBold, &text->fauxBold); + + napi_value fauxItalic; + napi_get_named_property(env, value, JPAGTEXT_FAUX_ITALIC, &fauxItalic); + napi_get_value_bool(env, fauxItalic, &text->fauxItalic); + + napi_value fillColor; + napi_get_named_property(env, value, JPAGTEXT_FILL_COLOR, &fillColor); + int color = 0; + napi_get_value_int32(env, fillColor, &color); + text->fillColor = ToColor(color); + + napi_value fontFamily; + napi_get_named_property(env, value, JPAGTEXT_FONT_FAMILY, &fontFamily); + char fontFamilyBuf[1024]; + size_t familyLength = 0; + napi_get_value_string_utf8(env, fontFamily, fontFamilyBuf, 1024, &familyLength); + text->fontFamily = {fontFamilyBuf, familyLength}; + + napi_value fontStyle; + napi_get_named_property(env, value, JPAGTEXT_FONT_STYLE, &fontStyle); + char fontStyleBuf[1024]; + size_t styleLength = 0; + napi_get_value_string_utf8(env, fontStyle, fontStyleBuf, 1024, &styleLength); + text->fontStyle = {fontStyleBuf, styleLength}; + + napi_value fontSize; + napi_get_named_property(env, value, JPAGTEXT_FONT_SIZE, &fontSize); + napi_get_value_double(env, fontSize, &temp); + text->fontSize = temp; + + napi_value strokeColor; + napi_get_named_property(env, value, JPAGTEXT_STROKE_COLOR, &strokeColor); + napi_get_value_int32(env, strokeColor, &color); + text->strokeColor = ToColor(color); + + napi_value strokeOverFill; + napi_get_named_property(env, value, JPAGTEXT_STROKE_OVER_FILL, &strokeOverFill); + napi_get_value_bool(env, strokeOverFill, &text->strokeOverFill); + + napi_value strokeWidth; + napi_get_named_property(env, value, JPAGTEXT_STROKE_WIDTH, &strokeWidth); + napi_get_value_double(env, strokeWidth, &temp); + text->strokeWidth = temp; + + napi_value content; + napi_get_named_property(env, value, JPAGTEXT_TEXT, &content); + char textBuf[1024]; + size_t textLength = 0; + napi_get_value_string_utf8(env, content, textBuf, 1024, &textLength); + text->text = {textBuf, textLength}; + + napi_value justification; + napi_get_named_property(env, value, JPAGTEXT_JUSTIFICATION, &justification); + int intTemp = 0; + napi_get_value_int32(env, justification, &intTemp); + text->justification = static_cast(intTemp); + + napi_value leading; + napi_get_named_property(env, value, JPAGTEXT_LEADING, &leading); + napi_get_value_double(env, leading, &temp); + text->leading = temp; + + napi_value tracking; + napi_get_named_property(env, value, JPAGTEXT_TRACKING, &tracking); + napi_get_value_double(env, tracking, &temp); + text->tracking = temp; + + napi_value backgroundColor; + napi_get_named_property(env, value, JPAGTEXT_BACKGROUND_COLOR, &backgroundColor); + napi_get_value_int32(env, backgroundColor, &color); + text->backgroundColor = ToColor(color); + + napi_value backgroundAlpha; + napi_get_named_property(env, value, JPAGTEXT_BACKGROUND_ALPHA, &backgroundAlpha); + napi_get_value_int32(env, backgroundAlpha, &intTemp); + text->backgroundAlpha = intTemp; + return text; +} + +napi_value JPAGText::ToJs(napi_env env, const std::shared_ptr& text) { + napi_value result; + auto status = napi_new_instance(env, GetConstructor(env, ClassName()), 0, nullptr, &result); + if (status != napi_ok) { + LOGE("JPAGText::ToJs napi_new_instance failed :%d", status); + return nullptr; + } + + napi_value applyFill; + napi_get_boolean(env, text->applyFill, &applyFill); + napi_set_named_property(env, result, JPAGTEXT_APPLY_FILL, applyFill); + + napi_value applyStroke; + napi_get_boolean(env, text->applyStroke, &applyStroke); + napi_set_named_property(env, result, JPAGTEXT_APPLY_STROKE, applyStroke); + + napi_value baselineShift; + napi_create_int32(env, text->baselineShift, &baselineShift); + napi_set_named_property(env, result, JPAGTEXT_BASELINE_SHIFT, baselineShift); + + napi_value boxText; + napi_get_boolean(env, text->boxText, &boxText); + napi_set_named_property(env, result, JPAGTEXT_BOX_TEXT, boxText); + + auto boxTextPosition = text->boxTextPos; + auto boxTextSize = text->boxTextSize; + napi_value boxTextRect = CreateRect( + env, Rect::MakeXYWH(boxTextPosition.x, boxTextPosition.y, boxTextSize.x, boxTextSize.y)); + napi_set_named_property(env, result, JPAGTEXT_BOX_TEXT_RECT, boxTextRect); + + napi_value firstBaseLine; + napi_create_int32(env, text->firstBaseLine, &firstBaseLine); + napi_set_named_property(env, result, JPAGTEXT_FIRST_BASE_LINE, firstBaseLine); + + napi_value fauxBold; + napi_get_boolean(env, text->fauxBold, &fauxBold); + napi_set_named_property(env, result, JPAGTEXT_FAUX_BOLD, fauxBold); + + napi_value fauxItalic; + napi_get_boolean(env, text->fauxItalic, &fauxItalic); + napi_set_named_property(env, result, JPAGTEXT_FAUX_ITALIC, fauxItalic); + + napi_value fillColor; + napi_create_int32(env, + MakeColorInt(text->fillColor.red, text->fillColor.green, text->fillColor.blue), + &fillColor); + napi_set_named_property(env, result, JPAGTEXT_FILL_COLOR, fillColor); + + napi_value fontFamily; + napi_create_string_utf8(env, text->fontFamily.c_str(), text->fontFamily.length(), &fontFamily); + napi_set_named_property(env, result, JPAGTEXT_FONT_FAMILY, fontFamily); + + napi_value fontStyle; + napi_create_string_utf8(env, text->fontStyle.c_str(), text->fontStyle.length(), &fontStyle); + napi_set_named_property(env, result, JPAGTEXT_FONT_STYLE, fontStyle); + + napi_value fontSize; + napi_create_double(env, text->fontSize, &fontSize); + napi_set_named_property(env, result, JPAGTEXT_FONT_SIZE, fontSize); + + napi_value strokeColor; + napi_create_int32( + env, MakeColorInt(text->strokeColor.red, text->strokeColor.green, text->strokeColor.blue), + &strokeColor); + napi_set_named_property(env, result, JPAGTEXT_STROKE_COLOR, strokeColor); + + napi_value strokeOverFill; + napi_get_boolean(env, text->strokeOverFill, &strokeOverFill); + napi_set_named_property(env, result, JPAGTEXT_STROKE_OVER_FILL, strokeOverFill); + + napi_value strokeWidth; + napi_create_double(env, text->strokeWidth, &strokeWidth); + napi_set_named_property(env, result, JPAGTEXT_STROKE_WIDTH, strokeWidth); + + napi_value content; + napi_create_string_utf8(env, text->text.c_str(), text->text.length(), &content); + napi_set_named_property(env, result, JPAGTEXT_TEXT, content); + + napi_value justification; + napi_create_int32(env, text->justification, &justification); + napi_set_named_property(env, result, JPAGTEXT_JUSTIFICATION, justification); + + napi_value leading; + napi_create_double(env, text->leading, &leading); + napi_set_named_property(env, result, JPAGTEXT_LEADING, leading); + + napi_value tracking; + napi_create_double(env, text->tracking, &tracking); + napi_set_named_property(env, result, JPAGTEXT_TRACKING, tracking); + + napi_value backgroundColor; + napi_create_int32(env, + MakeColorInt(text->backgroundColor.red, text->backgroundColor.green, + text->backgroundColor.blue), + &backgroundColor); + napi_set_named_property(env, result, JPAGTEXT_BACKGROUND_COLOR, backgroundColor); + + napi_value backgroundAlpha; + napi_create_int32(env, text->backgroundAlpha, &backgroundAlpha); + napi_set_named_property(env, result, JPAGTEXT_BACKGROUND_ALPHA, backgroundAlpha); + + return result; +} + +napi_value JPAGText::Constructor(napi_env env, napi_callback_info info) { + napi_value result = nullptr; + size_t argc = 0; + napi_value args[1]; + napi_get_cb_info(env, info, &argc, args, &result, nullptr); + return result; +} +} // namespace pag diff --git a/src/platform/ohos/JPAGText.h b/src/platform/ohos/JPAGText.h new file mode 100644 index 0000000000..9f5013fd96 --- /dev/null +++ b/src/platform/ohos/JPAGText.h @@ -0,0 +1,36 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include "pag/pag.h" + +namespace pag { +class JPAGText { + public: + static bool Init(napi_env env, napi_value exports); + static napi_value ToJs(napi_env env, const std::shared_ptr& text); + static std::shared_ptr FromJs(napi_env env, napi_value value); + static std::string ClassName() { + return "JPAGText"; + } + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); +}; +} // namespace pag diff --git a/src/platform/ohos/JPAGTextLayer.cpp b/src/platform/ohos/JPAGTextLayer.cpp new file mode 100644 index 0000000000..e292dbc71c --- /dev/null +++ b/src/platform/ohos/JPAGTextLayer.cpp @@ -0,0 +1,210 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAGLayerHandle.h" +#include "platform/ohos/JPAGFont.h" +#include "platform/ohos/JsHelper.h" + +namespace pag { + +static napi_value FillColor(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + napi_value result; + auto color = textLayer->fillColor(); + napi_create_int32(env, MakeColorInt(color.red, color.green, color.blue), &result); + return result; +} + +static napi_value SetFillColor(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + int color = 0; + napi_get_value_int32(env, args[0], &color); + auto textLayer = std::static_pointer_cast(layer); + textLayer->setFillColor(ToColor(color)); + return nullptr; +} + +static napi_value Font(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + auto font = textLayer->font(); + return JPAGFont::ToJs(env, font); +} +static napi_value SetFont(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + textLayer->setFont(JPAGFont::FromJs(env, args[0])); + return nullptr; +} +static napi_value FontSize(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + napi_value result; + napi_create_double(env, textLayer->fontSize(), &result); + return result; +} + +static napi_value SetFontSize(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + double fontsize = 0; + napi_get_value_double(env, args[0], &fontsize); + textLayer->setFontSize(fontsize); + return nullptr; +} + +static napi_value StrokeColor(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + napi_value result; + auto color = textLayer->strokeColor(); + napi_create_int32(env, MakeColorInt(color.red, color.green, color.blue), &result); + return result; +} +static napi_value SetStrokeColor(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + int color = 0; + napi_get_value_int32(env, args[0], &color); + textLayer->setStrokeColor(ToColor(color)); + return nullptr; +} + +static napi_value Text(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + napi_value result; + auto text = textLayer->text(); + napi_create_string_utf8(env, text.c_str(), text.size(), &result); + return result; +} + +static napi_value SetText(napi_env env, napi_callback_info info) { + size_t argc = 1; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + char buf[2048]; + size_t length = 0; + napi_get_value_string_utf8(env, args[0], buf, 2048, &length); + textLayer->setText({buf, length}); + return nullptr; +} + +static napi_value Reset(napi_env env, napi_callback_info info) { + size_t argc = 0; + napi_value args[1] = {nullptr}; + napi_value jsLayer = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsLayer, nullptr); + auto layer = JPAGLayerHandle::FromJs(env, jsLayer); + if (!layer) { + return nullptr; + } + auto textLayer = std::static_pointer_cast(layer); + textLayer->reset(); + return nullptr; +} + +bool JPAGLayerHandle::InitPAGTextLayerEnv(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = {PAG_DEFAULT_METHOD_ENTRY(fillColor, FillColor), + PAG_DEFAULT_METHOD_ENTRY(setFillColor, SetFillColor), + PAG_DEFAULT_METHOD_ENTRY(font, Font), + PAG_DEFAULT_METHOD_ENTRY(setFont, SetFont), + PAG_DEFAULT_METHOD_ENTRY(fontSize, FontSize), + PAG_DEFAULT_METHOD_ENTRY(setFontSize, SetFontSize), + PAG_DEFAULT_METHOD_ENTRY(strokeColor, StrokeColor), + PAG_DEFAULT_METHOD_ENTRY(setStrokeColor, SetStrokeColor), + PAG_DEFAULT_METHOD_ENTRY(text, Text), + PAG_DEFAULT_METHOD_ENTRY(setText, SetText), + PAG_DEFAULT_METHOD_ENTRY(reset, Reset)}; + auto status = DefineClass(env, exports, GetLayerClassName(LayerType::Text), + sizeof(classProp) / sizeof(classProp[0]), classProp, Constructor, + GetBaseClassName()); + return status == napi_ok; +} + +} // namespace pag diff --git a/src/platform/ohos/JPAGView.cpp b/src/platform/ohos/JPAGView.cpp new file mode 100644 index 0000000000..1a09240692 --- /dev/null +++ b/src/platform/ohos/JPAGView.cpp @@ -0,0 +1,574 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JPAGView.h" + +#include +#include + +#include "base/utils/Log.h" +#include "base/utils/UniqueID.h" +#include "platform/ohos/GPUDrawable.h" +#include "platform/ohos/JsHelper.h" +#include "platform/ohos/JPAGLayerHandle.h" + +namespace pag { +static int PAGViewStateStart = 0; +static int PAGViewStateCancel = 1; +static int PAGViewStateEnd = 2; +static int PAGViewStateRepeat = 3; + +static std::unordered_map> ViewMap = {}; + +void OnSurfaceCreatedCB(OH_NativeXComponent* component, void* window) { + if ((component == nullptr) || (window == nullptr)) { + 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) { + return; + } + + std::string id(idStr); + if (ViewMap.find(id) == ViewMap.end()) { + LOGE("Could not find PAGView on Surface Created id:%s", id.c_str()); + return; + } + auto drawable = pag::GPUDrawable::FromWindow(static_cast(window)); + auto view = ViewMap[id]; + view->player->setSurface(pag::PAGSurface::MakeFrom(drawable)); + view->animator->update(); +} + +void OnSurfaceChangedCB(OH_NativeXComponent* component, void* window) { + if ((component == nullptr) || (window == nullptr)) { + 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) { + return; + } + + std::string id(idStr); + if (ViewMap.find(id) == ViewMap.end()) { + LOGE("Could not find PAGView on Surface change id:%s", id.c_str()); + return; + } + auto surface = ViewMap[id]->player->getSurface(); + if (!surface) { + LOGE("PAGView id:%s without PAGSurface while surface size change", id.c_str()); + return; + } + surface->updateSize(); +} + +void OnSurfaceDestroyedCB(OH_NativeXComponent* component, void* window) { + if ((component == nullptr) || (window == nullptr)) { + 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) { + return; + } + + std::string id(idStr); + if (ViewMap.find(id) == ViewMap.end()) { + LOGE("Could not find PAGView on Surface Destroyed id:%s", id.c_str()); + return; + } + ViewMap[id]->player->setSurface(nullptr); +} + +static void DispatchTouchEventCB(OH_NativeXComponent*, void*) { +} + +static napi_value Flush(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->animator->update(); + } + return nullptr; +} + +static napi_value SetProgress(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + double progress = 0; + napi_get_value_double(env, args[0], &progress); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->animator->setProgress(progress); + } + return nullptr; +} + +static napi_value SetComposition(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + auto layer = JPAGLayerHandle::FromJs(env, args[0]); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + if (layer != nullptr) { + if (layer->layerType() == LayerType::PreCompose) { + view->player->setComposition(std::static_pointer_cast(layer)); + view->animator->setDuration(layer->duration()); + } + } else { + view->player->setComposition(nullptr); + view->animator->setDuration(0); + } + } + return nullptr; +} + +static napi_value SetRepeatCount(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + int repeatCount = 0; + napi_get_value_int32(env, args[0], &repeatCount); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->animator->setRepeatCount(repeatCount); + } + return nullptr; +} + +static napi_value Play(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->player->prepare(); + view->animator->start(); + } + return nullptr; +} + +static napi_value Pause(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->animator->cancel(); + } + return nullptr; +} + +static napi_value UniqueID(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + napi_value result; + napi_create_string_utf8(env, view->id.c_str(), view->id.length(), &result); + return result; +} + +static void StateChangeCallback(napi_env env, napi_value callback, void*, void* data) { + int state = *static_cast(data); + size_t argc = 1; + napi_value argv[1] = {0}; + napi_create_uint32(env, state, &argv[0]); + napi_value undefined; + napi_get_undefined(env, &undefined); + napi_call_function(env, undefined, callback, argc, argv, nullptr); +} + +static napi_value SetStateChangeCallback(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + + napi_value resourceName = nullptr; + napi_create_string_utf8(env, "PAGViewStateChangeCallback", NAPI_AUTO_LENGTH, &resourceName); + + napi_create_threadsafe_function(env, args[0], nullptr, resourceName, 0, 1, nullptr, nullptr, view, + StateChangeCallback, &view->playingStateCallback); + return nullptr; +} + +static void ProgressCallback(napi_env env, napi_value callback, void*, void* data) { + double* progressPtr = static_cast(data); + size_t argc = 1; + napi_value argv[1] = {0}; + napi_create_double(env, *progressPtr, &argv[0]); + napi_value undefined; + napi_get_undefined(env, &undefined); + napi_call_function(env, undefined, callback, argc, argv, nullptr); + delete progressPtr; +} + +static napi_value SetProgressUpdateCallback(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + napi_value resourceName = nullptr; + napi_create_string_utf8(env, "PAGViewProgressCallback", NAPI_AUTO_LENGTH, &resourceName); + napi_create_threadsafe_function(env, args[0], nullptr, resourceName, 0, 1, nullptr, nullptr, + nullptr, ProgressCallback, &view->progressCallback); + return nullptr; +} + +static napi_value SetSync(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + bool value = false; + napi_get_value_bool(env, args[0], &value); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->animator->setSync(value); + } + return nullptr; +} + +static napi_value SetVideoEnabled(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + bool value = false; + napi_get_value_bool(env, args[0], &value); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->player->setVideoEnabled(value); + } + return nullptr; +} + +static napi_value SetCacheEnabled(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + bool value = false; + napi_get_value_bool(env, args[0], &value); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->player->setCacheEnabled(value); + } + return nullptr; +} + +static napi_value SetCacheScale(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + double value = 1.0f; + napi_get_value_double(env, args[0], &value); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->player->setCacheScale(value); + } + return nullptr; +} + +static napi_value SetMaxFrameRate(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + double value = 60.0f; + napi_get_value_double(env, args[0], &value); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->player->setMaxFrameRate(value); + } + return nullptr; +} + +static napi_value SetScaleMode(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + int value = 0; + napi_get_value_int32(env, args[0], &value); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->player->setScaleMode(value); + } + return nullptr; +} + +static napi_value SetMatrix(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 1; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + if (argc == 0) { + return nullptr; + } + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view != nullptr) { + view->player->setMatrix(GetMatrix(env, args[0])); + } + return nullptr; +} + +static napi_value CurrentFrame(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view == nullptr) { + return nullptr; + } + napi_value result; + napi_create_int32(env, view->player->currentFrame(), &result); + return result; +} + +static napi_value GetLayersUnderPoint(napi_env env, napi_callback_info info) { + size_t argc = 2; + napi_value args[2] = {nullptr}; + napi_value jsView = nullptr; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (!view) { + return nullptr; + } + double surfaceX = 0; + napi_get_value_double(env, args[0], &surfaceX); + double surfaceY = 0; + napi_get_value_double(env, args[1], &surfaceY); + auto layers = view->player->getLayersUnderPoint(surfaceX, surfaceY); + napi_value result; + napi_create_array_with_length(env, layers.size(), &result); + for (uint32_t i = 0; i < layers.size(); i++) { + auto layer = JPAGLayerHandle::ToJs(env, layers[i]); + if (!layer) { + break; + } + napi_set_element(env, result, i, layer); + } + return result; +} + +static napi_value FreeCache(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view == nullptr) { + return nullptr; + } + auto surface = view->player->getSurface(); + if (surface) { + surface->freeCache(); + } + return nullptr; +} + +static napi_value MakeSnapshot(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + JPAGView* view = nullptr; + napi_unwrap(env, jsView, reinterpret_cast(&view)); + if (view == nullptr) { + return nullptr; + } + auto surface = view->player->getSurface(); + return MakeSnapshot(env, surface.get()); +} + +napi_value JPAGView::Constructor(napi_env env, napi_callback_info info) { + napi_value jsView = nullptr; + size_t argc = 0; + napi_value args[1] = {0}; + napi_get_cb_info(env, info, &argc, args, &jsView, nullptr); + std::string id = "PAGView" + std::to_string(UniqueID::Next()); + auto cView = std::make_shared(id); + cView->animator = PAGAnimator::MakeFrom(cView); + cView->animator->setRepeatCount(-1); + napi_wrap( + env, jsView, cView.get(), + [](napi_env, void* finalize_data, void*) { + JPAGView* view = static_cast(finalize_data); + ViewMap.erase(view->id); + delete view; + }, + nullptr, nullptr); + ViewMap.emplace(id, cView); + return jsView; +} + +bool JPAGView::Init(napi_env env, napi_value exports) { + napi_property_descriptor classProp[] = { + PAG_DEFAULT_METHOD_ENTRY(flush, Flush), + PAG_DEFAULT_METHOD_ENTRY(setProgress, SetProgress), + PAG_DEFAULT_METHOD_ENTRY(setComposition, SetComposition), + PAG_DEFAULT_METHOD_ENTRY(setRepeatCount, SetRepeatCount), + PAG_DEFAULT_METHOD_ENTRY(play, Play), + PAG_DEFAULT_METHOD_ENTRY(pause, Pause), + PAG_DEFAULT_METHOD_ENTRY(setStateChangeCallback, SetStateChangeCallback), + PAG_DEFAULT_METHOD_ENTRY(setProgressUpdateCallback, SetProgressUpdateCallback), + PAG_DEFAULT_METHOD_ENTRY(uniqueID, UniqueID), + PAG_DEFAULT_METHOD_ENTRY(setSync, SetSync), + PAG_DEFAULT_METHOD_ENTRY(setVideoEnabled, SetVideoEnabled), + PAG_DEFAULT_METHOD_ENTRY(setCacheEnabled, SetCacheEnabled), + PAG_DEFAULT_METHOD_ENTRY(setCacheScale, SetCacheScale), + PAG_DEFAULT_METHOD_ENTRY(setMaxFrameRate, SetMaxFrameRate), + PAG_DEFAULT_METHOD_ENTRY(setScaleMode, SetScaleMode), + PAG_DEFAULT_METHOD_ENTRY(setMatrix, SetMatrix), + PAG_DEFAULT_METHOD_ENTRY(currentFrame, CurrentFrame), + PAG_DEFAULT_METHOD_ENTRY(getLayersUnderPoint, GetLayersUnderPoint), + PAG_DEFAULT_METHOD_ENTRY(freeCache, FreeCache), + PAG_DEFAULT_METHOD_ENTRY(makeSnapshot, MakeSnapshot)}; + auto status = DefineClass(env, exports, ClassName(), sizeof(classProp) / sizeof(classProp[0]), + classProp, Constructor, ""); + if (status != napi_ok) { + return false; + } + napi_value exportInstance = nullptr; + if (napi_get_named_property(env, exports, OH_NATIVE_XCOMPONENT_OBJ, &exportInstance) != napi_ok) { + return true; + } + + OH_NativeXComponent* nativeXComponent = nullptr; + auto temp = napi_unwrap(env, exportInstance, reinterpret_cast(&nativeXComponent)); + if (temp != napi_ok) { + return true; + } + + static OH_NativeXComponent_Callback renderCallback; + renderCallback.OnSurfaceCreated = OnSurfaceCreatedCB; + renderCallback.OnSurfaceChanged = OnSurfaceChangedCB; + renderCallback.OnSurfaceDestroyed = OnSurfaceDestroyedCB; + renderCallback.DispatchTouchEvent = DispatchTouchEventCB; + + OH_NativeXComponent_RegisterCallback(nativeXComponent, &renderCallback); + return true; +} + +void JPAGView::onAnimationStart(PAGAnimator*) { + + napi_call_threadsafe_function(playingStateCallback, &PAGViewStateStart, + napi_threadsafe_function_call_mode::napi_tsfn_nonblocking); +} + +void JPAGView::onAnimationCancel(PAGAnimator*) { + napi_call_threadsafe_function(playingStateCallback, &PAGViewStateCancel, + napi_threadsafe_function_call_mode::napi_tsfn_nonblocking); +} + +void JPAGView::onAnimationEnd(PAGAnimator*) { + napi_call_threadsafe_function(playingStateCallback, &PAGViewStateEnd, + napi_threadsafe_function_call_mode::napi_tsfn_nonblocking); +} + +void JPAGView::onAnimationRepeat(PAGAnimator*) { + napi_call_threadsafe_function(playingStateCallback, &PAGViewStateRepeat, + napi_threadsafe_function_call_mode::napi_tsfn_nonblocking); +} + +void JPAGView::onAnimationUpdate(PAGAnimator* animator) { + napi_call_threadsafe_function(progressCallback, new double(animator->progress()), + napi_threadsafe_function_call_mode::napi_tsfn_nonblocking); + player->setProgress(animator->progress()); + player->flush(); +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JPAGView.h b/src/platform/ohos/JPAGView.h new file mode 100644 index 0000000000..1a36cc3cf0 --- /dev/null +++ b/src/platform/ohos/JPAGView.h @@ -0,0 +1,58 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// +#pragma once + +#include +#include "pag/pag.h" +#include "rendering/PAGAnimator.h" + +namespace pag { +class JPAGView : public PAGAnimator::Listener { + public: + static bool Init(napi_env env, napi_value exports); + static inline std::string ClassName() { + return "JPAGView"; + } + + explicit JPAGView(const std::string& id) : player(new PAGPlayer()), id(std::move(id)) { + } + virtual ~JPAGView() { + napi_release_threadsafe_function(progressCallback, napi_tsfn_abort); + napi_release_threadsafe_function(playingStateCallback, napi_tsfn_abort); + } + + void onAnimationStart(PAGAnimator*) override; + + void onAnimationCancel(PAGAnimator*) override; + + void onAnimationEnd(PAGAnimator*) override; + + void onAnimationRepeat(PAGAnimator*) override; + + void onAnimationUpdate(PAGAnimator* animator) override; + + std::unique_ptr player = nullptr; + std::string id; + std::shared_ptr animator = nullptr; + napi_threadsafe_function progressCallback; + napi_threadsafe_function playingStateCallback; + + private: + static napi_value Constructor(napi_env env, napi_callback_info info); +}; +} // namespace pag diff --git a/src/platform/ohos/JsHelper.cpp b/src/platform/ohos/JsHelper.cpp new file mode 100644 index 0000000000..1596acee57 --- /dev/null +++ b/src/platform/ohos/JsHelper.cpp @@ -0,0 +1,439 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "JsHelper.h" +#include +#include +#include +#include "base/utils/Log.h" + +namespace pag { + +static std::unordered_map ConstructorRefMap; + +bool SetConstructor(napi_env env, napi_value constructor, const std::string& name) { + if (env == nullptr || constructor == nullptr || name.empty()) { + return false; + } + if (ConstructorRefMap.find(name) != ConstructorRefMap.end()) { + napi_delete_reference(env, ConstructorRefMap.at(name)); + ConstructorRefMap.erase(name); + } + napi_ref ref; + napi_create_reference(env, constructor, 1, &ref); + ConstructorRefMap[name] = ref; + return true; +} + +napi_value GetConstructor(napi_env env, const std::string& name) { + if (env == nullptr || name.empty()) { + return nullptr; + } + napi_value result = nullptr; + if (ConstructorRefMap.find(name) != ConstructorRefMap.end()) { + napi_get_reference_value(env, ConstructorRefMap.at(name), &result); + } + return result; +} + +napi_status ExtendClass(napi_env env, napi_value constructor, const std::string& parentName) { + if (env == nullptr || constructor == nullptr || parentName.empty()) { + return napi_status::napi_invalid_arg; + } + napi_value baseConstructor = GetConstructor(env, parentName); + if (baseConstructor == nullptr) { + LOGE("ExtendClass get baseConstructor failed status"); + return napi_status::napi_invalid_arg; + } + napi_value basePrototype; + napi_status statusCode = + napi_get_named_property(env, baseConstructor, "prototype", &basePrototype); + if (statusCode != napi_status::napi_ok) { + LOGE("ExtendClass get baseConstructor's prototype failed status :%d", statusCode); + return statusCode; + } + napi_value derivedPrototype; + statusCode = napi_get_named_property(env, constructor, "prototype", &derivedPrototype); + if (statusCode != napi_status::napi_ok) { + LOGE("ExtendClass get constructor's prototype failed status :%d", statusCode); + return statusCode; + } + return napi_set_named_property(env, derivedPrototype, "__proto__", basePrototype); +} + +napi_status DefineClass(napi_env env, napi_value exports, const std::string& utf8name, + size_t propertyCount, const napi_property_descriptor* properties, + napi_callback constructor, const std::string& parentName) { + napi_value classConstructor; + auto status = napi_define_class(env, utf8name.c_str(), utf8name.length(), constructor, nullptr, + propertyCount, properties, &classConstructor); + if (status != napi_status::napi_ok) { + LOGE("DefineClass napi_define_class failed:%d", status); + return status; + } + status = napi_set_named_property(env, exports, utf8name.c_str(), classConstructor); + if (status != napi_status::napi_ok) { + LOGE("DefineClass napi_set_named_property failed:%d", status); + return status; + } + SetConstructor(env, classConstructor, utf8name); + if (parentName.empty()) { + return status; + } + status = ExtendClass(env, classConstructor, parentName); + if (status != napi_status::napi_ok) { + LOGE("DefineClass ExtendClass failed:%d", status); + return status; + } + return status; +} + +napi_value NewInstance(napi_env env, const std::string& name, void* handler) { + if (env == nullptr || handler == nullptr || name.empty()) { + return nullptr; + } + napi_value constructor = GetConstructor(env, name); + if (constructor == nullptr) { + return nullptr; + } + napi_value result = nullptr; + napi_value external[1]; + auto status = napi_create_external(env, handler, nullptr, nullptr, &external[0]); + if (status != napi_ok) { + LOGE("NewInstance napi_create_external failed :%d", status); + return nullptr; + } + status = napi_new_instance(env, constructor, 1, external, &result); + if (status != napi_ok) { + LOGE("NewInstance napi_new_instance failed :%d", status); + return nullptr; + } + return result; +} + +napi_value CreateMarker(napi_env env, const Marker* marker) { + if (env == nullptr || marker == nullptr) { + return nullptr; + } + napi_value result = nullptr; + auto status = napi_create_object(env, &result); + if (status != napi_ok) { + LOGE("CreateMarker napi_create_object failed :%d", status); + return nullptr; + } + napi_value startTime; + status = napi_create_int64(env, marker->startTime, &startTime); + if (status != napi_ok) { + LOGE("CreateMarker napi_create_int64 failed :%d", status); + return nullptr; + } + status = napi_set_named_property(env, result, "startTime", startTime); + if (status != napi_ok) { + LOGE("CreateMarker napi_set_named_property failed :%d", status); + return nullptr; + } + napi_value duration; + status = napi_create_int64(env, marker->duration, &duration); + if (status != napi_ok) { + LOGE("CreateMarker napi_create_int64 failed :%d", status); + return nullptr; + } + status = napi_set_named_property(env, result, "duration", duration); + if (status != napi_ok) { + LOGE("CreateMarker napi_set_named_property failed :%d", status); + return nullptr; + } + napi_value comment; + status = + napi_create_string_utf8(env, marker->comment.c_str(), marker->comment.length(), &comment); + if (status != napi_ok) { + LOGE("CreateMarker napi_create_string_utf8 failed :%d", status); + return nullptr; + } + status = napi_set_named_property(env, result, "comment", comment); + if (status != napi_ok) { + LOGE("CreateMarker napi_set_named_property failed :%d", status); + return nullptr; + } + return result; +} + +napi_value CreateMarkers(napi_env env, const std::vector& markers) { + napi_value result; + auto status = napi_create_array_with_length(env, markers.size(), &result); + if (status != napi_ok) { + return nullptr; + } + for (size_t i = 0; i < markers.size(); i++) { + auto jsMarker = CreateMarker(env, markers[i]); + if (jsMarker == nullptr) { + return nullptr; + } + napi_set_element(env, result, i, jsMarker); + } + return result; +} + +napi_value CreateRect(napi_env env, const Rect& rect) { + if (env == nullptr) { + return nullptr; + } + napi_value result = nullptr; + auto status = napi_create_array_with_length(env, 4, &result); + if (status != napi_ok) { + LOGE("CreateRect napi_create_array_with_length failed :%d", status); + return nullptr; + } + napi_value l; + status = napi_create_double(env, rect.left, &l); + if (status != napi_ok) { + LOGE("CreateRect napi_create_int64 failed :%d", status); + return nullptr; + } + napi_value t; + status = napi_create_double(env, rect.top, &t); + if (status != napi_ok) { + LOGE("CreateRect napi_create_double failed :%d", status); + return nullptr; + } + napi_value r; + status = napi_create_double(env, rect.right, &r); + if (status != napi_ok) { + LOGE("CreateRect napi_create_double failed :%d", status); + return nullptr; + } + + napi_value b; + status = napi_create_double(env, rect.bottom, &b); + if (status != napi_ok) { + LOGE("CreateRect napi_create_double failed :%d", status); + return nullptr; + } + + napi_value valueArray[] = {l, t, r, b}; + for (uint32_t i = 0; i < 4; i++) { + napi_set_element(env, result, i, valueArray[i]); + } + return result; +} + +Rect GetRect(napi_env env, napi_value value) { + uint32_t length = 0; + auto status = napi_get_array_length(env, value, &length); + if (status != napi_ok) { + LOGE("GetRect napi_get_array_length failed :%d", status); + return {}; + } + if (length != 4) { + LOGE("GetRect array length != 4"); + return {}; + } + double array[] = {0.0, 0.0, 0.0, 0.0}; + for (uint32_t i = 0; i < 4; i++) { + napi_value jsValue = nullptr; + status = napi_get_element(env, value, i, &jsValue); + if (status != napi_ok) { + LOGE("GetRect get values[%u] failed :%d", i, status); + return {}; + } + status = napi_get_value_double(env, jsValue, &array[i]); + if (status != napi_ok) { + LOGE("GetRect get values[%u] value failed :%d", i, status); + return {}; + } + } + return Rect::MakeXYWH(array[0], array[1], array[2], array[3]); +} + +napi_value CreateMatrix(napi_env env, const Matrix& matrix) { + if (env == nullptr) { + return nullptr; + } + float buffer[9]; + matrix.get9(buffer); + napi_value result = nullptr; + auto status = napi_create_array_with_length(env, 9, &result); + if (status != napi_ok) { + LOGE("CreateMatrix napi_create_array_with_length failed :%d", status); + return nullptr; + } + for (size_t i = 0; i < 9; i++) { + napi_value ele; + status = napi_create_double(env, buffer[i], &ele); + if (status != napi_ok) { + LOGE("CreateMatrix napi_create_int64 failed :%d", status); + return nullptr; + } + status = napi_set_element(env, result, i, ele); + if (status != napi_ok) { + LOGE("CreateMatrix napi_set_element failed :%d", status); + return nullptr; + } + } + return result; +} + +Matrix GetMatrix(napi_env env, napi_value value) { + if (env == nullptr || value == nullptr) { + return {}; + } + + Matrix result; + for (size_t i = 0; i < 9; i++) { + napi_value ele; + auto status = napi_get_element(env, value, i, &ele); + if (status != napi_ok) { + LOGE("GetMatrix napi_get_element failed :%d", status); + return {}; + } + double val = 0; + status = napi_get_value_double(env, ele, &val); + if (status != napi_ok) { + LOGE("GetMatrix napi_get_value_double failed :%d", status); + return {}; + } + result.set(i, val); + } + return result; +} + +napi_value CreateTextDocument(napi_env, TextDocumentHandle) { + return nullptr; +} + +TextDocumentHandle GetTextDocument(napi_env, napi_value) { + return nullptr; +} + +napi_value MakeSnapshot(napi_env env, PAGSurface* surface) { + if (surface == nullptr) { + return nullptr; + } + tgfx::ImageInfo imageInfo = + tgfx::ImageInfo::Make(surface->width(), surface->height(), tgfx::ColorType::BGRA_8888); + uint8_t* pixels = new (std::nothrow) uint8_t[imageInfo.byteSize()]; + if (pixels == nullptr) { + return nullptr; + } + if (!surface->readPixels(ColorType::BGRA_8888, AlphaType::Premultiplied, pixels, + imageInfo.rowBytes())) { + delete[] pixels; + return nullptr; + } + + OhosPixelMapCreateOps ops; + ops.width = imageInfo.width(); + ops.height = imageInfo.height(); + ops.pixelFormat = PIXEL_FORMAT_BGRA_8888; + ops.alphaType = OHOS_PIXEL_MAP_ALPHA_TYPE_PREMUL; + ops.editable = true; + napi_value pixelMap; + auto status = OH_PixelMap_CreatePixelMap(env, ops, pixels, imageInfo.byteSize(), &pixelMap); + if (status == napi_ok) { + return pixelMap; + } + return nullptr; +} + +int MakeColorInt(uint32_t red, uint32_t green, uint32_t blue) { + int color = (255 << 24) | (red << 16) | (green << 8) | (blue << 0); + return color; +} + +Color ToColor(int value) { + auto color = static_cast(value); + auto red = (((color) >> 16) & 0xFF); + auto green = (((color) >> 8) & 0xFF); + auto blue = (((color) >> 0) & 0xFF); + return {static_cast(red), static_cast(green), static_cast(blue)}; +} + +napi_value CreateVideoRange(napi_env env, const PAGVideoRange& videoRange) { + if (env == nullptr) { + return nullptr; + } + napi_value result = nullptr; + auto status = napi_create_object(env, &result); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_create_object failed :%d", status); + return nullptr; + } + napi_value startTime; + status = napi_create_int64(env, videoRange.startTime(), &startTime); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_create_int64 failed :%d", status); + return nullptr; + } + status = napi_set_named_property(env, result, "startTime", startTime); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_set_named_property failed :%d", status); + return nullptr; + } + napi_value endTime; + status = napi_create_int64(env, videoRange.endTime(), &endTime); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_create_int64 failed :%d", status); + return nullptr; + } + status = napi_set_named_property(env, result, "endTime", endTime); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_set_named_property failed :%d", status); + return nullptr; + } + napi_value playDuration; + status = napi_create_int64(env, videoRange.playDuration(), &playDuration); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_create_int64 failed :%d", status); + return nullptr; + } + status = napi_set_named_property(env, result, "playDuration", playDuration); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_set_named_property failed :%d", status); + return nullptr; + } + napi_value reversed; + status = napi_get_boolean(env, videoRange.reversed(), &reversed); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_get_boolean failed :%d", status); + return nullptr; + } + status = napi_set_named_property(env, result, "reversed", reversed); + if (status != napi_ok) { + LOGI("CreateVideoRange napi_set_named_property failed :%d", status); + return nullptr; + } + return result; +} + +napi_value CreateVideoRanges(napi_env env, const std::vector& videoRanges) { + napi_value result; + auto status = napi_create_array_with_length(env, videoRanges.size(), &result); + if (status != napi_ok) { + return nullptr; + } + for (size_t i = 0; i < videoRanges.size(); i++) { + auto jsVideoRange = CreateVideoRange(env, videoRanges[i]); + if (jsVideoRange == nullptr) { + return nullptr; + } + napi_set_element(env, result, i, jsVideoRange); + } + return result; +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/JsHelper.h b/src/platform/ohos/JsHelper.h new file mode 100644 index 0000000000..b61aaf4d2a --- /dev/null +++ b/src/platform/ohos/JsHelper.h @@ -0,0 +1,58 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include +#include "pag/pag.h" +#include "pag/types.h" + +#define PAG_DEFAULT_METHOD_ENTRY(name, func) \ + { #name, nullptr, func, nullptr, nullptr, nullptr, napi_default, nullptr } +#define PAG_STATIC_METHOD_ENTRY(name, func) \ + { #name, nullptr, func, nullptr, nullptr, nullptr, napi_static, nullptr } + +namespace pag { + +napi_status DefineClass(napi_env env, napi_value exports, const std::string& utf8name, + size_t propertyCount, const napi_property_descriptor* properties, + napi_callback constructor, const std::string& parentName); + +napi_value GetConstructor(napi_env env, const std::string& name); + +napi_value NewInstance(napi_env env, const std::string& name, void* handler); + +napi_value CreateMarkers(napi_env env, const std::vector& markers); + +napi_value CreateRect(napi_env env, const Rect& rect); + +Rect GetRect(napi_env env, napi_value value); + +napi_value CreateMatrix(napi_env env, const Matrix& matrix); + +Matrix GetMatrix(napi_env env, napi_value value); + +napi_value MakeSnapshot(napi_env env, PAGSurface* surface); + +int MakeColorInt(uint32_t red, uint32_t green, uint32_t blue); + +Color ToColor(int value); + +napi_value CreateVideoRanges(napi_env env, const std::vector& videoRanges); + +} // namespace pag diff --git a/src/platform/ohos/NativeDisplayLink.cpp b/src/platform/ohos/NativeDisplayLink.cpp new file mode 100644 index 0000000000..a22c8361d4 --- /dev/null +++ b/src/platform/ohos/NativeDisplayLink.cpp @@ -0,0 +1,51 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#include "NativeDisplayLink.h" + +namespace pag { + +void NativeDisplayLink::PAGVSyncCallback(long long, void* data) { + auto displayLink = static_cast(data); + displayLink->callback(); + if (displayLink->playing) { + OH_NativeVSync_RequestFrame(displayLink->vSync, &PAGVSyncCallback, displayLink); + } +} + +NativeDisplayLink::NativeDisplayLink(std::function callback) : callback(callback) { + char name[] = "pag_vsync"; + vSync = OH_NativeVSync_Create(name, strlen(name)); +} + +void NativeDisplayLink::start() { + if (playing == false) { + playing = true; + OH_NativeVSync_RequestFrame(vSync, &PAGVSyncCallback, this); + } +} + +void NativeDisplayLink::stop() { + playing = false; +} + +NativeDisplayLink::~NativeDisplayLink() { + OH_NativeVSync_Destroy(vSync); +} + +} // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/NativeDisplayLink.h b/src/platform/ohos/NativeDisplayLink.h new file mode 100644 index 0000000000..de446aed6d --- /dev/null +++ b/src/platform/ohos/NativeDisplayLink.h @@ -0,0 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +#pragma once +#include +#include +#include +#include "rendering/utils/DisplayLink.h" +namespace pag { + +class NativeDisplayLink : public DisplayLink { + public: + explicit NativeDisplayLink(std::function callback); + ~NativeDisplayLink() override; + + void start() override; + void stop() override; + + private: + static void PAGVSyncCallback(long long timestamp, void* data); + OH_NativeVSync* vSync = nullptr; + std::function callback = nullptr; + std::atomic playing = false; +}; +} // namespace pag diff --git a/src/platform/ohos/NativePlatform.cpp b/src/platform/ohos/NativePlatform.cpp index 13a85c75c6..618122b497 100644 --- a/src/platform/ohos/NativePlatform.cpp +++ b/src/platform/ohos/NativePlatform.cpp @@ -14,9 +14,11 @@ // either express or implied. see the license for the specific language governing permissions // and limitations under the license. // +///////////////////////////////////////////////////////////////////////////////////////////////// #include "NativePlatform.h" #include "platform/ohos/HardwareDecoder.h" +#include "platform/ohos/NativeDisplayLink.h" namespace pag { class HardwareDecoderFactory : public VideoDecoderFactory { @@ -49,29 +51,27 @@ std::vector NativePlatform::getVideoDecoderFactories } bool NativePlatform::registerFallbackFonts() const { - // to do, kevingpqi return false; } void NativePlatform::traceImage(const tgfx::ImageInfo& info, const void* pixels, const std::string& tag) const { - // to do, kevingpqi + // todo: kevingpqi if (info.isEmpty() || pixels || tag.c_str()) { } } std::string NativePlatform::getCacheDir() const { - // to do, kevingpqi + // todo: kevingpqi return ""; } std::shared_ptr NativePlatform::createDisplayLink( std::function callback) const { - // to do, kevingpqi - if (callback) { + if (!callback) { return nullptr; } - return nullptr; + return std::make_shared(callback); } } // namespace pag \ No newline at end of file diff --git a/src/platform/ohos/NativePlatform.h b/src/platform/ohos/NativePlatform.h index dce1fefc28..7532e11861 100644 --- a/src/platform/ohos/NativePlatform.h +++ b/src/platform/ohos/NativePlatform.h @@ -14,6 +14,7 @@ // either express or implied. see the license for the specific language governing permissions // and limitations under the license. // +///////////////////////////////////////////////////////////////////////////////////////////////// #pragma once From d8c504cd2abe582dbd514717f14085ba31f19301 Mon Sep 17 00:00:00 2001 From: Hparty <420024556@qq.com> Date: Tue, 6 Aug 2024 18:50:06 +0800 Subject: [PATCH 2/5] code format --- src/platform/ohos/JPAG.cpp | 4 ++-- src/platform/ohos/JPAGFile.cpp | 4 ++-- src/platform/ohos/JPAGFont.h | 2 +- src/platform/ohos/JPAGImage.h | 6 +++--- src/platform/ohos/JPAGPlayer.cpp | 2 +- src/platform/ohos/JPAGPlayer.h | 1 - src/platform/ohos/JPAGShapeLayer.cpp | 7 +++---- src/platform/ohos/JPAGSolidLayer.cpp | 10 ++++------ src/platform/ohos/JPAGSurface.cpp | 1 - src/platform/ohos/JPAGSurface.h | 4 ++-- src/platform/ohos/JPAGView.cpp | 4 +--- src/platform/ohos/NativeDisplayLink.h | 2 +- 12 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/platform/ohos/JPAG.cpp b/src/platform/ohos/JPAG.cpp index 84415d86ac..dd3bcf8b95 100644 --- a/src/platform/ohos/JPAG.cpp +++ b/src/platform/ohos/JPAG.cpp @@ -22,11 +22,11 @@ #include "platform/ohos/JPAG.h" #include "platform/ohos/JPAGFont.h" #include "platform/ohos/JPAGImage.h" -#include "platform/ohos/JPAGText.h" -#include "platform/ohos/JPAGView.h" #include "platform/ohos/JPAGLayerHandle.h" #include "platform/ohos/JPAGPlayer.h" #include "platform/ohos/JPAGSurface.h" +#include "platform/ohos/JPAGText.h" +#include "platform/ohos/JPAGView.h" #include "platform/ohos/JsHelper.h" namespace pag { diff --git a/src/platform/ohos/JPAGFile.cpp b/src/platform/ohos/JPAGFile.cpp index 4ccd18d7f6..168d5ac3f8 100644 --- a/src/platform/ohos/JPAGFile.cpp +++ b/src/platform/ohos/JPAGFile.cpp @@ -16,10 +16,10 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////// -#include -#include #include #include +#include +#include #include "JPAGLayerHandle.h" #include "JsHelper.h" #include "platform/ohos/JPAGImage.h" diff --git a/src/platform/ohos/JPAGFont.h b/src/platform/ohos/JPAGFont.h index afc6ecc573..c363be72b0 100644 --- a/src/platform/ohos/JPAGFont.h +++ b/src/platform/ohos/JPAGFont.h @@ -17,8 +17,8 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #pragma once -#include #include +#include #include "pag/pag.h" namespace pag { diff --git a/src/platform/ohos/JPAGImage.h b/src/platform/ohos/JPAGImage.h index ef6a16a631..10aa17d9a4 100644 --- a/src/platform/ohos/JPAGImage.h +++ b/src/platform/ohos/JPAGImage.h @@ -25,17 +25,17 @@ namespace pag { class JPAGImage { public: explicit JPAGImage(std::shared_ptr pagImage) : pagImage(pagImage) { - } + } static bool Init(napi_env env, napi_value exports); static napi_value ToJs(napi_env env, std::shared_ptr pagImage); static std::shared_ptr FromJs(napi_env env, napi_value value); static std::string ClassName() { return "JPAGImage"; } - + std::shared_ptr get() { return pagImage; - } + } private: static napi_value Constructor(napi_env env, napi_callback_info info); diff --git a/src/platform/ohos/JPAGPlayer.cpp b/src/platform/ohos/JPAGPlayer.cpp index 16bc445670..48695dab05 100644 --- a/src/platform/ohos/JPAGPlayer.cpp +++ b/src/platform/ohos/JPAGPlayer.cpp @@ -19,8 +19,8 @@ #include "JPAGPlayer.h" #include #include "JPAGLayerHandle.h" -#include "JsHelper.h" #include "JPAGSurface.h" +#include "JsHelper.h" namespace pag { diff --git a/src/platform/ohos/JPAGPlayer.h b/src/platform/ohos/JPAGPlayer.h index bd1d56cc16..d300bd755f 100644 --- a/src/platform/ohos/JPAGPlayer.h +++ b/src/platform/ohos/JPAGPlayer.h @@ -18,7 +18,6 @@ #pragma once #include - #include "pag/pag.h" namespace pag { diff --git a/src/platform/ohos/JPAGShapeLayer.cpp b/src/platform/ohos/JPAGShapeLayer.cpp index 26eab6ea52..26e3541ac0 100644 --- a/src/platform/ohos/JPAGShapeLayer.cpp +++ b/src/platform/ohos/JPAGShapeLayer.cpp @@ -16,15 +16,14 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////// -#include "pag/pag.h" #include "JPAGLayerHandle.h" #include "JsHelper.h" +#include "pag/pag.h" namespace pag { bool JPAGLayerHandle::InitPAGShapeLayerEnv(napi_env env, napi_value exports) { - auto status = DefineClass(env, exports, GetLayerClassName(LayerType::Shape), - 0, nullptr, Constructor, - GetBaseClassName()); + auto status = DefineClass(env, exports, GetLayerClassName(LayerType::Shape), 0, nullptr, + Constructor, GetBaseClassName()); return status == napi_status::napi_ok; } diff --git a/src/platform/ohos/JPAGSolidLayer.cpp b/src/platform/ohos/JPAGSolidLayer.cpp index 3303760fab..4d0f8ff379 100644 --- a/src/platform/ohos/JPAGSolidLayer.cpp +++ b/src/platform/ohos/JPAGSolidLayer.cpp @@ -16,9 +16,9 @@ // ///////////////////////////////////////////////////////////////////////////////////////////////// -#include "pag/pag.h" #include "JPAGLayerHandle.h" #include "JsHelper.h" +#include "pag/pag.h" namespace pag { static std::shared_ptr FromJs(napi_env env, napi_value value) { @@ -40,7 +40,7 @@ static napi_value SolidColor(napi_env env, napi_callback_info info) { } napi_value result; - Color color = solidLayer->solidColor(); + Color color = solidLayer->solidColor(); napi_create_int32(env, MakeColorInt(color.red, color.green, color.blue), &result); return result; } @@ -61,10 +61,8 @@ static napi_value SetSolidColor(napi_env env, napi_callback_info info) { } bool JPAGLayerHandle::InitPAGSolidLayerEnv(napi_env env, napi_value exports) { - napi_property_descriptor classProp[] = { - PAG_DEFAULT_METHOD_ENTRY(solidColor, SolidColor), - PAG_DEFAULT_METHOD_ENTRY(setSolidColor, SetSolidColor) - }; + napi_property_descriptor classProp[] = {PAG_DEFAULT_METHOD_ENTRY(solidColor, SolidColor), + PAG_DEFAULT_METHOD_ENTRY(setSolidColor, SetSolidColor)}; auto status = DefineClass(env, exports, GetLayerClassName(LayerType::Solid), sizeof(classProp) / sizeof(classProp[0]), classProp, Constructor, diff --git a/src/platform/ohos/JPAGSurface.cpp b/src/platform/ohos/JPAGSurface.cpp index e5e8ab27cd..4821c91073 100644 --- a/src/platform/ohos/JPAGSurface.cpp +++ b/src/platform/ohos/JPAGSurface.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "JPAGSurface.h" - #include #include "JsHelper.h" diff --git a/src/platform/ohos/JPAGSurface.h b/src/platform/ohos/JPAGSurface.h index fbf0380824..27bb66d6b9 100644 --- a/src/platform/ohos/JPAGSurface.h +++ b/src/platform/ohos/JPAGSurface.h @@ -17,10 +17,10 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #pragma once -#include -#include #include #include +#include +#include #include "pag/pag.h" namespace pag { diff --git a/src/platform/ohos/JPAGView.cpp b/src/platform/ohos/JPAGView.cpp index 1a09240692..cdf63e21b0 100644 --- a/src/platform/ohos/JPAGView.cpp +++ b/src/platform/ohos/JPAGView.cpp @@ -17,15 +17,13 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #include "JPAGView.h" - #include #include - #include "base/utils/Log.h" #include "base/utils/UniqueID.h" #include "platform/ohos/GPUDrawable.h" -#include "platform/ohos/JsHelper.h" #include "platform/ohos/JPAGLayerHandle.h" +#include "platform/ohos/JsHelper.h" namespace pag { static int PAGViewStateStart = 0; diff --git a/src/platform/ohos/NativeDisplayLink.h b/src/platform/ohos/NativeDisplayLink.h index de446aed6d..30a472ea41 100644 --- a/src/platform/ohos/NativeDisplayLink.h +++ b/src/platform/ohos/NativeDisplayLink.h @@ -17,9 +17,9 @@ ///////////////////////////////////////////////////////////////////////////////////////////////// #pragma once +#include #include #include -#include #include "rendering/utils/DisplayLink.h" namespace pag { From a24cb4b5765166933e595e7a04420d9dfe04c463 Mon Sep 17 00:00:00 2001 From: kevingpqi123 Date: Tue, 6 Aug 2024 21:06:18 +0800 Subject: [PATCH 3/5] Update autotest.yml --- .github/workflows/autotest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/autotest.yml b/.github/workflows/autotest.yml index 241a59e58d..904d370c3f 100644 --- a/.github/workflows/autotest.yml +++ b/.github/workflows/autotest.yml @@ -71,7 +71,7 @@ jobs: ./codecov.sh - name: Upload Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v3.1.6 with: token: ${{ secrets.CODECOV_TOKEN }} file: result/coverage.xml From d4f3fca69e58f823cd51ca2014c22fb98efb3fbc Mon Sep 17 00:00:00 2001 From: kevingpqi123 Date: Tue, 6 Aug 2024 21:22:52 +0800 Subject: [PATCH 4/5] Update autotest.yml --- .github/workflows/autotest.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/autotest.yml b/.github/workflows/autotest.yml index 904d370c3f..4999e86c2b 100644 --- a/.github/workflows/autotest.yml +++ b/.github/workflows/autotest.yml @@ -71,10 +71,11 @@ jobs: ./codecov.sh - name: Upload Codecov - uses: codecov/codecov-action@v3.1.6 + uses: codecov/codecov-action@v3 with: token: ${{ secrets.CODECOV_TOKEN }} file: result/coverage.xml + version: 'v0.7.3' - name: Save Environment Cache if: ${{ (github.event_name == 'push') && (steps.environment-cache.outputs.cache-hit != 'true') }} From 08f7881093d3ac88980c69e8bd08aec733b7d92d Mon Sep 17 00:00:00 2001 From: Hparty <420024556@qq.com> Date: Wed, 7 Aug 2024 15:24:29 +0800 Subject: [PATCH 5/5] update license info --- .../resources/base/media/app_icon.png | 4 +-- ohos/entry/hvigorfile.ts | 19 +++++++++++- .../src/main/ets/entryability/EntryAbility.ts | 31 ++++++++++--------- ohos/entry/src/main/ets/pages/Index.ets | 18 +++++++++++ ohos/entry/src/main/module.json5 | 31 ++++++++++--------- .../main/resources/base/element/string.json | 2 +- .../main/resources/en_US/element/string.json | 2 +- .../main/resources/zh_CN/element/string.json | 2 +- ohos/libpag/Index.ets | 18 +++++++++++ ohos/libpag/hvigorfile.ts | 22 +++++++++++-- ohos/libpag/src/main/ets/PAG.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGComposition.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGFile.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGFont.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGImage.ets | 19 +++++++++++- ohos/libpag/src/main/ets/PAGImageLayer.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGInit.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGLayer.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGMarker.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGPlayer.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGScaleMode.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGShapeLayer.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGSolidLayer.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGSurface.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGText.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGTextLayer.ets | 18 +++++++++++ ohos/libpag/src/main/ets/PAGVideoRange.ets | 24 ++++++++++++-- ohos/libpag/src/main/ets/PAGView.ets | 18 +++++++++++ ohos/libpag/src/main/ets/private/PAGUtils.ets | 18 +++++++++++ .../src/ohosTest/ets/test/Ability.test.ets | 18 +++++++++++ .../src/ohosTest/ets/test/List.test.ets | 18 +++++++++++ ohos/libpag/src/test/List.test.ets | 18 +++++++++++ ohos/libpag/src/test/LocalUnit.test.ets | 18 +++++++++++ 33 files changed, 531 insertions(+), 39 deletions(-) diff --git a/ohos/AppScope/resources/base/media/app_icon.png b/ohos/AppScope/resources/base/media/app_icon.png index 924274f1a4..f20d68b544 100644 --- a/ohos/AppScope/resources/base/media/app_icon.png +++ b/ohos/AppScope/resources/base/media/app_icon.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:79c27214e49332c1e5bcbbe9badeac547c13ee38f597658de313b907fdf2a4e6 -size 2777 +oid sha256:da5005c115d60a8b9b38a2e595325937e10b8820d4fd08edddc257ee6fe298d5 +size 4416 diff --git a/ohos/entry/hvigorfile.ts b/ohos/entry/hvigorfile.ts index 80e4ec5b81..f6a4604309 100755 --- a/ohos/entry/hvigorfile.ts +++ b/ohos/entry/hvigorfile.ts @@ -1,2 +1,19 @@ -// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/entry/src/main/ets/entryability/EntryAbility.ts b/ohos/entry/src/main/ets/entryability/EntryAbility.ts index aefdd5b7b8..22c4d657df 100755 --- a/ohos/entry/src/main/ets/entryability/EntryAbility.ts +++ b/ohos/entry/src/main/ets/entryability/EntryAbility.ts @@ -1,17 +1,20 @@ -/* - * 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. - */ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// import UIAbility from '@ohos.app.ability.UIAbility'; import hilog from '@ohos.hilog'; diff --git a/ohos/entry/src/main/ets/pages/Index.ets b/ohos/entry/src/main/ets/pages/Index.ets index 8d628ccc5f..9ea6e15ad1 100755 --- a/ohos/entry/src/main/ets/pages/Index.ets +++ b/ohos/entry/src/main/ets/pages/Index.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import * as pag from 'libpag'; @Entry diff --git a/ohos/entry/src/main/module.json5 b/ohos/entry/src/main/module.json5 index bac72d9592..762ebf7e07 100755 --- a/ohos/entry/src/main/module.json5 +++ b/ohos/entry/src/main/module.json5 @@ -1,17 +1,20 @@ -/* - * Copyright (c) 2023 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// { "module": { diff --git a/ohos/entry/src/main/resources/base/element/string.json b/ohos/entry/src/main/resources/base/element/string.json index 799199a5d9..263cfac685 100755 --- a/ohos/entry/src/main/resources/base/element/string.json +++ b/ohos/entry/src/main/resources/base/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "PAGDemo" + "value": "PAGViewer" } ] } \ No newline at end of file diff --git a/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/entry/src/main/resources/en_US/element/string.json index 799199a5d9..263cfac685 100755 --- a/ohos/entry/src/main/resources/en_US/element/string.json +++ b/ohos/entry/src/main/resources/en_US/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "PAGDemo" + "value": "PAGViewer" } ] } \ No newline at end of file diff --git a/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/entry/src/main/resources/zh_CN/element/string.json index a8eb3a6116..d64258c74f 100755 --- a/ohos/entry/src/main/resources/zh_CN/element/string.json +++ b/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -10,7 +10,7 @@ }, { "name": "EntryAbility_label", - "value": "PAGDemo" + "value": "PAGViewer" } ] } \ No newline at end of file diff --git a/ohos/libpag/Index.ets b/ohos/libpag/Index.ets index 50ca9b0c80..64225187c7 100644 --- a/ohos/libpag/Index.ets +++ b/ohos/libpag/Index.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + export { PAGView, PAGViewListener } from './src/main/ets/PAGView' export { PAGPlayer } from './src/main/ets/PAGPlayer' diff --git a/ohos/libpag/hvigorfile.ts b/ohos/libpag/hvigorfile.ts index d993120bd7..6b5f656300 100644 --- a/ohos/libpag/hvigorfile.ts +++ b/ohos/libpag/hvigorfile.ts @@ -1,6 +1,24 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + 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. */ + system: hspTasks, /* Built-in plugin of Hvigor. It cannot be modified. */ + plugins: [] /* Custom plugin to extend the functionality of Hvigor. */ } diff --git a/ohos/libpag/src/main/ets/PAG.ets b/ohos/libpag/src/main/ets/PAG.ets index f8eac6c363..4fe9a47fbb 100644 --- a/ohos/libpag/src/main/ets/PAG.ets +++ b/ohos/libpag/src/main/ets/PAG.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAG } from 'libpag.so'; export class PAG { diff --git a/ohos/libpag/src/main/ets/PAGComposition.ets b/ohos/libpag/src/main/ets/PAGComposition.ets index 0010c2ca24..0e9d6f3544 100644 --- a/ohos/libpag/src/main/ets/PAGComposition.ets +++ b/ohos/libpag/src/main/ets/PAGComposition.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { PAGLayer } from "./PAGLayer" import { JPAGLayer, JPAGComposition } from "libpag.so" import { PAGMarker } from './PAGMarker'; diff --git a/ohos/libpag/src/main/ets/PAGFile.ets b/ohos/libpag/src/main/ets/PAGFile.ets index 4969fc8617..d800f502bb 100644 --- a/ohos/libpag/src/main/ets/PAGFile.ets +++ b/ohos/libpag/src/main/ets/PAGFile.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGFile, JPAGLayer } from 'libpag.so' import { PAGComposition } from './PAGComposition' import { resourceManager } from '@kit.LocalizationKit'; diff --git a/ohos/libpag/src/main/ets/PAGFont.ets b/ohos/libpag/src/main/ets/PAGFont.ets index 2ec2d5bdc9..20bd87542e 100644 --- a/ohos/libpag/src/main/ets/PAGFont.ets +++ b/ohos/libpag/src/main/ets/PAGFont.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { resourceManager } from '@kit.LocalizationKit'; import { JPAGFont } from 'libpag.so'; import { PAGUtils } from './private/PAGUtils'; diff --git a/ohos/libpag/src/main/ets/PAGImage.ets b/ohos/libpag/src/main/ets/PAGImage.ets index c706ce957f..f5dadae1d8 100644 --- a/ohos/libpag/src/main/ets/PAGImage.ets +++ b/ohos/libpag/src/main/ets/PAGImage.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { resourceManager } from '@kit.LocalizationKit'; import { PAGUtils } from './private/PAGUtils'; import { Matrix4 } from '@kit.ArkUI'; @@ -5,7 +23,6 @@ import { PAGScaleMode } from './PAGScaleMode'; import { PAGInit } from './PAGInit'; import { JPAGImage } from 'libpag.so' - export class PAGImage { private constructor(nativeImage: JPAGImage) { PAGInit.Init(); diff --git a/ohos/libpag/src/main/ets/PAGImageLayer.ets b/ohos/libpag/src/main/ets/PAGImageLayer.ets index 3fab65a17a..004f40060f 100644 --- a/ohos/libpag/src/main/ets/PAGImageLayer.ets +++ b/ohos/libpag/src/main/ets/PAGImageLayer.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGImageLayer, JPAGLayer } from 'libpag.so'; import { PAGImage } from './PAGImage'; import { PAGLayer } from './PAGLayer'; diff --git a/ohos/libpag/src/main/ets/PAGInit.ets b/ohos/libpag/src/main/ets/PAGInit.ets index 1403317570..9ae7eb53c7 100644 --- a/ohos/libpag/src/main/ets/PAGInit.ets +++ b/ohos/libpag/src/main/ets/PAGInit.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { font } from '@kit.ArkUI'; import { JPAGFont } from 'libpag.so'; diff --git a/ohos/libpag/src/main/ets/PAGLayer.ets b/ohos/libpag/src/main/ets/PAGLayer.ets index 7fc1bda265..20b01d4ebd 100644 --- a/ohos/libpag/src/main/ets/PAGLayer.ets +++ b/ohos/libpag/src/main/ets/PAGLayer.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGLayer } from 'libpag.so' import { PAGComposition } from './PAGComposition'; import { PAGMarker } from './PAGMarker'; diff --git a/ohos/libpag/src/main/ets/PAGMarker.ets b/ohos/libpag/src/main/ets/PAGMarker.ets index 2506b85ff1..a930777d89 100644 --- a/ohos/libpag/src/main/ets/PAGMarker.ets +++ b/ohos/libpag/src/main/ets/PAGMarker.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + /** * Marker stores comments and other metadata and mark important times in a composition or layer. */ diff --git a/ohos/libpag/src/main/ets/PAGPlayer.ets b/ohos/libpag/src/main/ets/PAGPlayer.ets index 6f7fdd7116..ae638e9bd8 100644 --- a/ohos/libpag/src/main/ets/PAGPlayer.ets +++ b/ohos/libpag/src/main/ets/PAGPlayer.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { Matrix4, Rect } from '@ohos.arkui.node'; import { JPAGPlayer } from 'libpag.so' import { PAGComposition } from './PAGComposition'; diff --git a/ohos/libpag/src/main/ets/PAGScaleMode.ets b/ohos/libpag/src/main/ets/PAGScaleMode.ets index a0d49ededd..f6e5f98269 100644 --- a/ohos/libpag/src/main/ets/PAGScaleMode.ets +++ b/ohos/libpag/src/main/ets/PAGScaleMode.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + export enum PAGScaleMode { /** * The content is not scaled. diff --git a/ohos/libpag/src/main/ets/PAGShapeLayer.ets b/ohos/libpag/src/main/ets/PAGShapeLayer.ets index 97344d6e40..863c8a182c 100644 --- a/ohos/libpag/src/main/ets/PAGShapeLayer.ets +++ b/ohos/libpag/src/main/ets/PAGShapeLayer.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGLayer } from 'libpag.so'; import { PAGLayer } from './PAGLayer'; diff --git a/ohos/libpag/src/main/ets/PAGSolidLayer.ets b/ohos/libpag/src/main/ets/PAGSolidLayer.ets index b89d14e1bf..fc04c868d5 100644 --- a/ohos/libpag/src/main/ets/PAGSolidLayer.ets +++ b/ohos/libpag/src/main/ets/PAGSolidLayer.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGLayer, JPAGSolidLayer } from 'libpag.so'; import { PAGLayer } from './PAGLayer'; diff --git a/ohos/libpag/src/main/ets/PAGSurface.ets b/ohos/libpag/src/main/ets/PAGSurface.ets index 1f72cdba9f..94054cd56d 100644 --- a/ohos/libpag/src/main/ets/PAGSurface.ets +++ b/ohos/libpag/src/main/ets/PAGSurface.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGSurface } from 'libpag.so' import { PAGInit } from './PAGInit'; import { image } from '@kit.ImageKit'; diff --git a/ohos/libpag/src/main/ets/PAGText.ets b/ohos/libpag/src/main/ets/PAGText.ets index 41af707c7b..746d8c6497 100644 --- a/ohos/libpag/src/main/ets/PAGText.ets +++ b/ohos/libpag/src/main/ets/PAGText.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { Rect } from '@ohos.arkui.node'; export enum PAGTextJustification { diff --git a/ohos/libpag/src/main/ets/PAGTextLayer.ets b/ohos/libpag/src/main/ets/PAGTextLayer.ets index fd3998f9c0..ebcb4cf5ee 100644 --- a/ohos/libpag/src/main/ets/PAGTextLayer.ets +++ b/ohos/libpag/src/main/ets/PAGTextLayer.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGLayer, JPAGTextLayer } from 'libpag.so'; import { PAGLayer } from './PAGLayer'; import { PAGFont } from './PAGFont'; diff --git a/ohos/libpag/src/main/ets/PAGVideoRange.ets b/ohos/libpag/src/main/ets/PAGVideoRange.ets index 07038bf974..23cb8bee77 100644 --- a/ohos/libpag/src/main/ets/PAGVideoRange.ets +++ b/ohos/libpag/src/main/ets/PAGVideoRange.ets @@ -1,20 +1,40 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + /** * Represents a time range from the content of PAGImageLayer. */ - -export interface PAGVideoRange { +export interface PAGVideoRange { /** * The start time of the source video, in microseconds. */ startTime: number; + /** * The end time of the source video (not included), in microseconds. */ endTime: number; + /** * The duration for playing after applying speed. */ playDuration: number; + /** * Indicates whether the video should play backward. */ diff --git a/ohos/libpag/src/main/ets/PAGView.ets b/ohos/libpag/src/main/ets/PAGView.ets index d47f80cd97..2b6d694f8a 100644 --- a/ohos/libpag/src/main/ets/PAGView.ets +++ b/ohos/libpag/src/main/ets/PAGView.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { JPAGView } from 'libpag.so' import { PAGComposition } from './PAGComposition'; import { PAGInit } from "./PAGInit" diff --git a/ohos/libpag/src/main/ets/private/PAGUtils.ets b/ohos/libpag/src/main/ets/private/PAGUtils.ets index 32fe74ee38..308f5f6f13 100644 --- a/ohos/libpag/src/main/ets/private/PAGUtils.ets +++ b/ohos/libpag/src/main/ets/private/PAGUtils.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { Matrix4, Rect } from '@ohos.arkui.node'; import { JPAGFont, JPAGLayer, JPAGText } from 'libpag.so'; import { PAGComposition } from '../PAGComposition'; diff --git a/ohos/libpag/src/ohosTest/ets/test/Ability.test.ets b/ohos/libpag/src/ohosTest/ets/test/Ability.test.ets index 85c78f6757..1802541fc7 100644 --- a/ohos/libpag/src/ohosTest/ets/test/Ability.test.ets +++ b/ohos/libpag/src/ohosTest/ets/test/Ability.test.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { hilog } from '@kit.PerformanceAnalysisKit'; import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; diff --git a/ohos/libpag/src/ohosTest/ets/test/List.test.ets b/ohos/libpag/src/ohosTest/ets/test/List.test.ets index 794c7dc4ed..ac3eabb461 100644 --- a/ohos/libpag/src/ohosTest/ets/test/List.test.ets +++ b/ohos/libpag/src/ohosTest/ets/test/List.test.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import abilityTest from './Ability.test'; export default function testsuite() { diff --git a/ohos/libpag/src/test/List.test.ets b/ohos/libpag/src/test/List.test.ets index bb5b5c3731..f55d70c336 100644 --- a/ohos/libpag/src/test/List.test.ets +++ b/ohos/libpag/src/test/List.test.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import localUnitTest from './LocalUnit.test'; export default function testsuite() { diff --git a/ohos/libpag/src/test/LocalUnit.test.ets b/ohos/libpag/src/test/LocalUnit.test.ets index 165fc1615e..92116299d3 100644 --- a/ohos/libpag/src/test/LocalUnit.test.ets +++ b/ohos/libpag/src/test/LocalUnit.test.ets @@ -1,3 +1,21 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making libpag available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file +// except in compliance with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; export default function localUnitTest() {