diff --git a/.github/workflows/autotest.yml b/.github/workflows/autotest.yml
index 99c4a46899..6b3fb3752b 100644
--- a/.github/workflows/autotest.yml
+++ b/.github/workflows/autotest.yml
@@ -1,116 +1,118 @@
-# This is a basic workflow to help you get started with Actions
-
name: autotest
-# Controls when the workflow will run
on:
- # Triggers the workflow on push or pull request events but only for the master branch
pull_request:
branches: [ main ]
push:
branches: [ main ]
-# A workflow run is made up of one or more jobs that can run sequentially or in parallel
-jobs:
- autotest:
- # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
- # You can convert this to a matrix build if you need cross-platform coverage.
- # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
- runs-on: macos-latest
+jobs:
+ mac:
+ # the macos-latest may randomly give us macos-12.6.9 or macos-12.7.0 which may break the autotest.
+ runs-on: macos-13
steps:
- - name: Get environment cache
- id: cache-environment
- uses: actions/cache@v2
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ fetch-depth: 0
+ lfs: true
+
+ - name: Get Environment Cache
+ id: environment-cache
+ uses: actions/cache/restore@v3
with:
path: |
/usr/local/Cellar/ninja
/usr/local/Cellar/icu4c
/usr/local/bin/ninja
- /usr/local/Cellar/node
- /usr/local/bin/node
/usr/local/Cellar/yasm
/usr/local/bin/yasm
/usr/local/bin/depsync
/usr/local/lib/node_modules/depsync
/usr/local/Cellar/gcovr
/usr/local/bin/gcovr
- /usr/local/Cellar/emsdk
- /usr/local/Cellar/emsdk/upstream/emscripten
- /usr/local/Cellar/emsdk/node/14.18.2_64bit/bin
- /usr/local/bin/em++
- /usr/local/bin/em-config
- /usr/local/bin/emar
- /usr/local/bin/embuilder
- /usr/local/bin/emcc
- /usr/local/bin/emcmake
- /usr/local/bin/emconfigure
- /usr/local/bin/emdump
- /usr/local/bin/emdwp
- /usr/local/bin/emmake
- /usr/local/bin/emnm
- /usr/local/bin/emrun
- /usr/local/bin/emprofile
- /usr/local/bin/emscons
- /usr/local/bin/emsize
- /usr/local/bin/emstrip
- /usr/local/bin/emsymbolizer
- /usr/local/bin/emcc.py
- /usr/local/bin/emcmake.py
- /usr/local/bin/emar.py
- key: libpag-environment-autotest-20221018
- restore-keys: |
- libpag-environment-autotest-20221018
- - uses: actions/checkout@v3
- with:
- fetch-depth: 0
- lfs: true
- - name: Get thirdParty cache
- id: cache-thirdParty
- uses: actions/cache@v2
+ /usr/local/Cellar/python-lxml
+ /usr/local/Cellar/python-markupsafe
+ /usr/local/lib/python3.12/site-packages/lxml
+ /usr/local/lib/python3.12/site-packages/markupsafe
+ key: libpag-environment-autotest-20231029
+ restore-keys: libpag-environment-autotest-
+
+ - name: Get Third-Party Cache
+ id: third-party-cache
+ uses: actions/cache/restore@v3
with:
path: |
third_party
- vendor_tools
test/baseline/.cache
- key: third_party-autotest-01-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
- restore-keys: third_party-autotest-
- - name: Run sync_deps script
+ key: third-party-autotest-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+ restore-keys: third-party-autotest-
+
+ - name: Run depsync
run: |
- chmod +x sync_deps.sh
- ./sync_deps.sh
+ npm install depsync -g
+ depsync
shell: bash
- - if: github.event_name == 'push'
- name: Build cache(push)
+ - name: Check Code Format
run: |
- node build_vendor -p mac
- if [ ! $(which gcovr) ]; then
- brew install gcovr
- fi
- chmod +x update_baseline.sh
- ./update_baseline.sh 1
- mkdir result
- cp -r test/baseline result
+ chmod +x codeformat.sh
+ ./codeformat.sh
+ shell: bash
- - if: github.event_name == 'pull_request'
- name: Run autotest script
+ - name: Run Autotest
run: |
chmod +x autotest.sh
./autotest.sh
- - name: codecov
- if: github.event_name == 'pull_request'
- uses: codecov/codecov-action@v2.1.0
+ - name: Run Codecov
+ run: |
+ chmod +x codecov.sh
+ ./codecov.sh
+
+ - name: Upload Codecov
+ uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}
- file: libpag/result/coverage.xml
- - name: The job has failed
+ file: result/coverage.xml
+
+ - name: Save Environment Cache
+ if: ${{ (github.event_name == 'push') && (steps.environment-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ /usr/local/Cellar/ninja
+ /usr/local/Cellar/icu4c
+ /usr/local/bin/ninja
+ /usr/local/Cellar/yasm
+ /usr/local/bin/yasm
+ /usr/local/bin/depsync
+ /usr/local/lib/node_modules/depsync
+ /usr/local/Cellar/gcovr
+ /usr/local/bin/gcovr
+ /usr/local/Cellar/python-lxml
+ /usr/local/Cellar/python-markupsafe
+ /usr/local/lib/python3.12/site-packages/lxml
+ /usr/local/lib/python3.12/site-packages/markupsafe
+ key: libpag-environment-autotest-20231029
+
+ - name: Save Third-Party Cache
+ if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ third_party
+ test/baseline/.cache
+ key: third-party-autotest-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+
+ - name: Job Failed
if: ${{ failure() }}
- uses: actions/upload-artifact@v2
+ uses: actions/upload-artifact@v3
with:
name: result
path: result
- - uses: actions/upload-artifact@v2
+
+ - uses: actions/upload-artifact@v3
with:
name: result
path: result
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000000..d016802853
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,428 @@
+name: build
+
+on:
+ pull_request:
+ branches: [ main ]
+ push:
+ branches: [ main ]
+
+jobs:
+ ios:
+ runs-on: macos-latest
+ steps:
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ lfs: true
+
+ - name: Get Environment Cache
+ id: environment-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ /usr/local/Cellar/ninja
+ /usr/local/Cellar/icu4c
+ /usr/local/bin/ninja
+ /usr/local/Cellar/yasm
+ /usr/local/bin/yasm
+ /usr/local/bin/depsync
+ /usr/local/lib/node_modules/depsync
+ key: libpag-environment-ios-20231025
+ restore-keys: libpag-environment-ios-
+
+ - name: Get Third-Party Cache
+ id: third-party-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ third_party
+ key: third-party-ios-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+ restore-keys: third-party-ios-
+
+ - name: Install Build Tools
+ run: |
+ chmod +x install_tools.sh
+ ./install_tools.sh
+ shell: bash
+
+ - name: Run depsync
+ run: |
+ npm install depsync -g
+ depsync
+ shell: bash
+
+ - name: Build iOS
+ run: |
+ node build_pag -p ios -a arm64 -v
+
+ - name: Save Environment Cache
+ if: ${{ (github.event_name == 'push') && (steps.environment-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ /usr/local/Cellar/ninja
+ /usr/local/Cellar/icu4c
+ /usr/local/bin/ninja
+ /usr/local/Cellar/yasm
+ /usr/local/bin/yasm
+ /usr/local/bin/depsync
+ /usr/local/lib/node_modules/depsync
+ key: libpag-environment-ios-20231025
+
+ - name: Save Third-Party Cache
+ if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ third_party
+ key: third-party-ios-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+
+ - name: Job Failed
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: libpag_ios_arm64
+ path: out
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: libpag_ios_arm64
+ path: out
+
+ android:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ lfs: true
+
+ - name: Get Third-Party Cache
+ id: third-party-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ third_party
+ key: third-party-android-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+ restore-keys: third-party-android-
+
+ - uses: seanmiddleditch/gha-setup-ninja@master
+
+ - name: Run depsync
+ run: |
+ npm install depsync -g
+ depsync
+ shell: bash
+
+ - uses: nttld/setup-ndk@v1
+ id: setup-ndk
+ with:
+ ndk-version: r19c
+ local-cache: true
+
+ - name: Build Android
+ run: |
+ node build_pag -p android -a arm64 -v
+ env:
+ NDK_HOME: ${{ steps.setup-ndk.outputs.ndk-path }}
+
+ - name: Save Third-Party Cache
+ if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ third_party
+ key: third-party-android-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+
+ - name: Job Failed
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: libpag_android_arm64v8a
+ path: out
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: libpag_android_arm64v8a
+ path: out
+
+ web:
+ runs-on: macos-latest
+ steps:
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ lfs: true
+
+ - name: Get Environment Cache
+ id: environment-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ /usr/local/Cellar/ninja
+ /usr/local/Cellar/icu4c
+ /usr/local/bin/ninja
+ /usr/local/Cellar/yasm
+ /usr/local/bin/yasm
+ /usr/local/bin/depsync
+ /usr/local/lib/node_modules/depsync
+ /usr/local/Cellar/gcovr
+ /usr/local/bin/gcovr
+ /usr/local/Cellar/emsdk
+ /usr/local/Cellar/emsdk/upstream/emscripten
+ /usr/local/Cellar/emsdk/node/14.18.2_64bit/bin
+ /usr/local/bin/em++
+ /usr/local/bin/em-config
+ /usr/local/bin/emar
+ /usr/local/bin/embuilder
+ /usr/local/bin/emcc
+ /usr/local/bin/emcmake
+ /usr/local/bin/emconfigure
+ /usr/local/bin/emdump
+ /usr/local/bin/emdwp
+ /usr/local/bin/emmake
+ /usr/local/bin/emnm
+ /usr/local/bin/emrun
+ /usr/local/bin/emprofile
+ /usr/local/bin/emscons
+ /usr/local/bin/emsize
+ /usr/local/bin/emstrip
+ /usr/local/bin/emsymbolizer
+ /usr/local/bin/emcc.py
+ /usr/local/bin/emcmake.py
+ /usr/local/bin/emar.py
+ key: libpag-environment-web-20231025
+ restore-keys: libpag-environment-web-
+
+ - name: Get Third-Party Cache
+ id: third-party-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ third_party
+ key: third-party-web-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+ restore-keys: third-party-web-
+
+ - name: Run depsync
+ run: |
+ chmod +x sync_deps.sh
+ ./sync_deps.sh
+ shell: bash
+
+ - name: Build Web
+ run: |
+ node build_pag -p web -v
+
+ - name: Save Environment Cache
+ if: ${{ (github.event_name == 'push') && (steps.environment-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ /usr/local/Cellar/ninja
+ /usr/local/Cellar/icu4c
+ /usr/local/bin/ninja
+ /usr/local/Cellar/yasm
+ /usr/local/bin/yasm
+ /usr/local/bin/depsync
+ /usr/local/lib/node_modules/depsync
+ /usr/local/Cellar/gcovr
+ /usr/local/bin/gcovr
+ /usr/local/Cellar/emsdk
+ /usr/local/Cellar/emsdk/upstream/emscripten
+ /usr/local/Cellar/emsdk/node/14.18.2_64bit/bin
+ /usr/local/bin/em++
+ /usr/local/bin/em-config
+ /usr/local/bin/emar
+ /usr/local/bin/embuilder
+ /usr/local/bin/emcc
+ /usr/local/bin/emcmake
+ /usr/local/bin/emconfigure
+ /usr/local/bin/emdump
+ /usr/local/bin/emdwp
+ /usr/local/bin/emmake
+ /usr/local/bin/emnm
+ /usr/local/bin/emrun
+ /usr/local/bin/emprofile
+ /usr/local/bin/emscons
+ /usr/local/bin/emsize
+ /usr/local/bin/emstrip
+ /usr/local/bin/emsymbolizer
+ /usr/local/bin/emcc.py
+ /usr/local/bin/emcmake.py
+ /usr/local/bin/emar.py
+ key: libpag-environment-web-20231025
+
+ - name: Save Third-Party Cache
+ if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ third_party
+ key: third-party-web-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+
+ - name: Job Failed
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: libpag_web_wasm
+ path: out
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: libpag_web_wasm
+ path: out
+
+ win:
+ runs-on: windows-latest
+ steps:
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ lfs: true
+
+ - name: Get Third-Party Cache
+ id: third-party-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ third_party
+ key: third-party-windows-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+ restore-keys: third-party-windows-
+
+ - name: Run depsync
+ run: |
+ npm install depsync -g
+ depsync
+ shell: bash
+
+ - name: Build Windows
+ run: |
+ node build_pag -p win -a x64 -v
+
+ - name: Save Third-Party Cache
+ if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ third_party
+ key: third-party-windows-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+
+ - name: Job Failed
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: libpag_win_x64
+ path: out
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: libpag_win_x64
+ path: out
+
+ linux:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ lfs: true
+
+ - name: Get Third-Party Cache
+ id: third-party-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ third_party
+ key: third-party-linux-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+ restore-keys: third-party-linux-
+
+ - uses: seanmiddleditch/gha-setup-ninja@master
+
+ - name: Run depsync
+ run: |
+ npm install depsync -g
+ depsync
+ shell: bash
+
+ - name: Build Linux
+ run: |
+ node build_pag -DPAG_USE_SWIFTSHADER=ON -p linux -v
+
+ - name: Save Third-Party Cache
+ if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ third_party
+ key: third-party-linux-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+
+ - name: Job Failed
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: libpag_linux_x64
+ path: out
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: libpag_linux_x64
+ path: out
+
+ qt:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Check Out Repo
+ uses: actions/checkout@v3
+ with:
+ lfs: true
+
+ - name: Get Third-Party Cache
+ id: third-party-cache
+ uses: actions/cache/restore@v3
+ with:
+ path: |
+ third_party
+ key: third-party-qt-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+ restore-keys: third-party-qt-
+
+ - uses: seanmiddleditch/gha-setup-ninja@master
+
+ - name: Run depsync
+ run: |
+ npm install depsync -g
+ depsync
+ shell: bash
+
+ - name: Install Qt
+ uses: jurplel/install-qt-action@v3
+ with:
+ host: 'linux'
+ target: 'desktop'
+ dir: '${{github.workspace}}/qt/'
+ install-deps: 'true'
+ cache: 'true'
+ cache-key-prefix: 'install-qt-action'
+
+ - name: Build QT
+ run: |
+ node build_pag -DPAG_USE_QT=ON -DCMAKE_PREFIX_PATH="${{env.Qt5_Dir}}/lib/cmake/" -p linux -v
+
+ - name: Save Third-Party Cache
+ if: ${{ (github.event_name == 'push') && (steps.third-party-cache.outputs.cache-hit != 'true') }}
+ uses: actions/cache/save@v3
+ with:
+ path: |
+ third_party
+ key: third-party-qt-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}-${{ hashFiles('test/baseline/version.json') }}
+
+ - name: Job Failed
+ if: ${{ failure() }}
+ uses: actions/upload-artifact@v3
+ with:
+ name: libpag_qt_x64
+ path: out
+
+ - uses: actions/upload-artifact@v3
+ with:
+ name: libpag_qt_x64
+ path: out
diff --git a/.github/workflows/build_linux.yml b/.github/workflows/build_linux.yml
deleted file mode 100644
index b19d297732..0000000000
--- a/.github/workflows/build_linux.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
-name: build_linux
-
-# Controls when the workflow will run
-on:
- # Triggers the workflow on push or pull request events but only for the master branch
- pull_request:
- branches: [ main ]
- push:
- branches: [ main ]
-# A workflow run is made up of one or more jobs that can run sequentially or in parallel
-jobs:
- build_linux:
- runs-on: ubuntu-latest
-
- steps:
- - uses: actions/checkout@v3
- with:
- lfs: true
- - name: Get thirdParty cache
- id: cache-thirdParty
- uses: actions/cache@v2
- with:
- path: |
- third_party
- vendor_tools
- key: third_party-linux-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}
- restore-keys: third_party-linux-
-
- - uses: seanmiddleditch/gha-setup-ninja@master
- - name: Run sync_deps script
- run: |
- chmod +x sync_deps.sh
- ./sync_deps.sh
-
- - if: github.event_name == 'push'
- name: Build cache(push)
- run: |
- node build_vendor -p linux
-
- - if: github.event_name == 'pull_request'
- name: Run build_linux script
- run: |
- chmod +x build_linux.sh
- ./build_linux.sh
- cd linux
- mkdir build
- cd build
- cmake ../
- make -j8
\ No newline at end of file
diff --git a/.github/workflows/build_web.yml b/.github/workflows/build_web.yml
deleted file mode 100644
index c17e8dfe20..0000000000
--- a/.github/workflows/build_web.yml
+++ /dev/null
@@ -1,92 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
-name: build_web
-
-# Controls when the workflow will run
-on:
- # Triggers the workflow on push or pull request events but only for the master branch
- pull_request:
- branches: [ main ]
- push:
- branches: [ main ]
-# A workflow run is made up of one or more jobs that can run sequentially or in parallel
-jobs:
- build_web:
- # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
- # You can convert this to a matrix build if you need cross-platform coverage.
- # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
- runs-on: macos-latest
-
- steps:
- - name: Get environment cache
- id: cache-environment
- uses: actions/cache@v2
- with:
- path: |
- /usr/local/Cellar/ninja
- /usr/local/Cellar/icu4c
- /usr/local/bin/ninja
- /usr/local/Cellar/yasm
- /usr/local/bin/yasm
- /usr/local/bin/depsync
- /usr/local/lib/node_modules/depsync
- /usr/local/Cellar/gcovr
- /usr/local/bin/gcovr
- /usr/local/Cellar/emsdk
- /usr/local/Cellar/emsdk/upstream/emscripten
- /usr/local/Cellar/emsdk/node/14.18.2_64bit/bin
- /usr/local/bin/em++
- /usr/local/bin/em-config
- /usr/local/bin/emar
- /usr/local/bin/embuilder
- /usr/local/bin/emcc
- /usr/local/bin/emcmake
- /usr/local/bin/emconfigure
- /usr/local/bin/emdump
- /usr/local/bin/emdwp
- /usr/local/bin/emmake
- /usr/local/bin/emnm
- /usr/local/bin/emrun
- /usr/local/bin/emprofile
- /usr/local/bin/emscons
- /usr/local/bin/emsize
- /usr/local/bin/emstrip
- /usr/local/bin/emsymbolizer
- /usr/local/bin/emcc.py
- /usr/local/bin/emcmake.py
- /usr/local/bin/emar.py
- key: libpag-environment-autotest-20221018
- restore-keys: |
- libpag-environment-autotest-20221018
- - uses: actions/checkout@v3
- with:
- lfs: true
- - name: Get thirdParty cache
- id: cache-thirdParty
- uses: actions/cache@v2
- with:
- path: |
- third_party
- vendor_tools
- web/node_node_modules
- key: third_party-web-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}
- restore-keys: third_party-web-
-
- - name: Run sync_deps script
- run: |
- chmod +x sync_deps.sh
- ./sync_deps.sh
-
- - if: github.event_name == 'push'
- name: Build cache(push)
- run: |
- node build_vendor -p web
- if [ ! $(which gcovr) ]; then
- brew install gcovr
- fi
- - if: github.event_name == 'pull_request'
- name: Run build script
- run: |
- cd web/script
- chmod +x build.sh
- ./build.sh
diff --git a/.github/workflows/build_win.yml b/.github/workflows/build_win.yml
deleted file mode 100644
index efd18086a2..0000000000
--- a/.github/workflows/build_win.yml
+++ /dev/null
@@ -1,49 +0,0 @@
-# This is a basic workflow to help you get started with Actions
-
-name: build_win
-
-# Controls when the workflow will run
-on:
- # Triggers the workflow on push or pull request events but only for the master branch
- pull_request:
- branches: [ main ]
- push:
- branches: [ main ]
-# A workflow run is made up of one or more jobs that can run sequentially or in parallel
-jobs:
- build_win:
- # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
- # You can convert this to a matrix build if you need cross-platform coverage.
- # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
- runs-on: windows-latest
-
- steps:
- - uses: actions/checkout@v3
- with:
- lfs: true
- - name: Get thirdParty cache
- id: cache-thirdParty
- uses: actions/cache@v2
- with:
- path: |
- third_party
- vendor_tools
- key: third_party-win-${{ hashFiles('DEPS') }}-${{ hashFiles('vendor.json') }}
- restore-keys: third_party-win-
-
- - name: Run depsync
- run: |
- npm install depsync -g
- depsync
- shell: bash
-
- - if: github.event_name == 'push'
- name: Build cache(push)
- run: |
- node build_vendor -p win
-
- - if: github.event_name == 'pull_request'
- name: Windows build
- run: |
- node ./vendor_tools/cmake-build pag -p win -a x64 -o ./win/paglib -v -i -DPAG_BUILD_SHARED=ON
- shell: bash
\ No newline at end of file
diff --git a/.github/workflows/code_format.yml b/.github/workflows/code_format.yml
deleted file mode 100644
index b1ddf2c53c..0000000000
--- a/.github/workflows/code_format.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-name: code_format
-
-on:
- pull_request:
- branches: [ main ]
-
-env:
- # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
- BUILD_TYPE: Debug
-
-jobs:
- code_format:
- # The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
- # You can convert this to a matrix build if you need cross-platform coverage.
- # See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
- runs-on: macos-latest
- steps:
- - uses: actions/checkout@v2
- - name: Run codeformat script
- run: |
- chmod +x codeformat.sh
- ./codeformat.sh
- shell: bash
diff --git a/.gitignore b/.gitignore
index ee1613e091..2240482559 100644
--- a/.gitignore
+++ b/.gitignore
@@ -44,6 +44,8 @@ local.properties
/third_party
/out
+/result
+/vendor_tools
cmake-build-*
node_modules
Build/
@@ -71,9 +73,4 @@ win/Win32Demo/Debug/
win/Win32Demo/Release/
QTCMAKE.cfg
test/baseline/.cache
-/result
-
-
-vendor_tools/
-.vscode
-
+.vscode
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0213d8404d..a41a541cae 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -3,12 +3,11 @@
-
-
-
+
+
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 26023963e2..e877d386c2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -10,7 +10,9 @@ project(PAG)
# Uncomment the next line to enable debug mode for third-party libraries.
#set(VENDOR_DEBUG ON)
#set(CMAKE_VERBOSE_MAKEFILE ON)
-include(./vendor_tools/vendor.cmake)
+
+
+include(./third_party/vendor_tools/vendor.cmake)
# Options for building libpag
option(PAG_USE_OPENGL "allow use of OpenGL as GPU backend" ON)
@@ -18,6 +20,7 @@ option(PAG_USE_SWIFTSHADER "allow build with SwiftShader library" OFF)
option(PAG_USE_QT "allow build with QT frameworks" OFF)
option(PAG_USE_RTTR "enable RTTR support" OFF)
option(PAG_USE_HARFBUZZ "enable HarfBuzz support" OFF)
+option(PAG_USE_C "enable c API" OFF)
if (NOT APPLE AND NOT WEB)
option(PAG_USE_FREETYPE "Allow use of embedded freetype library" ON)
@@ -41,7 +44,9 @@ if (NOT WEB)
option(PAG_BUILD_SHARED "Build shared library" ON)
endif ()
-if (MACOS)
+string(FIND ${CMAKE_COMMAND} "/CLion.app/" CLionPosition)
+get_directory_property(HasParent PARENT_DIRECTORY)
+if (CLionPosition GREATER -1 AND NOT HasParent)
# CLion project needs test targets.
option(PAG_BUILD_TESTS "Build libpag tests" ON)
endif ()
@@ -91,13 +96,35 @@ endif ()
if (PAG_BUILD_TESTS)
set(PAG_USE_FREETYPE ON)
set(PAG_USE_HARFBUZZ ON)
+ set(PAG_BUILD_SHARED OFF)
+endif ()
+
+file(STRINGS "src/rendering/PAG.cpp" VERSION_FILE)
+set(PAG_VERSION "")
+while (VERSION_FILE)
+ list(POP_FRONT VERSION_FILE LINE)
+ if (LINE MATCHES "\\sdkVersion[^ $]+")
+ string(REGEX MATCH "\\\"[^ $]+" VERSION ${LINE})
+ string(LENGTH ${VERSION} VERSION_LENGTH)
+ MATH(EXPR VERSION_LENGTH "${VERSION_LENGTH}-2")
+ string(SUBSTRING ${VERSION} 1 ${VERSION_LENGTH} PAG_VERSION)
+ break()
+ endif ()
+endwhile ()
+
+if (NOT TGFX_DIR)
+ set(TGFX_DIR third_party/tgfx)
endif ()
+get_filename_component(TGFX_DIR "${TGFX_DIR}" REALPATH BASE_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
+message("PAG_VERSION: ${PAG_VERSION}")
message("PAG_USE_LIBAVC: ${PAG_USE_LIBAVC}")
message("PAG_USE_RTTR: ${PAG_USE_RTTR}")
message("PAG_USE_HARFBUZZ: ${PAG_USE_HARFBUZZ}")
+message("PAG_USE_C: ${PAG_USE_C}")
message("PAG_BUILD_SHARED: ${PAG_BUILD_SHARED}")
message("PAG_BUILD_TESTS: ${PAG_BUILD_TESTS}")
+message("TGFX_DIR: ${TGFX_DIR}")
set(TGFX_USE_OPENGL ${PAG_USE_OPENGL})
set(TGFX_USE_QT ${PAG_USE_QT})
@@ -111,8 +138,13 @@ set(TGFX_USE_WEBP_DECODE ${PAG_USE_WEBP_DECODE})
set(TGFX_USE_WEBP_ENCODE ${PAG_USE_WEBP_ENCODE})
set(CMAKE_POLICY_DEFAULT_CMP0077 NEW)
-add_subdirectory(tgfx/ EXCLUDE_FROM_ALL)
-list(APPEND PAG_INCLUDES tgfx/include)
+add_subdirectory(${TGFX_DIR} tgfx EXCLUDE_FROM_ALL)
+list(APPEND PAG_INCLUDES ${TGFX_DIR}/include)
+
+if (PAG_USE_C)
+ file(GLOB PAG_C_FILES src/c/*.* src/c/ext/*.*)
+ list(APPEND PAG_FILES ${PAG_C_FILES})
+endif ()
if (PAG_USE_LIBAVC)
add_definitions(-DPAG_USE_LIBAVC)
@@ -134,9 +166,9 @@ if (PAG_USE_QT)
list(APPEND PAG_PLATFORM_FILES ${CGL_PLATFORM_FILES})
endif ()
elseif (PAG_USE_SWIFTSHADER)
- file(GLOB SWIFTSHADER_LIBRARIES vendor/swiftshader/${LIBRARY_ENTRY}/*${CMAKE_SHARED_LIBRARY_SUFFIX})
+ file(GLOB SWIFTSHADER_LIBRARIES ${TGFX_DIR}/vendor/swiftshader/${PLATFORM}/${ARCH}/*${CMAKE_SHARED_LIBRARY_SUFFIX})
list(APPEND PAG_PLATFORM_SHARED_LIBS ${SWIFTSHADER_LIBRARIES})
- list(APPEND PAG_PLATFORM_INCLUDES vendor/swiftshader/include)
+ list(APPEND PAG_PLATFORM_INCLUDES ${TGFX_DIR}/vendor/swiftshader/include)
file(GLOB_RECURSE PAG_PLATFORM_FILES src/platform/swiftshader/*.*)
endif ()
@@ -204,6 +236,8 @@ elseif (IOS)
endif ()
file(GLOB_RECURSE PAG_PLATFORM_FILES src/platform/ios/*.* src/platform/cocoa/*.*)
+ file(GLOB IOS_PLATFORM_HEADERS src/platform/ios/*.h src/platform/cocoa/*.h)
+ list(APPEND PAG_PLATFORM_HEADERS ${IOS_PLATFORM_HEADERS})
find_include_dirs(IOS_PLATFORM_INCLUDES
src/platform/ios/*.h
src/platform/ios/private/*.h
@@ -240,6 +274,8 @@ elseif (MACOS)
endif ()
file(GLOB_RECURSE PAG_PLATFORM_FILES src/platform/mac/*.* src/platform/cocoa/*.*)
+ file(GLOB MAC_PLATFORM_HEADERS src/platform/mac/*.h src/platform/cocoa/*.h)
+ list(APPEND PAG_PLATFORM_HEADERS ${MAC_PLATFORM_HEADERS})
find_include_dirs(MAC_PLATFORM_INCLUDES
src/platform/mac/*.h
src/platform/mac/private/*.h
@@ -278,8 +314,8 @@ elseif (WIN32)
add_definitions(-DNOMINMAX -D_USE_MATH_DEFINES)
if (USE_NATIVE_PLATFORM)
- list(APPEND PAG_PLATFORM_INCLUDES vendor/angle/include)
- file(GLOB ANGLE_LIBS vendor/angle/${PLATFORM}/${ARCH}/*${CMAKE_STATIC_LIBRARY_SUFFIX})
+ list(APPEND PAG_PLATFORM_INCLUDES ${TGFX_DIR}/vendor/angle/include)
+ file(GLOB ANGLE_LIBS ${TGFX_DIR}/vendor/angle/${PLATFORM}/${ARCH}/*${CMAKE_STATIC_LIBRARY_SUFFIX})
list(APPEND PAG_PLATFORM_STATIC_LIBS ${ANGLE_LIBS})
file(GLOB_RECURSE PAG_PLATFORM_FILES src/platform/win/*.*)
endif ()
@@ -310,6 +346,12 @@ else ()
list(APPEND PAG_PLATFORM_FILES third_party/lz4/lib/lz4.c)
endif ()
+if (PAG_USE_C)
+ if (ANDROID OR WIN32)
+ list(APPEND PAG_PLATFORM_FILES src/c/ext/egl/pag_egl_globals.cpp)
+ endif ()
+endif ()
+
add_vendor_target(PAG STATIC_VENDORS ${PAG_STATIC_VENDORS} SHARED_VENDORS ${PAG_SHARED_VENDORS})
list(APPEND PAG_PLATFORM_STATIC_LIBS ${PAG_VENDOR_STATIC_LIBRARIES})
list(APPEND PAG_PLATFORM_SHARED_LIBS ${PAG_VENDOR_SHARED_LIBRARIES})
@@ -326,6 +368,16 @@ else ()
target_link_libraries(pag ${PAG_PLATFORM_STATIC_LIBS} ${TGFX_PLATFORM_STATIC_LIBS} ${PAG_PLATFORM_SHARED_LIBS})
endif ()
+if (MACOS OR IOS)
+ set_target_properties(pag PROPERTIES
+ FRAMEWORK TRUE
+ PUBLIC_HEADER "${PAG_PLATFORM_HEADERS}"
+ MACOSX_FRAMEWORK_IDENTIFIER "com.tencent.libpag"
+ MACOSX_FRAMEWORK_BUNDLE_VERSION ${PAG_VERSION}
+ MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PAG_VERSION})
+ set_target_properties(pag PROPERTIES OUTPUT_NAME libpag)
+endif ()
+
if (PAG_BUILD_TESTS)
execute_process(COMMAND git rev-parse --short HEAD OUTPUT_VARIABLE HEAD_COMMIT)
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/HEAD "${HEAD_COMMIT}")
@@ -339,67 +391,48 @@ if (PAG_BUILD_TESTS)
message(WARNING "The local md5 cache is out of date! Please run the 'update_baseline.sh' to regenerate the cache.")
endif ()
- add_library(pag-static STATIC ${PAG_VENDOR_TARGET} ${PAG_FILES} ${PAG_PLATFORM_FILES} $)
- merge_libraries_into(pag-static ${PAG_PLATFORM_STATIC_LIBS} ${TGFX_PLATFORM_STATIC_LIBS})
- target_include_directories(pag-static PUBLIC ${PAG_INCLUDES} ${PAG_PLATFORM_INCLUDES})
- target_link_libraries(pag-static tgfx ${PAG_PLATFORM_STATIC_LIBS} ${TGFX_PLATFORM_STATIC_LIBS} ${PAG_PLATFORM_SHARED_LIBS})
-
- list(APPEND TEST_STATIC_VENDORS googletest)
- add_vendor_target(Test STATIC_VENDORS ${TEST_STATIC_VENDORS} SHARED_VENDORS ${TEST_SHARED_VENDORS})
- list(APPEND TEST_PLATFORM_LIBS ${Test_VENDOR_STATIC_LIBRARIES})
- list(APPEND TEST_PLATFORM_LIBS ${Test_VENDOR_SHARED_LIBRARIES})
- list(APPEND TEST_PLATFORM_LIBS pag-static ${PAG_PLATFORM_SHARED_LIBS})
- set(TEST_INCLUDES third_party/googletest/googletest third_party/googletest/googletest/include third_party/json/include)
- list(APPEND TEST_INCLUDES ${PAG_INCLUDES})
-
- file(GLOB PAG_TEST_FILES
- test/*.*
- test/framework/*.*
- test/framework/utils/*.*)
-
- file(GLOB PAG_SMOKE_TEST_FILES
- test/PAGSmokeTest.cpp
- test/TestUtils.cpp
- test/framework/*.cpp
- test/framework/utils/*.cpp)
-
- file(GLOB PAG_PERFORMANCE_TEST_FILES
- test/PAGPerformanceTest.cpp
- test/TestUtils.cpp
- test/framework/*.cpp
- test/framework/utils/*.cpp)
+ file(GLOB_RECURSE PAG_TEST_FILES test/src/*.*)
+ list(APPEND TEST_PLATFORM_LIBS pag ${PAG_PLATFORM_SHARED_LIBS})
+ list(APPEND TEST_INCLUDES ${PAG_INCLUDES} test/src ${TGFX_DIR}/third_party/json/include)
+
+ set(GOOGLE_TEST_DIR ${TGFX_DIR}/third_party/googletest/googletest)
+ list(APPEND TEST_INCLUDES ${GOOGLE_TEST_DIR} ${GOOGLE_TEST_DIR}/include)
+ list(APPEND PAG_TEST_FILES ${GOOGLE_TEST_DIR}/src/gtest-all.cc)
file(GLOB FFAVC_LIB vendor/ffavc/${PLATFORM}/${ARCH}/*${CMAKE_SHARED_LIBRARY_SUFFIX})
list(APPEND TEST_PLATFORM_LIBS ${FFAVC_LIB})
- list(APPEND TEST_INCLUDES tgfx/src vendor/ffavc/include)
+ list(APPEND TEST_INCLUDES vendor/ffavc/include)
+
+ if (MACOS AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 15.0)
+ list(APPEND TEST_LINK_OPTIONS "-ld_classic")
+ endif ()
# used to update the local md5 data for baseline testing.
- add_executable(PAGBaseline ${Test_VENDOR_TARGET} ${PAG_TEST_FILES})
- target_include_directories(PAGBaseline PUBLIC ${TEST_INCLUDES})
- target_compile_definitions(PAGBaseline PUBLIC UPDATE_BASELINE)
- target_link_libraries(PAGBaseline ${TEST_PLATFORM_LIBS})
- set_target_properties(PAGBaseline PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")
+ add_executable(UpdateBaseline ${PAG_TEST_FILES})
+ target_include_directories(UpdateBaseline PUBLIC ${TEST_INCLUDES})
+ target_compile_definitions(UpdateBaseline PUBLIC UPDATE_BASELINE)
+ target_link_options(UpdateBaseline PRIVATE ${TEST_LINK_OPTIONS})
+ target_link_libraries(UpdateBaseline ${TEST_PLATFORM_LIBS})
+ set_target_properties(UpdateBaseline PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")
# used to generate baseline images to the out/ directory. each image has a "_base" suffix.
- add_executable(PAGGenerateImages ${Test_VENDOR_TARGET} ${PAG_TEST_FILES})
- target_include_directories(PAGGenerateImages PUBLIC ${TEST_INCLUDES})
- target_compile_definitions(PAGGenerateImages PUBLIC GENERATOR_BASELINE_IMAGES)
- target_link_libraries(PAGGenerateImages ${TEST_PLATFORM_LIBS})
- set_target_properties(PAGGenerateImages PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")
-
- add_executable(PAGUnitTest ${Test_VENDOR_TARGET} ${PAG_TEST_FILES})
+ add_executable(GenerateImages ${PAG_TEST_FILES})
+ target_include_directories(GenerateImages PUBLIC ${TEST_INCLUDES})
+ target_compile_definitions(GenerateImages PUBLIC GENERATOR_BASELINE_IMAGES)
+ target_link_options(GenerateImages PRIVATE ${TEST_LINK_OPTIONS})
+ target_link_libraries(GenerateImages ${TEST_PLATFORM_LIBS})
+ set_target_properties(GenerateImages PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")
+
+ add_executable(PAGUnitTest ${PAG_TEST_FILES})
target_include_directories(PAGUnitTest PUBLIC ${TEST_INCLUDES})
target_compile_definitions(PAGUnitTest PUBLIC SKIP_FRAME_COMPARE)
+ target_link_options(PAGUnitTest PRIVATE ${TEST_LINK_OPTIONS})
target_link_libraries(PAGUnitTest ${TEST_PLATFORM_LIBS})
set_target_properties(PAGUnitTest PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")
- add_executable(PAGFullTest ${Test_VENDOR_TARGET} ${PAG_TEST_FILES})
+ add_executable(PAGFullTest ${PAG_TEST_FILES})
target_include_directories(PAGFullTest PUBLIC ${TEST_INCLUDES})
+ target_link_options(PAGFullTest PRIVATE ${TEST_LINK_OPTIONS})
target_link_libraries(PAGFullTest ${TEST_PLATFORM_LIBS})
set_target_properties(PAGFullTest PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -fno-access-control")
-
- add_executable(PAGPerformanceTest ${Test_VENDOR_TARGET} ${PAG_PERFORMANCE_TEST_FILES})
- target_include_directories(PAGPerformanceTest PUBLIC ${TEST_INCLUDES})
- target_compile_definitions(PAGPerformanceTest PUBLIC PERFORMANCE_TEST)
- target_link_libraries(PAGPerformanceTest ${TEST_PLATFORM_LIBS})
endif ()
diff --git a/CODEOWNERS b/CODEOWNERS
index c8cd1832ca..f597319848 100644
--- a/CODEOWNERS
+++ b/CODEOWNERS
@@ -1,11 +1,11 @@
# Default owners:
* @domchen @lvpengwei @luckyzhliu
-*.js @zenoslin @domchen @lvpengwei @luckyzhliu
-*.ts @zenoslin @domchen @lvpengwei @luckyzhliu
+*.js @domchen @lvpengwei @luckyzhliu
+*.ts @domchen @lvpengwei @luckyzhliu
*.sh @kevingpqi123 @domchen @lvpengwei @luckyzhliu
/* @kevingpqi123 @domchen @lvpengwei @luckyzhliu
-/web/ @zenoslin @domchen @lvpengwei @luckyzhliu
+/web/ @domchen @lvpengwei @luckyzhliu
/.github/ @kevingpqi123 @domchen @lvpengwei @luckyzhliu
/test/ @kevingpqi123 @domchen @lvpengwei @luckyzhliu
/linux/ @kevingpqi123 @domchen @lvpengwei @luckyzhliu
diff --git a/DEPS b/DEPS
index 8732d34135..ca8a76ff64 100644
--- a/DEPS
+++ b/DEPS
@@ -1,5 +1,5 @@
{
- "version": "1.2.2",
+ "version": "1.3.1",
"vars": {
"PAG_GROUP": "https://github.com/libpag"
},
@@ -7,69 +7,27 @@
"common": [
{
"url": "${PAG_GROUP}/vendor_tools.git",
- "commit": "de569142433f1c2ed447de01c20bdd908bde8915",
- "dir": "vendor_tools"
+ "commit": "0d499ca10dcc1a1453301e337f5b77ec20f9ecc9",
+ "dir": "third_party/vendor_tools"
},
{
- "url": "${PAG_GROUP}/pathkit.git",
- "commit": "f0c4736442a8e640e7f7978b6b9ed322148245bb",
- "dir": "third_party/pathkit"
- },
- {
- "url": "${PAG_GROUP}/skcms.git",
- "commit": "26af768d918c8f9a693ce6ee1a0fc6611559d29e",
- "dir": "third_party/skcms"
+ "url": "${PAG_GROUP}/tgfx.git",
+ "commit": "c462c6e2d201856d822a773949dc952753465dc1",
+ "dir": "third_party/tgfx",
+ "keeps": [
+ "third_party"
+ ]
},
{
"url": "${PAG_GROUP}/libavc.git",
"commit": "c2bf4c84a6d39788929e59514417e819185af98e",
"dir": "third_party/libavc"
},
- {
- "url": "${PAG_GROUP}/swiftshader.git",
- "commit": "040ee43bfeba9b6b532dbd8222df737aac2d55b1",
- "dir": "third_party/swiftshader"
- },
- {
- "url": "https://github.com/madler/zlib.git",
- "commit": "cacf7f1d4e3d44d871b605da3b647f07d718623f",
- "dir": "third_party/zlib"
- },
- {
- "url": "https://github.com/glennrp/libpng.git",
- "commit": "a40189cf881e9f0db80511c382292a5604c3c3d1",
- "dir": "third_party/libpng"
- },
- {
- "url": "https://github.com/webmproject/libwebp.git",
- "commit": "233960a0ad8c640acd458a6966dea09e12c1325a",
- "dir": "third_party/libwebp"
- },
- {
- "url": "https://github.com/libjpeg-turbo/libjpeg-turbo.git",
- "commit": "0a9b9721782d3a60a5c16c8c9a7abf3d4b1ecd42",
- "dir": "third_party/libjpeg-turbo"
- },
- {
- "url": "https://github.com/freetype/freetype.git",
- "commit": "86bc8a95056c97a810986434a3f268cbe67f2902",
- "dir": "third_party/freetype"
- },
{
"url": "https://github.com/rttrorg/rttr.git",
"commit": "7edbd580cfad509a3253c733e70144e36f02ecd4",
"dir": "third_party/rttr"
},
- {
- "url": "https://github.com/google/googletest.git",
- "commit": "e2239ee6043f73722e7aa812a459f54a28552929",
- "dir": "third_party/googletest"
- },
- {
- "url": "https://github.com/nlohmann/json.git",
- "commit": "fec56a1a16c6e1c1b1f4e116a20e79398282626c",
- "dir": "third_party/json"
- },
{
"url": "https://github.com/harfbuzz/harfbuzz.git",
"commit": "f1f2be776bcd994fa9262622e1a7098a066e5cf7",
@@ -87,6 +45,10 @@
{
"command": "depsync --clean",
"dir": "third_party"
+ },
+ {
+ "command": "git lfs pull",
+ "dir": "./"
}
]
}
diff --git a/README.md b/README.md
index 7a9a47f84f..bffddc2ce6 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@
[![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/Tencent/libpag/pulls)
[![codecov](https://codecov.io/gh/Tencent/libpag/branch/main/graph/badge.svg)](https://codecov.io/gh/Tencent/libpag)
[![Actions Status](https://github.com/Tencent/libpag/workflows/autotest/badge.svg?branch=main)](https://github.com/Tencent/libpag/actions)
+[![build](https://github.com/Tencent/libpag/actions/workflows/build.yml/badge.svg?branch=main)](https://github.com/Tencent/libpag/actions/workflows/build.yml)
[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/Tencent/libpag)](https://github.com/Tencent/libpag/releases)
English | [简体中文](./README.zh_CN.md) | [Homepage](https://pag.art)
@@ -176,7 +177,7 @@ We recommend using CLion IDE on the macOS platform for development.
- The `main` branch is our active developing branch which contains the latest features and bugfixes.
- The branches under `release/` are our stable milestone branches which are fully tested. We will
periodically cut a `release/{version}` branch from the `main` branch. After one `release/{version}`
-branch is cut, only high priority fixes are checked into it.
+branch is cut, only high-priority fixes are checked into it.
**Note: This repository only contains the latest code since PAG 4.0. To use the legacy PAG 3.0
versions, you can download the precompiled libraries from [here](https://github.com/Tencent/libpag/releases).**
@@ -184,24 +185,24 @@ versions, you can download the precompiled libraries from [here](https://github.
### Build Prerequisites
- Xcode 11.0+
-- GCC 7.0+
+- GCC 8.0+
- CMake 3.10.2+
- Visual Studio 2019
- NDK 19.2.5345600 (**Please use this exact version of NDK, other versions may fail.**)
### Dependency Management
-libpag uses `depsync` tool to manage third-party dependencies.
+libpag uses [depsync](https://github.com/domchen/depsync) tool to manage third-party dependencies.
**For macOS platform:**
-Just simply run the script in the root of libpag project:
+Run the script in the root of the project:
```
./sync_deps.sh
```
-This script will automatically install necessary tools and synchronize all third-party repositories.
+This script will automatically install the necessary tools and synchronize all third-party repositories.
**For other platforms:**
@@ -212,7 +213,7 @@ computer after this step). And then run the following command to install depsync
npm install -g depsync
```
-And then run `depsync` in the root directory of libpag project.
+And then run `depsync` in the root directory of the project.
```
depsync
diff --git a/README.zh_CN.md b/README.zh_CN.md
index fb9c5743b5..5b32f39844 100644
--- a/README.zh_CN.md
+++ b/README.zh_CN.md
@@ -6,7 +6,7 @@
[![Actions Status](https://github.com/Tencent/libpag/workflows/autotest/badge.svg?branch=main)](https://github.com/Tencent/libpag/actions)
[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/Tencent/libpag)](https://github.com/Tencent/libpag/releases)
-[English](./README.md) | 简体中文 | [官网](https://pag.art) | [官方论坛](https://bbs.pag.art)
+[English](./README.md) | 简体中文 | [官网](https://pag.art)
## 介绍
@@ -175,14 +175,14 @@ Web 端更多接入方式请参考:[Web端接入指南](https://pag.art/docs/s
### 编译环境
- Xcode 11.0 版本及以上
-- GCC 7.0 版本及以上
+- GCC 8.0 版本及以上
- CMake 3.10.2 版本及以上
- Visual Studio 2019
- NDK 19.2.5345600 (**其他 NDK 版本可能会存在编译报错**)
### 依赖管理
-libpag 使用 depsync 命令行工具管理第三方依赖项。
+libpag 使用 [depsync](https://github.com/domchen/depsync) 命令行工具管理第三方依赖项。
**macOS 平台:**
diff --git a/android/libpag/src/main/java/org/libpag/PAGView.java b/android/libpag/src/main/java/org/libpag/PAGView.java
index 1d303aac8d..6b2db668d2 100644
--- a/android/libpag/src/main/java/org/libpag/PAGView.java
+++ b/android/libpag/src/main/java/org/libpag/PAGView.java
@@ -29,10 +29,8 @@
import android.util.AttributeSet;
import android.view.TextureView;
import android.view.View;
-
import org.extra.tools.Lifecycle;
import org.extra.tools.LifecycleListener;
-
import java.util.ArrayList;
@@ -633,6 +631,15 @@ public void onAnimationEnd(PAGAnimator animator) {
}
}
+ @Override
+ public void setVisibility(int visibility) {
+ super.setVisibility(visibility);
+ // When calling the setVisibility function,
+ // it does not necessarily trigger a callback to the onVisibilityAggregated method.
+ // Therefore, it is necessary to handle this specific situation on your own.
+ checkVisible();
+ }
+
public void onAnimationCancel(PAGAnimator animator) {
ArrayList arrayList;
synchronized (PAGView.this) {
diff --git a/autotest.sh b/autotest.sh
index ec571be918..675ca47812 100755
--- a/autotest.sh
+++ b/autotest.sh
@@ -5,20 +5,7 @@ function make_dir() {
mkdir -p $1
}
echo "shell log - autotest start"
-if [[ $(uname) == 'Darwin' ]]; then
- MAC_REQUIRED_TOOLS="gcovr"
- for TOOL in ${MAC_REQUIRED_TOOLS[@]}; do
- if [ ! $(which $TOOL) ]; then
- if [ ! $(which brew) ]; then
- echo "Homebrew not found. Trying to install..."
- /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ||
- exit 1
- fi
- echo "$TOOL not found. Trying to install..."
- brew install $TOOL || exit 1
- fi
- done
-fi
+./install_tools.sh
echo $(pwd)
@@ -32,11 +19,14 @@ make_dir result
make_dir build
./update_baseline.sh 1
+if test $? -ne 0; then
+ exit 1
+fi
cp -r $WORKSPACE/test/baseline $WORKSPACE/result
cd build
-cmake -DCMAKE_CXX_FLAGS="-fprofile-arcs -ftest-coverage -g -O0" -DPAG_USE_SWIFTSHADER=ON -DCMAKE_BUILD_TYPE=Debug ../
+cmake -DCMAKE_CXX_FLAGS="-fprofile-arcs -ftest-coverage -g -O0" -DPAG_USE_SWIFTSHADER=ON -DPAG_BUILD_TESTS=ON -DCMAKE_BUILD_TYPE=Debug ../
if test $? -eq 0; then
echo "~~~~~~~~~~~~~~~~~~~CMakeLists OK~~~~~~~~~~~~~~~~~~"
else
@@ -65,11 +55,6 @@ cp -a $WORKSPACE/build/*.json $WORKSPACE/result/
cd ..
-gcovr -r . -e='test/*.*' -e='vendor/*.*'--html -o ./result/coverage.html
-gcovr -r . -e='test/*.*' -e='vendor/*.*' --xml-pretty -o ./result/coverage.xml
-
-rm -rf build
-
cp -r $WORKSPACE/test/out $WORKSPACE/result
if [ "$COMPLIE_RESULT" == false ]; then
diff --git a/build_linux.sh b/build_linux.sh
index 26629cd9d1..604175b43d 100755
--- a/build_linux.sh
+++ b/build_linux.sh
@@ -47,7 +47,7 @@ make_dir linux/vendor/pag/$PLATFORM/x64
cp -a $BUILD_DIR/libpag.a linux/vendor/pag/$PLATFORM/x64
make_dir linux/vendor/swiftshader
-cp -a vendor/swiftshader/* linux/vendor/swiftshader
+cp -a third_party/tgfx/vendor/swiftshader/* linux/vendor/swiftshader
rm -rf $BUILD_DIR
diff --git a/build_pag b/build_pag
new file mode 100755
index 0000000000..77bfc71558
--- /dev/null
+++ b/build_pag
@@ -0,0 +1,2 @@
+#!/usr/bin/env node
+require("./third_party/vendor_tools/lib-build");
diff --git a/build_vendor b/build_vendor
index dcf1bdd287..4abaa0d201 100755
--- a/build_vendor
+++ b/build_vendor
@@ -1,3 +1,3 @@
#!/usr/bin/env node
// run 'node build_vendor -h" to print help message
-require("./vendor_tools/build");
\ No newline at end of file
+require("./third_party/vendor_tools/vendor-build");
\ No newline at end of file
diff --git a/codecov.sh b/codecov.sh
new file mode 100755
index 0000000000..924290b49d
--- /dev/null
+++ b/codecov.sh
@@ -0,0 +1,17 @@
+#!/bin/bash -e
+cd $(dirname $0)
+
+if [[ `uname` == 'Darwin' ]]; then
+ if [ ! $(which gcovr) ]; then
+ if [ ! $(which brew) ]; then
+ echo "Homebrew not found. Trying to install..."
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ||
+ exit 1
+ fi
+ echo "gcovr not found. Trying to install..."
+ brew install gcovr || exit 1
+ fi
+fi
+
+mkdir -p result
+gcovr -r . -f='src/' -f='include/' --xml-pretty -o ./result/coverage.xml
\ No newline at end of file
diff --git a/codeformat.sh b/codeformat.sh
index 6c1dffabcb..cb8cc0755a 100755
--- a/codeformat.sh
+++ b/codeformat.sh
@@ -24,9 +24,6 @@ fi
echo "----begin to scan code format----"
find include/ -iname '*.h' -print0 | xargs clang-format -i
-find tgfx/include -iname '*.h' -print0 | xargs clang-format -i
-# shellcheck disable=SC2038
-find tgfx/src -iname "*.h" -print -o -iname "*.cpp" -print | xargs clang-format -i
# shellcheck disable=SC2038
find src -name "*.cpp" -print -o -name "*.h" -print -o -name "*.mm" -print -o -name "*.m" -print | xargs clang-format -i
# shellcheck disable=SC2038
diff --git a/tgfx/.idea/fileTemplates/includes/TGFX File Header.h b/include/pag/c/ext/egl/pag_egl_globals.h
similarity index 86%
rename from tgfx/.idea/fileTemplates/includes/TGFX File Header.h
rename to include/pag/c/ext/egl/pag_egl_globals.h
index 077666620b..a3b643dd91 100644
--- a/tgfx/.idea/fileTemplates/includes/TGFX File Header.h
+++ b/include/pag/c/ext/egl/pag_egl_globals.h
@@ -15,3 +15,13 @@
// and limitations under the license.
//
/////////////////////////////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#include "pag/c/pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+PAG_API egl_globals* pag_egl_globals_get();
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/src/images/RasterGenerator.cpp b/include/pag/c/ext/pag_surface_ext.h
similarity index 51%
rename from tgfx/src/images/RasterGenerator.cpp
rename to include/pag/c/ext/pag_surface_ext.h
index 2510c60aaf..eec4e7d08f 100644
--- a/tgfx/src/images/RasterGenerator.cpp
+++ b/include/pag/c/ext/pag_surface_ext.h
@@ -16,31 +16,38 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////
-#include "RasterGenerator.h"
-#include "tgfx/core/Bitmap.h"
-
-namespace tgfx {
-std::shared_ptr RasterGenerator::MakeFrom(const ImageInfo& info,
- std::shared_ptr pixels) {
- if (info.isEmpty() || pixels == nullptr || info.byteSize() > pixels->size()) {
- return nullptr;
- }
- return std::shared_ptr(new RasterGenerator(info, std::move(pixels)));
-}
-
-RasterGenerator::RasterGenerator(const ImageInfo& info, std::shared_ptr pixels)
- : ImageGenerator(info.width(), info.height()), info(info), pixels(std::move(pixels)) {
-}
-
-std::shared_ptr RasterGenerator::onMakeBuffer(bool tryHardware) const {
- Bitmap bitmap(width(), height(), isAlphaOnly(), tryHardware);
- if (bitmap.isEmpty()) {
- return nullptr;
- }
- auto success = bitmap.writePixels(info, pixels->data());
- if (!success) {
- return nullptr;
- }
- return bitmap.makeBuffer();
-}
-} // namespace tgfx
+#pragma once
+
+#include "pag/c/pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+/**
+ * Create a new pag_surface for double-buffered off-screen rendering.
+ * Release it by pag_release.
+ */
+PAG_API pag_surface* pag_surface_make_offscreen_double_buffered(int width, int height,
+ bool tryHardware,
+ void* sharedContext);
+
+/**
+ * Returns the front texture of the surface.
+ */
+PAG_API pag_backend_texture* pag_surface_get_front_texture(pag_surface* surface);
+
+/**
+ * Returns the back texture of the surface.
+ */
+PAG_API pag_backend_texture* pag_surface_get_back_texture(pag_surface* surface);
+
+/**
+ * Returns the front hardware buffer of the surface.
+ */
+PAG_API void* pag_surface_get_front_hardware_buffer(pag_surface* surface);
+
+/**
+ * Returns the back hardware buffer of the surface.
+ */
+PAG_API void* pag_surface_get_back_hardware_buffer(pag_surface* surface);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag.h b/include/pag/c/pag.h
new file mode 100644
index 0000000000..7b294ac55e
--- /dev/null
+++ b/include/pag/c/pag.h
@@ -0,0 +1,37 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "ext/pag_surface_ext.h"
+#include "pag_animator.h"
+#include "pag_backend_semaphore.h"
+#include "pag_backend_texture.h"
+#include "pag_byte_data.h"
+#include "pag_composition.h"
+#include "pag_decoder.h"
+#include "pag_disk_cache.h"
+#include "pag_file.h"
+#include "pag_font.h"
+#include "pag_image.h"
+#include "pag_image_layer.h"
+#include "pag_layer.h"
+#include "pag_player.h"
+#include "pag_solid_layer.h"
+#include "pag_surface.h"
+#include "pag_text_document.h"
diff --git a/include/pag/c/pag_animator.h b/include/pag/c/pag_animator.h
new file mode 100644
index 0000000000..4a3e84f891
--- /dev/null
+++ b/include/pag/c/pag_animator.h
@@ -0,0 +1,54 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+/**
+ * Creates a new pag_animator with the specified listener. Release it by pag_release.
+ */
+PAG_API pag_animator* pag_animator_create(pag_animator_listener* listener, void* user);
+
+PAG_API bool pag_animator_is_sync(pag_animator* animator);
+
+PAG_API void pag_animator_set_sync(pag_animator* animator, bool sync);
+
+PAG_API int64_t pag_animator_get_duration(pag_animator* animator);
+
+PAG_API void pag_animator_set_duration(pag_animator* animator, int64_t duration);
+
+PAG_API int pag_animator_get_repeat_count(pag_animator* animator);
+
+PAG_API void pag_animator_set_repeat_count(pag_animator* animator, int repeatCount);
+
+PAG_API double pag_animator_get_progress(pag_animator* animator);
+
+PAG_API void pag_animator_set_progress(pag_animator* animator, double progress);
+
+PAG_API bool pag_animator_is_running(pag_animator* animator);
+
+PAG_API void pag_animator_start(pag_animator* animator);
+
+PAG_API void pag_animator_cancel(pag_animator* animator);
+
+PAG_API void pag_animator_update(pag_animator* animator);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_backend_semaphore.h b/include/pag/c/pag_backend_semaphore.h
new file mode 100644
index 0000000000..450647552d
--- /dev/null
+++ b/include/pag/c/pag_backend_semaphore.h
@@ -0,0 +1,36 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+/**
+ * Creates a new pag_backend_semaphore. Release it by pag_release.
+ */
+PAG_API pag_backend_semaphore* pag_backend_semaphore_create();
+
+PAG_API bool pag_backend_semaphore_is_initialized(pag_backend_semaphore* semaphore);
+
+PAG_API void pag_backend_semaphore_init_gl(pag_backend_semaphore* semaphore, void* glSync);
+
+PAG_API void* pag_backend_semaphore_get_gl_sync(pag_backend_semaphore* semaphore);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/src/gpu/ExternalTexture.h b/include/pag/c/pag_backend_texture.h
similarity index 53%
rename from tgfx/src/gpu/ExternalTexture.h
rename to include/pag/c/pag_backend_texture.h
index 6501bd7e83..8f90828ff6 100644
--- a/tgfx/src/gpu/ExternalTexture.h
+++ b/include/pag/c/pag_backend_texture.h
@@ -18,30 +18,24 @@
#pragma once
-#include "gpu/Texture.h"
+#include "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
-namespace tgfx {
/**
- * Texture created externally to TGFX
+ * Creates a new pag_backend_texture with texture info, width and height.
+ * Release it by pag_release.
*/
-class ExternalTexture : public Texture {
- public:
- static std::shared_ptr MakeFrom(Context* context, const BackendTexture& backendTexture,
- ImageOrigin origin, bool adopted);
-
- size_t memoryUsage() const override;
+PAG_API pag_backend_texture* pag_backend_texture_create_from_gl_texture_info(
+ pag_gl_texture_info textureInfo, int width, int height);
- const TextureSampler* getSampler() const override {
- return sampler.get();
- }
+PAG_API bool pag_backend_texture_get_gl_texture_info(pag_backend_texture* texture,
+ pag_gl_texture_info* textureInfo);
- private:
- std::unique_ptr sampler = {};
- bool adopted = false;
+PAG_API bool pag_backend_texture_get_vk_image_info(pag_backend_texture* texture,
+ pag_vk_image_info* imageInfo);
- ExternalTexture(std::unique_ptr sampler, int width, int height,
- ImageOrigin origin, bool adopted);
+PAG_API bool pag_backend_texture_get_mtl_texture_info(pag_backend_texture* texture,
+ pag_mtl_texture_info* mtl_texture_info);
- void onReleaseGPU() override;
-};
-} // namespace tgfx
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/include/tgfx/metal/MtlTypes.h b/include/pag/c/pag_byte_data.h
similarity index 78%
rename from tgfx/include/tgfx/metal/MtlTypes.h
rename to include/pag/c/pag_byte_data.h
index 4cee107477..6c34cf66e3 100644
--- a/tgfx/include/tgfx/metal/MtlTypes.h
+++ b/include/pag/c/pag_byte_data.h
@@ -18,15 +18,13 @@
#pragma once
-namespace tgfx {
+#include "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
/**
- * Types for interacting with Metal resources created externally to TGFX. Holds the MTLTexture as a
- * const void*.
+ * Creates a new pag_byte_data and copy the bytes and length. Release it by pag_release.
*/
-struct MtlTextureInfo {
- /**
- * Pointer to MTLTexture.
- */
- const void* texture = nullptr;
-};
-} // namespace tgfx
+PAG_API pag_byte_data* pag_byte_data_copy(const void* bytes, size_t length);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/include/tgfx/platform/android/HardwareBufferJNI.h b/include/pag/c/pag_composition.h
similarity index 55%
rename from tgfx/include/tgfx/platform/android/HardwareBufferJNI.h
rename to include/pag/c/pag_composition.h
index 919cf60e8d..47a6e53535 100644
--- a/tgfx/include/tgfx/platform/android/HardwareBufferJNI.h
+++ b/include/pag/c/pag_composition.h
@@ -18,20 +18,24 @@
#pragma once
-#include
-#include "tgfx/platform/HardwareBuffer.h"
+#include "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+PAG_API int pag_composition_get_width(pag_composition* composition);
+
+PAG_API int pag_composition_get_height(pag_composition* composition);
-namespace tgfx {
/**
- * Return the HardwareBufferRef associated with a Java HardwareBuffer object, for interacting with
- * it through native code. This method does not acquire any additional reference to the returned
- * HardwareBufferRef. To keep the HardwareBufferRef live after the Java HardwareBuffer object got
- * garbage collected, make sure to use HardwareBufferRetain() to acquire an additional reference.
+ * Returns an array of layers that match the specified layer name. Release it by pag_release.
*/
-HardwareBufferRef HardwareBufferFromJavaObject(JNIEnv* env, jobject hardwareBufferObject);
+PAG_API pag_layer** pag_composition_get_layers_by_name(pag_composition* composition,
+ const char* layerName, size_t* count);
/**
- * Return a new Java HardwareBuffer object that wraps the passed native HardwareBufferRef object.
+ * Returns an array of layers that match the specified layer type. Release it by pag_release.
*/
-jobject HardwareBufferToJavaObject(JNIEnv* env, HardwareBufferRef hardwareBuffer);
-} // namespace tgfx
+PAG_API pag_layer** pag_composition_get_layers_by_type(pag_composition* composition,
+ pag_layer_type layerType, size_t* count);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_decoder.h b/include/pag/c/pag_decoder.h
new file mode 100644
index 0000000000..3e39249b92
--- /dev/null
+++ b/include/pag/c/pag_decoder.h
@@ -0,0 +1,48 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+/**
+ * Creates a new pag_decoder with a pag_composition, a frame rate limit, and a scale factor for the
+ * decoded image size. Release it by pag_release.
+ */
+PAG_API pag_decoder* pag_decoder_create(pag_composition* composition, float maxFrameRate,
+ float scale);
+
+PAG_API int pag_decoder_get_width(pag_decoder* decoder);
+
+PAG_API int pag_decoder_get_height(pag_decoder* decoder);
+
+PAG_API int pag_decoder_get_num_frames(pag_decoder* decoder);
+
+PAG_API float pag_decoder_get_frame_rate(pag_decoder* decoder);
+
+PAG_API bool pag_decoder_check_frame_changed(pag_decoder* decoder, int index);
+
+PAG_API bool pag_decoder_read_frame(pag_decoder* decoder, int index, void* pixels, size_t rowBytes,
+ pag_color_type colorType, pag_alpha_type alphaType);
+
+PAG_API bool pag_decoder_read_frame_to_hardware_buffer(pag_decoder* decoder, int index,
+ void* buffer);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/src/gpu/UniqueKey.cpp b/include/pag/c/pag_disk_cache.h
similarity index 78%
rename from tgfx/src/gpu/UniqueKey.cpp
rename to include/pag/c/pag_disk_cache.h
index dc361ed205..3341bcea82 100644
--- a/tgfx/src/gpu/UniqueKey.cpp
+++ b/include/pag/c/pag_disk_cache.h
@@ -16,15 +16,16 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////
-#include
+#pragma once
-#include "tgfx/gpu/ResourceKey.h"
-#include "utils/UniqueID.h"
+#include "pag_types.h"
-namespace tgfx {
-UniqueKey UniqueKey::Next() {
- UniqueKey uniqueKey = {};
- uniqueKey.id = std::make_shared(UniqueID::Next());
- return uniqueKey;
-}
-} // namespace tgfx
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+PAG_API size_t pag_disk_cache_get_max_disk_size();
+
+PAG_API void pag_disk_cache_set_max_disk_size(size_t maxDiskSize);
+
+PAG_API void pag_disk_cache_remove_all();
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_file.h b/include/pag/c/pag_file.h
new file mode 100644
index 0000000000..82b4979547
--- /dev/null
+++ b/include/pag/c/pag_file.h
@@ -0,0 +1,66 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+/**
+ * Load a pag file from byte data, return null if the bytes is empty, or it's not a valid pag
+ * file. Release it by pag_release.
+ */
+PAG_API pag_file* pag_file_load(const void* bytes, size_t length, const char* filePath,
+ const char* password);
+
+PAG_API void pag_file_set_duration(pag_file* file, int64_t duration);
+
+PAG_API int pag_file_get_num_texts(pag_file* file);
+
+PAG_API int pag_file_get_num_images(pag_file* file);
+
+PAG_API int pag_file_get_num_videos(pag_file* file);
+
+PAG_API pag_time_stretch_mode pag_file_get_time_stretch_mode(pag_file* file);
+
+PAG_API void pag_file_set_time_stretch_mode(pag_file* file, pag_time_stretch_mode mode);
+
+/**
+ * Get a text data of the specified index. The index ranges from 0 to numTexts - 1. Release it by
+ * pag_release.
+ * Note: It always returns the default text data.
+ */
+PAG_API pag_text_document* pag_file_get_text_data(pag_file* file, int editableTextIndex);
+
+PAG_API void pag_file_replace_text(pag_file* file, int editableTextIndex, pag_text_document* text);
+
+PAG_API void pag_file_replace_image(pag_file* file, int editableImageIndex, pag_image* image);
+
+/**
+ * Return an array of layers by specified editable index and layer type.
+ * Release them by pag_release.
+ */
+PAG_API pag_layer** pag_file_get_layers_by_editable_index(pag_file* file, int editableIndex,
+ pag_layer_type layerType,
+ size_t* numLayers);
+
+PAG_API int* pag_file_get_editable_indices(pag_file* file, pag_layer_type layerType,
+ size_t* numIndexes);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/include/tgfx/opengl/GLTypes.h b/include/pag/c/pag_font.h
similarity index 53%
rename from tgfx/include/tgfx/opengl/GLTypes.h
rename to include/pag/c/pag_font.h
index 06f169fce6..307bf9fe0d 100644
--- a/tgfx/include/tgfx/opengl/GLTypes.h
+++ b/include/pag/c/pag_font.h
@@ -18,37 +18,25 @@
#pragma once
-namespace tgfx {
+#include "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
/**
- * Types for interacting with GL textures created externally to TGFX.
+ * Registers a font required by the text layers in pag files, so that they can be rendered as
+ * designed. Release it by pag_release.
*/
-struct GLTextureInfo {
- /**
- * the id of this texture.
- */
- unsigned id = 0;
- /**
- * The target of this texture.
- */
- unsigned target = 0x0DE1; // GL_TEXTURE_2D;
- /**
- * The pixel format of this texture.
- */
- unsigned format = 0x8058; // GL_RGBA8;
-};
-
+PAG_API pag_font* pag_font_register_from_path(const char* filePath, int ttcIndex,
+ const char* fontFamily, const char* fontStyle);
/**
- * Types for interacting with GL frame buffers created externally to tgfx.
+ * Registers a font required by the text layers in pag files, so that they can be rendered as
+ * designed. Release it by pag_release.
*/
-struct GLFrameBufferInfo {
- /**
- * The id of this frame buffer.
- */
- unsigned id = 0;
+PAG_API pag_font* pag_font_register_from_data(const void* data, size_t length, int ttcIndex,
+ const char* fontFamily, const char* fontStyle);
+
+PAG_API const char* pag_font_get_family(pag_font* font);
+
+PAG_API const char* pag_font_get_style(pag_font* font);
- /**
- * The pixel format of this frame buffer.
- */
- unsigned format = 0x8058; // GL_RGBA8;
-};
-} // namespace tgfx
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/src/gpu/PlainTexture.h b/include/pag/c/pag_image.h
similarity index 52%
rename from tgfx/src/gpu/PlainTexture.h
rename to include/pag/c/pag_image.h
index bdbf76701a..9b55f5835b 100644
--- a/tgfx/src/gpu/PlainTexture.h
+++ b/include/pag/c/pag_image.h
@@ -18,35 +18,27 @@
#pragma once
-#include "gpu/Texture.h"
+#include "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
-namespace tgfx {
/**
- * Texture with a single plane.
+ * Creates a pag_image object from an array of pixel data, return null if it's not valid pixels.
+ * Release it by pag_release.
*/
-class PlainTexture : public Texture {
- public:
- /**
- * Returns true if the specified texture size and format can be created by the GPU backend.
- */
- static bool CheckSizeAndFormat(Context* context, int width, int height, PixelFormat format);
-
- PlainTexture(std::unique_ptr sampler, int width, int height, ImageOrigin origin);
-
- size_t memoryUsage() const override;
-
- const TextureSampler* getSampler() const override {
- return sampler.get();
- }
-
- protected:
- void computeScratchKey(BytesKey* scratchKey) const override;
+PAG_API pag_image* pag_image_from_pixels(const void* pixels, int width, int height, size_t rowBytes,
+ pag_color_type colorType, pag_alpha_type alphaType);
+/**
+ * Creates a pag_image object from a hardware buffer. Release it by pag_release.
+ */
+PAG_API pag_image* pag_image_from_hardware_buffer(void* buffer);
- private:
- std::unique_ptr sampler = {};
+/**
+ * Creates a pag_image object from the specified backend texture, return null if the texture is
+ * invalid. Release it by pag_release.
+ */
+PAG_API pag_image* pag_image_from_backend_texture(pag_backend_texture* texture);
- void onReleaseGPU() override;
+PAG_API void pag_image_set_scale_mode(pag_image* image, pag_scale_mode mode);
- friend class Texture;
-};
-} // namespace tgfx
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_image_layer.h b/include/pag/c/pag_image_layer.h
new file mode 100644
index 0000000000..52369fed3f
--- /dev/null
+++ b/include/pag/c/pag_image_layer.h
@@ -0,0 +1,28 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+PAG_API uint8_t* pag_image_layer_get_image_rgba_data(pag_layer* imageLayer, size_t* count,
+ size_t* width, size_t* height);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/src/platform/android/HandlerThread.h b/include/pag/c/pag_layer.h
similarity index 68%
rename from tgfx/src/platform/android/HandlerThread.h
rename to include/pag/c/pag_layer.h
index e1c9d52e1f..b471a3202f 100644
--- a/tgfx/src/platform/android/HandlerThread.h
+++ b/include/pag/c/pag_layer.h
@@ -18,26 +18,20 @@
#pragma once
-#include
-#include "JNIUtil.h"
+#include "pag_types.h"
-namespace tgfx {
-class HandlerThread {
- public:
- static void JNIInit(JNIEnv* env);
+PAG_C_PLUS_PLUS_BEGIN_GUARD
- static std::shared_ptr Make();
+PAG_API pag_layer_type pag_layer_get_layer_type(pag_layer* layer);
- HandlerThread(JNIEnv* env, jobject thread);
+PAG_API const char* pag_layer_get_layer_name(pag_layer* layer);
- ~HandlerThread();
+PAG_API int64_t pag_layer_get_duration(pag_layer* layer);
- jobject getLooper() const {
- return looper.get();
- }
+PAG_API float pag_layer_get_frame_rate(pag_layer* layer);
- private:
- Global thread;
- Global looper;
-};
-} // namespace tgfx
+PAG_API float pag_layer_get_alpha(pag_layer* layer);
+
+PAG_API void pag_layer_set_alpha(pag_layer* layer, float alpha);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_player.h b/include/pag/c/pag_player.h
new file mode 100644
index 0000000000..4f728d83ba
--- /dev/null
+++ b/include/pag/c/pag_player.h
@@ -0,0 +1,57 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+/**
+ * Creates a pag_player object. Release it by pag_release.
+ */
+PAG_API pag_player* pag_player_create();
+
+PAG_API void pag_player_set_composition(pag_player* player, pag_composition* composition);
+
+PAG_API void pag_player_set_surface(pag_player* player, pag_surface* surface);
+
+PAG_API bool pag_player_get_cache_enable(pag_player* player);
+
+PAG_API void pag_player_set_cache_enable(pag_player* player, bool cacheEnable);
+
+PAG_API double pag_player_get_progress(pag_player* player);
+
+PAG_API void pag_player_set_progress(pag_player* player, double progress);
+
+PAG_API bool pag_player_wait(pag_player* player, pag_backend_semaphore* semaphore);
+
+PAG_API bool pag_player_flush(pag_player* player);
+
+PAG_API bool pag_player_flush_and_signal_semaphore(pag_player* player,
+ pag_backend_semaphore* semaphore);
+
+PAG_API pag_scale_mode pag_player_get_scale_mode(pag_player* player);
+
+PAG_API void pag_player_set_scale_mode(pag_player* player, pag_scale_mode scaleMode);
+
+PAG_API int64_t pag_player_get_duration(pag_player* player);
+
+PAG_API int64_t pag_player_get_graphics_memory(pag_player* player);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_solid_layer.h b/include/pag/c/pag_solid_layer.h
new file mode 100644
index 0000000000..8f3a1b1b76
--- /dev/null
+++ b/include/pag/c/pag_solid_layer.h
@@ -0,0 +1,29 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+PAG_API pag_color pag_solid_layer_get_solid_color(pag_solid_layer* layer);
+
+PAG_API void pag_solid_layer_set_solid_color(pag_solid_layer* layer, pag_color color);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/tgfx/include/tgfx/core/AlphaType.h b/include/pag/c/pag_surface.h
similarity index 68%
rename from tgfx/include/tgfx/core/AlphaType.h
rename to include/pag/c/pag_surface.h
index e2d01199c2..fc9b8ed335 100644
--- a/tgfx/include/tgfx/core/AlphaType.h
+++ b/include/pag/c/pag_surface.h
@@ -18,26 +18,17 @@
#pragma once
-namespace tgfx {
+#include "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
/**
- * Describes how to interpret the alpha component of a pixel.
+ * Creates a new pag_surface for off-screen rendering with the specified size.
+ * Release it by pag_release.
*/
-enum class AlphaType {
- /**
- * uninitialized.
- */
- Unknown,
- /**
- * pixel is opaque.
- */
- Opaque,
- /**
- * pixel components are premultiplied by alpha.
- */
- Premultiplied,
- /**
- * pixel components are independent of alpha.
- */
- Unpremultiplied,
-};
-} // namespace tgfx
+PAG_API pag_surface* pag_surface_make_offscreen(int width, int height);
+
+PAG_API bool pag_surface_read_pixels(pag_surface* surface, pag_color_type colorType,
+ pag_alpha_type alphaType, void* dstPixels, size_t dstRowBytes);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_text_document.h b/include/pag/c/pag_text_document.h
new file mode 100644
index 0000000000..173269464d
--- /dev/null
+++ b/include/pag/c/pag_text_document.h
@@ -0,0 +1,119 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag_types.h"
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+PAG_API bool pag_text_document_get_apply_fill(pag_text_document* document);
+
+PAG_API void pag_text_document_set_apply_fill(pag_text_document* document, bool applyFill);
+
+PAG_API bool pag_text_document_get_apply_stroke(pag_text_document* document);
+
+PAG_API void pag_text_document_set_apply_stroke(pag_text_document* document, bool applyStroke);
+
+PAG_API float pag_text_document_get_baseline_shift(pag_text_document* document);
+
+PAG_API void pag_text_document_set_baseline_shift(pag_text_document* document, float baselineShift);
+
+PAG_API bool pag_text_document_get_box_text(pag_text_document* document);
+
+PAG_API void pag_text_document_set_box_text(pag_text_document* document, bool boxText);
+
+PAG_API pag_point pag_text_document_get_box_text_pos(pag_text_document* document);
+
+PAG_API void pag_text_document_set_box_text_pos(pag_text_document* document, pag_point boxTextPos);
+
+PAG_API pag_point pag_text_document_get_box_text_size(pag_text_document* document);
+
+PAG_API void pag_text_document_set_box_text_size(pag_text_document* document,
+ pag_point boxTextSize);
+
+PAG_API float pag_text_document_get_first_baseline(pag_text_document* document);
+
+PAG_API void pag_text_document_set_first_baseline(pag_text_document* document, float firstBaseline);
+
+PAG_API bool pag_text_document_get_faux_bold(pag_text_document* document);
+
+PAG_API void pag_text_document_set_faux_bold(pag_text_document* document, bool fauxBold);
+
+PAG_API bool pag_text_document_get_faux_italic(pag_text_document* document);
+
+PAG_API void pag_text_document_set_faux_italic(pag_text_document* document, bool fauxItalic);
+
+PAG_API pag_color pag_text_document_get_fill_color(pag_text_document* document);
+
+PAG_API void pag_text_document_set_fill_color(pag_text_document* document, pag_color fillColor);
+
+PAG_API const char* pag_text_document_get_font_family(pag_text_document* document);
+
+PAG_API void pag_text_document_set_font_family(pag_text_document* document, const char* fontFamily);
+
+PAG_API const char* pag_text_document_get_font_style(pag_text_document* document);
+
+PAG_API void pag_text_document_set_font_style(pag_text_document* document, const char* fontStyle);
+
+PAG_API float pag_text_document_get_font_size(pag_text_document* document);
+
+PAG_API void pag_text_document_set_font_size(pag_text_document* document, float fontSize);
+
+PAG_API pag_color pag_text_document_get_stroke_color(pag_text_document* document);
+
+PAG_API void pag_text_document_set_stroke_color(pag_text_document* document, pag_color strokeColor);
+
+PAG_API bool pag_text_document_get_stroke_over_fill(pag_text_document* document);
+
+PAG_API void pag_text_document_set_stroke_over_fill(pag_text_document* document,
+ bool strokeOverFill);
+
+PAG_API float pag_text_document_get_stroke_width(pag_text_document* document);
+
+PAG_API void pag_text_document_set_stroke_width(pag_text_document* document, float strokeWidth);
+
+PAG_API const char* pag_text_document_get_text(pag_text_document* document);
+
+PAG_API void pag_text_document_set_text(pag_text_document* document, const char* text);
+
+PAG_API pag_paragraph_justification
+pag_text_document_get_justification(pag_text_document* document);
+
+PAG_API void pag_text_document_set_justification(pag_text_document* document,
+ pag_paragraph_justification justification);
+
+PAG_API float pag_text_document_get_leading(pag_text_document* document);
+
+PAG_API void pag_text_document_set_leading(pag_text_document* document, float leading);
+
+PAG_API float pag_text_document_get_tracking(pag_text_document* document);
+
+PAG_API void pag_text_document_set_tracking(pag_text_document* document, float tracking);
+
+PAG_API pag_color pag_text_document_get_background_color(pag_text_document* document);
+
+PAG_API void pag_text_document_set_background_color(pag_text_document* document,
+ pag_color backgroundColor);
+
+PAG_API uint8_t pag_text_document_get_background_alpha(pag_text_document* document);
+
+PAG_API void pag_text_document_set_background_alpha(pag_text_document* document,
+ uint8_t backgroundAlpha);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/c/pag_types.h b/include/pag/c/pag_types.h
new file mode 100644
index 0000000000..3b8347cba7
--- /dev/null
+++ b/include/pag/c/pag_types.h
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/defines.h"
+
+#ifdef __cplusplus
+#define PAG_C_PLUS_PLUS_BEGIN_GUARD extern "C" {
+#define PAG_C_PLUS_PLUS_END_GUARD }
+#else
+#define PAG_C_PLUS_PLUS_BEGIN_GUARD
+#define PAG_C_PLUS_PLUS_END_GUARD
+#endif
+
+PAG_C_PLUS_PLUS_BEGIN_GUARD
+
+typedef enum {
+ pag_time_stretch_mode_none,
+ pag_time_stretch_mode_scale,
+ pag_time_stretch_mode_repeat,
+ pag_time_stretch_mode_repeat_inverted,
+} pag_time_stretch_mode;
+
+typedef enum {
+ pag_color_type_unknown,
+ pag_color_type_alpha_8,
+ pag_color_type_rgba_8888,
+ pag_color_type_bgra_8888,
+ pag_color_type_rgb_565,
+ pag_color_type_gray_8,
+ pag_color_type_rgba_f16,
+ pag_color_type_rgba_101012,
+} pag_color_type;
+
+typedef enum {
+ pag_alpha_type_unknown,
+ pag_alpha_type_opaque,
+ pag_alpha_type_premultiplied,
+ pag_alpha_type_unpremultiplied,
+} pag_alpha_type;
+
+typedef enum {
+ pag_scale_mode_none,
+ pag_scale_mode_stretch,
+ pag_scale_mode_letter_box,
+ pag_scale_mode_zoom,
+} pag_scale_mode;
+
+typedef enum {
+ pag_layer_type_unknown,
+ pag_layer_type_null,
+ pag_layer_type_solid,
+ pag_layer_type_text,
+ pag_layer_type_shape,
+ pag_layer_type_image,
+ pag_layer_type_pre_compose,
+ pag_layer_type_camera,
+} pag_layer_type;
+
+typedef struct pag_gl_texture_info {
+ unsigned id = 0;
+ unsigned target = 0x0DE1; // GL_TEXTURE_2D;
+ unsigned format = 0x8058; // GL_RGBA8;
+} pag_gl_texture_info;
+
+typedef struct pag_vk_image_info {
+ void* image = nullptr;
+} pag_vk_image_info;
+
+typedef struct pag_mtl_texture_info {
+ void* texture = nullptr;
+} pag_mtl_texture_info;
+
+typedef struct pag_point {
+ float x;
+ float y;
+} pag_point;
+
+typedef struct pag_color {
+ uint8_t red;
+ uint8_t green;
+ uint8_t blue;
+} pag_color;
+
+typedef enum {
+ pag_paragraph_justification_left_justify,
+ pag_paragraph_justification_center_justify,
+ pag_paragraph_justification_right_justify,
+ pag_paragraph_justification_full_justify_last_line_left,
+ pag_paragraph_justification_full_justify_last_line_right,
+ pag_paragraph_justification_full_justify_last_line_center,
+ pag_paragraph_justification_full_justify_last_line_full,
+} pag_paragraph_justification;
+
+typedef struct pag_display_link_functions {
+ void* (*create)(void* user, void (*callback)(void* user));
+ void (*start)(void* displayLink);
+ void (*stop)(void* displayLink);
+ void (*release)(void* displayLink);
+} pag_display_link_functions;
+
+typedef struct pag_egl_globals {
+ void* display = nullptr;
+} egl_globals;
+
+typedef const void* pag_object;
+typedef struct pag_byte_data pag_byte_data;
+typedef struct pag_text_document pag_text_document;
+typedef struct pag_layer pag_layer;
+typedef pag_layer pag_solid_layer;
+typedef pag_layer pag_composition;
+typedef pag_composition pag_file;
+typedef struct pag_player pag_player;
+typedef struct pag_surface pag_surface;
+typedef struct pag_image pag_image;
+typedef struct pag_font pag_font;
+typedef struct pag_backend_texture pag_backend_texture;
+typedef struct pag_backend_semaphore pag_backend_semaphore;
+typedef struct pag_decoder PAGDecoder;
+typedef struct pag_animator pag_animator;
+
+typedef struct pag_animator_listener {
+ void (*on_animation_start)(pag_animator* animator, void* user);
+ void (*on_animation_end)(pag_animator* animator, void* user);
+ void (*on_animation_cancel)(pag_animator* animator, void* user);
+ void (*on_animation_repeat)(pag_animator* animator, void* user);
+ void (*on_animation_update)(pag_animator* animator, void* user);
+} pag_animator_listener;
+
+/**
+ * Release a pag_object.
+ */
+PAG_API void pag_release(pag_object object);
+
+PAG_API void pag_display_link_set_functions(pag_display_link_functions* functions);
+
+PAG_C_PLUS_PLUS_END_GUARD
diff --git a/include/pag/file.h b/include/pag/file.h
index 71bf0a8f64..316fcc2198 100644
--- a/include/pag/file.h
+++ b/include/pag/file.h
@@ -812,7 +812,7 @@ class PAG_API MosaicEffect : public Effect {
RTTR_ENABLE(Effect)
};
-class BrightnessContrastEffect : public Effect {
+class PAG_API BrightnessContrastEffect : public Effect {
public:
~BrightnessContrastEffect() override;
@@ -852,7 +852,7 @@ class PAG_API ChannelControlType {
static const int Count = 7;
};
-class HueSaturationEffect : public Effect {
+class PAG_API HueSaturationEffect : public Effect {
public:
~HueSaturationEffect() override;
diff --git a/include/pag/pag.h b/include/pag/pag.h
index 1d4e200120..4b5493d7e1 100644
--- a/include/pag/pag.h
+++ b/include/pag/pag.h
@@ -1270,9 +1270,16 @@ class PAG_API PAGSurface {
void unlockContext();
bool wait(const BackendSemaphore& waitSemaphore);
+ BackendTexture getFrontTexture();
+ BackendTexture getBackTexture();
+ HardwareBufferRef getFrontHardwareBuffer();
+ HardwareBufferRef getBackHardwareBuffer();
+
friend class PAGPlayer;
friend class FileReporter;
+
+ friend class PAGSurfaceExt;
};
class FileReporter;
diff --git a/include/pag/types.h b/include/pag/types.h
index 4a9656d13f..7629d02087 100644
--- a/include/pag/types.h
+++ b/include/pag/types.h
@@ -1309,7 +1309,7 @@ class PAG_API Matrix {
* of zero values are different. Returns false if either Matrix contains NaN, even if the other
* Matrix also contains NaN.
*/
- friend bool operator==(const Matrix& a, const Matrix& b);
+ friend PAG_API bool operator==(const Matrix& a, const Matrix& b);
/**
* Compares a and b; returns true if a and b are not numerically equal. Returns false even if
diff --git a/install_tools.sh b/install_tools.sh
new file mode 100755
index 0000000000..cd1cfb1cb9
--- /dev/null
+++ b/install_tools.sh
@@ -0,0 +1,28 @@
+#!/bin/bash -e
+cd $(dirname $0)
+
+if [[ `uname` == 'Darwin' ]]; then
+ MAC_REQUIRED_TOOLS="node cmake ninja yasm git-lfs"
+ for TOOL in ${MAC_REQUIRED_TOOLS[@]}; do
+ if [ ! $(which $TOOL) ]; then
+ if [ ! $(which brew) ]; then
+ echo "Homebrew not found. Trying to install..."
+ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ||
+ exit 1
+ fi
+ echo "$TOOL not found. Trying to install..."
+ brew install $TOOL || exit 1
+ fi
+ done
+fi
+
+NODE_REQUIRED_TOOLS="depsync"
+
+for TOOL in ${NODE_REQUIRED_TOOLS[@]}; do
+ if [ ! $(which $TOOL) ]; then
+ echo "$TOOL not found. Trying to install..."
+ npm install -g $TOOL > /dev/null
+ fi
+done
+
+npm update -g depsync --silent
\ No newline at end of file
diff --git a/libpag.podspec b/libpag.podspec
index 62a3ddac13..b0b1202220 100644
--- a/libpag.podspec
+++ b/libpag.podspec
@@ -1,29 +1,68 @@
PAG_ROOT = __dir__
+TGFX_ROOT = PAG_ROOT+"/third_party/tgfx"
-vendorNames = "pathkit skcms libwebp"
+tgfxVendors = "pathkit skcms libwebp"
commonCFlags = ["-DGLES_SILENCE_DEPRECATION -DTGFX_USE_WEBP_DECODE -DPAG_DLL -fvisibility=hidden -Wall -Wextra -Weffc++ -pedantic -Werror=return-type"]
# PAG_USE_FREETYPE=ON pod install
if ENV["PAG_USE_FREETYPE"] == 'ON' and ENV["PLATFORM"] == "mac"
- vendorNames += " freetype"
+ tgfxVendors += " freetype"
commonCFlags += ["-DTGFX_USE_FREETYPE"]
- $rasterSourceFiles = ['tgfx/src/vectors/freetype/**/*.{h,cpp,mm}']
+ $rasterSourceFiles = ['third_party/tgfx/src/vectors/freetype/**/*.{h,cpp,mm}']
else
commonCFlags += ["-DTGFX_USE_CORE_GRAPHICS"]
- $rasterSourceFiles = ['tgfx/src/vectors/coregraphics/**/*.{h,cpp,mm}']
+ $rasterSourceFiles = ['third_party/tgfx/src/vectors/coregraphics/**/*.{h,cpp,mm}']
end
+
+
+if ENV["PLATFORM"] == "mac"
+ system("depsync mac")
+ system("cd #{TGFX_ROOT} && node build_vendor #{tgfxVendors} -o #{PAG_ROOT}/mac/Pods/tgfx-vendor -p mac --xcframework")
+else
+ system("depsync ios")
+ system("cd #{TGFX_ROOT} && node build_vendor #{tgfxVendors} -o #{PAG_ROOT}/ios/Pods/tgfx-vendor -p ios --xcframework")
+end
+
+ios_vendored_frameworks = ['ios/Pods/tgfx-vendor/libtgfx-vendor.xcframework']
+mac_vendored_frameworks = ['mac/Pods/tgfx-vendor/libtgfx-vendor.xcframework']
+
# PAG_USE_LIBAVC=OFF pod install
if ENV["PAG_USE_LIBAVC"] != 'OFF'
- vendorNames += " libavc"
commonCFlags += ["-DPAG_USE_LIBAVC"]
+ if ENV["PLATFORM"] == "mac"
+ system("node build_vendor libavc -o #{PAG_ROOT}/mac/Pods/pag-vendor -p mac --xcframework")
+ mac_vendored_frameworks += ['mac/Pods/pag-vendor/libpag-vendor.xcframework']
+ else
+ system("node build_vendor libavc -o #{PAG_ROOT}/ios/Pods/pag-vendor -p ios --xcframework")
+ ios_vendored_frameworks += ['ios/Pods/pag-vendor/libpag-vendor.xcframework']
+ end
end
-if ENV["PLATFORM"] == "mac"
- system("depsync mac")
- system("node build_vendor #{vendorNames} -o #{PAG_ROOT}/mac/Pods/pag-vendor -p mac --xcframework")
+
+iosSourceFiles = ['src/platform/ios/*.{h,cpp,mm,m}',
+ 'src/platform/ios/private/*.{h,cpp,mm,m}',
+ 'src/platform/cocoa/**/*.{h,cpp,mm,m}',
+ 'third_party/tgfx/src/opengl/eagl/*.{h,cpp,mm}',
+ 'third_party/tgfx/src/platform/apple/**/*.{h,cpp,mm,m}']
+
+if ENV["PAG_USE_QT"] == 'ON'
+ macSourceFiles = ['src/platform/qt/**/*.{h,cpp,mm,m}',
+ 'third_party/tgfx/src/platform/apple/*.{h,cpp,m,mm}',
+ 'third_party/tgfx/src/opengl/qt/*.{h,cpp,mm}',
+ 'third_party/tgfx/src/opengl/cgl/CGLHardwareTexture.mm',
+ 'src/platform/mac/private/HardwareDecoder.mm']
else
- system("depsync ios")
- system("node build_vendor #{vendorNames} -o #{PAG_ROOT}/ios/Pods/pag-vendor -p ios --xcframework")
+ macSourceFiles = ['src/platform/mac/**/*.{h,cpp,mm,m}',
+ 'src/platform/cocoa/**/*.{h,cpp,mm,m}',
+ 'third_party/tgfx/src/opengl/cgl/*.{h,cpp,mm}',
+ 'third_party/tgfx/src/platform/apple/**/*.{h,cpp,mm,m}']
+end
+
+cSourceFiles = []
+if ENV["PAG_USE_C"] == 'ON'
+ cSourceFiles += ["src/c/*.*"]
+ iosSourceFiles += ["src/c/*.{h,cpp,mm,m}", "src/c/ext/*.{h,cpp,mm,m}"]
+ macSourceFiles += ["src/c/*.{h,cpp,mm,m}", "src/c/ext/*.{h,cpp,mm,m}"]
end
Pod::Spec.new do |s|
@@ -49,38 +88,32 @@ Pod::Spec.new do |s|
'src/video/**/*.{h,cpp}',
'src/rendering/**/*.{h,cpp}',
'src/platform/*.{h,cpp}',
- 'tgfx/src/core/*.{h,cpp}',
- 'tgfx/src/codecs/*.{h,cpp}',
- 'tgfx/src/effects/**/*.{h,cpp}',
- 'tgfx/src/images/**/*.{h,cpp}',
- 'tgfx/src/shaders/**/*.{h,cpp}',
- 'tgfx/src/shapes/**/*.{h,cpp}',
- 'tgfx/src/utils/**/*.{h,cpp}',
- 'tgfx/src/vectors/*.{h,cpp}',
- 'tgfx/src/gpu/**/*.{h,cpp}',
- 'tgfx/src/opengl/*.{h,cpp,mm}',
- 'tgfx/src/platform/*.{h,cpp}',
- 'tgfx/src/codecs/webp/**/*.{h,cpp,mm}'
-
- s.source_files = $source_files + $rasterSourceFiles;
+ 'third_party/tgfx/src/core/*.{h,cpp}',
+ 'third_party/tgfx/src/codecs/*.{h,cpp}',
+ 'third_party/tgfx/src/effects/**/*.{h,cpp}',
+ 'third_party/tgfx/src/images/**/*.{h,cpp}',
+ 'third_party/tgfx/src/shaders/**/*.{h,cpp}',
+ 'third_party/tgfx/src/shapes/**/*.{h,cpp}',
+ 'third_party/tgfx/src/utils/**/*.{h,cpp}',
+ 'third_party/tgfx/src/vectors/*.{h,cpp}',
+ 'third_party/tgfx/src/gpu/**/*.{h,cpp}',
+ 'third_party/tgfx/src/opengl/*.{h,cpp,mm}',
+ 'third_party/tgfx/src/opengl/processors/**/*.{h,cpp}',
+ 'third_party/tgfx/src/platform/*.{h,cpp}',
+ 'third_party/tgfx/src/codecs/webp/**/*.{h,cpp,mm}'
+
+ s.source_files = $source_files + $rasterSourceFiles + cSourceFiles;
s.compiler_flags = '-Wno-documentation'
if ENV["PAG_USE_QT"] == 'ON'
- s.osx.public_header_files = ['src/platform/qt/*.h', 'tgfx/src/opengl/*.h']
- s.osx.source_files = 'src/platform/qt/**/*.{h,cpp,mm,m}',
- 'tgfx/src/platform/apple/*.{h,cpp,m,mm}',
- 'tgfx/src/opengl/qt/*.{h,cpp,mm}',
- 'tgfx/src/opengl/cgl/CGLHardwareTexture.mm',
- 'src/platform/mac/private/HardwareDecoder.mm'
+ s.osx.public_header_files = ['src/platform/qt/*.h', 'third_party/tgfx/src/opengl/*.h']
else
s.osx.public_header_files = 'src/platform/mac/*.h',
'src/platform/cocoa/*.h'
- s.osx.source_files = 'src/platform/mac/**/*.{h,cpp,mm,m}',
- 'src/platform/cocoa/**/*.{h,cpp,mm,m}',
- 'tgfx/src/opengl/cgl/*.{h,cpp,mm}',
- 'tgfx/src/platform/apple/**/*.{h,cpp,mm,m}'
end
+
+ s.osx.source_files = macSourceFiles
s.osx.frameworks = ['ApplicationServices', 'AGL', 'OpenGL', 'QuartzCore', 'Cocoa', 'Foundation', 'VideoToolbox', 'CoreMedia']
s.osx.libraries = ["iconv", "c++", "compression"]
@@ -88,20 +121,16 @@ Pod::Spec.new do |s|
s.ios.public_header_files = 'src/platform/ios/*.h',
'src/platform/cocoa/*.h'
- s.ios.source_files = 'src/platform/ios/*.{h,cpp,mm,m}',
- 'src/platform/ios/private/*.{h,cpp,mm,m}',
- 'src/platform/cocoa/**/*.{h,cpp,mm,m}',
- 'tgfx/src/opengl/eagl/*.{h,cpp,mm}',
- 'tgfx/src/platform/apple/**/*.{h,cpp,mm,m}'
+ s.ios.source_files = iosSourceFiles
s.ios.frameworks = ['UIKit', 'CoreFoundation', 'QuartzCore', 'CoreGraphics', 'CoreText', 'OpenGLES', 'VideoToolbox', 'CoreMedia']
s.ios.libraries = ["iconv", "compression"]
armv7CFlags = commonCFlags + ["-fno-aligned-allocation"]
- s.xcconfig = {'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17','CLANG_CXX_LIBRARY' => 'libc++',"HEADER_SEARCH_PATHS" => "#{PAG_ROOT}/src #{PAG_ROOT}/include #{PAG_ROOT}/tgfx/src #{PAG_ROOT}/tgfx/include #{PAG_ROOT}/third_party/pathkit #{PAG_ROOT}/third_party/skcms #{PAG_ROOT}/third_party/freetype/include #{PAG_ROOT}/third_party/libwebp/src #{PAG_ROOT}/third_party/libavc/common #{PAG_ROOT}/third_party/libavc/decoder"}
- s.ios.xcconfig = {"OTHER_CFLAGS" => commonCFlags.join(" "),"OTHER_CFLAGS[sdk=iphoneos*][arch=armv7]" => armv7CFlags.join(" "),"EXPORTED_SYMBOLS_FILE" => "${PODS_ROOT}/../libpag.lds","OTHER_LDFLAGS" => "-w","VALIDATE_WORKSPACE_SKIPPED_SDK_FRAMEWORKS" => "OpenGLES"}
+ s.xcconfig = {'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17','CLANG_CXX_LIBRARY' => 'libc++',"HEADER_SEARCH_PATHS" => "#{PAG_ROOT}/src #{PAG_ROOT}/include #{TGFX_ROOT}/src #{TGFX_ROOT}/include #{TGFX_ROOT}/third_party/pathkit #{TGFX_ROOT}/third_party/skcms #{TGFX_ROOT}/third_party/freetype/include #{TGFX_ROOT}/third_party/libwebp/src #{PAG_ROOT}/third_party/libavc/common #{PAG_ROOT}/third_party/libavc/decoder"}
+ s.ios.xcconfig = {"OTHER_CFLAGS" => commonCFlags.join(" "),"OTHER_CFLAGS[sdk=iphoneos*][arch=armv7]" => armv7CFlags.join(" "),"EXPORTED_SYMBOLS_FILE" => "${PODS_ROOT}/../libpag.lds","OTHER_LDFLAGS" => "-w -ld_classic","VALIDATE_WORKSPACE_SKIPPED_SDK_FRAMEWORKS" => "OpenGLES"}
s.osx.xcconfig = {"OTHER_CFLAGS" => commonCFlags.join(" ")}
- s.ios.vendored_frameworks = 'ios/Pods/pag-vendor/libpag-vendor.xcframework'
- s.osx.vendored_frameworks = 'mac/Pods/pag-vendor/libpag-vendor.xcframework'
+ s.ios.vendored_frameworks = ios_vendored_frameworks
+ s.osx.vendored_frameworks = mac_vendored_frameworks
end
diff --git a/mac/PAGViewer.xcodeproj/project.pbxproj b/mac/PAGViewer.xcodeproj/project.pbxproj
index 8be833989c..98c15ccc23 100644
--- a/mac/PAGViewer.xcodeproj/project.pbxproj
+++ b/mac/PAGViewer.xcodeproj/project.pbxproj
@@ -7,8 +7,8 @@
objects = {
/* Begin PBXBuildFile section */
- 14A1C3A0D1F6C577289F66C1 /* libPods-PAGViewer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8DD1EA514E38456948659573 /* libPods-PAGViewer.a */; };
27815BAA255A79400086594A /* text_matte.pag in Resources */ = {isa = PBXBuildFile; fileRef = 27815BA9255A79400086594A /* text_matte.pag */; };
+ 51317B945151CCD171EEA1FA /* Pods_PAGViewer.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0694879C7283A6AA46DF40B4 /* Pods_PAGViewer.framework */; };
7785F05225ADB58D004D5CE9 /* WindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 7785F05125ADB58D004D5CE9 /* WindowController.m */; };
7785F05525ADB630004D5CE9 /* red.pag in Resources */ = {isa = PBXBuildFile; fileRef = 7785F05425ADB630004D5CE9 /* red.pag */; };
857B02A82455D81100E533CF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 857B02A72455D81100E533CF /* AppDelegate.m */; };
@@ -68,6 +68,7 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ 0694879C7283A6AA46DF40B4 /* Pods_PAGViewer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_PAGViewer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
27815BA9255A79400086594A /* text_matte.pag */ = {isa = PBXFileReference; lastKnownFileType = file; path = text_matte.pag; sourceTree = ""; };
6E097EDDF5BF083DFCB0CBB0 /* Pods-PAGViewer.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PAGViewer.debug.xcconfig"; path = "Target Support Files/Pods-PAGViewer/Pods-PAGViewer.debug.xcconfig"; sourceTree = ""; };
7785F05025ADB58D004D5CE9 /* WindowController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WindowController.h; sourceTree = ""; };
@@ -133,7 +134,6 @@
857B02ED2455DA7C00E533CF /* Bulge-unpin-s.pag */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Bulge-unpin-s.pag"; sourceTree = ""; };
85C9A3D925309D7C00B2CA8C /* DragFilePAGView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DragFilePAGView.h; sourceTree = ""; };
85C9A3DA25309D7C00B2CA8C /* DragFilePAGView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DragFilePAGView.m; sourceTree = ""; };
- 8DD1EA514E38456948659573 /* libPods-PAGViewer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-PAGViewer.a"; sourceTree = BUILT_PRODUCTS_DIR; };
949348D34F56C006A7678170 /* Pods-PAGViewer.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-PAGViewer.release.xcconfig"; path = "Target Support Files/Pods-PAGViewer/Pods-PAGViewer.release.xcconfig"; sourceTree = ""; };
/* End PBXFileReference section */
@@ -142,7 +142,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- 14A1C3A0D1F6C577289F66C1 /* libPods-PAGViewer.a in Frameworks */,
+ 51317B945151CCD171EEA1FA /* Pods_PAGViewer.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -282,7 +282,7 @@
EBC250D9EF61A8E129790DCC /* Frameworks */ = {
isa = PBXGroup;
children = (
- 8DD1EA514E38456948659573 /* libPods-PAGViewer.a */,
+ 0694879C7283A6AA46DF40B4 /* Pods_PAGViewer.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -298,6 +298,7 @@
857B029F2455D81100E533CF /* Sources */,
857B02A02455D81100E533CF /* Frameworks */,
857B02A12455D81100E533CF /* Resources */,
+ F8C195E5F614458D028161BF /* [CP] Embed Pods Frameworks */,
);
buildRules = (
);
@@ -425,6 +426,23 @@
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
+ F8C195E5F614458D028161BF /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-PAGViewer/Pods-PAGViewer-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-PAGViewer/Pods-PAGViewer-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-PAGViewer/Pods-PAGViewer-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
diff --git a/src/base/TimeRange.cpp b/src/base/TimeRange.cpp
index a9f68db184..9e6eb32956 100644
--- a/src/base/TimeRange.cpp
+++ b/src/base/TimeRange.cpp
@@ -145,7 +145,7 @@ std::vector OffsetTimeRanges(const std::vector& timeRanges
bool HasVaryingTimeRange(const std::vector* staticTimeRanges, Frame startTime,
Frame duration) {
if (staticTimeRanges->size() == 1) {
- const auto& range = (*staticTimeRanges)[0];
+ const auto& range = *staticTimeRanges->data();
if (range.start == startTime && range.end == startTime + duration - 1) {
return false;
}
diff --git a/src/base/utils/Log.h b/src/base/utils/Log.h
index a530b96c21..112e9c852f 100644
--- a/src/base/utils/Log.h
+++ b/src/base/utils/Log.h
@@ -22,10 +22,10 @@
#include "tgfx/platform/Print.h"
namespace pag {
-#define ABORT(msg) \
- do { \
- tgfx::PrintError("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, #msg); \
- ::abort(); \
+#define ABORT(msg) \
+ do { \
+ ::tgfx::PrintError("%s:%d: fatal error: \"%s\"\n", __FILE__, __LINE__, #msg); \
+ ::abort(); \
} while (false)
#ifdef NO_LOG
@@ -36,8 +36,8 @@ namespace pag {
#else
-#define LOGI(...) tgfx::PrintLog(__VA_ARGS__)
-#define LOGE(...) tgfx::PrintError(__VA_ARGS__)
+#define LOGI(...) ::tgfx::PrintLog(__VA_ARGS__)
+#define LOGE(...) ::tgfx::PrintError(__VA_ARGS__)
#define ASSERT(assertion) \
if (!(assertion)) { \
ABORT(#assertion); \
diff --git a/src/base/utils/TGFXCast.cpp b/src/base/utils/TGFXCast.cpp
index 171ae742e3..8538beba40 100644
--- a/src/base/utils/TGFXCast.cpp
+++ b/src/base/utils/TGFXCast.cpp
@@ -162,6 +162,18 @@ tgfx::BackendTexture ToTGFX(const BackendTexture& texture) {
return {sampler, texture.width(), texture.height()};
}
+BackendTexture ToPAG(const tgfx::BackendTexture& texture) {
+ tgfx::GLTextureInfo glInfo = {};
+ if (!texture.getGLTextureInfo(&glInfo)) {
+ return {};
+ }
+ GLTextureInfo sampler = {};
+ sampler.id = glInfo.id;
+ sampler.target = glInfo.target;
+ sampler.format = glInfo.format;
+ return {sampler, texture.width(), texture.height()};
+}
+
tgfx::BackendRenderTarget ToTGFX(const BackendRenderTarget& renderTarget) {
GLFrameBufferInfo glInfo = {};
if (!renderTarget.getGLFramebufferInfo(&glInfo)) {
diff --git a/src/base/utils/TGFXCast.h b/src/base/utils/TGFXCast.h
index 4b3563a99f..1882c8d722 100644
--- a/src/base/utils/TGFXCast.h
+++ b/src/base/utils/TGFXCast.h
@@ -54,6 +54,8 @@ ColorType ToPAG(tgfx::ColorType colorType);
tgfx::BackendTexture ToTGFX(const BackendTexture& texture);
+BackendTexture ToPAG(const tgfx::BackendTexture& texture);
+
tgfx::BackendRenderTarget ToTGFX(const BackendRenderTarget& renderTarget);
tgfx::BackendSemaphore ToTGFX(const BackendSemaphore& semaphore);
diff --git a/src/c/ext/egl/pag_egl_globals.cpp b/src/c/ext/egl/pag_egl_globals.cpp
new file mode 100644
index 0000000000..b322b5b1bc
--- /dev/null
+++ b/src/c/ext/egl/pag_egl_globals.cpp
@@ -0,0 +1,29 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/ext/egl/pag_egl_globals.h"
+#include
+#include "tgfx/opengl/egl/EGLGlobals.h"
+
+static std::mutex eglGlobalsLocker = {};
+
+egl_globals* pag_egl_globals_get() {
+ std::lock_guard lock(eglGlobalsLocker);
+ static pag_egl_globals globals = {tgfx::EGLGlobals::Get()->display};
+ return &globals;
+}
diff --git a/src/c/ext/pag_surface_ext.cpp b/src/c/ext/pag_surface_ext.cpp
new file mode 100644
index 0000000000..ed13ee60ec
--- /dev/null
+++ b/src/c/ext/pag_surface_ext.cpp
@@ -0,0 +1,72 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/ext/pag_surface_ext.h"
+#include "c/pag_types_priv.h"
+#include "pag/pag.h"
+#include "rendering/drawables/DoubleBufferedDrawable.h"
+#include "tgfx/opengl/GLDevice.h"
+
+pag_surface* pag_surface_make_offscreen_double_buffered(int width, int height, bool tryHardware,
+ void* sharedContext) {
+ auto device = tgfx::GLDevice::Make(sharedContext);
+ if (device == nullptr) {
+ return nullptr;
+ }
+ if (auto surface = pag::PAGSurface::MakeFrom(
+ pag::DoubleBufferedDrawable::Make(width, height, tryHardware, device))) {
+ return new pag_surface(std::move(surface));
+ }
+ return nullptr;
+}
+
+pag_backend_texture* pag_surface_get_front_texture(pag_surface* surface) {
+ if (surface == nullptr) {
+ return nullptr;
+ }
+ auto texture = surface->ext->getFrontTexture();
+ if (!texture.isValid()) {
+ return nullptr;
+ }
+ return new pag_backend_texture(texture);
+}
+
+pag_backend_texture* pag_surface_get_back_texture(pag_surface* surface) {
+ if (surface == nullptr) {
+ return nullptr;
+ }
+ auto texture = surface->ext->getBackTexture();
+ if (!texture.isValid()) {
+ return nullptr;
+ }
+ return new pag_backend_texture(texture);
+}
+
+void* pag_surface_get_front_hardware_buffer(pag_surface* surface) {
+ if (surface == nullptr) {
+ return nullptr;
+ }
+ return surface->ext->getFrontHardwareBuffer();
+}
+
+void* pag_surface_get_back_hardware_buffer(pag_surface* surface) {
+ if (surface == nullptr) {
+ return nullptr;
+ }
+ return surface->ext->getBackHardwareBuffer();
+}
diff --git a/src/c/pag_animator.cpp b/src/c/pag_animator.cpp
new file mode 100644
index 0000000000..4d41d189d2
--- /dev/null
+++ b/src/c/pag_animator.cpp
@@ -0,0 +1,165 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_animator.h"
+#include "pag_types_priv.h"
+#include "rendering/PAGAnimator.h"
+
+class PAGAnimatorListenerWrapper : public pag::PAGAnimator::Listener {
+ public:
+ static std::shared_ptr Make(pag_animator_listener* listener,
+ void* user) {
+ if (listener) {
+ return std::shared_ptr(
+ new PAGAnimatorListenerWrapper(listener, user));
+ }
+ return nullptr;
+ }
+
+ void onAnimationStart(pag::PAGAnimator*) override {
+ listener->on_animation_start(_animator, user);
+ }
+
+ void onAnimationEnd(pag::PAGAnimator*) override {
+ listener->on_animation_end(_animator, user);
+ }
+
+ void onAnimationCancel(pag::PAGAnimator*) override {
+ listener->on_animation_cancel(_animator, user);
+ }
+
+ void onAnimationRepeat(pag::PAGAnimator*) override {
+ listener->on_animation_repeat(_animator, user);
+ }
+
+ void onAnimationUpdate(pag::PAGAnimator*) override {
+ listener->on_animation_update(_animator, user);
+ }
+
+ void setAnimator(pag_animator* animator) {
+ _animator = animator;
+ }
+
+ private:
+ PAGAnimatorListenerWrapper(pag_animator_listener* listener, void* user)
+ : listener(listener), user(user) {
+ }
+
+ pag_animator* _animator = nullptr;
+ pag_animator_listener* listener = nullptr;
+ void* user = nullptr;
+};
+
+pag_animator* pag_animator_create(pag_animator_listener* listener, void* user) {
+ auto wrapper = PAGAnimatorListenerWrapper::Make(listener, user);
+ if (wrapper == nullptr) {
+ return nullptr;
+ }
+ if (auto animator = pag::PAGAnimator::MakeFrom(wrapper)) {
+ auto* ret = new pag_animator();
+ wrapper->setAnimator(ret);
+ ret->p = std::move(animator);
+ ret->listener = std::move(wrapper);
+ return ret;
+ }
+ return nullptr;
+}
+
+bool pag_animator_is_sync(pag_animator* animator) {
+ if (animator == nullptr) {
+ return false;
+ }
+ return animator->p->isSync();
+}
+
+void pag_animator_set_sync(pag_animator* animator, bool sync) {
+ if (animator == nullptr) {
+ return;
+ }
+ animator->p->setSync(sync);
+}
+
+int64_t pag_animator_get_duration(pag_animator* animator) {
+ if (animator == nullptr) {
+ return 0;
+ }
+ return animator->p->duration();
+}
+
+void pag_animator_set_duration(pag_animator* animator, int64_t duration) {
+ if (animator == nullptr) {
+ return;
+ }
+ animator->p->setDuration(duration);
+}
+
+int pag_animator_get_repeat_count(pag_animator* animator) {
+ if (animator == nullptr) {
+ return 0;
+ }
+ return animator->p->repeatCount();
+}
+
+void pag_animator_set_repeat_count(pag_animator* animator, int repeatCount) {
+ if (animator == nullptr) {
+ return;
+ }
+ animator->p->setRepeatCount(repeatCount);
+}
+
+double pag_animator_get_progress(pag_animator* animator) {
+ if (animator == nullptr) {
+ return 0;
+ }
+ return animator->p->progress();
+}
+
+void pag_animator_set_progress(pag_animator* animator, double progress) {
+ if (animator == nullptr) {
+ return;
+ }
+ animator->p->setProgress(progress);
+}
+
+bool pag_animator_is_running(pag_animator* animator) {
+ if (animator == nullptr) {
+ return false;
+ }
+ return animator->p->isRunning();
+}
+
+void pag_animator_start(pag_animator* animator) {
+ if (animator == nullptr) {
+ return;
+ }
+ animator->p->start();
+}
+
+void pag_animator_cancel(pag_animator* animator) {
+ if (animator == nullptr) {
+ return;
+ }
+ animator->p->cancel();
+}
+
+void pag_animator_update(pag_animator* animator) {
+ if (animator == nullptr) {
+ return;
+ }
+ animator->p->update();
+}
diff --git a/tgfx/src/core/SimpleTextBlob.h b/src/c/pag_backend_semaphore.cpp
similarity index 59%
rename from tgfx/src/core/SimpleTextBlob.h
rename to src/c/pag_backend_semaphore.cpp
index 9fae378101..1f43747c5a 100644
--- a/tgfx/src/core/SimpleTextBlob.h
+++ b/src/c/pag_backend_semaphore.cpp
@@ -16,36 +16,30 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma once
+#include "pag/c/pag_backend_semaphore.h"
+#include "pag_types_priv.h"
-#include "tgfx/core/TextBlob.h"
+pag_backend_semaphore* pag_backend_semaphore_create() {
+ return new pag_backend_semaphore();
+}
-namespace tgfx {
-class SimpleTextBlob : public TextBlob {
- public:
- bool hasColor() const override;
-
- Rect getBounds(const Stroke* stroke = nullptr) const override;
-
- bool getPath(Path* path, const Stroke* stroke = nullptr) const override;
-
- const Font& getFont() const {
- return font;
+bool pag_backend_semaphore_is_initialized(pag_backend_semaphore* semaphore) {
+ if (semaphore == nullptr) {
+ return false;
}
+ return semaphore->p.isInitialized();
+}
- const std::vector& getGlyphIDs() const {
- return glyphIDs;
+void pag_backend_semaphore_init_gl(pag_backend_semaphore* semaphore, void* glSync) {
+ if (semaphore == nullptr) {
+ return;
}
+ semaphore->p.initGL(glSync);
+}
- const std::vector& getPositions() const {
- return positions;
+void* pag_backend_semaphore_get_gl_sync(pag_backend_semaphore* semaphore) {
+ if (semaphore == nullptr) {
+ return nullptr;
}
-
- private:
- Font font = {};
- std::vector glyphIDs = {};
- std::vector positions = {};
-
- friend class TextBlob;
-};
-} // namespace tgfx
+ return semaphore->p.glSync();
+}
diff --git a/src/c/pag_backend_texture.cpp b/src/c/pag_backend_texture.cpp
new file mode 100644
index 0000000000..53a49a56e6
--- /dev/null
+++ b/src/c/pag_backend_texture.cpp
@@ -0,0 +1,73 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_backend_texture.h"
+#include "pag_types_priv.h"
+
+using namespace pag;
+
+pag_backend_texture* pag_backend_texture_create_from_gl_texture_info(
+ pag_gl_texture_info textureInfo, int width, int height) {
+ pag::GLTextureInfo info;
+ info.id = textureInfo.id;
+ info.target = textureInfo.target;
+ info.format = textureInfo.format;
+ pag::BackendTexture backendTexture(info, width, height);
+ return new pag_backend_texture(backendTexture);
+}
+
+bool pag_backend_texture_get_gl_texture_info(pag_backend_texture* texture,
+ pag_gl_texture_info* textureInfo) {
+ if (texture == nullptr || textureInfo == nullptr) {
+ return false;
+ }
+ GLTextureInfo info;
+ if (texture->p.getGLTextureInfo(&info)) {
+ textureInfo->id = info.id;
+ textureInfo->target = info.target;
+ textureInfo->format = info.format;
+ return true;
+ }
+ return false;
+}
+
+bool pag_backend_texture_get_vk_image_info(pag_backend_texture* texture,
+ pag_vk_image_info* imageInfo) {
+ if (texture == nullptr || imageInfo == nullptr) {
+ return false;
+ }
+ VkImageInfo info;
+ if (texture->p.getVkImageInfo(&info)) {
+ imageInfo->image = info.image;
+ return true;
+ }
+ return false;
+}
+
+bool pag_backend_texture_get_mtl_texture_info(pag_backend_texture* texture,
+ pag_mtl_texture_info* mtl_texture_info) {
+ if (texture == nullptr || mtl_texture_info == nullptr) {
+ return false;
+ }
+ MtlTextureInfo info;
+ if (texture->p.getMtlTextureInfo(&info)) {
+ mtl_texture_info->texture = info.texture;
+ return true;
+ }
+ return false;
+}
diff --git a/src/c/pag_byte_data.cpp b/src/c/pag_byte_data.cpp
new file mode 100644
index 0000000000..4393c6a51b
--- /dev/null
+++ b/src/c/pag_byte_data.cpp
@@ -0,0 +1,29 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_byte_data.h"
+#include "pag_types_priv.h"
+
+using namespace pag;
+
+pag_byte_data* pag_byte_data_copy(const void* bytes, size_t length) {
+ if (auto data = ByteData::MakeCopy(bytes, length)) {
+ return new pag_byte_data(std::move(data));
+ }
+ return nullptr;
+}
diff --git a/src/c/pag_composition.cpp b/src/c/pag_composition.cpp
new file mode 100644
index 0000000000..491c915dc6
--- /dev/null
+++ b/src/c/pag_composition.cpp
@@ -0,0 +1,110 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_composition.h"
+#include "pag_types_priv.h"
+
+PAG_API int pag_composition_get_width(pag_composition* composition) {
+ auto p = ToPAGComposition(composition);
+ if (p == nullptr) {
+ return 0;
+ }
+ return p->width();
+}
+
+PAG_API int pag_composition_get_height(pag_composition* composition) {
+ auto p = ToPAGComposition(composition);
+ if (p == nullptr) {
+ return 0;
+ }
+ return p->height();
+}
+
+pag_layer** pag_composition_get_layers_by_name(pag_composition* composition, const char* layerName,
+ size_t* count) {
+ auto p = ToPAGComposition(composition);
+ if (p == nullptr) {
+ return nullptr;
+ }
+ auto pagLayers = p->getLayersByName(layerName);
+ if (pagLayers.empty()) {
+ return nullptr;
+ }
+ auto** layers = static_cast(malloc(sizeof(pag_layer*) * pagLayers.size()));
+ if (layers == nullptr) {
+ return nullptr;
+ }
+ for (size_t i = 0; i < pagLayers.size(); ++i) {
+ layers[i] = new pag_layer(std::move(pagLayers[i]));
+ }
+ *count = pagLayers.size();
+ return layers;
+}
+
+static void PAGCompositionFindLayers(const std::function& filterFunc,
+ std::vector>* result,
+ std::shared_ptr pagLayer) {
+ if (filterFunc(pagLayer.get())) {
+ result->push_back(pagLayer);
+ }
+ if (pagLayer->trackMatteLayer()) {
+ PAGCompositionFindLayers(filterFunc, result, pagLayer->trackMatteLayer());
+ }
+ if (pagLayer->layerType() == pag::LayerType::PreCompose) {
+ auto* composition = static_cast(pagLayer.get());
+ auto count = composition->numChildren();
+ for (int i = 0; i < count; ++i) {
+ auto childLayer = composition->getLayerAt(i);
+ PAGCompositionFindLayers(filterFunc, result, childLayer);
+ }
+ }
+}
+
+static std::vector> PAGCompositionGetLayersBy(
+ const std::function& filterFunc,
+ std::shared_ptr pagLayer) {
+ std::vector> result = {};
+ PAGCompositionFindLayers(filterFunc, &result, pagLayer);
+ return result;
+}
+
+pag_layer** pag_composition_get_layers_by_type(pag_composition* composition,
+ pag_layer_type layerType, size_t* count) {
+ auto p = ToPAGComposition(composition);
+ if (p == nullptr) {
+ return nullptr;
+ }
+
+ pag::LayerType pagLayerType;
+ FromCLayerType(layerType, &pagLayerType);
+
+ auto pagLayers = PAGCompositionGetLayersBy(
+ [=](pag::PAGLayer* pagLayer) -> bool { return pagLayer->layerType() == pagLayerType; }, p);
+ if (pagLayers.empty()) {
+ return nullptr;
+ }
+ auto** layers = static_cast(malloc(sizeof(pag_layer*) * pagLayers.size()));
+ if (layers == nullptr) {
+ return nullptr;
+ }
+ for (size_t i = 0; i < pagLayers.size(); ++i) {
+ layers[i] = new pag_layer(std::move(pagLayers[i]));
+ }
+ *count = pagLayers.size();
+ return layers;
+}
diff --git a/src/c/pag_decoder.cpp b/src/c/pag_decoder.cpp
new file mode 100644
index 0000000000..12cf3fbcce
--- /dev/null
+++ b/src/c/pag_decoder.cpp
@@ -0,0 +1,93 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_decoder.h"
+#include "pag_types_priv.h"
+
+pag_decoder* pag_decoder_create(pag_composition* composition, float maxFrameRate, float scale) {
+ if (composition == nullptr) {
+ return nullptr;
+ }
+ if (auto pagComposition = ToPAGComposition(composition)) {
+ if (auto decoder = pag::PAGDecoder::MakeFrom(pagComposition, maxFrameRate, scale)) {
+ return new pag_decoder(std::move(decoder));
+ }
+ }
+ return nullptr;
+}
+
+int pag_decoder_get_width(pag_decoder* decoder) {
+ if (decoder == nullptr) {
+ return 0;
+ }
+ return decoder->p->width();
+}
+
+int pag_decoder_get_height(pag_decoder* decoder) {
+ if (decoder == nullptr) {
+ return 0;
+ }
+ return decoder->p->height();
+}
+
+int pag_decoder_get_num_frames(pag_decoder* decoder) {
+ if (decoder == nullptr) {
+ return 0;
+ }
+ return decoder->p->numFrames();
+}
+
+float pag_decoder_get_frame_rate(pag_decoder* decoder) {
+ if (decoder == nullptr) {
+ return 0.0f;
+ }
+ return decoder->p->frameRate();
+}
+
+bool pag_decoder_check_frame_changed(pag_decoder* decoder, int index) {
+ if (decoder == nullptr) {
+ return false;
+ }
+ return decoder->p->checkFrameChanged(index);
+}
+
+bool pag_decoder_read_frame(pag_decoder* decoder, int index, void* pixels, size_t rowBytes,
+ pag_color_type colorType, pag_alpha_type alphaType) {
+ if (decoder == nullptr) {
+ return false;
+ }
+ pag::ColorType color;
+ if (!FromCColorType(colorType, &color)) {
+ return false;
+ }
+ pag::AlphaType alpha;
+ if (!FromCAlphaType(alphaType, &alpha)) {
+ return false;
+ }
+ return decoder->p->readFrame(index, pixels, rowBytes, color, alpha);
+}
+
+bool pag_decoder_read_frame_to_hardware_buffer(pag_decoder* decoder, int index, void* buffer) {
+ if (decoder == nullptr) {
+ return false;
+ }
+ if (buffer == nullptr) {
+ return false;
+ }
+ return decoder->p->readFrame(index, static_cast(buffer));
+}
diff --git a/tgfx/src/platform/web/WebCodec.cpp b/src/c/pag_disk_cache.cpp
similarity index 74%
rename from tgfx/src/platform/web/WebCodec.cpp
rename to src/c/pag_disk_cache.cpp
index 317b6f9b43..e3276ed6b7 100644
--- a/tgfx/src/platform/web/WebCodec.cpp
+++ b/src/c/pag_disk_cache.cpp
@@ -16,17 +16,17 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////
-#include "tgfx/platform/web/WebCodec.h"
-#include
+#include "pag/c/pag_disk_cache.h"
+#include "pag/pag.h"
-namespace tgfx {
-static std::atomic_bool AsyncSupportEnabled = false;
+size_t pag_disk_cache_get_max_disk_size() {
+ return pag::PAGDiskCache::MaxDiskSize();
+}
-bool WebCodec::AsyncSupport() {
- return AsyncSupportEnabled;
+void pag_disk_cache_set_max_disk_size(size_t maxDiskSize) {
+ pag::PAGDiskCache::SetMaxDiskSize(maxDiskSize);
}
-void WebCodec::SetAsyncSupport(bool enabled) {
- AsyncSupportEnabled = enabled;
+void pag_disk_cache_remove_all() {
+ pag::PAGDiskCache::RemoveAll();
}
-} // namespace tgfx
\ No newline at end of file
diff --git a/src/c/pag_file.cpp b/src/c/pag_file.cpp
new file mode 100644
index 0000000000..78306108d9
--- /dev/null
+++ b/src/c/pag_file.cpp
@@ -0,0 +1,170 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_file.h"
+#include "pag_types_priv.h"
+
+pag_file* pag_file_load(const void* bytes, size_t length, const char* filePath,
+ const char* password) {
+ std::string path(filePath);
+ std::string pwd(password);
+ if (auto file = pag::PAGFile::Load(bytes, length, path, pwd)) {
+ return new pag_file(std::move(file));
+ }
+ return nullptr;
+}
+
+void pag_file_set_duration(pag_file* file, int64_t duration) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return;
+ }
+ pagFile->setDuration(duration);
+}
+
+int pag_file_get_num_texts(pag_file* file) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return 0;
+ }
+ return pagFile->numTexts();
+}
+
+int pag_file_get_num_images(pag_file* file) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return 0;
+ }
+ return pagFile->numImages();
+}
+
+int pag_file_get_num_videos(pag_file* file) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return 0;
+ }
+ return pagFile->numVideos();
+}
+
+pag_time_stretch_mode pag_file_get_time_stretch_mode(pag_file* file) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return pag_time_stretch_mode_none;
+ }
+ pag_time_stretch_mode mode;
+ if (ToCTimeStretchMode(pagFile->timeStretchMode(), &mode)) {
+ return mode;
+ }
+ return pag_time_stretch_mode_none;
+}
+
+void pag_file_set_time_stretch_mode(pag_file* file, pag_time_stretch_mode mode) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return;
+ }
+ pag::Enum pagMode;
+ if (FromCTimeStretchMode(mode, &pagMode)) {
+ pagFile->setTimeStretchMode(pagMode);
+ }
+}
+
+pag_text_document* pag_file_get_text_data(pag_file* file, int editableTextIndex) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return nullptr;
+ }
+ if (auto text = pagFile->getTextData(editableTextIndex)) {
+ return new pag_text_document(std::move(text));
+ }
+ return nullptr;
+}
+
+void pag_file_replace_text(pag_file* file, int editableTextIndex, pag_text_document* text) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return;
+ }
+ if (text) {
+ pagFile->replaceText(editableTextIndex, text->p);
+ } else {
+ pagFile->replaceText(editableTextIndex, nullptr);
+ }
+}
+
+void pag_file_replace_image(pag_file* file, int editableImageIndex, pag_image* image) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return;
+ }
+ if (image) {
+ pagFile->replaceImage(editableImageIndex, image->p);
+ } else {
+ pagFile->replaceImage(editableImageIndex, nullptr);
+ }
+}
+
+pag_layer** pag_file_get_layers_by_editable_index(pag_file* file, int editableIndex,
+ pag_layer_type layerType, size_t* numLayers) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return nullptr;
+ }
+
+ pag::LayerType pagLayerType;
+ FromCLayerType(layerType, &pagLayerType);
+
+ auto pagLayers = pagFile->getLayersByEditableIndex(editableIndex, pagLayerType);
+ if (pagLayers.empty()) {
+ return nullptr;
+ }
+ auto** layers = static_cast(malloc(sizeof(pag_layer*) * pagLayers.size()));
+ if (layers == nullptr) {
+ return nullptr;
+ }
+ for (size_t i = 0; i < pagLayers.size(); ++i) {
+ layers[i] = new pag_layer(std::move(pagLayers[i]));
+ }
+ *numLayers = pagLayers.size();
+ return layers;
+}
+
+PAG_API int* pag_file_get_editable_indices(pag_file* file, pag_layer_type layerType,
+ size_t* numIndexes) {
+ auto pagFile = ToPAGFile(file);
+ if (pagFile == nullptr) {
+ return nullptr;
+ }
+
+ pag::LayerType pagLayerType;
+ FromCLayerType(layerType, &pagLayerType);
+
+ auto indexes = pagFile->getEditableIndices(pagLayerType);
+ if (indexes.empty()) {
+ return nullptr;
+ }
+ int* editableIndexes = static_cast(malloc(sizeof(int) * indexes.size()));
+ if (editableIndexes == nullptr) {
+ return nullptr;
+ }
+ for (size_t i = 0; i < indexes.size(); ++i) {
+ editableIndexes[i] = indexes[i];
+ }
+ *numIndexes = indexes.size();
+ return editableIndexes;
+}
diff --git a/src/c/pag_font.cpp b/src/c/pag_font.cpp
new file mode 100644
index 0000000000..dbb5f22c87
--- /dev/null
+++ b/src/c/pag_font.cpp
@@ -0,0 +1,53 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_font.h"
+#include "pag_types_priv.h"
+
+pag_font* pag_font_register_from_path(const char* filePath, int ttcIndex, const char* fontFamily,
+ const char* fontStyle) {
+ std::string path(filePath);
+ std::string family(fontFamily);
+ std::string style(fontStyle);
+ return new pag_font(pag::PAGFont::RegisterFont(path, ttcIndex, family, style));
+}
+
+pag_font* pag_font_register_from_data(const void* data, size_t length, int ttcIndex,
+ const char* fontFamily, const char* fontStyle) {
+ std::string family(fontFamily);
+ std::string style(fontStyle);
+ return new pag_font(pag::PAGFont::RegisterFont(data, length, ttcIndex, family, style));
+}
+
+const char* pag_font_get_family(pag_font* font) {
+ if (font == nullptr || font->p.fontFamily.empty()) {
+ return nullptr;
+ }
+ return font->p.fontFamily.c_str();
+}
+
+const char* pag_font_get_style(pag_font* font) {
+ if (font == nullptr || font->p.fontStyle.empty()) {
+ return nullptr;
+ }
+ return font->p.fontStyle.c_str();
+}
+
+void PAGFontRelease(pag_font* font) {
+ delete font;
+}
diff --git a/src/c/pag_image.cpp b/src/c/pag_image.cpp
new file mode 100644
index 0000000000..6a6ac5c771
--- /dev/null
+++ b/src/c/pag_image.cpp
@@ -0,0 +1,66 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_image.h"
+#include "pag_types_priv.h"
+#include "rendering/editing/StillImage.h"
+#include "tgfx/core/Image.h"
+
+pag_image* pag_image_from_pixels(const void* pixels, int width, int height, size_t rowBytes,
+ pag_color_type colorType, pag_alpha_type alphaType) {
+ pag::ColorType color;
+ if (!FromCColorType(colorType, &color)) {
+ return nullptr;
+ }
+ pag::AlphaType alpha;
+ if (!FromCAlphaType(alphaType, &alpha)) {
+ return nullptr;
+ }
+ if (auto image = pag::PAGImage::FromPixels(pixels, width, height, rowBytes, color, alpha)) {
+ return new pag_image(std::move(image));
+ }
+ return nullptr;
+}
+
+pag_image* pag_image_from_hardware_buffer(void* buffer) {
+ if (buffer == nullptr) {
+ return nullptr;
+ }
+ if (auto image = pag::StillImage::MakeFrom(
+ tgfx::Image::MakeFrom(static_cast(buffer)))) {
+ return new pag_image(std::move(image));
+ }
+ return nullptr;
+}
+
+pag_image* pag_image_from_backend_texture(pag_backend_texture* texture) {
+ if (texture == nullptr) {
+ return nullptr;
+ }
+ if (auto image = pag::PAGImage::FromTexture(texture->p, pag::ImageOrigin::TopLeft)) {
+ return new pag_image(std::move(image));
+ }
+ return nullptr;
+}
+
+void pag_image_set_scale_mode(pag_image* image, pag_scale_mode mode) {
+ if (image == nullptr) {
+ return;
+ }
+ image->p->setScaleMode(static_cast(mode));
+}
diff --git a/src/c/pag_image_layer.cpp b/src/c/pag_image_layer.cpp
new file mode 100644
index 0000000000..6a1dd17335
--- /dev/null
+++ b/src/c/pag_image_layer.cpp
@@ -0,0 +1,50 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_image_layer.h"
+#include "pag/c/pag_image.h"
+#include "pag_types_priv.h"
+#include "tgfx/core/ImageCodec.h"
+#include "tgfx/core/ImageInfo.h"
+
+uint8_t* pag_image_layer_get_image_rgba_data(pag_layer* imageLayer, size_t* count, size_t* width,
+ size_t* height) {
+ if (imageLayer == nullptr) {
+ return nullptr;
+ }
+ std::shared_ptr imgLayer =
+ std::static_pointer_cast(imageLayer->p);
+ if (!imgLayer) {
+ return nullptr;
+ }
+ pag::ByteData* imageBytes = imgLayer->imageBytes();
+ auto data = tgfx::Data::MakeWithoutCopy(imageBytes->data(), imageBytes->length());
+ std::shared_ptr webp = tgfx::ImageCodec::MakeFrom(data);
+ auto info = tgfx::ImageInfo::Make(webp->width(), webp->height(), tgfx::ColorType::RGBA_8888,
+ tgfx::AlphaType::Premultiplied);
+ *count = 4 * webp->width() * webp->height();
+ *width = webp->width();
+ *height = webp->height();
+ auto rgbaData = new uint8_t[*count];
+ auto success = webp->readPixels(info, rgbaData);
+ if (success) {
+ return rgbaData;
+ } else {
+ return nullptr;
+ }
+}
diff --git a/src/c/pag_layer.cpp b/src/c/pag_layer.cpp
new file mode 100644
index 0000000000..aeacf31efc
--- /dev/null
+++ b/src/c/pag_layer.cpp
@@ -0,0 +1,71 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_layer.h"
+#include "pag_types_priv.h"
+
+PAG_API pag_layer_type pag_layer_get_layer_type(pag_layer* layer) {
+ if (layer == nullptr) {
+ return pag_layer_type_unknown;
+ }
+ pag_layer_type type = pag_layer_type_unknown;
+ if (TocLayerType(layer->p->layerType(), &type)) {
+ return type;
+ }
+ return pag_layer_type_unknown;
+}
+
+const char* pag_layer_get_layer_name(pag_layer* layer) {
+ if (layer == nullptr) {
+ return nullptr;
+ }
+ auto layerName = layer->p->layerName();
+ auto length = layerName.length();
+ auto name = malloc(sizeof(char) * (length + 1));
+ memset(name, 0, length + 1);
+ memcpy(name, layerName.c_str(), length);
+ return static_cast(name);
+}
+
+int64_t pag_layer_get_duration(pag_layer* layer) {
+ if (layer == nullptr) {
+ return 0;
+ }
+ return layer->p->duration();
+}
+
+float pag_layer_get_frame_rate(pag_layer* layer) {
+ if (layer == nullptr) {
+ return 0;
+ }
+ return layer->p->frameRate();
+}
+
+float pag_layer_get_alpha(pag_layer* layer) {
+ if (layer == nullptr) {
+ return 1.0f;
+ }
+ return layer->p->alpha();
+}
+
+void pag_layer_set_alpha(pag_layer* layer, float alpha) {
+ if (layer == nullptr) {
+ return;
+ }
+ layer->p->setAlpha(alpha);
+}
diff --git a/src/c/pag_player.cpp b/src/c/pag_player.cpp
new file mode 100644
index 0000000000..41e870007e
--- /dev/null
+++ b/src/c/pag_player.cpp
@@ -0,0 +1,137 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_player.h"
+#include "pag_types_priv.h"
+
+pag_player* pag_player_create() {
+ return new pag_player(std::make_shared());
+}
+
+void PAGPlayerRelease(pag_player* player) {
+ delete player;
+}
+
+void pag_player_set_composition(pag_player* player, pag_composition* composition) {
+ if (player == nullptr) {
+ return;
+ }
+ if (auto pagComposition = ToPAGComposition(composition)) {
+ player->p->setComposition(pagComposition);
+ } else {
+ player->p->setComposition(nullptr);
+ }
+}
+
+void pag_player_set_surface(pag_player* player, pag_surface* surface) {
+ if (player == nullptr) {
+ return;
+ }
+ if (surface) {
+ player->p->setSurface(surface->p);
+ } else {
+ player->p->setSurface(nullptr);
+ }
+}
+
+bool pag_player_get_cache_enable(pag_player* player) {
+ if (player == nullptr) {
+ return false;
+ }
+ return player->p->cacheEnabled();
+}
+
+void pag_player_set_cache_enable(pag_player* player, bool cacheEnable) {
+ if (player == nullptr) {
+ return;
+ }
+ player->p->setCacheEnabled(cacheEnable);
+}
+
+double pag_player_get_progress(pag_player* player) {
+ if (player == nullptr) {
+ return 0.0;
+ }
+ return player->p->getProgress();
+}
+
+void pag_player_set_progress(pag_player* player, double progress) {
+ if (player == nullptr) {
+ return;
+ }
+ player->p->setProgress(progress);
+}
+
+bool pag_player_wait(pag_player* player, pag_backend_semaphore* semaphore) {
+ if (player == nullptr || semaphore == nullptr) {
+ return false;
+ }
+ return player->p->wait(semaphore->p);
+}
+
+bool pag_player_flush(pag_player* player) {
+ if (player == nullptr) {
+ return false;
+ }
+ return player->p->flush();
+}
+
+bool pag_player_flush_and_signal_semaphore(pag_player* player, pag_backend_semaphore* semaphore) {
+ if (player == nullptr) {
+ return false;
+ }
+ if (semaphore == nullptr) {
+ return player->p->flush();
+ }
+ return player->p->flushAndSignalSemaphore(&semaphore->p);
+}
+
+pag_scale_mode pag_player_get_scale_mode(pag_player* player) {
+ if (player == nullptr) {
+ return pag_scale_mode_none;
+ }
+ pag_scale_mode scaleMode;
+ if (ToCScaleMode(player->p->scaleMode(), &scaleMode)) {
+ return scaleMode;
+ }
+ return pag_scale_mode_none;
+}
+
+void pag_player_set_scale_mode(pag_player* player, pag_scale_mode scaleMode) {
+ if (player == nullptr) {
+ return;
+ }
+ pag::Enum pagScaleMode;
+ if (FromCScaleMode(scaleMode, &pagScaleMode)) {
+ player->p->setScaleMode(pagScaleMode);
+ }
+}
+
+int64_t pag_player_get_duration(pag_player* player) {
+ if (player == nullptr) {
+ return 0;
+ }
+ return player->p->duration();
+}
+
+int64_t pag_player_get_graphics_memory(pag_player* player) {
+ if (player == nullptr) {
+ return 0;
+ }
+ return player->p->graphicsMemory();
+}
diff --git a/tgfx/src/platform/android/JNIInit.cpp b/src/c/pag_solid_layer.cpp
similarity index 62%
rename from tgfx/src/platform/android/JNIInit.cpp
rename to src/c/pag_solid_layer.cpp
index b9ae3a3d8c..f8cafb1c9e 100644
--- a/tgfx/src/platform/android/JNIInit.cpp
+++ b/src/c/pag_solid_layer.cpp
@@ -16,26 +16,21 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////
-#include "JNIInit.h"
-#include "HandlerThread.h"
-#include "NativeCodec.h"
-#include "platform/android/SurfaceTexture.h"
+#include "pag/c/pag_solid_layer.h"
+#include "pag_types_priv.h"
-namespace tgfx {
-void JNIInit::Run() {
- static bool initialized = false;
- if (initialized) {
- return;
+pag_color pag_solid_layer_get_solid_color(pag_solid_layer* layer) {
+ if (layer == nullptr) {
+ return {0, 0, 0};
}
- JNIEnvironment environment;
- auto env = environment.current();
- if (env == nullptr) {
+ auto color = std::static_pointer_cast(layer->p)->solidColor();
+ return pag_color{color.red, color.green, color.blue};
+}
+
+void pag_solid_layer_set_solid_color(pag_solid_layer* layer, pag_color color) {
+ if (layer == nullptr) {
return;
}
- initialized = true;
- NativeCodec::JNIInit(env);
- HandlerThread::JNIInit(env);
- SurfaceTexture::JNIInit(env);
- env->ExceptionClear();
+ auto c = pag::Color{color.red, color.green, color.blue};
+ std::static_pointer_cast(layer->p)->setSolidColor(c);
}
-} // namespace tgfx
diff --git a/tgfx/src/images/TextureSource.cpp b/src/c/pag_surface.cpp
similarity index 56%
rename from tgfx/src/images/TextureSource.cpp
rename to src/c/pag_surface.cpp
index ff5a33d88e..4a34c4db4d 100644
--- a/tgfx/src/images/TextureSource.cpp
+++ b/src/c/pag_surface.cpp
@@ -16,27 +16,28 @@
//
/////////////////////////////////////////////////////////////////////////////////////////////////
-#include "TextureSource.h"
+#include "pag/c/pag_surface.h"
+#include "pag_types_priv.h"
-namespace tgfx {
-BackendTexture TextureSource::getBackendTexture() const {
- if (!texture->hasUniqueKey(uniqueKey)) {
- return {};
- }
- return texture->getBackendTexture();
-}
-
-std::shared_ptr TextureSource::makeTextureSource(Context* context) const {
- if (texture->getContext() == context && texture->hasUniqueKey(uniqueKey)) {
- return std::static_pointer_cast(weakThis.lock());
+pag_surface* pag_surface_make_offscreen(int width, int height) {
+ if (auto surface = pag::PAGSurface::MakeOffscreen(width, height)) {
+ return new pag_surface(std::move(surface));
}
return nullptr;
}
-std::shared_ptr TextureSource::onMakeTextureProxy(Context* context, uint32_t) const {
- if (!texture->hasUniqueKey(uniqueKey)) {
- return {};
+bool pag_surface_read_pixels(pag_surface* surface, pag_color_type colorType,
+ pag_alpha_type alphaType, void* dstPixels, size_t dstRowBytes) {
+ if (surface == nullptr) {
+ return false;
+ }
+ pag::ColorType pagColorType;
+ if (!FromCColorType(colorType, &pagColorType)) {
+ return false;
+ }
+ pag::AlphaType pagAlphaType;
+ if (!FromCAlphaType(alphaType, &pagAlphaType)) {
+ return false;
}
- return context->proxyProvider()->wrapTexture(texture);
+ return surface->p->readPixels(pagColorType, pagAlphaType, dstPixels, dstRowBytes);
}
-} // namespace tgfx
\ No newline at end of file
diff --git a/src/c/pag_text_document.cpp b/src/c/pag_text_document.cpp
new file mode 100644
index 0000000000..9e5e866d7a
--- /dev/null
+++ b/src/c/pag_text_document.cpp
@@ -0,0 +1,350 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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/c/pag_text_document.h"
+#include "pag_types_priv.h"
+
+bool pag_text_document_get_apply_fill(pag_text_document* document) {
+ if (document == nullptr) {
+ return false;
+ }
+ return document->p->applyFill;
+}
+
+void pag_text_document_set_apply_fill(pag_text_document* document, bool applyFill) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->applyFill = applyFill;
+}
+
+bool pag_text_document_get_apply_stroke(pag_text_document* document) {
+ if (document == nullptr) {
+ return false;
+ }
+ return document->p->applyStroke;
+}
+
+void pag_text_document_set_apply_stroke(pag_text_document* document, bool applyStroke) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->applyStroke = applyStroke;
+}
+
+float pag_text_document_get_baseline_shift(pag_text_document* document) {
+ if (document == nullptr) {
+ return 0.0f;
+ }
+ return document->p->baselineShift;
+}
+
+void pag_text_document_set_baseline_shift(pag_text_document* document, float baselineShift) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->baselineShift = baselineShift;
+}
+
+bool pag_text_document_get_box_text(pag_text_document* document) {
+ if (document == nullptr) {
+ return false;
+ }
+ return document->p->boxText;
+}
+
+void pag_text_document_set_box_text(pag_text_document* document, bool boxText) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->boxText = boxText;
+}
+
+pag_point pag_text_document_get_box_text_pos(pag_text_document* document) {
+ if (document == nullptr) {
+ return {0.0f, 0.0f};
+ }
+ auto point = document->p->boxTextPos;
+ return pag_point{point.x, point.y};
+}
+
+void pag_text_document_set_box_text_pos(pag_text_document* document, pag_point boxTextPos) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->boxTextPos.x = boxTextPos.x;
+ document->p->boxTextPos.y = boxTextPos.y;
+}
+
+pag_point pag_text_document_get_box_text_size(pag_text_document* document) {
+ if (document == nullptr) {
+ return {0.0f, 0.0f};
+ }
+ auto point = document->p->boxTextSize;
+ return pag_point{point.x, point.y};
+}
+
+void pag_text_document_set_box_text_size(pag_text_document* document, pag_point boxTextSize) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->boxTextSize.x = boxTextSize.x;
+ document->p->boxTextSize.y = boxTextSize.y;
+}
+
+float pag_text_document_get_first_baseline(pag_text_document* document) {
+ if (document == nullptr) {
+ return 0.0f;
+ }
+ return document->p->firstBaseLine;
+}
+
+void pag_text_document_set_first_baseline(pag_text_document* document, float firstBaseline) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->firstBaseLine = firstBaseline;
+}
+
+bool pag_text_document_get_faux_bold(pag_text_document* document) {
+ if (document == nullptr) {
+ return false;
+ }
+ return document->p->fauxBold;
+}
+
+void pag_text_document_set_faux_bold(pag_text_document* document, bool fauxBold) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->fauxBold = fauxBold;
+}
+
+bool pag_text_document_get_faux_italic(pag_text_document* document) {
+ if (document == nullptr) {
+ return false;
+ }
+ return document->p->fauxItalic;
+}
+
+void pag_text_document_set_faux_italic(pag_text_document* document, bool fauxItalic) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->fauxItalic = fauxItalic;
+}
+
+pag_color pag_text_document_get_fill_color(pag_text_document* document) {
+ if (document == nullptr) {
+ return {0, 0, 0};
+ }
+ auto color = document->p->fillColor;
+ return pag_color{color.red, color.green, color.blue};
+}
+
+void pag_text_document_set_fill_color(pag_text_document* document, pag_color fillColor) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->fillColor.red = fillColor.red;
+ document->p->fillColor.green = fillColor.green;
+ document->p->fillColor.blue = fillColor.blue;
+}
+
+const char* pag_text_document_get_font_family(pag_text_document* document) {
+ if (document == nullptr) {
+ return nullptr;
+ }
+ return document->p->fontFamily.c_str();
+}
+
+void pag_text_document_set_font_family(pag_text_document* document, const char* fontFamily) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->fontFamily = fontFamily;
+}
+
+const char* pag_text_document_get_font_style(pag_text_document* document) {
+ if (document == nullptr) {
+ return nullptr;
+ }
+ return document->p->fontStyle.c_str();
+}
+
+void pag_text_document_set_font_style(pag_text_document* document, const char* fontStyle) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->fontStyle = fontStyle;
+}
+
+float pag_text_document_get_font_size(pag_text_document* document) {
+ if (document == nullptr) {
+ return 0.0f;
+ }
+ return document->p->fontSize;
+}
+
+void pag_text_document_set_font_size(pag_text_document* document, float fontSize) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->fontSize = fontSize;
+}
+
+pag_color pag_text_document_get_stroke_color(pag_text_document* document) {
+ if (document == nullptr) {
+ return {0, 0, 0};
+ }
+ auto color = document->p->strokeColor;
+ return pag_color{color.red, color.green, color.blue};
+}
+
+void pag_text_document_set_stroke_color(pag_text_document* document, pag_color strokeColor) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->strokeColor.red = strokeColor.red;
+ document->p->strokeColor.green = strokeColor.green;
+ document->p->strokeColor.blue = strokeColor.blue;
+}
+
+bool pag_text_document_get_stroke_over_fill(pag_text_document* document) {
+ if (document == nullptr) {
+ return false;
+ }
+ return document->p->strokeOverFill;
+}
+
+void pag_text_document_set_stroke_over_fill(pag_text_document* document, bool strokeOverFill) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->strokeOverFill = strokeOverFill;
+}
+
+float pag_text_document_get_stroke_width(pag_text_document* document) {
+ if (document == nullptr) {
+ return 0.0f;
+ }
+ return document->p->strokeWidth;
+}
+
+void pag_text_document_set_stroke_width(pag_text_document* document, float strokeWidth) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->strokeWidth = strokeWidth;
+}
+
+const char* pag_text_document_get_text(pag_text_document* document) {
+ if (document == nullptr) {
+ return nullptr;
+ }
+ return document->p->text.c_str();
+}
+
+void pag_text_document_set_text(pag_text_document* document, const char* text) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->text = text;
+}
+
+pag_paragraph_justification pag_text_document_get_justification(pag_text_document* document) {
+ if (document == nullptr) {
+ return pag_paragraph_justification_left_justify;
+ }
+ pag_paragraph_justification justification;
+ if (ToCParagraphJustification(document->p->justification, &justification)) {
+ return justification;
+ }
+ return pag_paragraph_justification_left_justify;
+}
+
+void pag_text_document_set_justification(pag_text_document* document,
+ pag_paragraph_justification justification) {
+ if (document == nullptr) {
+ return;
+ }
+ pag::Enum pagJustification;
+ if (FromCParagraphJustification(justification, &pagJustification)) {
+ document->p->justification = pagJustification;
+ }
+}
+
+float pag_text_document_get_leading(pag_text_document* document) {
+ if (document == nullptr) {
+ return 0.0f;
+ }
+ return document->p->leading;
+}
+
+void pag_text_document_set_leading(pag_text_document* document, float leading) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->leading = leading;
+}
+
+float pag_text_document_get_tracking(pag_text_document* document) {
+ if (document == nullptr) {
+ return 0.0f;
+ }
+ return document->p->tracking;
+}
+
+void pag_text_document_set_tracking(pag_text_document* document, float tracking) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->tracking = tracking;
+}
+
+pag_color pag_text_document_get_background_color(pag_text_document* document) {
+ if (document == nullptr) {
+ return {0, 0, 0};
+ }
+ auto color = document->p->backgroundColor;
+ return pag_color{color.red, color.green, color.blue};
+}
+
+void pag_text_document_set_background_color(pag_text_document* document,
+ pag_color backgroundColor) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->backgroundColor.red = backgroundColor.red;
+ document->p->backgroundColor.green = backgroundColor.green;
+ document->p->backgroundColor.blue = backgroundColor.blue;
+}
+
+uint8_t pag_text_document_get_background_alpha(pag_text_document* document) {
+ if (document == nullptr) {
+ return 0;
+ }
+ return document->p->backgroundAlpha;
+}
+
+void pag_text_document_set_background_alpha(pag_text_document* document, uint8_t backgroundAlpha) {
+ if (document == nullptr) {
+ return;
+ }
+ document->p->backgroundAlpha = backgroundAlpha;
+}
diff --git a/src/c/pag_types.cpp b/src/c/pag_types.cpp
new file mode 100644
index 0000000000..6a0fb0ac22
--- /dev/null
+++ b/src/c/pag_types.cpp
@@ -0,0 +1,304 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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_types_priv.h"
+
+static void DeletePAGByteData(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGTextDocument(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGLayer(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGPlayer(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGSurface(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGImage(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGFont(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGBackendTexture(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGBackendSemaphore(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGDecoder(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void DeletePAGAnimator(const void* pointer) {
+ delete reinterpret_cast(pointer);
+}
+
+static void (*DeleteFunctions[])(const void*) = {
+ DeletePAGByteData, DeletePAGTextDocument, DeletePAGLayer, DeletePAGPlayer,
+ DeletePAGSurface, DeletePAGImage, DeletePAGFont, DeletePAGBackendTexture,
+ DeletePAGBackendSemaphore, DeletePAGDecoder, DeletePAGAnimator};
+
+void pag_release(pag_object object) {
+ if (object == nullptr) {
+ return;
+ }
+ auto type = *reinterpret_cast(object);
+ if (type == PAGObjectType::Unknown || type >= PAGObjectType::Count) {
+ return;
+ }
+ DeleteFunctions[static_cast(type) - 1](object);
+}
+
+namespace pag {
+BackendTexture PAGSurfaceExt::getFrontTexture() {
+ return surface->getFrontTexture();
+}
+BackendTexture PAGSurfaceExt::getBackTexture() {
+ return surface->getBackTexture();
+}
+HardwareBufferRef PAGSurfaceExt::getFrontHardwareBuffer() {
+ return surface->getFrontHardwareBuffer();
+}
+HardwareBufferRef PAGSurfaceExt::getBackHardwareBuffer() {
+ return surface->getBackHardwareBuffer();
+}
+} // namespace pag
+
+std::shared_ptr ToPAGComposition(pag_composition* composition) {
+ if (composition == nullptr) {
+ return nullptr;
+ }
+ return std::static_pointer_cast(composition->p);
+}
+
+std::shared_ptr ToPAGFile(pag_file* file) {
+ if (file == nullptr || !file->p->isPAGFile()) {
+ return nullptr;
+ }
+ return std::static_pointer_cast(file->p);
+}
+const struct {
+ pag_time_stretch_mode C;
+ pag::Enum Pag;
+} gTimeStretchPairs[] = {
+ {pag_time_stretch_mode_none, pag::PAGTimeStretchMode::None},
+ {pag_time_stretch_mode_scale, pag::PAGTimeStretchMode::Scale},
+ {pag_time_stretch_mode_repeat_inverted, pag::PAGTimeStretchMode::Repeat},
+ {pag_time_stretch_mode_repeat_inverted, pag::PAGTimeStretchMode::RepeatInverted},
+};
+
+bool FromCTimeStretchMode(pag_time_stretch_mode cTimeStretchMode, pag::Enum* timeStretchMode) {
+ for (auto& pair : gTimeStretchPairs) {
+ if (pair.C == cTimeStretchMode) {
+ *timeStretchMode = pair.Pag;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ToCTimeStretchMode(pag::Enum timeStretchMode, pag_time_stretch_mode* cTimeStretchMode) {
+ for (auto& pair : gTimeStretchPairs) {
+ if (pair.Pag == timeStretchMode) {
+ *cTimeStretchMode = pair.C;
+ return true;
+ }
+ }
+ return false;
+}
+
+const struct {
+ pag_color_type C;
+ pag::ColorType Pag;
+} gColorTypePairs[] = {
+ {pag_color_type_unknown, pag::ColorType::Unknown},
+ {pag_color_type_alpha_8, pag::ColorType::ALPHA_8},
+ {pag_color_type_rgba_8888, pag::ColorType::RGBA_8888},
+ {pag_color_type_bgra_8888, pag::ColorType::BGRA_8888},
+ {pag_color_type_rgb_565, pag::ColorType::RGB_565},
+ {pag_color_type_gray_8, pag::ColorType::Gray_8},
+ {pag_color_type_rgba_f16, pag::ColorType::RGBA_F16},
+ {pag_color_type_rgba_101012, pag::ColorType::RGBA_1010102},
+};
+
+bool FromCColorType(pag_color_type cColorType, pag::ColorType* colorType) {
+ for (auto& pair : gColorTypePairs) {
+ if (pair.C == cColorType) {
+ *colorType = pair.Pag;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ToCColorType(pag::ColorType colorType, pag_color_type* cColorType) {
+ for (auto& pair : gColorTypePairs) {
+ if (pair.Pag == colorType) {
+ *cColorType = pair.C;
+ return true;
+ }
+ }
+ return false;
+}
+
+const struct {
+ pag_alpha_type C;
+ pag::AlphaType Pag;
+} gAlphaTypePairs[] = {
+ {pag_alpha_type_unknown, pag::AlphaType::Unknown},
+ {pag_alpha_type_opaque, pag::AlphaType::Opaque},
+ {pag_alpha_type_premultiplied, pag::AlphaType::Premultiplied},
+ {pag_alpha_type_unpremultiplied, pag::AlphaType::Unpremultiplied},
+};
+
+bool FromCAlphaType(pag_alpha_type cAlphaType, pag::AlphaType* alphaType) {
+ for (auto& pair : gAlphaTypePairs) {
+ if (pair.C == cAlphaType) {
+ *alphaType = pair.Pag;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ToCAlphaType(pag::AlphaType alphaType, pag_alpha_type* cAlphaType) {
+ for (auto& pair : gAlphaTypePairs) {
+ if (pair.Pag == alphaType) {
+ *cAlphaType = pair.C;
+ return true;
+ }
+ }
+ return false;
+}
+
+const struct {
+ pag_scale_mode C;
+ pag::Enum Pag;
+} gScaleModePairs[] = {
+ {pag_scale_mode_none, pag::PAGScaleMode::None},
+ {pag_scale_mode_stretch, pag::PAGScaleMode::Stretch},
+ {pag_scale_mode_letter_box, pag::PAGScaleMode::LetterBox},
+ {pag_scale_mode_zoom, pag::PAGScaleMode::Zoom},
+};
+
+bool FromCScaleMode(pag_scale_mode cScaleMode, pag::Enum* scaleMode) {
+ for (auto& pair : gScaleModePairs) {
+ if (pair.C == cScaleMode) {
+ *scaleMode = pair.Pag;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ToCScaleMode(pag::Enum scaleMode, pag_scale_mode* cScaleMode) {
+ for (auto& pair : gScaleModePairs) {
+ if (pair.Pag == scaleMode) {
+ *cScaleMode = pair.C;
+ return true;
+ }
+ }
+ return false;
+}
+
+const struct {
+ pag_paragraph_justification C;
+ pag::Enum Pag;
+} gParagraphJustificationPairs[] = {
+ {pag_paragraph_justification_left_justify, pag::ParagraphJustification::LeftJustify},
+ {pag_paragraph_justification_center_justify, pag::ParagraphJustification::CenterJustify},
+ {pag_paragraph_justification_right_justify, pag::ParagraphJustification::RightJustify},
+ {pag_paragraph_justification_full_justify_last_line_left,
+ pag::ParagraphJustification::FullJustifyLastLineLeft},
+ {pag_paragraph_justification_full_justify_last_line_right,
+ pag::ParagraphJustification::FullJustifyLastLineRight},
+ {pag_paragraph_justification_full_justify_last_line_center,
+ pag::ParagraphJustification::FullJustifyLastLineCenter},
+ {pag_paragraph_justification_full_justify_last_line_full,
+ pag::ParagraphJustification::FullJustifyLastLineFull},
+};
+
+bool FromCParagraphJustification(pag_paragraph_justification cParagraphJustification,
+ pag::Enum* paragraphJustification) {
+ for (auto& pair : gParagraphJustificationPairs) {
+ if (pair.C == cParagraphJustification) {
+ *paragraphJustification = pair.Pag;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool ToCParagraphJustification(pag::Enum paragraphJustification,
+ pag_paragraph_justification* cParagraphJustification) {
+ for (auto& pair : gParagraphJustificationPairs) {
+ if (pair.Pag == paragraphJustification) {
+ *cParagraphJustification = pair.C;
+ return true;
+ }
+ }
+ return false;
+}
+
+const struct {
+ pag_layer_type C;
+ pag::LayerType Pag;
+} gLayerTypePairs[] = {
+ {pag_layer_type_unknown, pag::LayerType::Unknown},
+ {pag_layer_type_null, pag::LayerType::Null},
+ {pag_layer_type_solid, pag::LayerType::Solid},
+ {pag_layer_type_text, pag::LayerType::Text},
+ {pag_layer_type_shape, pag::LayerType::Shape},
+ {pag_layer_type_image, pag::LayerType::Image},
+ {pag_layer_type_pre_compose, pag::LayerType::PreCompose},
+ {pag_layer_type_camera, pag::LayerType::Camera},
+};
+
+bool FromCLayerType(pag_layer_type cLayerType, pag::LayerType* layerType) {
+ for (auto& pair : gLayerTypePairs) {
+ if (pair.C == cLayerType) {
+ *layerType = pair.Pag;
+ return true;
+ }
+ }
+ return false;
+}
+
+bool TocLayerType(pag::LayerType layerType, pag_layer_type* cLayerType) {
+ for (auto& pair : gLayerTypePairs) {
+ if (pair.Pag == layerType) {
+ *cLayerType = pair.C;
+ return true;
+ }
+ }
+ return false;
+}
diff --git a/src/c/pag_types_priv.h b/src/c/pag_types_priv.h
new file mode 100644
index 0000000000..af7aee1f5a
--- /dev/null
+++ b/src/c/pag_types_priv.h
@@ -0,0 +1,182 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "pag/c/pag_types.h"
+#include "pag/pag.h"
+#include "rendering/PAGAnimator.h"
+#include "tgfx/gpu/Device.h"
+
+enum class PAGObjectType : uint8_t {
+ Unknown = 0,
+ ByteData,
+ TextDocument,
+ Layer,
+ Player,
+ Surface,
+ Image,
+ Font,
+ BackendTexture,
+ BackendSemaphore,
+ Decoder,
+ PAGAnimator,
+
+ Count,
+};
+
+struct pag_byte_data {
+ explicit pag_byte_data(std::unique_ptr byteData) : p(std::move(byteData)) {
+ }
+
+ PAGObjectType type = PAGObjectType::ByteData;
+ std::unique_ptr p;
+};
+
+struct pag_text_document {
+ explicit pag_text_document(std::shared_ptr textDocument)
+ : p(std::move(textDocument)) {
+ }
+
+ PAGObjectType type = PAGObjectType::TextDocument;
+ std::shared_ptr p;
+};
+
+struct pag_layer {
+ explicit pag_layer(std::shared_ptr layer) : p(std::move(layer)) {
+ }
+
+ PAGObjectType type = PAGObjectType::Layer;
+ std::shared_ptr p;
+};
+
+struct pag_player {
+ explicit pag_player(std::shared_ptr player) : p(std::move(player)) {
+ }
+
+ PAGObjectType type = PAGObjectType::Player;
+ std::shared_ptr p;
+};
+
+namespace pag {
+class PAGSurfaceExt {
+ public:
+ explicit PAGSurfaceExt(std::shared_ptr surface) : surface(std::move(surface)) {
+ }
+
+ BackendTexture getFrontTexture();
+
+ BackendTexture getBackTexture();
+
+ HardwareBufferRef getFrontHardwareBuffer();
+
+ HardwareBufferRef getBackHardwareBuffer();
+
+ std::shared_ptr surface;
+};
+} // namespace pag
+
+struct pag_surface {
+ explicit pag_surface(std::shared_ptr surface)
+ : p(surface), ext(std::make_shared(surface)) {
+ }
+
+ PAGObjectType type = PAGObjectType::Surface;
+ std::shared_ptr p;
+ std::shared_ptr ext;
+};
+
+struct pag_image {
+ explicit pag_image(std::shared_ptr image) : p(std::move(image)) {
+ }
+
+ PAGObjectType type = PAGObjectType::Image;
+ std::shared_ptr p;
+};
+
+struct pag_font {
+ explicit pag_font(pag::PAGFont font) : p(std::move(font)) {
+ }
+
+ PAGObjectType type = PAGObjectType::Font;
+ pag::PAGFont p;
+};
+
+struct pag_backend_texture {
+ explicit pag_backend_texture(const pag::BackendTexture& backendTexture) : p(backendTexture) {
+ }
+ explicit pag_backend_texture(void* otherBackend) : otherBackend(otherBackend) {
+ }
+
+ PAGObjectType type = PAGObjectType::BackendTexture;
+ pag::BackendTexture p;
+ void* otherBackend = nullptr;
+};
+
+struct pag_backend_semaphore {
+ pag_backend_semaphore() = default;
+
+ PAGObjectType type = PAGObjectType::BackendSemaphore;
+ pag::BackendSemaphore p;
+};
+
+struct pag_decoder {
+ explicit pag_decoder(std::shared_ptr decoder) : p(std::move(decoder)) {
+ }
+
+ PAGObjectType type = PAGObjectType::Decoder;
+ std::shared_ptr p;
+};
+
+struct pag_animator {
+ pag_animator() = default;
+
+ PAGObjectType type = PAGObjectType::PAGAnimator;
+ std::shared_ptr p;
+ std::shared_ptr listener;
+};
+
+std::shared_ptr ToPAGFile(pag_file* file);
+
+std::shared_ptr ToPAGComposition(pag_composition* composition);
+
+bool FromCTimeStretchMode(pag_time_stretch_mode cTimeStretchMode, pag::Enum* timeStretchMode);
+
+bool ToCTimeStretchMode(pag::Enum timeStretchMode, pag_time_stretch_mode* cTimeStretchMode);
+
+bool FromCColorType(pag_color_type cColorType, pag::ColorType* colorType);
+
+bool ToCColorType(pag::ColorType colorType, pag_color_type* cColorType);
+
+bool FromCAlphaType(pag_alpha_type cAlphaType, pag::AlphaType* alphaType);
+
+bool ToCAlphaType(pag::AlphaType alphaType, pag_alpha_type* cAlphaType);
+
+bool FromCScaleMode(pag_scale_mode cScaleMode, pag::Enum* scaleMode);
+
+bool ToCScaleMode(pag::Enum scaleMode, pag_scale_mode* cScaleMode);
+
+bool FromCParagraphJustification(pag_paragraph_justification cParagraphJustification,
+ pag::Enum* paragraphJustification);
+
+bool ToCParagraphJustification(pag::Enum paragraphJustification,
+ pag_paragraph_justification* cParagraphJustification);
+
+bool FromCLayerType(pag_layer_type cLayerType, pag::LayerType* layerType);
+
+bool TocLayerType(pag::LayerType layerType, pag_layer_type* cLayerType);
diff --git a/src/codec/AttributeHelper.h b/src/codec/AttributeHelper.h
index f9f29880e0..dd329bad99 100644
--- a/src/codec/AttributeHelper.h
+++ b/src/codec/AttributeHelper.h
@@ -390,7 +390,7 @@ void WriteTimeEase(EncodeStream* stream, const std::vector*>& keyfra
}
}
auto count = static_cast(bezierList.size());
- stream->writeFloatList(&bezierList[0], count, BEZIER_PRECISION);
+ stream->writeFloatList(bezierList.data(), count, BEZIER_PRECISION);
}
template
@@ -411,7 +411,7 @@ void WriteSpatialEase(EncodeStream* stream, const std::vector*>& key
}
}
auto count = static_cast(spatialList.size());
- stream->writeFloatList(&spatialList[0], count, SPATIAL_PRECISION);
+ stream->writeFloatList(spatialList.data(), count, SPATIAL_PRECISION);
}
template
diff --git a/src/codec/DataTypes.cpp b/src/codec/DataTypes.cpp
index 1e3a3492ef..a5daee81f3 100644
--- a/src/codec/DataTypes.cpp
+++ b/src/codec/DataTypes.cpp
@@ -459,7 +459,8 @@ static void WritePathInternal(EncodeStream* stream, pag::PathHandle value) {
break;
}
}
- stream->writeFloatList(&pointList[0], static_cast(pointList.size()), SPATIAL_PRECISION);
+ stream->writeFloatList(pointList.data(), static_cast(pointList.size()),
+ SPATIAL_PRECISION);
}
void WritePath(EncodeStream* stream, pag::PathHandle value) {
diff --git a/src/codec/utils/EncodeStream.cpp b/src/codec/utils/EncodeStream.cpp
index 69b0477c9b..a6cab05aff 100644
--- a/src/codec/utils/EncodeStream.cpp
+++ b/src/codec/utils/EncodeStream.cpp
@@ -185,8 +185,8 @@ void EncodeStream::writeEncodedUint64(uint64_t value) {
}
void EncodeStream::writeBits(int32_t value, uint8_t numBits) {
- auto data = static_cast(value << (33 - numBits));
- data >>= 33 - numBits;
+ auto data = static_cast(value) << (33 - numBits);
+ data >>= (33 - numBits);
if (value < 0) {
data |= 1 << (numBits - 1);
}
@@ -228,7 +228,7 @@ uint8_t GetBitLength(uint32_t data) {
}
uint8_t GetBitLength(int32_t value) {
- auto data = static_cast(value < 0 ? -value : value);
+ auto data = static_cast(value < 0 ? -static_cast(value) : value);
uint8_t length = GetBitLength(data);
if (length >= 32) {
length = 31;
diff --git a/src/platform/Platform.cpp b/src/platform/Platform.cpp
index 2bec064c0f..c4bd114ce3 100644
--- a/src/platform/Platform.cpp
+++ b/src/platform/Platform.cpp
@@ -52,4 +52,4 @@ std::string Platform::getSandboxPath(std::string filePath) const {
std::shared_ptr Platform::createDisplayLink(std::function) const {
return nullptr;
}
-} // namespace pag
\ No newline at end of file
+} // namespace pag
diff --git a/src/platform/android/JPAGDiskCache.cpp b/src/platform/android/JPAGDiskCache.cpp
index f27ee89ddb..125a753274 100644
--- a/src/platform/android/JPAGDiskCache.cpp
+++ b/src/platform/android/JPAGDiskCache.cpp
@@ -74,7 +74,7 @@ PAG_API jboolean JNICALL Java_org_libpag_PAGDiskCache_WriteFile(JNIEnv* env, jcl
jbyteArray bytes) {
auto key = pag::SafeConvertToStdString(env, jkey);
if (bytes == nullptr || key.empty()) {
- LOGE("PAGFile.LoadFromBytes() Invalid image bytes specified.");
+ LOGE("PAGDiskCache.WriteFile() Invalid file bytes specified.");
return JNI_FALSE;
}
auto data = env->GetByteArrayElements(bytes, nullptr);
diff --git a/src/platform/android/JPAGFile.cpp b/src/platform/android/JPAGFile.cpp
index 2a6ee1f995..7a553f3e3a 100644
--- a/src/platform/android/JPAGFile.cpp
+++ b/src/platform/android/JPAGFile.cpp
@@ -68,7 +68,7 @@ PAG_API jobject Java_org_libpag_PAGFile_LoadFromPath(JNIEnv* env, jclass, jstrin
PAG_API jobject Java_org_libpag_PAGFile_LoadFromBytes(JNIEnv* env, jclass, jbyteArray bytes,
jint length, jstring jpath) {
if (bytes == nullptr) {
- LOGE("PAGFile.LoadFromBytes() Invalid image bytes specified.");
+ LOGE("PAGFile.LoadFromBytes() Invalid pag file bytes specified.");
return NULL;
}
auto data = env->GetByteArrayElements(bytes, nullptr);
@@ -76,7 +76,7 @@ PAG_API jobject Java_org_libpag_PAGFile_LoadFromBytes(JNIEnv* env, jclass, jbyte
auto pagFile = PAGFile::Load(data, static_cast(length), path);
env->ReleaseByteArrayElements(bytes, data, 0);
if (pagFile == nullptr) {
- LOGE("PAGFile.LoadFromBytes() Invalid image bytes specified.");
+ LOGE("PAGFile.LoadFromBytes() Invalid pag file bytes specified.");
return NULL;
}
return ToPAGLayerJavaObject(env, pagFile);
diff --git a/src/platform/cocoa/private/NativeTextShaper.mm b/src/platform/cocoa/private/NativeTextShaper.mm
index ccbc675296..e9987b950f 100644
--- a/src/platform/cocoa/private/NativeTextShaper.mm
+++ b/src/platform/cocoa/private/NativeTextShaper.mm
@@ -29,12 +29,12 @@
return std::nullopt;
}
std::vector clusters;
- const char* textStart = &(text[0]);
+ const char* textStart = text.data();
const char* textStop = textStart + text.size();
while (textStart < textStop) {
auto oldPosition = textStart;
auto uni = tgfx::UTF::NextUTF8(&textStart, textStop);
- auto cluster = oldPosition - &(text[0]);
+ auto cluster = oldPosition - text.data();
clusters.emplace_back(static_cast(cluster));
if (0x10000 <= uni && uni <= 0x10FFFF) {
clusters.emplace_back(static_cast(cluster));
@@ -63,9 +63,9 @@
}
auto count = CTRunGetGlyphCount(run);
std::vector glyphs(count);
- CTRunGetGlyphs(run, CFRangeMake(0, count), &(glyphs[0]));
+ CTRunGetGlyphs(run, CFRangeMake(0, count), glyphs.data());
std::vector indices(count);
- CTRunGetStringIndices(run, CFRangeMake(0, count), &(indices[0]));
+ CTRunGetStringIndices(run, CFRangeMake(0, count), indices.data());
for (size_t j = 0; j < glyphs.size(); j++) {
glyphIDs.emplace_back(face, static_cast(glyphs[j]), clusters[indices[j]]);
}
diff --git a/src/platform/ios/PAGImageView.mm b/src/platform/ios/PAGImageView.mm
index 09b6afe65f..5627416bde 100644
--- a/src/platform/ios/PAGImageView.mm
+++ b/src/platform/ios/PAGImageView.mm
@@ -262,9 +262,9 @@ - (BOOL)updateImageViewFrom:(CVPixelBufferRef)pixelBuffer atIndex:(NSInteger)fra
}
return YES;
}
- PAGDecoder* pagDecoder = [self getPAGDecoder];
- if ([pagDecoder checkFrameChanged:(int)frameIndex]) {
- BOOL status = [pagDecoder readFrame:frameIndex to:pixelBuffer];
+ PAGDecoder* decoder = [self getPAGDecoder];
+ if ([decoder checkFrameChanged:(int)frameIndex]) {
+ BOOL status = [decoder readFrame:frameIndex to:pixelBuffer];
if (!status) {
return status;
}
diff --git a/src/platform/ios/PAGView.m b/src/platform/ios/PAGView.m
index 53dffe0003..8b1fde139f 100644
--- a/src/platform/ios/PAGView.m
+++ b/src/platform/ios/PAGView.m
@@ -211,9 +211,9 @@ - (void)setPathAsync:(NSString*)path completionBlock:(void (^)(PAGFile*))callbac
}
filePath = [path retain];
[PAGFile LoadAsync:path
- completionBlock:^(PAGFile* pagFile) {
- [self setComposition:pagFile];
- callback(pagFile);
+ completionBlock:^(PAGFile* file) {
+ [self setComposition:file];
+ callback(file);
}];
}
diff --git a/src/platform/ios/private/HardwareDecoder.mm b/src/platform/ios/private/HardwareDecoder.mm
index 64532f4c2c..f41c3e84a7 100644
--- a/src/platform/ios/private/HardwareDecoder.mm
+++ b/src/platform/ios/private/HardwareDecoder.mm
@@ -94,8 +94,8 @@ void DidDecompress(void*, void* sourceFrameRefCon, OSStatus status, VTDecodeInfo
if (mimeType == "video/hevc") {
if (@available(iOS 11.0, *)) {
status = CMVideoFormatDescriptionCreateFromHEVCParameterSets(
- kCFAllocatorDefault, size, ¶meterSetPointers[0], ¶meterSetSizes[0], 4, NULL,
- &videoFormatDescription);
+ kCFAllocatorDefault, size, parameterSetPointers.data(), parameterSetSizes.data(), 4,
+ NULL, &videoFormatDescription);
} else {
status = -1;
}
@@ -107,8 +107,8 @@ void DidDecompress(void*, void* sourceFrameRefCon, OSStatus status, VTDecodeInfo
// create video format description
status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault,
size, // param count
- ¶meterSetPointers[0],
- ¶meterSetSizes[0],
+ parameterSetPointers.data(),
+ parameterSetSizes.data(),
4, // nal start code size
&videoFormatDescription);
if (status != noErr) {
diff --git a/src/platform/ios/private/PAGAnimationCallback.h b/src/platform/ios/private/PAGAnimationCallback.h
index f52b1caf8e..2e5b43f084 100644
--- a/src/platform/ios/private/PAGAnimationCallback.h
+++ b/src/platform/ios/private/PAGAnimationCallback.h
@@ -17,6 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////////////////////
#import
+#import
#include
@interface PAGAnimationCallback : NSObject {
diff --git a/src/platform/ios/private/PAGAnimationCallback.mm b/src/platform/ios/private/PAGAnimationCallback.mm
index 6fdda36df3..8d3080aea5 100644
--- a/src/platform/ios/private/PAGAnimationCallback.mm
+++ b/src/platform/ios/private/PAGAnimationCallback.mm
@@ -20,10 +20,10 @@
@implementation PAGAnimationCallback
-- (instancetype)initWithCallback:(std::function)callback {
+- (instancetype)initWithCallback:(std::function)animationCallback {
self = [super init];
if (self) {
- self->callback = callback;
+ self->callback = animationCallback;
}
return self;
}
diff --git a/src/platform/mac/private/HardwareDecoder.mm b/src/platform/mac/private/HardwareDecoder.mm
index a7fb86307d..1c320d39e3 100644
--- a/src/platform/mac/private/HardwareDecoder.mm
+++ b/src/platform/mac/private/HardwareDecoder.mm
@@ -111,7 +111,7 @@ void DidDecompress(void*, void* sourceFrameRefCon, OSStatus status, VTDecodeInfo
if (mimeType == "video/hevc") {
status = CMVideoFormatDescriptionCreateFromHEVCParameterSets(
- kCFAllocatorDefault, size, ¶meterSetPointers[0], ¶meterSetSizes[0], 4, NULL,
+ kCFAllocatorDefault, size, parameterSetPointers.data(), parameterSetSizes.data(), 4, NULL,
&videoFormatDescription);
if (status != noErr) {
@@ -122,8 +122,8 @@ void DidDecompress(void*, void* sourceFrameRefCon, OSStatus status, VTDecodeInfo
// create video format description
status = CMVideoFormatDescriptionCreateFromH264ParameterSets(kCFAllocatorDefault,
size, // param count
- ¶meterSetPointers[0],
- ¶meterSetSizes[0],
+ parameterSetPointers.data(),
+ parameterSetSizes.data(),
4, // nal start code size
&videoFormatDescription);
diff --git a/src/platform/qt/GPUDrawable.cpp b/src/platform/qt/GPUDrawable.cpp
index cf09804968..3bc0b8b1ed 100644
--- a/src/platform/qt/GPUDrawable.cpp
+++ b/src/platform/qt/GPUDrawable.cpp
@@ -31,7 +31,7 @@ std::shared_ptr GPUDrawable::MakeFrom(QQuickItem* quickItem,
}
GPUDrawable::GPUDrawable(QQuickItem* quickItem, std::shared_ptr window)
- : quickItem(quickItem), window(std::move(window)) {
+ : DoubleBufferedDrawable(std::move(window)), quickItem(quickItem) {
GPUDrawable::updateSize();
}
@@ -42,26 +42,15 @@ void GPUDrawable::updateSize() {
_height = static_cast(ceil(quickItem->height() * pixelRatio));
}
-std::shared_ptr GPUDrawable::onCreateDevice() {
- if (_width <= 0 || _height <= 0) {
- return nullptr;
- }
- return window->getDevice();
-}
-
-std::shared_ptr GPUDrawable::onCreateSurface(tgfx::Context* context) {
- return window->createSurface(context);
-}
-
-void GPUDrawable::present(tgfx::Context* context) {
- window->present(context);
+std::shared_ptr GPUDrawable::qGLWindow() const {
+ return std::static_pointer_cast(window);
}
void GPUDrawable::moveToThread(QThread* targetThread) {
- window->moveToThread(targetThread);
+ qGLWindow()->moveToThread(targetThread);
}
QSGTexture* GPUDrawable::getTexture() {
- return window->getTexture();
+ return qGLWindow()->getTexture();
}
} // namespace pag
diff --git a/src/platform/qt/GPUDrawable.h b/src/platform/qt/GPUDrawable.h
index 66d251e2a2..27e0f4a53a 100644
--- a/src/platform/qt/GPUDrawable.h
+++ b/src/platform/qt/GPUDrawable.h
@@ -24,45 +24,29 @@
#include
#include
#pragma clang diagnostic pop
-#include "rendering/drawables/Drawable.h"
+#include "rendering/drawables/DoubleBufferedDrawable.h"
namespace tgfx {
class QGLWindow;
}
namespace pag {
-class GPUDrawable : public Drawable {
+class GPUDrawable : public DoubleBufferedDrawable {
public:
static std::shared_ptr MakeFrom(QQuickItem* quickItem,
QOpenGLContext* sharedContext = nullptr);
- int width() const override {
- return _width;
- }
-
- int height() const override {
- return _height;
- }
-
void updateSize() override;
- void present(tgfx::Context* context) override;
-
void moveToThread(QThread* targetThread);
QSGTexture* getTexture();
- protected:
- std::shared_ptr onCreateDevice() override;
-
- std::shared_ptr onCreateSurface(tgfx::Context* context) override;
-
private:
- int _width = 0;
- int _height = 0;
QQuickItem* quickItem = nullptr;
- std::shared_ptr window = nullptr;
GPUDrawable(QQuickItem* quickItem, std::shared_ptr window);
+
+ std::shared_ptr qGLWindow() const;
};
} // namespace pag
diff --git a/src/platform/web/NativeTextShaper.cpp b/src/platform/web/NativeTextShaper.cpp
index 3708d0fa9c..a24df8d89a 100644
--- a/src/platform/web/NativeTextShaper.cpp
+++ b/src/platform/web/NativeTextShaper.cpp
@@ -97,10 +97,10 @@ static void MergeClusters(std::vector& infos) {
PositionedGlyphs NativeTextShaper::Shape(const std::string& text,
const std::shared_ptr& typeface) {
std::vector infos;
- const char* textStart = &(text[0]);
+ const char* textStart = text.data();
const char* textStop = textStart + text.size();
while (textStart < textStop) {
- auto cluster = static_cast(textStart - &(text[0]));
+ auto cluster = static_cast(textStart - text.data());
infos.emplace_back(Info{tgfx::UTF::NextUTF8(&textStart, textStop), cluster});
}
diff --git a/src/platform/web/PAGWasmBindings.cpp b/src/platform/web/PAGWasmBindings.cpp
index 81e7e30269..ba0c5c5acd 100644
--- a/src/platform/web/PAGWasmBindings.cpp
+++ b/src/platform/web/PAGWasmBindings.cpp
@@ -24,7 +24,6 @@
#include "platform/web/GPUDrawable.h"
#include "platform/web/WebSoftwareDecoderFactory.h"
#include "rendering/editing/StillImage.h"
-#include "tgfx/core/FontMetrics.h"
#include "tgfx/core/ImageInfo.h"
#include "tgfx/core/PathTypes.h"
#include "tgfx/opengl/GLDefines.h"
@@ -499,52 +498,4 @@ EMSCRIPTEN_BINDINGS(pag) {
register_vector("VectorString");
register_vector("VectorInt");
register_vector("VectorMarker");
-
- class_("TGFXMatrix")
- .function("_get", &tgfx::Matrix::get)
- .function("_set", &tgfx::Matrix::set);
-
- class_("TGFXImageInfo")
- .property("width", &tgfx::ImageInfo::width)
- .property("height", &tgfx::ImageInfo::height)
- .property("rowBytes", &tgfx::ImageInfo::rowBytes)
- .property("colorType", &tgfx::ImageInfo::colorType);
-
- class_("TGFXStroke")
- .property("width", &tgfx::Stroke::width)
- .property("cap", &tgfx::Stroke::cap)
- .property("join", &tgfx::Stroke::join)
- .property("miterLimit", &tgfx::Stroke::miterLimit);
-
- value_object("TGFXFontMetrics")
- .field("ascent", &tgfx::FontMetrics::ascent)
- .field("descent", &tgfx::FontMetrics::descent)
- .field("xHeight", &tgfx::FontMetrics::xHeight)
- .field("capHeight", &tgfx::FontMetrics::capHeight);
-
- value_object("TGFXRect")
- .field("left", &tgfx::Rect::left)
- .field("top", &tgfx::Rect::top)
- .field("right", &tgfx::Rect::right)
- .field("bottom", &tgfx::Rect::bottom);
-
- enum_("TGFXPathFillType")
- .value("Winding", tgfx::PathFillType::Winding)
- .value("EvenOdd", tgfx::PathFillType::EvenOdd)
- .value("InverseWinding", tgfx::PathFillType::InverseWinding)
- .value("InverseEvenOdd", tgfx::PathFillType::InverseEvenOdd);
-
- enum_("TGFXLineCap")
- .value("Butt", tgfx::LineCap::Butt)
- .value("Round", tgfx::LineCap::Round)
- .value("Square", tgfx::LineCap::Square);
-
- enum_("TGFXLineJoin")
- .value("Miter", tgfx::LineJoin::Miter)
- .value("Round", tgfx::LineJoin::Round)
- .value("Bevel", tgfx::LineJoin::Bevel);
-
- value_object("TGFXPoint").field("x", &tgfx::Point::x).field("y", &tgfx::Point::y);
-
- register_vector("VectorTGFXPoint");
}
diff --git a/src/rendering/PAG.cpp b/src/rendering/PAG.cpp
index f71a3a075e..cd331a2096 100644
--- a/src/rendering/PAG.cpp
+++ b/src/rendering/PAG.cpp
@@ -20,7 +20,7 @@
namespace pag {
-static const char sdkVersion[] = "4.0.0.1";
+static const char sdkVersion[] = "4.0.0";
std::string PAG::SDKVersion() {
return sdkVersion;
diff --git a/src/rendering/PAGAnimator.cpp b/src/rendering/PAGAnimator.cpp
index a3cb53d6c2..41bdfe8e32 100644
--- a/src/rendering/PAGAnimator.cpp
+++ b/src/rendering/PAGAnimator.cpp
@@ -19,6 +19,7 @@
#include "PAGAnimator.h"
#include "base/utils/TimeUtil.h"
#include "platform/Platform.h"
+#include "rendering/utils/DisplayLinkWrapper.h"
#include "tgfx/utils/Clock.h"
#include "tgfx/utils/Task.h"
@@ -35,7 +36,11 @@ class AnimationTicker {
}
AnimationTicker() {
- displayLink = Platform::Current()->createDisplayLink([this] { onFrameAvailable(); });
+ auto callback = [this] { onFrameAvailable(); };
+ displayLink = DisplayLinkWrapper::Make(callback);
+ if (displayLink == nullptr) {
+ displayLink = Platform::Current()->createDisplayLink(callback);
+ }
}
bool available() {
diff --git a/src/rendering/PAGSurface.cpp b/src/rendering/PAGSurface.cpp
index 4b8352fc63..9cb918e00c 100644
--- a/src/rendering/PAGSurface.cpp
+++ b/src/rendering/PAGSurface.cpp
@@ -105,6 +105,66 @@ HardwareBufferRef PAGSurface::getHardwareBuffer() {
return hardwareBuffer;
}
+BackendTexture PAGSurface::getFrontTexture() {
+ LockGuard autoLock(rootLocker);
+ auto context = lockContext(true);
+ if (context == nullptr) {
+ return {};
+ }
+ if (drawable->getSurface(context, true) == nullptr) {
+ unlockContext();
+ return {};
+ }
+ auto texture = drawable->getFrontSurface()->getBackendTexture();
+ unlockContext();
+ return ToPAG(texture);
+}
+
+BackendTexture PAGSurface::getBackTexture() {
+ LockGuard autoLock(rootLocker);
+ auto context = lockContext(true);
+ if (context == nullptr) {
+ return {};
+ }
+ if (drawable->getSurface(context, true) == nullptr) {
+ unlockContext();
+ return {};
+ }
+ auto texture = drawable->getBackSurface()->getBackendTexture();
+ unlockContext();
+ return ToPAG(texture);
+}
+
+HardwareBufferRef PAGSurface::getFrontHardwareBuffer() {
+ LockGuard autoLock(rootLocker);
+ auto context = lockContext(true);
+ if (context == nullptr) {
+ return nullptr;
+ }
+ if (drawable->getSurface(context, true) == nullptr) {
+ unlockContext();
+ return nullptr;
+ }
+ auto buffer = drawable->getFrontSurface()->getHardwareBuffer();
+ unlockContext();
+ return buffer;
+}
+
+HardwareBufferRef PAGSurface::getBackHardwareBuffer() {
+ LockGuard autoLock(rootLocker);
+ auto context = lockContext(true);
+ if (context == nullptr) {
+ return nullptr;
+ }
+ if (drawable->getSurface(context, true) == nullptr) {
+ unlockContext();
+ return nullptr;
+ }
+ auto buffer = drawable->getBackSurface()->getHardwareBuffer();
+ unlockContext();
+ return buffer;
+}
+
bool PAGSurface::readPixels(ColorType colorType, AlphaType alphaType, void* dstPixels,
size_t dstRowBytes) {
LockGuard autoLock(rootLocker);
diff --git a/src/rendering/PAGSurfaceFactory.cpp b/src/rendering/PAGSurfaceFactory.cpp
index 0b888e09ca..788db3726e 100644
--- a/src/rendering/PAGSurfaceFactory.cpp
+++ b/src/rendering/PAGSurfaceFactory.cpp
@@ -63,7 +63,6 @@ std::shared_ptr PAGSurface::MakeFrom(const BackendTexture& texture,
}
std::shared_ptr PAGSurface::MakeOffscreen(int width, int height) {
-
auto drawable = OffscreenDrawable::Make(width, height);
return MakeFrom(drawable);
}
diff --git a/src/rendering/caches/LayerCache.cpp b/src/rendering/caches/LayerCache.cpp
index 0b12f6fdaf..8607b74068 100644
--- a/src/rendering/caches/LayerCache.cpp
+++ b/src/rendering/caches/LayerCache.cpp
@@ -57,13 +57,17 @@ LayerCache::LayerCache(Layer* layer) : layer(layer) {
}
contentCache->update();
transformCache = new TransformCache(layer);
+ bool hasFeatherMask = false;
for (auto mask : layer->masks) {
if (mask->maskFeather != nullptr ||
(mask->maskOpacity->animatable() || mask->maskOpacity->value != 255)) {
- featherMaskCache = new FeatherMaskCache(layer);
+ hasFeatherMask = true;
+ break;
}
}
- if (!layer->masks.empty() && featherMaskCache == nullptr) {
+ if (hasFeatherMask) {
+ featherMaskCache = new FeatherMaskCache(layer);
+ } else if (!layer->masks.empty()) {
maskCache = new MaskCache(layer);
}
updateStaticTimeRanges();
@@ -75,6 +79,7 @@ LayerCache::~LayerCache() {
delete transformCache;
delete maskCache;
delete contentCache;
+ delete featherMaskCache;
}
Transform* LayerCache::getTransform(Frame contentFrame) {
diff --git a/src/rendering/caches/SequenceFile.cpp b/src/rendering/caches/SequenceFile.cpp
index e7bea7ebbd..414d112a4e 100644
--- a/src/rendering/caches/SequenceFile.cpp
+++ b/src/rendering/caches/SequenceFile.cpp
@@ -356,7 +356,7 @@ bool SequenceFile::compatible(const tgfx::ImageInfo& info, int frameCount, float
_staticTimeRanges.size() != staticTimeRanges.size()) {
return false;
}
- return memcmp(&_staticTimeRanges[0], &staticTimeRanges[0],
+ return memcmp(_staticTimeRanges.data(), staticTimeRanges.data(),
sizeof(TimeRange) * staticTimeRanges.size()) == 0;
}
} // namespace pag
diff --git a/src/rendering/caches/TextAtlas.cpp b/src/rendering/caches/TextAtlas.cpp
index fbfaa52487..c3941d48e9 100644
--- a/src/rendering/caches/TextAtlas.cpp
+++ b/src/rendering/caches/TextAtlas.cpp
@@ -78,9 +78,11 @@ class RectanglePack {
auto point = Point::Make(x, y);
if (x + w - _width < y + h - _height) {
x += w;
+ _width = std::max(_width, x);
_height = std::max(_height, y + h);
} else {
y += h;
+ _height = std::max(_height, y);
_width = std::max(_width, x + w);
}
return point;
@@ -224,7 +226,7 @@ std::shared_ptr DrawMask(tgfx::Context* context, const Page& page)
return nullptr;
}
for (auto& textRun : page.textRuns) {
- auto blob = tgfx::TextBlob::MakeFrom(&textRun.glyphIDs[0], &textRun.positions[0],
+ auto blob = tgfx::TextBlob::MakeFrom(textRun.glyphIDs.data(), textRun.positions.data(),
textRun.glyphIDs.size(), textRun.textFont);
if (textRun.paint.getStyle() == tgfx::PaintStyle::Fill) {
mask->fillText(blob.get());
@@ -245,8 +247,8 @@ std::shared_ptr DrawColor(tgfx::Context* context, const Page& page)
auto totalMatrix = canvas->getMatrix();
for (auto& textRun : page.textRuns) {
canvas->setMatrix(totalMatrix);
- auto glyphs = &textRun.glyphIDs[0];
- auto positions = &textRun.positions[0];
+ auto glyphs = textRun.glyphIDs.data();
+ auto positions = textRun.positions.data();
canvas->drawGlyphs(glyphs, positions, textRun.glyphIDs.size(), textRun.textFont, textRun.paint);
}
canvas->setMatrix(totalMatrix);
diff --git a/src/rendering/drawables/DoubleBufferDrawable.cpp b/src/rendering/drawables/DoubleBufferDrawable.cpp
new file mode 100644
index 0000000000..d28ccd7f24
--- /dev/null
+++ b/src/rendering/drawables/DoubleBufferDrawable.cpp
@@ -0,0 +1,62 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "DoubleBufferedDrawable.h"
+#include "base/utils/TGFXCast.h"
+#include "tgfx/opengl/GLDevice.h"
+#include "tgfx/platform/HardwareBuffer.h"
+
+namespace pag {
+std::shared_ptr DoubleBufferedDrawable::Make(
+ int width, int height, bool tryHardware, std::shared_ptr device) {
+ if (device == nullptr || width <= 0 || height <= 0) {
+ return nullptr;
+ }
+ auto window = tgfx::DoubleBufferedWindow::Make(std::move(device), width, height, tryHardware);
+ if (window == nullptr) {
+ return nullptr;
+ }
+ return std::shared_ptr(
+ new DoubleBufferedDrawable(width, height, std::move(window)));
+}
+
+DoubleBufferedDrawable::DoubleBufferedDrawable(std::shared_ptr window)
+ : window(std::move(window)) {
+}
+
+DoubleBufferedDrawable::DoubleBufferedDrawable(int width, int height,
+ std::shared_ptr window)
+ : _width(width), _height(height), window(std::move(window)) {
+}
+
+std::shared_ptr DoubleBufferedDrawable::onCreateDevice() {
+ if (_width <= 0 || _height <= 0) {
+ return nullptr;
+ }
+ return window->getDevice();
+}
+
+std::shared_ptr DoubleBufferedDrawable::onCreateSurface(tgfx::Context* context) {
+ return window->createSurface(context);
+}
+
+void DoubleBufferedDrawable::present(tgfx::Context* context) {
+ window->present(context);
+ surface = window->getBackSurface();
+}
+} // namespace pag
diff --git a/tgfx/src/platform/web/WebImageStream.h b/src/rendering/drawables/DoubleBufferedDrawable.h
similarity index 50%
rename from tgfx/src/platform/web/WebImageStream.h
rename to src/rendering/drawables/DoubleBufferedDrawable.h
index b713eaa8b1..f5c12fd23e 100644
--- a/tgfx/src/platform/web/WebImageStream.h
+++ b/src/rendering/drawables/DoubleBufferedDrawable.h
@@ -18,22 +18,14 @@
#pragma once
-#include
-#include "core/ImageStream.h"
+#include "rendering/drawables/Drawable.h"
+#include "tgfx/gpu/DoubleBufferedWindow.h"
-namespace tgfx {
-/**
- * The WebImageStream class allows direct access to image buffers rendered into a TexImageSource
- * object on the web platform. It is typically used with the ImageReader class.
- */
-class WebImageStream : public ImageStream {
+namespace pag {
+class DoubleBufferedDrawable : public Drawable {
public:
- /**
- * Creates a new WebImageStream from the specified TexImageSource object and the size. Returns
- * nullptr if the source is null or the buffer size is zero.
- */
- static std::shared_ptr MakeFrom(emscripten::val source, int width, int height,
- bool alphaOnly = false);
+ static std::shared_ptr Make(int width, int height, bool tryHardware,
+ std::shared_ptr device);
int width() const override {
return _width;
@@ -43,27 +35,28 @@ class WebImageStream : public ImageStream {
return _height;
}
- bool isAlphaOnly() const override {
- return alphaOnly;
- }
+ void present(tgfx::Context* context) override;
+
+ protected:
+ explicit DoubleBufferedDrawable(std::shared_ptr window);
- bool isHardwareBacked() const override {
- return false;
+ std::shared_ptr getFrontSurface() const override {
+ return window->getFrontSurface();
}
- protected:
- WebImageStream(emscripten::val source, int width, int height, bool alphaOnly);
+ std::shared_ptr getBackSurface() const override {
+ return window->getBackSurface();
+ }
- std::shared_ptr onMakeTexture(Context* context, bool mipMapped) override;
+ std::shared_ptr onCreateSurface(tgfx::Context* context) override;
- bool onUpdateTexture(std::shared_ptr texture, const Rect& bounds) override;
+ std::shared_ptr onCreateDevice() override;
- private:
- emscripten::val source = emscripten::val::null();
int _width = 0;
int _height = 0;
- bool alphaOnly = false;
+ std::shared_ptr window;
- friend class WebMask;
+ private:
+ DoubleBufferedDrawable(int width, int height, std::shared_ptr window);
};
-} // namespace tgfx
+} // namespace pag
diff --git a/src/rendering/drawables/Drawable.h b/src/rendering/drawables/Drawable.h
index 032f65cd3b..7cca20655a 100644
--- a/src/rendering/drawables/Drawable.h
+++ b/src/rendering/drawables/Drawable.h
@@ -40,6 +40,14 @@ class Drawable {
virtual std::shared_ptr onCreateSurface(tgfx::Context* context) = 0;
+ virtual std::shared_ptr getFrontSurface() const {
+ return surface;
+ }
+
+ virtual std::shared_ptr getBackSurface() const {
+ return surface;
+ }
+
private:
std::shared_ptr device = nullptr;
diff --git a/src/rendering/filters/CornerPinFilter.cpp b/src/rendering/filters/CornerPinFilter.cpp
index 55f6194861..9ddd349c47 100644
--- a/src/rendering/filters/CornerPinFilter.cpp
+++ b/src/rendering/filters/CornerPinFilter.cpp
@@ -144,7 +144,7 @@ void CornerPinFilter::bindVertices(tgfx::Context* context, const FilterSource* s
gl->bindVertexArray(filterProgram->vertexArray);
}
gl->bindBuffer(GL_ARRAY_BUFFER, filterProgram->vertexBuffer);
- gl->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STREAM_DRAW);
+ gl->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STREAM_DRAW);
gl->vertexAttribPointer(static_cast(positionHandle), 2, GL_FLOAT, GL_FALSE,
5 * sizeof(float), static_cast(0));
gl->enableVertexAttribArray(static_cast(positionHandle));
diff --git a/src/rendering/filters/LayerFilter.cpp b/src/rendering/filters/LayerFilter.cpp
index a96a0a2944..6aa9470c30 100644
--- a/src/rendering/filters/LayerFilter.cpp
+++ b/src/rendering/filters/LayerFilter.cpp
@@ -304,7 +304,7 @@ void LayerFilter::bindVertices(tgfx::Context* context, const FilterSource* sourc
gl->bindVertexArray(filterProgram->vertexArray);
}
gl->bindBuffer(GL_ARRAY_BUFFER, filterProgram->vertexBuffer);
- gl->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), &vertices[0], GL_STREAM_DRAW);
+ gl->bufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), vertices.data(), GL_STREAM_DRAW);
gl->vertexAttribPointer(static_cast(positionHandle), 2, GL_FLOAT, GL_FALSE,
4 * sizeof(float), static_cast(0));
gl->enableVertexAttribArray(static_cast(positionHandle));
diff --git a/src/rendering/graphics/Text.cpp b/src/rendering/graphics/Text.cpp
index 44dd26cd4e..61bed2d962 100644
--- a/src/rendering/graphics/Text.cpp
+++ b/src/rendering/graphics/Text.cpp
@@ -276,9 +276,10 @@ static void Draw(tgfx::Canvas* canvas, const TextAtlas* atlas, const Parameters&
if (parameters.matrices.empty()) {
return;
}
- canvas->drawAtlas(
- atlas->getAtlasImage(parameters.imageIndex), ¶meters.matrices[0], ¶meters.rects[0],
- parameters.colors.empty() ? nullptr : ¶meters.colors[0], parameters.matrices.size());
+ canvas->drawAtlas(atlas->getAtlasImage(parameters.imageIndex), parameters.matrices.data(),
+ parameters.rects.data(),
+ parameters.colors.empty() ? nullptr : parameters.colors.data(),
+ parameters.matrices.size());
}
static bool RectStaysRectAndNoScale(const tgfx::Matrix& matrix) {
@@ -354,8 +355,8 @@ void Text::drawTextRuns(tgfx::Canvas* canvas, int paintIndex) const {
}
canvas->setMatrix(totalMatrix);
canvas->concat(textRun->matrix);
- auto ids = &textRun->glyphIDs[0];
- auto positions = &textRun->positions[0];
+ auto ids = textRun->glyphIDs.data();
+ auto positions = textRun->positions.data();
canvas->drawGlyphs(ids, positions, textRun->glyphIDs.size(), textRun->textFont, *textPaint);
}
canvas->setMatrix(totalMatrix);
diff --git a/src/rendering/sequences/DiskSequenceReader.cpp b/src/rendering/sequences/DiskSequenceReader.cpp
index 201f604354..dc39979868 100644
--- a/src/rendering/sequences/DiskSequenceReader.cpp
+++ b/src/rendering/sequences/DiskSequenceReader.cpp
@@ -94,18 +94,18 @@ std::shared_ptr DiskSequenceReader::onMakeBuffer(Frame target
}
}
- if (!pagDecoder->checkFrameChanged(targetFrame)) {
+ if (!pagDecoder->checkFrameChanged(static_cast(targetFrame))) {
return imageBuffer;
}
bool success = false;
auto renderBuffer = useFrontBuffer ? frontHardWareBuffer : backHardwareBuffer;
if (frontHardWareBuffer) {
- success = pagDecoder->readFrame(targetFrame, renderBuffer);
+ success = pagDecoder->readFrame(static_cast(targetFrame), renderBuffer);
} else {
if (pixels) {
success =
- pagDecoder->readFrame(targetFrame, const_cast(pixels->data()), info.rowBytes(),
- ToPAG(info.colorType()), ToPAG(info.alphaType()));
+ pagDecoder->readFrame(static_cast(targetFrame), const_cast(pixels->data()),
+ info.rowBytes(), ToPAG(info.colorType()), ToPAG(info.alphaType()));
}
}
if (!success) {
diff --git a/src/rendering/utils/DisplayLinkWrapper.cpp b/src/rendering/utils/DisplayLinkWrapper.cpp
new file mode 100644
index 0000000000..88adc7dc08
--- /dev/null
+++ b/src/rendering/utils/DisplayLinkWrapper.cpp
@@ -0,0 +1,74 @@
+/////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Tencent is pleased to support the open source community by making libpag available.
+//
+// Copyright (C) 2023 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 "DisplayLinkWrapper.h"
+
+static pag_display_link_functions* DisplayLinkFunctions = nullptr;
+
+void pag_display_link_set_functions(pag_display_link_functions* functions) {
+ DisplayLinkFunctions = functions;
+}
+
+namespace pag {
+static void DisplayLinkWrapperUpdate(void* user) {
+ if (user == nullptr) {
+ return;
+ }
+ auto* wrapper = static_cast(user);
+ wrapper->update();
+}
+
+std::shared_ptr DisplayLinkWrapper::Make(std::function callback) {
+ if (DisplayLinkFunctions == nullptr || callback == nullptr) {
+ return nullptr;
+ }
+ auto* ret = new DisplayLinkWrapper();
+ if (auto* displayLink = DisplayLinkFunctions->create(ret, DisplayLinkWrapperUpdate)) {
+ ret->displayLink = displayLink;
+ ret->callback = std::move(callback);
+ return std::shared_ptr(ret);
+ }
+ delete ret;
+ return nullptr;
+}
+
+DisplayLinkWrapper::~DisplayLinkWrapper() {
+ DisplayLinkWrapper::stop();
+ DisplayLinkFunctions->release(displayLink);
+}
+
+void DisplayLinkWrapper::start() {
+ if (started) {
+ return;
+ }
+ started = true;
+ DisplayLinkFunctions->start(displayLink);
+}
+
+void DisplayLinkWrapper::stop() {
+ if (!started) {
+ return;
+ }
+ started = false;
+ DisplayLinkFunctions->stop(displayLink);
+}
+
+void DisplayLinkWrapper::update() {
+ callback();
+}
+} // namespace pag
diff --git a/tgfx/include/tgfx/platform/NativeImage.h b/src/rendering/utils/DisplayLinkWrapper.h
similarity index 64%
rename from tgfx/include/tgfx/platform/NativeImage.h
rename to src/rendering/utils/DisplayLinkWrapper.h
index 21fa0a803d..1b367990f7 100644
--- a/tgfx/include/tgfx/platform/NativeImage.h
+++ b/src/rendering/utils/DisplayLinkWrapper.h
@@ -18,36 +18,29 @@
#pragma once
-#if defined(__EMSCRIPTEN__)
-#include
-#elif defined(__ANDROID__) || defined(ANDROID)
+#include
+#include
+#include "pag/c/pag_types.h"
+#include "rendering/utils/DisplayLink.h"
-class _jobject;
+namespace pag {
+class DisplayLinkWrapper : public DisplayLink {
+ public:
+ static std::shared_ptr Make(std::function callback);
-#elif defined(__APPLE__)
+ ~DisplayLinkWrapper() override;
-struct CGImage;
+ void start() override;
-#endif
+ void stop() override;
-namespace tgfx {
-#if defined(__EMSCRIPTEN__)
+ void update();
-typedef emscripten::val NativeImageRef;
+ private:
+ DisplayLinkWrapper() = default;
-#elif defined(__ANDROID__) || defined(ANDROID)
-
-typedef _jobject* NativeImageRef;
-
-#elif defined(__APPLE__)
-
-typedef CGImage* NativeImageRef;
-
-#else
-
-struct NativeImage {};
-
-typedef NativeImage* NativeImageRef;
-
-#endif
-} // namespace tgfx
\ No newline at end of file
+ bool started = false;
+ void* displayLink = nullptr;
+ std::function callback;
+};
+} // namespace pag
diff --git a/src/rendering/utils/shaper/TextShaperPrimitive.cpp b/src/rendering/utils/shaper/TextShaperPrimitive.cpp
index 023d2ce08d..c767dd014c 100644
--- a/src/rendering/utils/shaper/TextShaperPrimitive.cpp
+++ b/src/rendering/utils/shaper/TextShaperPrimitive.cpp
@@ -23,7 +23,7 @@
namespace pag {
PositionedGlyphs TextShaperPrimitive::Shape(const std::string& text,
std::shared_ptr typeface) {
- const char* textStart = &(text[0]);
+ const char* textStart = text.data();
const char* textStop = textStart + text.size();
std::vector, tgfx::GlyphID, uint32_t>> glyphs;
auto fallbackTypefaces = FontManager::GetFallbackTypefaces();
@@ -42,16 +42,16 @@ PositionedGlyphs TextShaperPrimitive::Shape(const std::string& text,
}
glyphID = face->getGlyphID(str);
if (glyphID != 0) {
- glyphs.emplace_back(std::move(face), glyphID, oldPosition - &(text[0]));
+ glyphs.emplace_back(std::move(face), glyphID, oldPosition - text.data());
found = true;
break;
}
}
if (!found) {
- glyphs.emplace_back(typeface, glyphID, oldPosition - &(text[0]));
+ glyphs.emplace_back(typeface, glyphID, oldPosition - text.data());
}
} else {
- glyphs.emplace_back(typeface, glyphID, oldPosition - &(text[0]));
+ glyphs.emplace_back(typeface, glyphID, oldPosition - text.data());
}
}
return PositionedGlyphs(glyphs);
diff --git a/sync_deps.sh b/sync_deps.sh
index c6612e9e52..7c6cb4cd05 100755
--- a/sync_deps.sh
+++ b/sync_deps.sh
@@ -1,35 +1,19 @@
#!/bin/bash -e
cd $(dirname $0)
+sh ./install_tools.sh
+
if [[ `uname` == 'Darwin' ]]; then
- MAC_REQUIRED_TOOLS="node cmake ninja yasm git-lfs emcc"
- for TOOL in ${MAC_REQUIRED_TOOLS[@]}; do
- if [ ! $(which $TOOL) ]; then
- if [ ! $(which brew) ]; then
- echo "Homebrew not found. Trying to install..."
- /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ||
- exit 1
- fi
- if [ $TOOL == 'emcc' ]; then
+ if [ ! $(which emcc) ]; then
echo "emscripten not found. Trying to install..."
sh ./web/script/install-emscripten.sh || exit 1
- else
- echo "$TOOL not found. Trying to install..."
- brew install $TOOL || exit 1
- fi
fi
- done
-fi
-
-NODE_REQUIRED_TOOLS="depsync"
-
-for TOOL in ${NODE_REQUIRED_TOOLS[@]}; do
- if [ ! $(which $TOOL) ]; then
- echo "$TOOL not found. Trying to install..."
- npm install -g $TOOL > /dev/null
+ if [ ! $(which gcovr) ]; then
+ echo "gcovr not found. Trying to install..."
+ brew install gcovr || exit 1
fi
-done
+fi
depsync
-git lfs prune
-git lfs pull
+
+git lfs prune
\ No newline at end of file
diff --git a/test/CanvasTest.cpp b/test/CanvasTest.cpp
deleted file mode 100644
index 3f1c560dea..0000000000
--- a/test/CanvasTest.cpp
+++ /dev/null
@@ -1,786 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////////////////////////
-//
-// Tencent is pleased to support the open source community by making libpag available.
-//
-// Copyright (C) 2021 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 "framework/pag_test.h"
-#include "framework/utils/PAGTestUtils.h"
-#include "framework/utils/TestConstants.h"
-#include "gpu/DrawingManager.h"
-#include "gpu/ops/FillRectOp.h"
-#include "gpu/ops/RRectOp.h"
-#include "gpu/ops/TriangulatingPathOp.h"
-#include "opengl/GLCaps.h"
-#include "opengl/GLSampler.h"
-#include "rendering/utils/shaper/TextShaper.h"
-#include "tgfx/core/Canvas.h"
-#include "tgfx/core/ImageCodec.h"
-#include "tgfx/core/ImageReader.h"
-#include "tgfx/core/Mask.h"
-#include "tgfx/core/PathEffect.h"
-#include "tgfx/gpu/Surface.h"
-#include "tgfx/opengl/GLDevice.h"
-#include "tgfx/opengl/GLFunctions.h"
-
-using namespace pag;
-
-namespace tgfx {
-/**
- * 用例描述: 测试 ColorMatrixFilter
- */
-PAG_TEST(CanvasTest, ColorMatrixFilter) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- auto image = MakeImage("resources/apitest/test_timestretch.png");
- ASSERT_TRUE(image != nullptr);
- auto surface = Surface::Make(context, image->width(), image->height());
- auto canvas = surface->getCanvas();
- tgfx::Paint paint;
- std::array matrix = {1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0};
- paint.setColorFilter(ColorFilter::Matrix(matrix));
- canvas->drawImage(image, &paint);
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/identityMatrix"));
- canvas->clear();
- std::array greyColorMatrix = {0.21f, 0.72f, 0.07f, 0.41f, 0, // red
- 0.21f, 0.72f, 0.07f, 0.41f, 0, // green
- 0.21f, 0.72f, 0.07f, 0.41f, 0, // blue
- 0, 0, 0, 1.0f, 0};
- paint.setColorFilter(ColorFilter::Matrix(greyColorMatrix));
- canvas->drawImage(image, &paint);
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/greyColorMatrix"));
- device->unlock();
-}
-
-PAG_TEST(CanvasTest, Blur) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- auto codec = MakeImageCodec("resources/apitest/rotation.jpg");
- ASSERT_TRUE(codec != nullptr);
- auto image = Image::MakeFrom(codec);
- ASSERT_TRUE(image != nullptr);
- auto imageMatrix = EncodedOriginToMatrix(codec->origin(), codec->width(), codec->height());
- imageMatrix.postScale(0.2, 0.2);
- auto bounds = Rect::MakeWH(codec->width(), codec->height());
- imageMatrix.mapRect(&bounds);
- auto imageWidth = static_cast(bounds.width());
- auto imageHeight = static_cast(bounds.height());
- auto padding = 30.f;
- Paint paint;
- auto surface = Surface::Make(context, static_cast(imageWidth * 2.f + padding * 3.f),
- static_cast(imageHeight * 2.f + padding * 3.f));
- auto canvas = surface->getCanvas();
- canvas->concat(tgfx::Matrix::MakeTrans(padding, padding));
- canvas->save();
- canvas->concat(imageMatrix);
- canvas->drawImage(image, &paint);
- canvas->restore();
- Path path;
- path.addRect(Rect::MakeWH(imageWidth, imageHeight));
- Stroke stroke(1.f);
- PathEffect::MakeStroke(&stroke)->applyTo(&path);
- paint.setImageFilter(nullptr);
- paint.setColor(Color{1.f, 0.f, 0.f, 1.f});
- canvas->drawPath(path, paint);
-
- canvas->concat(tgfx::Matrix::MakeTrans(imageWidth + padding, 0));
- canvas->save();
- canvas->concat(imageMatrix);
- paint.setImageFilter(ImageFilter::Blur(130, 130, TileMode::Decal));
- canvas->drawImage(image, &paint);
- canvas->restore();
- paint.setImageFilter(nullptr);
- canvas->drawPath(path, paint);
-
- canvas->concat(tgfx::Matrix::MakeTrans(-imageWidth - padding, imageHeight + padding));
- canvas->save();
- canvas->concat(imageMatrix);
- paint.setImageFilter(ImageFilter::Blur(130, 130, TileMode::Clamp,
- tgfx::Rect::MakeWH(codec->width(), codec->height())));
- canvas->drawImage(image, &paint);
- canvas->restore();
- paint.setImageFilter(nullptr);
- canvas->drawPath(path, paint);
-
- canvas->concat(tgfx::Matrix::MakeTrans(imageWidth + padding, 0));
- canvas->save();
- canvas->concat(imageMatrix);
- paint.setImageFilter(
- ImageFilter::Blur(130, 130, TileMode::Clamp, tgfx::Rect::MakeLTRB(-100, -100, 2000, 1000)));
- canvas->drawImage(image, &paint);
- paint.setImageFilter(
- ImageFilter::Blur(130, 130, TileMode::Clamp, tgfx::Rect::MakeXYWH(1000, 1000, 1000, 1000)));
- canvas->drawImage(image, &paint);
- paint.setImageFilter(
- ImageFilter::Blur(130, 130, TileMode::Clamp, tgfx::Rect::MakeXYWH(2000, 1000, 1000, 1000)));
- canvas->drawImage(image, &paint);
- canvas->restore();
- paint.setImageFilter(nullptr);
- canvas->drawPath(path, paint);
-
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/blur"));
- device->unlock();
-}
-
-PAG_TEST(CanvasTest, DropShadow) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- auto image = MakeImage("resources/apitest/image_as_mask.png");
- ASSERT_TRUE(image != nullptr);
- auto imageWidth = static_cast(image->width());
- auto imageHeight = static_cast(image->height());
- auto padding = 30.f;
- Paint paint;
- auto surface = Surface::Make(context, static_cast(imageWidth * 2.f + padding * 3.f),
- static_cast(imageHeight * 2.f + padding * 3.f));
- auto canvas = surface->getCanvas();
- canvas->concat(tgfx::Matrix::MakeTrans(padding, padding));
- paint.setImageFilter(ImageFilter::Blur(15, 15));
- canvas->drawImage(image, &paint);
-
- canvas->concat(tgfx::Matrix::MakeTrans(imageWidth + padding, 0));
- paint.setImageFilter(ImageFilter::DropShadowOnly(0, 0, 15, 15, tgfx::Color::White()));
- canvas->drawImage(image, &paint);
-
- canvas->concat(tgfx::Matrix::MakeTrans(-imageWidth - padding, imageWidth + padding));
- paint.setImageFilter(ImageFilter::DropShadow(0, 0, 15, 15, tgfx::Color::White()));
- canvas->drawImage(image, &paint);
-
- canvas->concat(tgfx::Matrix::MakeTrans(imageWidth + padding, 0));
- auto filter = ImageFilter::DropShadow(3, 3, 0, 0, tgfx::Color::White());
- paint.setImageFilter(filter);
- canvas->drawImage(image, &paint);
-
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/dropShadow"));
- device->unlock();
-
- auto src = Rect::MakeXYWH(10, 10, 10, 10);
- auto bounds = filter->filterBounds(src);
- EXPECT_EQ(bounds, Rect::MakeXYWH(10, 10, 13, 13));
- bounds = ImageFilter::DropShadowOnly(3, 3, 0, 0, Color::White())->filterBounds(src);
- EXPECT_EQ(bounds, Rect::MakeXYWH(13, 13, 10, 10));
-}
-
-PAG_TEST(CanvasTest, clip) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- auto width = 1080;
- auto height = 1776;
- tgfx::GLTextureInfo textureInfo;
- pag::CreateGLTexture(context, width, height, &textureInfo);
- auto glTexture =
- Texture::MakeFrom(context, {textureInfo, width, height}, ImageOrigin::BottomLeft);
- auto surface = Surface::MakeFrom(glTexture);
- auto canvas = surface->getCanvas();
- canvas->clear();
- canvas->setMatrix(tgfx::Matrix::MakeScale(3));
- auto clipPath = Path();
- clipPath.addRect(tgfx::Rect::MakeLTRB(0, 0, 200, 300));
- auto paint = Paint();
- paint.setColor(tgfx::Color::FromRGBA(0, 0, 0));
- paint.setStyle(PaintStyle::Stroke);
- paint.setStroke(Stroke(1));
- canvas->drawPath(clipPath, paint);
- canvas->clipPath(clipPath);
- auto drawPath = Path();
- drawPath.addRect(tgfx::Rect::MakeLTRB(50, 295, 150, 590));
- paint.setColor(tgfx::Color::FromRGBA(255, 0, 0));
- paint.setStyle(PaintStyle::Fill);
- canvas->drawPath(drawPath, paint);
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/Clip"));
- auto gl = GLFunctions::Get(context);
- gl->deleteTextures(1, &textureInfo.id);
- device->unlock();
-}
-
-/**
- * 用例描述: 测试绘制 Rectangle 纹理时使用 TileMode::Repeat 和 TileMode::Mirror。
- */
-PAG_TEST(CanvasTest, TileMode) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- auto codec = MakeImageCodec("resources/apitest/rotation.jpg");
- ASSERT_TRUE(codec != nullptr);
- auto image = Image::MakeFrom(codec);
- auto surface = Surface::Make(context, codec->width() / 2, codec->height() / 2);
- auto canvas = surface->getCanvas();
- Paint paint;
- paint.setShader(Shader::MakeImageShader(image, TileMode::Repeat, TileMode::Mirror)
- ->makeWithPreLocalMatrix(Matrix::MakeScale(0.125f)));
- canvas->drawRect(Rect::MakeWH(static_cast(surface->width()),
- static_cast(surface->height()) * 0.9f),
- paint);
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/tileMode"));
- device->unlock();
-}
-
-/**
- * 用例描述: 测试 rect 合并绘制
- */
-PAG_TEST(CanvasTest, merge_draw_call_rect) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- int width = 72;
- int height = 72;
- auto surface = Surface::Make(context, width, height);
- auto canvas = surface->getCanvas();
- canvas->clear(Color::White());
- Paint paint;
- paint.setColor(Color{0.8f, 0.8f, 0.8f, 1.f});
- paint.setColorFilter(ColorFilter::MakeLumaColorFilter());
- int tileSize = 8;
- size_t drawCallCount = 0;
- for (int y = 0; y < height; y += tileSize) {
- bool draw = (y / tileSize) % 2 == 1;
- for (int x = 0; x < width; x += tileSize) {
- if (draw) {
- auto rect = Rect::MakeXYWH(static_cast(x), static_cast(y),
- static_cast(tileSize), static_cast(tileSize));
- canvas->drawRect(rect, paint);
- drawCallCount++;
- }
- draw = !draw;
- }
- }
- auto* drawingManager = context->drawingManager();
- EXPECT_TRUE(drawingManager->tasks.size() == 1);
- auto task = std::static_pointer_cast(drawingManager->tasks[0]);
- EXPECT_TRUE(task->ops.size() == 2);
- EXPECT_EQ(static_cast(task->ops[1].get())->rects.size(), drawCallCount);
- canvas->flush();
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/merge_draw_call_rect"));
- device->unlock();
-}
-
-/**
- * 用例描述: 测试 path 合并绘制
- */
-PAG_TEST(CanvasTest, merge_draw_call_triangle) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- auto image = MakeImage("resources/apitest/imageReplacement.png");
- ASSERT_TRUE(image != nullptr);
- int width = 72;
- int height = 72;
- auto surface = Surface::Make(context, width, height);
- auto canvas = surface->getCanvas();
- canvas->clear(Color::White());
- Paint paint;
- paint.setShader(Shader::MakeImageShader(image)->makeWithPreLocalMatrix(
- Matrix::MakeScale(static_cast(width) / static_cast(image->width()),
- static_cast(height) / static_cast(image->height()))));
- int tileSize = 8;
- int drawCallCount = 0;
- for (int y = 0; y < height; y += tileSize) {
- bool draw = (y / tileSize) % 2 == 1;
- for (int x = 0; x < width; x += tileSize) {
- if (draw) {
- auto rect = Rect::MakeXYWH(static_cast(x), static_cast(y),
- static_cast(tileSize), static_cast(tileSize));
- auto centerX = rect.x() + rect.width() / 2.f;
- auto centerY = rect.y() + rect.height() / 2.f;
- Path path;
- path.addRect(rect);
- Matrix matrix = Matrix::I();
- matrix.postRotate(45, centerX, centerY);
- path.transform(matrix);
- canvas->drawPath(path, paint);
- drawCallCount += 1;
- }
- draw = !draw;
- }
- }
- auto* drawingManager = context->drawingManager();
- EXPECT_TRUE(drawingManager->tasks.size() == 1);
- auto task = std::static_pointer_cast(drawingManager->tasks[0]);
- EXPECT_TRUE(task->ops.size() == 2);
- EXPECT_EQ(static_cast(task->ops[1].get())->vertexCount, drawCallCount * 30);
- canvas->flush();
- EXPECT_TRUE(Baseline::Compare(surface, "CanvasTest/merge_draw_call_triangle"));
- device->unlock();
-}
-
-/**
- * 用例描述: 测试 rrect 合并绘制
- */
-PAG_TEST(CanvasTest, merge_draw_call_rrect) {
- auto device = GLDevice::Make();
- auto context = device->lockContext();
- ASSERT_TRUE(context != nullptr);
- int width = 72;
- int height = 72;
- auto surface = Surface::Make(context, width, height);
- auto canvas = surface->getCanvas();
- canvas->clear(Color::White());
- Paint paint;
- paint.setShader(Shader::MakeLinearGradient(
- Point{0.f, 0.f}, Point{static_cast(width), static_cast(height)},
- {Color{0.f, 1.f, 0.f, 1.f}, Color{0.f, 0.f, 0.f, 1.f}}, {}));
- int tileSize = 8;
- size_t drawCallCount = 0;
- for (int y = 0; y < height; y += tileSize) {
- bool draw = (y / tileSize) % 2 == 1;
- for (int x = 0; x < width; x += tileSize) {
- if (draw) {
- auto rect = Rect::MakeXYWH(static_cast(x), static_cast(y),
- static_cast(tileSize), static_cast(tileSize));
- Path path;
- auto radius = static_cast(tileSize) / 4.f;
- path.addRoundRect(rect, radius, radius);
- canvas->drawPath(path, paint);
- drawCallCount++;
- }
- draw = !draw;
- }
- }
- auto* drawingManager = context->drawingManager();
- EXPECT_TRUE(drawingManager->tasks.size() == 1);
- auto task = std::static_pointer_cast