diff --git a/.github/workflows/CI.yaml b/.github/workflows/CI.yaml
index c7df273..19a48ac 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 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
sccache: 'true'
manylinux: auto
- name: Upload wheels
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..e30e6cb 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -10,14 +10,20 @@ 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"
[profile.release.package."*"]
-opt-level = 3
+codegen-units = 1
+opt-level ='z'
+strip = true
[profile.release]
+panic = "abort"
+codegen-units = 1
lto = "fat"
-opt-level = 3
+opt-level ='z'
+strip = true
\ No newline at end of file
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
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..c352425 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"
+"dev" = "maturin build"
\ No newline at end of file
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) {}
+}