From c75c53945515c294bea95271152e139bfd9a9aa0 Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:30:52 +0600 Subject: [PATCH 1/9] add --- Cargo.lock | 1 + Cargo.toml | 1 + resvg_py.pyi | 23 ++++++++++-------- src/rust/lib.rs | 44 ++++++++++++++++++++++++++++++++-- tests/font/test_font_render.py | 3 +++ 5 files changed, 60 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4af2fb9..a4ec3e2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -384,6 +384,7 @@ dependencies = [ name = "resvg_py" version = "0.1.4" dependencies = [ + "log", "pyo3", "resvg", "svgtypes", diff --git a/Cargo.toml b/Cargo.toml index f49a81c..41ce791 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ path = "src/rust/lib.rs" crate-type = ["cdylib"] [dependencies] +log = "0.4.21" pyo3 = "0.21.2" resvg = { version = "0.41.0", features = ["raster-images","text"] } svgtypes = "0.15.0" diff --git a/resvg_py.pyi b/resvg_py.pyi index 75a2506..3722250 100644 --- a/resvg_py.pyi +++ b/resvg_py.pyi @@ -3,17 +3,22 @@ from typing import Literal def svg_to_bytes( svg_string: str | None = None, svg_path: str | None = None, + background: str | None = None, + skip_system_fonts: bool | None = False, + log_information: bool = False, width: int | None = None, height: int | None = None, + zoom: int | None = None, + dpi: int | None = 0, resources_dir: str | None = None, - languages: list[str] | None = None, - font_size: int | None = None, - font_family: str | None = None, - serif_family: str | None = None, - sans_serif_family: str | None = None, - cursive_family: str | None = None, - fantasy_family: str | None = None, - monospace_family: str | None = None, + languages: list[str] | None = [], + font_size: int | None = 16, + font_family: str | None = Literal["Times New Roman"], + serif_family: str | None = Literal["Times New Roman"], + sans_serif_family: str | None = Literal["Arial"], + cursive_family: str | None = Literal["Comic Sans MS"], + fantasy_family: str | None = ["Impact"], + monospace_family: str | None = Literal["Courier New"], font_files: list[str] | None = None, font_dirs: list[str] | None = None, shape_rendering: Literal[ @@ -25,8 +30,6 @@ def svg_to_bytes( image_rendering: Literal["optimize_quality", "optimize_speed"] = Literal[ "optimize_quality" ], - background: str | None = None, - skip_system_fonts: bool | None = None, ) -> list[bytes]: """ :param svg_str: A string containing valid svg. diff --git a/src/rust/lib.rs b/src/rust/lib.rs index c5ad513..12f4cdf 100644 --- a/src/rust/lib.rs +++ b/src/rust/lib.rs @@ -65,7 +65,7 @@ fn load_fonts(options: &mut Opts, fontdb: &mut resvg::usvg::fontdb::Database) { if let Some(font_files) = &options.font_files { for path in font_files { if let Err(e) = fontdb.load_font_file(path) { - println!("Failed to load '{}' cause {}.", path.to_string(), e); + log::warn!("Failed to load '{}' cause {}.", path.to_string(), e); } } } @@ -144,6 +144,8 @@ fn svg_to_bytes( height: Option, zoom: Option, dpi: Option, + // Log informations + log_information: Option, // Resource Directory resources_dir: Option, // Fonts @@ -166,6 +168,12 @@ fn svg_to_bytes( // Skip System Fonts skip_system_fonts: Option, ) -> PyResult> { + if log_information.unwrap_or(false) { + if let Ok(()) = log::set_logger(&LOGGER) { + log::set_max_level(log::LevelFilter::Warn); + } + } + let mut _svg_string = String::new(); if let Some(svg_string) = svg_string { @@ -254,7 +262,7 @@ fn svg_to_bytes( let usvg_options = resvg::usvg::Options { resources_dir: _resources_dir, dpi: dpi.unwrap_or(0) as f32, - font_family: font_family.unwrap_or_else(|| "Times New Roman".to_string()), + font_family: font_family.unwrap_or("Times New Roman".to_owned()), font_size: font_size.unwrap_or(16) as f32, languages: languages.unwrap_or(vec![]), shape_rendering: _shape_rendering, @@ -293,3 +301,35 @@ fn resvg_py(_py: Python, m: &Bound<'_, PyModule>) -> PyResult<()> { m.add_function(wrap_pyfunction!(version, m)?)?; Ok(()) } + +/// A simple stderr logger. +static LOGGER: SimpleLogger = SimpleLogger; +struct SimpleLogger; +impl log::Log for SimpleLogger { + fn enabled(&self, metadata: &log::Metadata) -> bool { + metadata.level() <= log::LevelFilter::Warn + } + + fn log(&self, record: &log::Record) { + if self.enabled(record.metadata()) { + let target = if !record.target().is_empty() { + record.target() + } else { + record.module_path().unwrap_or_default() + }; + + let line = record.line().unwrap_or(0); + let args = record.args(); + + match record.level() { + log::Level::Error => println!("Error (in {}:{}): {}", target, line, args), + log::Level::Warn => println!("Warning (in {}:{}): {}", target, line, args), + log::Level::Info => println!("Info (in {}:{}): {}", target, line, args), + log::Level::Debug => println!("Debug (in {}:{}): {}", target, line, args), + log::Level::Trace => println!("Trace (in {}:{}): {}", target, line, args), + } + } + } + + fn flush(&self) {} +} diff --git a/tests/font/test_font_render.py b/tests/font/test_font_render.py index c1a912e..b712df1 100644 --- a/tests/font/test_font_render.py +++ b/tests/font/test_font_render.py @@ -42,3 +42,6 @@ def test_wtih_kokoro_font(): ).decode("utf-8") assert base == output_dict["svg_with_kokoro_font_output"] + + +test_wtih_kokoro_font() From 5c1a81a1d3dd4b1ea256edac55ca7c4b70ab1737 Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:31:45 +0600 Subject: [PATCH 2/9] Update test_font_render.py --- tests/font/test_font_render.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/font/test_font_render.py b/tests/font/test_font_render.py index b712df1..c1a912e 100644 --- a/tests/font/test_font_render.py +++ b/tests/font/test_font_render.py @@ -42,6 +42,3 @@ def test_wtih_kokoro_font(): ).decode("utf-8") assert base == output_dict["svg_with_kokoro_font_output"] - - -test_wtih_kokoro_font() From d5fdef2fe09fa577c26abc8ebea00f34e9ca0826 Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:34:43 +0600 Subject: [PATCH 3/9] Update CI.yaml --- .github/workflows/CI.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index c7df273..bcbeaf6 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -1,15 +1,14 @@ # This file is autogenerated by maturin v1.5.1 # To update, run # -# maturin generate-ci github +# maturin generate-ci --zig github # name: CI on: push: branches: - - main - - master + - '*' tags: - '*' pull_request: @@ -45,7 +44,7 @@ jobs: uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter + args: --release --out dist --find-interpreter --zig sccache: 'true' manylinux: auto - name: Upload wheels From b503c41797673cab955eacaf713da8b2473cd26d Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:37:22 +0600 Subject: [PATCH 4/9] Update Cargo.toml --- Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 41ce791..c4a8f0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,5 +20,8 @@ svgtypes = "0.15.0" opt-level = 3 [profile.release] +panic = "abort" +codegen-units = 1 lto = "fat" -opt-level = 3 +opt-level ='z' +strip = true \ No newline at end of file From 7b854d3e9bf435e8832d0dd068b3ea97698edb83 Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:45:32 +0600 Subject: [PATCH 5/9] add --- Cargo.toml | 4 +++- poetry.lock | 59 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 7 ++++++ 3 files changed, 68 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c4a8f0e..6e3781b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,9 @@ +cargo-features = ["edition2024"] + [package] name = "resvg_py" version = "0.1.4" -edition = "2021" +edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] diff --git a/poetry.lock b/poetry.lock index 6cfba74..7904402 100644 --- a/poetry.lock +++ b/poetry.lock @@ -340,6 +340,17 @@ files = [ {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, ] +[[package]] +name = "pastel" +version = "0.2.1" +description = "Bring colors to your terminal." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, + {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, +] + [[package]] name = "pluggy" version = "1.5.0" @@ -355,6 +366,24 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "poethepoet" +version = "0.26.1" +description = "A task runner that works well with poetry." +optional = false +python-versions = ">=3.8" +files = [ + {file = "poethepoet-0.26.1-py3-none-any.whl", hash = "sha256:aa43b443fec5d17d7e76771cccd484e5285805301721a74f059c483ad3276edd"}, + {file = "poethepoet-0.26.1.tar.gz", hash = "sha256:aaad8541f6072617a60bcff2562d00779b58b353bd0f1847b06d8d0f2b6dc192"}, +] + +[package.dependencies] +pastel = ">=0.2.1,<0.3.0" +tomli = ">=1.2.2" + +[package.extras] +poetry-plugin = ["poetry (>=1.0,<2.0)"] + [[package]] name = "pygments" version = "2.18.0" @@ -602,6 +631,17 @@ lint = ["docutils-stubs", "flake8", "mypy"] standalone = ["Sphinx (>=5)"] test = ["pytest"] +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + [[package]] name = "tornado" version = "6.4" @@ -639,7 +679,24 @@ h2 = ["h2 (>=4,<5)"] socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] zstd = ["zstandard (>=0.18.0)"] +[[package]] +name = "ziglang" +version = "0.12.0" +description = "Zig is a general-purpose programming language and toolchain for maintaining robust, optimal, and reusable software." +optional = false +python-versions = "~=3.5" +files = [ + {file = "ziglang-0.12.0-py3-none-macosx_10_9_x86_64.whl", hash = "sha256:c6d1053f0e1d486cdf374f33b7ed00d99040d03f45eed5122a7522b0b7a75946"}, + {file = "ziglang-0.12.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:1f9291fd98c4e1ece04285ddf019b9999b2e81fb4f785b550b6d91b1e1699bc9"}, + {file = "ziglang-0.12.0-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:1cb9e6938ec8cddba124ebf2dcaf950e19b5b807eaa18cb976c569e6edef5ae3"}, + {file = "ziglang-0.12.0-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:0c777f1d5d9be32d0edffc79956d03ed35f868a8db7b0552da0984182aa10ff0"}, + {file = "ziglang-0.12.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:8da631bfb5e49390f0551a4412111c8a14671fd7f151e1adcc420317b02efcf6"}, + {file = "ziglang-0.12.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:ccec405a443016647c47edcd48faf15be9d3add21c2c13bc77217b8fe87a1508"}, + {file = "ziglang-0.12.0-py3-none-win32.whl", hash = "sha256:9373c68cf654d69f46411eff2fd48cb8495b8d9bcd6e88b65783ef8ab4bfe4ae"}, + {file = "ziglang-0.12.0-py3-none-win_amd64.whl", hash = "sha256:044136e276e80dfdc7cfaada80efe8679d0ba9f8abf911f8c68afa44ca259148"}, +] + [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "6e6f724ac7d4c9d3fbf916a57381bdaffc5dca5fd727b55a0e208e22541809ad" +content-hash = "c3a7e31d5d8cc1c622df22d9c5906ea6a55ddb1fda172759e2fd9f07f7b686b4" diff --git a/pyproject.toml b/pyproject.toml index 8d54141..2bacbfc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,8 +9,10 @@ package-mode = false [tool.poetry.dependencies] python = "^3.12" + [tool.poetry.group.dev.dependencies] pytest = "^8.1.1" +poethepoet = "^0.26.1" [tool.poetry.group.docs.dependencies] sphinx = "^7.2.6" @@ -38,3 +40,8 @@ Documentation = "https://resvg-py.readthedocs.io/" [tool.maturin] features = ["pyo3/extension-module"] + +[tool.poe.tasks] +test = "pytest . -rP" +"build:release" = "maturin build --release" +"develop" = "maturin build" \ No newline at end of file From 55771db619e59ff7b30c512538516e45b862e34d Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:46:12 +0600 Subject: [PATCH 6/9] Update CI.yaml --- .github/workflows/CI.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml index bcbeaf6..19a48ac 100644 --- a/.github/workflows/CI.yaml +++ b/.github/workflows/CI.yaml @@ -1,7 +1,7 @@ # This file is autogenerated by maturin v1.5.1 # To update, run # -# maturin generate-ci --zig github +# maturin generate-ci github # name: CI @@ -44,7 +44,7 @@ jobs: uses: PyO3/maturin-action@v1 with: target: ${{ matrix.platform.target }} - args: --release --out dist --find-interpreter --zig + args: --release --out dist --find-interpreter sccache: 'true' manylinux: auto - name: Upload wheels From 4d4893392eff8c3b2e162167e509e4c7b2495386 Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:48:22 +0600 Subject: [PATCH 7/9] Update Cargo.toml --- Cargo.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6e3781b..d960f12 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,8 @@ -cargo-features = ["edition2024"] [package] name = "resvg_py" version = "0.1.4" -edition = "2024" +edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [lib] From 1e9c9bf222e51bef37b44237dd69b5f6a3608796 Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 15:49:36 +0600 Subject: [PATCH 8/9] Reduce more size? --- Cargo.toml | 5 +++-- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d960f12..e30e6cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,3 @@ - [package] name = "resvg_py" version = "0.1.4" @@ -18,7 +17,9 @@ svgtypes = "0.15.0" [profile.release.package."*"] -opt-level = 3 +codegen-units = 1 +opt-level ='z' +strip = true [profile.release] panic = "abort" diff --git a/pyproject.toml b/pyproject.toml index 2bacbfc..c352425 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,4 +44,4 @@ features = ["pyo3/extension-module"] [tool.poe.tasks] test = "pytest . -rP" "build:release" = "maturin build --release" -"develop" = "maturin build" \ No newline at end of file +"dev" = "maturin build" \ No newline at end of file From f6ee3ddeeeec09593c5f4cc8e7e72e3c5732d8cd Mon Sep 17 00:00:00 2001 From: baseplate-admin <61817579+baseplate-admin@users.noreply.github.com> Date: Thu, 9 May 2024 16:03:11 +0600 Subject: [PATCH 9/9] add debugging information --- docs/debugging.rst | 37 +++++++++++++++++++++++++++++++++++++ docs/index.rst | 1 + docs/resvg.rst | 2 +- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 docs/debugging.rst diff --git a/docs/debugging.rst b/docs/debugging.rst new file mode 100644 index 0000000..cbdb6b2 --- /dev/null +++ b/docs/debugging.rst @@ -0,0 +1,37 @@ +Debugging +========= + +While `resvg-py`_ is a very thin wrapper around the `resvg`_ project there might be bugs in *resvg-py* (or *resvg*). + +In order to debug the issue you have to enable logging in `resvg-py`_ + +How to log in `resvg-py`_? + +When you call `resvg-py`_'s function in your code you can pass `log_information=True` to print debug information to the stdout + +For example: + +.. code-block:: python + + import resvg_py + import base64 + + svg_string = """ + +   + + """ + + # a large list of bytes + png_bytes: list[bytes] = resvg_py.svg_to_bytes( + svg_string=svg_string, + log_information = True ## <----------- CHECK THIS LINE + ) + base64_utf8_str = base64.b64encode(bytes(png_bytes)).decode("utf-8") + print(f"data:image/png;base64,{base64_utf8_str}") + + + + +.. _resvg-py: https://github.com/baseplate-admin/resvg-py +.. _resvg: https://docs.rs/resvg/latest/resvg/ \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 197d7bb..d743e6e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -15,6 +15,7 @@ Safe bindings for `resvg `_ installation usage resvg + debugging contributing Indices and tables diff --git a/docs/resvg.rst b/docs/resvg.rst index 1967ba9..dee3569 100644 --- a/docs/resvg.rst +++ b/docs/resvg.rst @@ -5,4 +5,4 @@ Resvg Module .. autofunction:: svg_to_bytes -.. autofuncton:: version \ No newline at end of file +.. autofunction:: version \ No newline at end of file