Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 35 additions & 35 deletions package/Runtime/Sys/TvgLib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,48 +30,48 @@ internal static class TvgLib
{
private enum Result
{
Success = 0,
InvalidArguments,
InsufficientCondition,
FailedAllocation,
MemoryCorruption,
NonSupport,
Unknown = 255
Success = 0,
InvalidArguments,
InsufficientCondition,
FailedAllocation,
MemoryCorruption,
NonSupport,
Unknown = 255
}

private enum ColorSpace
{
Abgr8888 = 0
Abgr8888 = 0
}

private enum EngineOption
{
// No special features
None = 0
// No special features
None = 0
}

private static void Check(int code, string msg)
{
switch ((TvgLib.Result)code)
switch ((Result)code)
{
case TvgLib.Result.Success:
case Result.Success:
return;
case TvgLib.Result.InvalidArguments:
case Result.InvalidArguments:
msg += " (Invalid Arguments)";
break;
case TvgLib.Result.InsufficientCondition:
case Result.InsufficientCondition:
msg += " (Insufficient Condition)";
break;
case TvgLib.Result.FailedAllocation:
case Result.FailedAllocation:
msg += " (Failed Allocation)";
break;
case TvgLib.Result.MemoryCorruption:
case Result.MemoryCorruption:
msg += " (Memory Corruption)";
break;
case TvgLib.Result.NonSupport:
case Result.NonSupport:
msg += " (Non Support)";
break;
case TvgLib.Result.Unknown:
case Result.Unknown:
msg += " (Unknown)";
break;
default:
Expand All @@ -94,19 +94,19 @@ internal struct AnimationHandle
public IntPtr Picture;
}

/************************************************************************/
/* Engine API */
/************************************************************************/
/************************************************************************/
/* Engine API */
/************************************************************************/

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int tvg_engine_init(int threads);

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int tvg_engine_term();

/************************************************************************/
/* Canvas API */
/************************************************************************/
/************************************************************************/
/* Canvas API */
/************************************************************************/

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr tvg_swcanvas_create(EngineOption option);
Expand All @@ -115,7 +115,7 @@ internal struct AnimationHandle
private static extern int tvg_canvas_destroy(IntPtr handle);

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int tvg_canvas_push(IntPtr handle, IntPtr paint);
private static extern int tvg_canvas_add(IntPtr handle, IntPtr paint);

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int tvg_swcanvas_set_target(IntPtr handle, IntPtr buffer, uint stride, uint w, uint h, ColorSpace colorspace);
Expand All @@ -129,9 +129,9 @@ internal struct AnimationHandle
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int tvg_canvas_draw(IntPtr handle, bool clear);

/************************************************************************/
/* Animation API */
/************************************************************************/
/************************************************************************/
/* Animation API */
/************************************************************************/

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr tvg_animation_new();
Expand All @@ -151,9 +151,9 @@ internal struct AnimationHandle
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr tvg_animation_get_picture(IntPtr handle);

/************************************************************************/
/* Picture API */
/************************************************************************/
/************************************************************************/
/* Picture API */
/************************************************************************/

[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int tvg_picture_load_data(IntPtr handle, string data, uint size, string mimetype, string rpath, bool copy);
Expand All @@ -164,9 +164,9 @@ internal struct AnimationHandle
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern int tvg_picture_get_size(IntPtr handle, out float w, out float h);

/************************************************************************/
/* Public API */
/************************************************************************/
/************************************************************************/
/* Public API */
/************************************************************************/

public static void EngineInit()
{
Expand All @@ -192,7 +192,7 @@ public static AnimationHandle CreateAnimation(string data)

// Load the animation data
Check(tvg_picture_load_data(picture, data, (uint)data.Length, "", "", true), "Picture Load");
Check(tvg_canvas_push(canvas, picture), "Canvas Push");
Check(tvg_canvas_add(canvas, picture), "Canvas Add");

return new AnimationHandle
{
Expand Down
94 changes: 68 additions & 26 deletions scripts/build-thorvg.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
python build-thorvg.py <tag> wasm # Build for WebGL

Examples:
python build-thorvg.py v1.0-pre34 desktop
python build-thorvg.py v1.0.0 desktop
"""

import argparse
Expand All @@ -23,7 +23,7 @@

# Configuration
THORVG_REPO = "https://github.com/thorvg/thorvg.git"
UNITY_PLUGINS = Path(__file__).parent.parent / "package" / "Plugins"
UNITY_PLUGINS = (Path(__file__).parent.parent / "package" / "Plugins").resolve()

# These will be set based on CLI arguments
THORVG_TAG = ""
Expand All @@ -43,6 +43,9 @@
"-Dbuildtype=release",
]

# Set working directory
os.chdir(Path(__file__).parent.resolve())


def check_dependencies():
"""Check if required build tools are installed"""
Expand Down Expand Up @@ -218,6 +221,44 @@ def create_android_cross_file(arch, ndk_path, api_level=24):
return cross_file


def find_built_library(build_dir, extension):
"""Auto-find the built ThorVG library, skipping symlinks.

Searches build_dir/src/ for real (non-symlink) files containing
'thorvg' with the given extension.

Args:
build_dir: The meson build directory.
extension: Extension to match within the filename (e.g. '.dylib').

Returns:
Path to the found library file.
"""
search_dir = build_dir / "src"
matches = [
f
for f in search_dir.rglob("*")
if not f.is_dir()
and not f.is_symlink()
and "thorvg" in f.name
and extension in f.name
]

if not matches:
print(f"[ERROR] No ThorVG library (*thorvg*{extension}) found in {search_dir}")
if search_dir.exists():
print(" Available files:")
for f in sorted(search_dir.rglob("*")):
if not f.is_dir():
sym = " (symlink)" if f.is_symlink() else ""
print(f" {f.relative_to(build_dir)}{sym}")
sys.exit(1)

result = sorted(matches)[0]
print(f" Found: {result.relative_to(build_dir)}")
return result


def build_desktop():
"""Build for current desktop platform (macOS, Windows, Linux)"""
print("\n=== Building for Desktop ===")
Expand All @@ -235,26 +276,23 @@ def build_desktop():
# Compile
run_command(["meson", "compile", "-C", str(build_dir)])

# Copy to appropriate plugin folder
# Auto-find built library and copy to plugin folder
if system == "Darwin":
# macOS
source = find_built_library(build_dir, ".dylib")
output_dir = UNITY_PLUGINS / "macOS"
output_file = "libthorvg.dylib"
source = build_dir / "src" / output_file
dest_name = "libthorvg.dylib"
elif system == "Windows":
# Windows
source = find_built_library(build_dir, ".dll")
output_dir = UNITY_PLUGINS / "x86_64"
output_file = "libthorvg.dll"
source = build_dir / "src" / "libthorvg-1.dll"
dest_name = "libthorvg.dll"
else:
# Linux
source = find_built_library(build_dir, ".so")
output_dir = UNITY_PLUGINS / "x86_64"
output_file = "libthorvg.so"
source = build_dir / "src" / output_file
dest_name = "libthorvg.so"

output_dir.mkdir(parents=True, exist_ok=True)
shutil.copy2(source, output_dir / output_file)
print(f"[OK] Desktop build copied to {output_dir / output_file}")
shutil.copy2(source, output_dir / dest_name)
print(f"[OK] Desktop build copied to {output_dir / dest_name}")


def build_ios():
Expand Down Expand Up @@ -285,11 +323,11 @@ def build_ios():
# Compile
run_command(["meson", "compile", "-C", str(build_dir)])

# Copy to Unity plugins
# Auto-find and copy to Unity plugins
source = find_built_library(build_dir, ".a")
output_dir = UNITY_PLUGINS / "iOS" / "arm64"
output_dir.mkdir(parents=True, exist_ok=True)

source = build_dir / "src" / "libthorvg.a"
shutil.copy2(source, output_dir / "libthorvg.a")
print(f"[OK] iOS build copied to {output_dir / 'libthorvg.a'}")

Expand Down Expand Up @@ -334,11 +372,11 @@ def build_android():
# Compile
run_command(["meson", "compile", "-C", str(build_dir)])

# Copy to Unity plugins
# Auto-find and copy to Unity plugins
source = find_built_library(build_dir, ".so")
output_dir = UNITY_PLUGINS / "Android" / "libs" / arch
output_dir.mkdir(parents=True, exist_ok=True)

source = build_dir / "src" / "libthorvg.so"
shutil.copy2(source, output_dir / "libthorvg.so")
print(f"[OK] {arch} build copied to {output_dir / 'libthorvg.so'}")
finally:
Expand Down Expand Up @@ -407,14 +445,18 @@ def build_wasm():
# Compile
run_command(["meson", "compile", "-C", str(build_dir)])

# Copy WASM module files to package StreamingAssets
# Auto-find and copy WASM module files to package StreamingAssets
# Unity will copy these to Build/StreamingAssets/Packages/com.thorvg.unity/WebGL/
output_dir = Path(__file__).parent.parent / "package" / "StreamingAssets" / "WebGL"
js_source = find_built_library(build_dir, ".js")
wasm_source = find_built_library(build_dir, ".wasm")

output_dir = (
Path(__file__).parent.parent / "package" / "StreamingAssets" / "WebGL"
)
output_dir.mkdir(parents=True, exist_ok=True)

wasm_output = build_dir / "src" / "bindings" / "wasm"
shutil.copy2(wasm_output / "thorvg.js", output_dir / "thorvg.js")
shutil.copy2(wasm_output / "thorvg.wasm", output_dir / "thorvg.wasm")
shutil.copy2(js_source, output_dir / "thorvg.js")
shutil.copy2(wasm_source, output_dir / "thorvg.wasm")
print(f"[OK] WebGL module copied to {output_dir}")
finally:
# Clean up
Expand All @@ -431,8 +473,8 @@ def main():
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Examples:
python build-thorvg.py v1.0-pre34 desktop
python build-thorvg.py v1.0-pre34 android ios
python build-thorvg.py v1.0.0 desktop
python build-thorvg.py v1.0.0 android ios
""",
)
parser.add_argument(
Expand All @@ -450,7 +492,7 @@ def main():

# Set global configuration based on tag
THORVG_TAG = args.tag
THORVG_DIR = Path(__file__).parent / f"thorvg-{THORVG_TAG}"
THORVG_DIR = Path(f"thorvg-{THORVG_TAG}")

# Normalize targets
targets = set()
Expand Down