Showing preview only (1,367K chars total). Download the full file or copy to clipboard to get everything.
Repository: linebender/resvg
Branch: main
Commit: 3a0fdba53ccf
Files: 135
Total size: 1.3 MB
Directory structure:
gitextract_vwl0jp28/
├── .github/
│ ├── copyright.sh
│ ├── pull_request_template.md
│ └── workflows/
│ ├── main.yml
│ └── tagged-release.yml
├── .gitignore
├── .typos.toml
├── AUTHORS
├── CHANGELOG.md
├── Cargo.toml
├── LICENSE-APACHE
├── LICENSE-MIT
├── README.md
├── crates/
│ ├── c-api/
│ │ ├── Cargo.toml
│ │ ├── LICENSE-APACHE
│ │ ├── LICENSE-MIT
│ │ ├── README.md
│ │ ├── ResvgQt.h
│ │ ├── cbindgen.toml
│ │ ├── examples/
│ │ │ └── cairo/
│ │ │ ├── Makefile
│ │ │ ├── README.md
│ │ │ └── example.c
│ │ ├── lib.rs
│ │ └── resvg.h
│ ├── resvg/
│ │ ├── Cargo.toml
│ │ ├── LICENSE-APACHE
│ │ ├── LICENSE-MIT
│ │ ├── examples/
│ │ │ ├── custom_href_resolver.rs
│ │ │ ├── draw_bboxes.rs
│ │ │ └── minimal.rs
│ │ ├── src/
│ │ │ ├── clip.rs
│ │ │ ├── filter/
│ │ │ │ ├── box_blur.rs
│ │ │ │ ├── color_matrix.rs
│ │ │ │ ├── component_transfer.rs
│ │ │ │ ├── composite.rs
│ │ │ │ ├── convolve_matrix.rs
│ │ │ │ ├── displacement_map.rs
│ │ │ │ ├── iir_blur.rs
│ │ │ │ ├── lighting.rs
│ │ │ │ ├── mod.rs
│ │ │ │ ├── morphology.rs
│ │ │ │ └── turbulence.rs
│ │ │ ├── geom.rs
│ │ │ ├── image.rs
│ │ │ ├── lib.rs
│ │ │ ├── main.rs
│ │ │ ├── mask.rs
│ │ │ ├── path.rs
│ │ │ └── render.rs
│ │ └── tests/
│ │ ├── README.md
│ │ ├── fonts/
│ │ │ ├── Amiri-LICENSE-OFL.txt
│ │ │ ├── CFF-and-SBIX-LICENSE-APACHE.txt
│ │ │ ├── CFF-and-SBIX.otf
│ │ │ ├── MPLUS1p-LICENSE-OFL.txt
│ │ │ ├── Noto-LICENSE-OFL.txt
│ │ │ ├── NotoColorEmojiCBDT-LICENSE_APACHE.txt
│ │ │ ├── NotoZnamennyMusicalNotation-OFL.txt
│ │ │ ├── README.md
│ │ │ ├── RobotoFlex-LICENSE-OFL.txt
│ │ │ ├── SedgwickAveDisplay-LICENSE-OFL.txt
│ │ │ ├── SourceSansPro-LICENSE-OFL.md
│ │ │ ├── TwitterColorEmoji-LICENSE-MIT.txt
│ │ │ └── Yellowtail-LICENSE-Apache2.txt
│ │ ├── gen-tests.py
│ │ ├── integration/
│ │ │ ├── extra.rs
│ │ │ ├── main.rs
│ │ │ └── render.rs
│ │ └── resources/
│ │ ├── green.css
│ │ └── image.svgz
│ └── usvg/
│ ├── Cargo.toml
│ ├── LICENSE-APACHE
│ ├── LICENSE-MIT
│ ├── README.md
│ ├── codegen/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── attributes.txt
│ │ ├── elements.txt
│ │ └── main.rs
│ ├── docs/
│ │ ├── post-processing.md
│ │ └── spec.adoc
│ ├── src/
│ │ ├── lib.rs
│ │ ├── main.rs
│ │ ├── parser/
│ │ │ ├── clippath.rs
│ │ │ ├── converter.rs
│ │ │ ├── filter.rs
│ │ │ ├── image.rs
│ │ │ ├── marker.rs
│ │ │ ├── mask.rs
│ │ │ ├── mod.rs
│ │ │ ├── options.rs
│ │ │ ├── paint_server.rs
│ │ │ ├── shapes.rs
│ │ │ ├── style.rs
│ │ │ ├── svgtree/
│ │ │ │ ├── mod.rs
│ │ │ │ ├── names.rs
│ │ │ │ ├── parse.rs
│ │ │ │ └── text.rs
│ │ │ ├── switch.rs
│ │ │ ├── text.rs
│ │ │ ├── units.rs
│ │ │ └── use_node.rs
│ │ ├── text/
│ │ │ ├── colr.rs
│ │ │ ├── flatten.rs
│ │ │ ├── layout.rs
│ │ │ └── mod.rs
│ │ ├── tree/
│ │ │ ├── filter.rs
│ │ │ ├── geom.rs
│ │ │ ├── mod.rs
│ │ │ └── text.rs
│ │ └── writer.rs
│ └── tests/
│ ├── parser.rs
│ └── write.rs
├── docs/
│ ├── svg2-changelog.md
│ └── unsupported.md
├── tools/
│ ├── explorer-thumbnailer/
│ │ ├── Cargo.toml
│ │ ├── LICENSE-APACHE
│ │ ├── LICENSE-MIT
│ │ ├── LICENSE-SUMMARY.txt
│ │ ├── install/
│ │ │ └── installer.iss
│ │ └── src/
│ │ ├── error.rs
│ │ ├── interfaces/
│ │ │ ├── iinitialize_with_stream.rs
│ │ │ ├── ithumbnail_provider.rs
│ │ │ └── mod.rs
│ │ ├── lib.rs
│ │ ├── thumbnail_provider.rs
│ │ └── utils.rs
│ └── viewsvg/
│ ├── .gitignore
│ ├── README.md
│ ├── main.cpp
│ ├── mainwindow.cpp
│ ├── mainwindow.h
│ ├── mainwindow.ui
│ ├── svgview.cpp
│ ├── svgview.h
│ └── viewsvg.pro
└── version-bump.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/copyright.sh
================================================
#!/bin/bash
# If there are new files with headers that can't match the conditions here,
# then the files can be ignored by an additional glob argument via the -g flag.
# For example:
# -g "!src/special_file.rs"
# -g "!src/special_directory"
# Check all the standard Rust source files
output=$(rg "^// Copyright (19|20)[\d]{2} (.+ and )?the Resvg Authors( and .+)?$\n^// SPDX-License-Identifier: Apache-2\.0 OR MIT$\n\n" --files-without-match --multiline -g "*.{rs,c,cpp,h}" .)
if [ -n "$output" ]; then
echo -e "The following files lack the correct copyright header:\n"
echo $output
echo -e "\n\nPlease add the following header:\n"
echo "// Copyright $(date +%Y) the Resvg Authors"
echo "// SPDX-License-Identifier: Apache-2.0 OR MIT"
echo -e "\n... rest of the file ...\n"
exit 1
fi
echo "All files have correct copyright headers."
exit 0
================================================
FILE: .github/pull_request_template.md
================================================
Pull requests that include:
- dependencies updates
- code formatting fixes
- clippy fixes
- compiler warnings fixes
will not be accepted.
The only exception are spellchecking and grammar fixes.
A pull request must contain a meaningful improvement to the project.
================================================
FILE: .github/workflows/main.yml
================================================
name: Build
on: [push, pull_request]
env:
CARGO_TERM_COLOR: always
jobs:
fmt:
name: formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# TODO: Enable this when more of the Linebender CI has been applied.
#- name: install stable toolchain
# uses: dtolnay/rust-toolchain@master
# with:
# toolchain: ${{ env.RUST_STABLE_VER }}
# components: rustfmt
- name: cargo fmt
run: cargo fmt --all --check
- name: install ripgrep
run: |
sudo apt update
sudo apt install ripgrep
- name: check copyright headers
run: bash .github/copyright.sh
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
# We have to use the Release mode, otherwise it would take forever.
- name: Test
run: cargo test --all --release
- name: Build C API
working-directory: crates/c-api
run: cargo build
- name: Build C API without default features
working-directory: crates/c-api
run: cargo build --no-default-features
- name: Build resvg without default support
working-directory: crates/resvg
run: cargo check --no-default-features
- name: Build usvg without default support
working-directory: crates/usvg
run: cargo check --no-default-features
msrv:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install toolchain
uses: dtolnay/rust-toolchain@stable
with:
toolchain: 1.87.0
- name: Build
run: cargo build
# We have some Windows specific code that we should check on each commit.
windows:
runs-on: windows-latest
steps:
- name: Checkout
uses: actions/checkout@v3
# Toolchain is stable-x86_64-pc-windows-msvc by default. No need to change it.
- name: Build thumbnailer
working-directory: tools/explorer-thumbnailer
env:
RUSTFLAGS: -Ctarget-feature=+crt-static # make sure it's static
run: cargo build
# Unlike other binaries, viewsvg isn't built with crt-static
- name: Build C API
working-directory: crates/c-api
run: cargo build --release
# If this fails, consider changing your text or adding something to .typos.toml.
typos:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: check typos
uses: crate-ci/typos@v1.28.4
================================================
FILE: .github/workflows/tagged-release.yml
================================================
name: "Tagged Release"
on:
push:
tags:
- "v*"
env:
CARGO_TERM_COLOR: always
jobs:
create-release:
name: Create Release
runs-on: ubuntu-latest
steps:
- name: Create Release
id: create_release
uses: softprops/action-gh-release@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
name: ${{ github.ref_name }}
body: |
- `resvg-0.*.0.tar.xz` is a sources archive with vendored Rust dependencies
- `resvg-explorer-extension.exe` is an SVG thumbnailer for Windows Explorer
Check [CHANGELOG](https://github.com/linebender/resvg/blob/${{ github.ref }}/CHANGELOG.md).
draft: false
prerelease: false
outputs:
upload_url: ${{ steps.create_release.outputs.upload_url }}
release-linux:
name: Release Linux
runs-on: ubuntu-latest
needs: ["create-release"]
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Build resvg
run: cargo build --release
- name: Build usvg
working-directory: crates/usvg
run: cargo build --release
- name: Collect
working-directory: target/release
run: |
strip -s resvg
strip -s usvg
tar czf resvg-linux-x86_64.tar.gz resvg
tar czf usvg-linux-x86_64.tar.gz usvg
mkdir ../../bin
cp resvg-linux-x86_64.tar.gz ../../bin/
cp usvg-linux-x86_64.tar.gz ../../bin/
- name: Get version
id: get_version
uses: battila7/get-version-action@v2
- name: Make vendored archive
run: |
VERSION=${{ steps.get_version.outputs.version-without-v }}
echo $VERSION
git clone https://github.com/linebender/resvg resvg-$VERSION
cd resvg-"$VERSION"
mkdir -p .cargo
cargo vendor > .cargo/config
cd ..
env XZ_OPT="-9e" tar \
--exclude=".git" \
--exclude="resvg-$VERSION/.github" \
--exclude="resvg-$VERSION/version-bump.md" \
--exclude="resvg-$VERSION/docs" \
-cJf resvg-"$VERSION".tar.xz resvg-"$VERSION"
cp resvg-"$VERSION".tar.xz bin/
- name: Upload binaries
uses: alexellis/upload-assets@0.2.2
env:
GITHUB_TOKEN: ${{ github.token }}
with:
asset_paths: '["bin/*"]'
release-windows:
name: Release Windows
runs-on: windows-2019
needs: ["create-release"]
steps:
- name: Checkout
uses: actions/checkout@v2
# Toolchain is stable-x86_64-pc-windows-msvc by default. No need to change it.
- name: Build resvg
env:
RUSTFLAGS: -Ctarget-feature=+crt-static # make sure it's static
run: cargo build --release
- name: Build usvg
working-directory: crates/usvg
env:
RUSTFLAGS: -Ctarget-feature=+crt-static # make sure it's static
run: cargo build --release
- name: Compress
working-directory: target/release
shell: cmd
run: |
7z a -tzip -mx9 resvg-win64.zip resvg.exe
7z a -tzip -mx9 usvg-win64.zip usvg.exe
- name: Build thumbnailer
working-directory: tools/explorer-thumbnailer
env:
RUSTFLAGS: -Ctarget-feature=+crt-static # make sure it's static
run: cargo build --release
- name: Build thumbnailer installer
working-directory: tools/explorer-thumbnailer/install
shell: cmd
run: |
"%programfiles(x86)%\Inno Setup 6\iscc.exe" "installer.iss"
# Unlike other binaries, viewsvg isn't built with crt-static
- name: Build C API
working-directory: crates/c-api
run: cargo build --release
- name: Prepare Developer Command Prompt for MSVC
uses: ilammy/msvc-dev-cmd@v1
- name: Collect
run: |
mkdir bin
cp target/release/resvg-win64.zip bin/
cp target/release/usvg-win64.zip bin/
cp tools/explorer-thumbnailer/install/resvg-explorer-extension.exe bin/
- name: Upload binaries
uses: alexellis/upload-assets@0.2.2
env:
GITHUB_TOKEN: ${{ github.token }}
with:
asset_paths: '["bin/*"]'
release-macos-aarch64:
name: Release macOS (aarch64)
runs-on: macos-latest
needs: ["create-release"]
steps:
- name: Checkout
uses: actions/checkout@v2
# Some weird CI glitch. Make sure we have the latest Rust.
- name: Install latest stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Build resvg
run: cargo build --release
- name: Build usvg
working-directory: crates/usvg
run: cargo build --release
- name: Compress
working-directory: target/release
run: |
7z a -tzip -mx9 resvg-macos-aarch64.zip resvg
7z a -tzip -mx9 usvg-macos-aarch64.zip usvg
- name: Build C API
working-directory: crates/c-api
run: cargo build --release
- name: Collect
run: |
mkdir bin
cp target/release/resvg-macos-aarch64.zip bin/
cp target/release/usvg-macos-aarch64.zip bin/
- name: Upload binaries
uses: alexellis/upload-assets@0.2.2
env:
GITHUB_TOKEN: ${{ github.token }}
with:
asset_paths: '["bin/*"]'
release-macos-intel:
name: Release macOS (intel)
runs-on: macos-15-intel
needs: ["create-release"]
steps:
- name: Checkout
uses: actions/checkout@v2
# Some weird CI glitch. Make sure we have the latest Rust.
- name: Install latest stable toolchain
uses: dtolnay/rust-toolchain@stable
- name: Build resvg
run: cargo build --release
- name: Build usvg
working-directory: crates/usvg
run: cargo build --release
- name: Compress
working-directory: target/release
run: |
7z a -tzip -mx9 resvg-macos-x86_64.zip resvg
7z a -tzip -mx9 usvg-macos-x86_64.zip usvg
- name: Build C API
working-directory: crates/c-api
run: cargo build --release
- name: Collect
run: |
mkdir bin
cp target/release/resvg-macos-x86_64.zip bin/
cp target/release/usvg-macos-x86_64.zip bin/
- name: Upload binaries
uses: alexellis/upload-assets@0.2.2
env:
GITHUB_TOKEN: ${{ github.token }}
with:
asset_paths: '["bin/*"]'
================================================
FILE: .gitignore
================================================
target
.directory
.DS_Store
.vscode
tools/build-*
**/diffs
================================================
FILE: .typos.toml
================================================
# See the configuration reference at
# https://github.com/crate-ci/typos/blob/master/docs/reference.md
# Corrections take the form of a key/value pair. The key is the incorrect word
# and the value is the correct word. If the key and value are the same, the
# word is treated as always correct. If the value is an empty string, the word
# is treated as always incorrect.
# Match Identifier - Case Sensitive
[default.extend-identifiers]
ba = "ba"
flate2 = "flate2"
Hel = "Hel"
PNGs = "PNGs"
SVGinOT = "SVGinOT"
# Match Inside a Word - Case Insensitive
[default.extend-words]
wdth = "wdth"
[files]
# Include .github, .cargo, etc.
ignore-hidden = false
extend-exclude = [
# /.git isn't in .gitignore, because git never tracks it.
# Typos doesn't know that, though.
"/.git",
"*.svg",
]
================================================
FILE: AUTHORS
================================================
# This is the list of Resvg's significant contributors.
#
# This does not necessarily list everyone who has contributed code,
# especially since many employees of one corporation may be contributing.
# To see the full list of contributors, see the revision history in
# source control.
Yevhenii Reizner
Laurenz Stampfl
================================================
FILE: CHANGELOG.md
================================================
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
This changelog also contains important changes in dependencies.
## [Unreleased]
This release has an MSRV of 1.87.0 for `usvg` and `resvg` and the C API.
## [0.47.0] 2026-02-05
This release has an MSRV of 1.87.0 for `usvg` and `resvg` and the C API.
### Added
- Focal radius (`fr`) supported for Radial Gradients. (#1014 by @wmedrano)
- Support for variable fonts based on font-variation-settings CSS property. (#997 by @oetiker)
### Changed
- `tiny-skia` has a major version bump from 0.11 to 0.12.
## [0.46.0]
This release has an MSRV of 1.87.0 for `usvg` and `resvg` and the C API.
### Added
- Support SVGs without the xmlns attribute on the root. Thanks to [@JosefKuchar][].
- Add a from_data_nested method to usvg::Tree (#955 by @tovrstra)
- Use cache for glyph outlining (#957 by @newinnovations)
- Support loading nested embedded images (#958 by @LaurenzV)
### Changed
- Bump dependencies, bump MSRV to 1.87, Upgrade to edition 2024 (#1002 and #1003 @LaurenzV)
- Upgraded kurbo to 0.13 and svgtypes to 0.16.1. Thanks to [@HaHa421][].
- Bump zune_jpeg (#964 by @LaurenzV)
- Fix abs_bounding_box calculation for image (#924 by @Dabble63)
- Fix crash caused by glyph splitting (#929 by @arnaud-secondlayer)
- Fix a bug with incorrect resolving of fill/stroke color (#953 by @LaurenzV)
- Fix inverted condition in has_text_nodes method (#967 by @Daaiid)
- Do not write empty defs nodes (#980 by @Its-Just-Nans)
- Check if text paths need to be written out (#981 by @Its-Just-Nans)
- Use checked arithmetic when computing bounding box (#987 by @Its-Just-Nans)
- Fix bug in rewriting of clip paths with transformed path (#988 by @Its-Just-Nans)
### Removed
- Remove unused phf dependency (#920)
## [0.45.1] - 2025-04-16
### Changed
- Support SVGs without the xmlns attribute on the root (#892)
- Add optimization for paths with markers in paint-order but no actual markers (#887)
### Removed
- tools/kde-dolphin-thumbnailer. This was never a released tool, and it doesn't support current versions of KDE/dolphin ([#897][] by [@DJMcNab][])
## [0.45.0] - 2025-02-26
This is the first release under the stewardship of [Linebender][], who is now responsible for maintenance of this crate.
Many thanks to Yevhenii Reizner for the years of hard work that he has poured into this and other crates.
Please note that the license of this project changed from `MPL-2.0` to `Apache-2.0 OR MIT`.
See [resvg#838](https://github.com/linebender/resvg/issues/838) for more information.
This release has an MSRV of 1.65 for `usvg` and 1.67.1 for `resvg` and the C API.
### Added
- Support for the `background-color` attribute.
- Support for additional `image-rendering` attributes.
- Support for the `!important` CSS flag.
- Support for Luma JPEG images.
- (c-api) `resvg_options_set_stylesheet`.
Thanks to [@michabay05][].
- (svgtypes) Support for floating point hue in `hsl()` and `hsla()`.
### Changed
- License to `Apache-2.0 OR MIT`.
See [resvg#838](https://github.com/linebender/resvg/issues/838) for more information.
- Updated WebP decoder for bug fixes and improved performance.
Thanks to [@Shnatsel][].
- MSRV of resvg and c-api bumped to 1.67.1.
- `fontdb` and `rustybuzz` have been updated.
- Updated other dependencies.
- (svgtypes) Simplified color component rounding and bounds checking.
- Improved handling of paths with paint order `markers` but no actual markers.
### Fixed
- Relative unit handling when `use` references `symbol`.
- (svgtypes) Rounding of hues in HSL to RGB conversion.
- (svgtypes) Rounding of alpha.
## [0.44.0] - 2024-09-28
### Added
- Stylesheet injection support.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- (c-api) `resvg_get_object_bbox`
- (c-api) `cargo-c` metadata.
Thanks to [@lu-zero](https://github.com/lu-zero).
- Implement `From` for `fontdb` and `usvg` font types.
Thanks to [@dhardy](https://github.com/dhardy).
### Changed
- (c-api) `resvg_get_image_bbox` returns a _layer_ and not _object_ bounding box now.
Use `resvg_get_object_bbox` to preserve the old behavior.
### Fixed
- (svgtypes) Path parsing with `S` or `T` segments after `A`.
- Bounding box calculation for the root group used for `viewBox` flattening.
## [0.43.0] - 2024-08-10
### Added
- Support WebP images.
Thanks to [@notjosh](https://github.com/notjosh).
### Changed
- Use `zune-jpeg` instead of `jpeg-decoder`.
Thanks to [@mattfbacon](https://github.com/mattfbacon).
- Update dependencies.
### Fixed
- Canvas size limits calculation.
- SVG fonts handling.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- Transforms in COLR fonts.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
## [0.42.0] - 2024-06-01
### Added
- `resvg` can render color fonts now, aka Emojis.<br>
In TrueType terms, `COLRv0`, `COLRv1` (mostly), `sbix`, `CBDT` and `SVG` tables are supported.<br>
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- Fonts matching and fallback can be controlled by the caller via `usvg::FontResolver` now.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- `usvg::Options::font_resolver`. Similar to `usvg::Options::image_href_resolver` we already had.
- `usvg::Options::fontdb`
- Support double-quoted FuncIRIs, aka `url("#id")`.
- `image` element viewbox flattening.<br>
Instead of having `usvg::Image::view_box` that the caller should handle themselves,
we instead replace it with `transform` and optional `clip-path`.
This greatly simplifies `image` rendering.
- `usvg::Image::size`
- Tree viewbox flattening.<br>
Similar to `image` above, but affects the root `svg` element instead.
- `pattern` viewbox flattening.<br>
Similar to `image` above, but for patterns.
- Improve vertical text rendering.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
### Changed
- `usvg::fontdb::Database` should be set in `usvg::Options` and not passed
to the parser separately now.
- `usvg::Options` and `usvg::ImageHrefResolver` have a lifetime now.
- Replace `usvg::Visibility` enum with just `bool`.
- `usvg::Path::visibility()` is replaced with `usvg::Path::is_visible()`
- `usvg::Image::visibility()` is replaced with `usvg::Image::is_visible()`
- `usvg::TextSpan::visibility()` is replaced with `usvg::TextSpan::is_visible()`
- Always represent `feImage` content as a link to an element.<br>
In SVG, `feImage` can contain a link to an element or a base64 image data, just like `image`.
From now, the inlined base64 data will always be represented by a link to an actual `image` element.
```xml
<filter>
<feImage xlink:href="data:image/png;base64,..."/>
</filter>
```
will be parsed as
```xml
<image id="image1" xlink:href="data:image/png;base64,..."/>
<filter>
<feImage xlink:href="#image1"/>
</filter>
```
This simplifies `feImage` rendering, since we don't have to handle both cases now.
- The `--list-fonts` resvg argument can be used without providing an SVG file now.
Can simply call `resvg --list-fonts` now.
- The `--list-fonts` resvg argument includes generic font family names as well now.
- Make sure all warning and errors are printed to stderr.
Thanks to [@ahaoboy](https://github.com/ahaoboy).
### Removed
- `usvg::ViewBox`, `usvg::AspectRatio`, `usvg::Align` types. Nol longer used.
- `usvg::filter::Image::aspect`. No longer needed.
- `usvg::filter::Image::rendering_mode`. No longer needed.
- `usvg::filter::Image::data`. Use `usvg::filter::Image::root` instead.
- `usvg::Tree::view_box`. No longer needed.
- `usvg::Image::view_box`. No longer needed.
- `usvg::Image::pattern`. No longer needed.
- `usvg::utils::align_pos`. No longer needed.
- `usvg::Visibility`. No longer needed.
- (c-api) `resvg_get_image_viewbox`. Use `resvg_get_image_size` instead.
### Fixed
- `context-fill` handling.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
## [0.41.0] - 2024-04-03
### Added
- `context-fill` and `context-stroke` support.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- `usvg::Text::layouted()`, which returns a list of glyph IDs.
It can be used to manually draw glyphs, unlike with `usvg::Text::flattened()`, which returns
just vector paths.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
### Fixed
- Missing text when a `text` element uses multiple fonts and one of them produces ligatures.
- Absolute transform propagation during `use` resolving.
- Absolute transform propagation during nested `svg` resolving.
- `Node::abs_transform` documentation. The current element's transform _is_ included.
## [0.40.0] - 2024-02-17
### Added
- `usvg::Tree` is `Send + Sync` compatible now.
- `usvg::WriteOptions::preserve_text` to control how `usvg` generates an SVG.
- `usvg::Image::abs_bounding_box`
### Changed
- All types in `usvg` are immutable now. Meaning that `usvg::Tree` cannot be modified
after creation anymore.
- All struct fields in `usvg` are private now. Use getters instead.
- All `usvg::Tree` parsing methods require the `fontdb` argument now.
- All `defs` children like gradients, patterns, clipPaths, masks and filters are guarantee
to have a unique, non-empty ID.
- All `defs` children like gradients, patterns, clipPaths, masks and filters are guarantee
to have `userSpaceOnUse` units now. No `objectBoundingBox` units anymore.
- `usvg::Mask` is allowed to have no children now.
- Text nodes will not be parsed when the `text` build feature isn't enabled.
- `usvg::Tree::clip_paths`, `usvg::Tree::masks`, `usvg::Tree::filters` returns
a pre-collected slice of unique nodes now.
It's no longer a closure and you do not have to deduplicate nodes by yourself.
- `usvg::filter::Primitive::x`, `y`, `width` and `height` methods were replaced
with `usvg::filter::Primitive::rect`.
- Split `usvg::Tree::paint_servers` into `usvg::Tree::linear_gradients`,
`usvg::Tree::radial_gradients`, `usvg::Tree::patterns`.
All three returns pre-collected slices now.
- A `usvg::Path` no longer can have an invalid bbox. Paths with an invalid bbox will be
rejected during parsing.
- All `usvg` methods that return bounding boxes return non-optional `Rect` now.
No `NonZeroRect` as well.
- `usvg::Text::flattened` returns `&Group` and not `Option<&Group>` now.
- `usvg::ImageHrefDataResolverFn` and `usvg::ImageHrefStringResolverFn`
require `fontdb::Database` argument.
- All shared nodes are stored in `Arc` and not `Rc<RefCell>` now.
- `resvg::render_node` now includes filters bounding box. Meaning that a node with a blur filter
no longer be clipped.
- Replace `usvg::utils::view_box_to_transform` with `usvg::ViewBox::to_transform`.
- Rename `usvg::XmlOptions` into `usvg::WriteOptions` and embed `xmlwriter::Options`.
### Removed
- `usvg::Tree::postprocess()` and `usvg::PostProcessingSteps`. No longer needed.
- `usvg::ClipPath::units()`, `usvg::Mask::units()`, `usvg::Mask::content_units()`,
`usvg::Filter::units()`, `usvg::Filter::content_units()`, `usvg::LinearGradient::units()`,
`usvg::RadialGradient::units()`, `usvg::Pattern::units()`, `usvg::Pattern::content_units()`
and `usvg::Paint::units()`. They are always `userSpaceOnUse` now.
- `usvg::Units`. No longer needed.
### Fixed
- Text bounding box is accounted during SVG size resolving.
Previously, only paths and images were included.
- Font selection when an italic font isn't explicitly marked as one.
- Preserve `image` aspect ratio when only `width` or `height` are present.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
## [0.39.0] - 2024-02-06
### Added
- `font` shorthand parsing.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- `usvg::Group::abs_bounding_box`
- `usvg::Group::abs_stroke_bounding_box`
- `usvg::Path::abs_bounding_box`
- `usvg::Path::abs_stroke_bounding_box`
- `usvg::Text::abs_bounding_box`
- `usvg::Text::abs_stroke_bounding_box`
### Changed
- All `usvg-*` crates merged into one. There is just the `usvg` crate now, as before.
### Removed
- `usvg::Group::abs_bounding_box()` method. It's a field now.
- `usvg::Group::abs_filters_bounding_box()`
- `usvg::TreeParsing`, `usvg::TreePostProc` and `usvg::TreeWriting` traits.
They are no longer needed.
### Fixed
- `font-family` parsing.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- Absolute bounding box calculation for paths.
## [0.38.0] - 2024-01-21
### Added
- Each `usvg::Node` stores its absolute transform now.
`Node::abs_transform()` executes in constant time now.
- `usvg::Tree::calculate_bounding_boxes` to calculate all bounding boxes beforehand.
- `usvg::Node::bounding_box` which returns a precalculated node's bounding box in object coordinates.
- `usvg::Node::abs_bounding_box` which returns a precalculated node's bounding box in canvas coordinates.
- `usvg::Node::stroke_bounding_box` which returns a precalculated node's bounding box,
including stroke, in object coordinates.
- `usvg::Node::abs_stroke_bounding_box` which returns a precalculated node's bounding box,
including stroke, in canvas coordinates.
- (c-api) `resvg_get_node_stroke_bbox`
- `usvg::Node::filters_bounding_box`
- `usvg::Node::abs_filters_bounding_box`
- `usvg::Tree::postprocess`
### Changed
- `resvg` renders `usvg::Tree` directly again. `resvg::Tree` is gone.
- `usvg` no longer uses `rctree` for the nodes tree implementation.
The tree is a regular `enum` now.
- A caller no longer need to use the awkward `*node.borrow()`.
- No more panics on incorrect mutable `Rc<RefCell>` access.
- Tree nodes respect tree's mutability rules. Before, one could mutate tree nodes when the tree
itself is not mutable. Because `Rc<RefCell>` provides a shared mutable access.
- Filters, clip paths, masks and patterns are stored as `Rc<RefCell<T>>` instead of `Rc<T>`.
This is required for proper mutability since `Node` itself is no longer an `Rc`.
- Rename `usvg::NodeKind` into `usvg::Node`.
- Upgrade to Rust 2021 edition.
### Removed
- `resvg::Tree`. No longer needed. `resvg` can render `usvg::Tree` directly once again.
- `rctree::Node` methods. The `Node` API is completely different now.
- `usvg::NodeExt`. No longer needed.
- `usvg::Node::calculate_bbox`. Use `usvg::Node::abs_bounding_box` instead.
- `usvg::Tree::convert_text`. Use `usvg::Tree::postprocess` instead.
- `usvg::TreeTextToPath` trait. No longer needed.
### Fixed
- Mark `mask-type` as a presentation attribute.
- Do not show needless warnings when parsing some attributes.
- `feImage` rendering with a non-default position.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
## [0.37.0] - 2023-12-16
### Added
- `usvg` can write text back to SVG now.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- `--preserve-text` flag to the `usvg` CLI tool.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- Support [`transform-origin`](https://drafts.csswg.org/css-transforms/#transform-origin-property)
property.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- Support non-default markers order via
[`paint-order`](https://svgwg.org/svg2-draft/painting.html#PaintOrder).
Previously, only fill and stroke could have been swapped.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- `usvg_tree::Text::flattened` that will contain a flattened/outlined text.
- `usvg_tree::Text::bounding_box`. Will be set only after text flattening.
- Optimize `usvg_tree::NodeExt::abs_transform` by storing absolute transforms in the tree
instead of calculating them each time.
### Changed
- `usvg_tree::Text::positions` was replaced with `usvg_tree::Text::dx` and `usvg_tree::Text::dy`.<br>
`usvg_tree::CharacterPosition::x` and `usvg_tree::CharacterPosition::y` are gone.
They were redundant and you should use `usvg_tree::TextChunk::x`
and `usvg_tree::TextChunk::y` instead.
- `usvg_tree::LinearGradient::id` and `usvg_tree::RadialGradient::id` are moved to
`usvg_tree::BaseGradient::id`.
- Do not generate element IDs during parsing. Previously, some elements like `clipPath`s
and `filter`s could have generated IDs, but it wasn't very reliable and mostly unnecessary.
Renderer doesn't rely on them and usvg writer would generate them anyway.
- Text-to-paths conversion via `usvg_text_layout::Tree::convert_text` no longer replaces
original text elements with paths, but instead puts them into `usvg_tree::Text::flattened`.
### Removed
- The `transform` field from `usvg_tree::Path`, `usvg_tree::Image` and `usvg_tree::Text`.
Only `usvg_tree::Group` can have it.<br>
It doesn't break anything, because those properties were never used before anyway.<br>
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- `usvg_tree::CharacterPosition`
- `usvg_tree::Path::text_bbox`. Use `usvg_tree::Text::bounding_box` instead.
- `usvg_text_layout::TextToPath` trait for `Text` nodes.
Only the whole tree can be converted at once.
### Fixed
- Path object bounding box calculation. We were using point bounds instead of tight contour bounds.
Was broken since v0.34
- Convert text-to-paths in embedded SVGs as well. The one inside the `Image` node.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- Indirect `text-decoration` resolving in some cases.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- (usvg) Clip paths writing to SVG.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
## [0.36.0] - 2023-10-01
### Added
- `stroke-linejoin=miter-clip` support. SVG2.
Thanks to [@torokati44](https://github.com/torokati44).
- Quoted FuncIRI support. Like `fill="url('#gradient')"`. SVG2.
Thanks to [@romanzes](https://github.com/romanzes).
- Allow float values in `rgb()` and `rgba()` colors. SVG2.
Thanks to [@yisibl](https://github.com/yisibl).
- `auto-start-reverse` variant support to `orient` in markers. SVG2.
Thanks to [@EpicEricEE](https://github.com/EpicEricEE).
### Changed
- Update dependencies.
### Fixed
- Increase precision of the zero-scale transform check.
Was rejecting some valid transforms before.
- Panic when rendering a very specific text.
- Greatly improve parsing performance when an SVG has a lot of references.
Thanks to [@wez](https://github.com/wez).
- (Qt API) Fix scaling factor calculation.
Thanks to [@missdeer](https://github.com/missdeer).
## [0.35.0] - 2023-06-27
### Fixed
- Panic when an element is completely outside the viewbox.
### Removed
- `FillPaint` and `StrokePaint` filter inputs support.
It's a mostly undocumented SVG feature that no one supports and no one uses.
And it was adding a significant complexity to the codebase.
- `usvg::filter::Filter::fill_paint` and `usvg::filter::Filter::stroke_paint`.
- `BackgroundImage`, `BackgroundAlpha`, `FillPaint` and `StrokePaint` from `usvg::filter::Input`.
- `usvg::Group::filter_fill_paint` and `usvg::Group::filter_stroke_paint`.
## [0.34.1] - 2023-05-28
### Fixed
- Transform components order. Affects only `usvg` SVG output and C API.
## [0.34.0] - 2023-05-27
### Changed
- `usvg` uses `tiny-skia` geometry primitives now, including the `Path` container.<br>
The main difference compared to the old `usvg` primitives
is that `tiny-skia` uses `f32` instead of `f64`.
So while in theory we could loose some precision, in practice, `f32` is used mainly
as a storage type and precise math operations are still done using `f64`.<br>
`tiny-skia` primitives are move robust, strict and have a nicer API.<br>
More importantly, this change reduces the peak memory usages for SVGs with large paths
(in terms of the number of segments).
And removes the need to convert `usvg::PathData` into `tiny-skia::Path` before rendering.
Which was just a useless reallocation.
- All numbers are stored as `f32` instead of `f64` now.
- Because we use `tiny-skia::Path` now, we allow _quadratic curves_ as well.
This includes `usvg` CLI output.
- Because we allow _quadratic curves_ now, text might render slightly differently (better?).
This is because TrueType fonts contain only _quadratic curves_
and we were converting them to cubic before.
- `usvg::Path` no longer implements `Default`. Use `usvg::Path::new` instead.
- Replace `usvg::Rect` with `tiny_skia::NonZeroRect`.
- Replace `usvg::PathBbox` with `tiny_skia::Rect`.
- Unlike the old `usvg::PathBbox`, `tiny_skia::Rect` allows both width and height to be zero.
This is not an error.
- `usvg::filter::Turbulence::base_frequency` was split into `base_frequency_x` and `base_frequency_y`.
- `usvg::NodeExt::calculate_bbox` no longer includes stroke bbox.
- (c-api) Use `float` instead of `double` everywhere.
- The `svgfilters` crate was merged into `resvg`.
- The `rosvgtree` crate was merged into `usvg-parser`.
- `usvg::Group::filter_fill` moved to `usvg::filter::Filter::fill_paint`.
- `usvg::Group::filter_stroke` moved to `usvg::filter::Filter::stroke_paint`.
### Remove
- `usvg::Point`. Use `tiny_skia::Point` instead.
- `usvg::FuzzyEq`. Use `usvg::ApproxEqUlps` instead.
- `usvg::FuzzyZero`. Use `usvg::ApproxZeroUlps` instead.
- (c-api) `resvg_path_bbox`. Use `resvg_rect` instead.
- `svgfilters` crate.
- `rosvgtree` crate.
### Fixed
- Write `transform` on `clipPath` children in `usvg` SVG output.
- Do not duplicate marker children IDs.
Previously, each element resolved for a marker would preserve its ID.
Affects only `usvg` SVG output and doesn't affect rendering.
## [0.33.0] - 2023-05-17
### Added
- A new rendering algorithm.<br>
When rendering [isolated groups](https://razrfalcon.github.io/notes-on-svg-parsing/isolated-groups.html),
aka layers, we have to know the layer bounding box beforehand, which is ridiculously hard in SVG.<br>
Previously, resvg would simply use the canvas size for all the layers.
Meaning that to render a 10x10px layer on a 1000x1000px canvas, we would have to allocate and then blend
a 1000x1000px layer, which is just a waste of CPU cycles.<br>
The new rendering algorithm is able to calculate layer bounding boxes, which dramatically improves
performance when rendering a lot of tiny layers on a large canvas.<br>
Moreover, it makes performance more linear with a canvas size increase.<br>
The [paris-30k.svg](https://github.com/google/forma/blob/681e8bfd348caa61aab47437e7d857764c2ce522/assets/svgs/paris-30k.svg)
sample from [google/forma](https://github.com/google/forma) is rendered _115 times_ faster on M1 Pro now.
From ~33760ms down to ~290ms. 5269x3593px canvas.<br>
If we restrict the canvas to 1000x1000px, which would contain only the actual `paris-30k.svg` content,
then we're _13 times_ faster. From ~3252ms down to ~253ms.
- `resvg::Tree`, aka a render tree, which is an even simpler version of `usvg::Tree`.
`usvg::Tree` had to be converted into `resvg::Tree` before rendering now.
### Changed
- Restructure the root directory. All crates are in the `crates` directory now.
- Restructure tests. New directory structure and naming scheme.
- Use `resvg::Tree::render` instead of `resvg::render`.
- resvg's `--export-area-drawing` option uses calculated bounds instead of trimming
excessive alpha now. It's faster, but can lead to a slightly different output.
- (c-api) Removed `fit_to` argument from `resvg_render`.
- (c-api) Removed `fit_to` argument from `resvg_render_node`.
- `usvg::ScreenSize` moved to `resvg`.
- `usvg::ScreenRect` moved to `resvg`.
- Rename `resvg::ScreenSize` into `resvg::IntSize`.
- Rename `resvg::ScreenRect` into `resvg::IntRect`.
### Removed
- `filter` build feature from `resvg`. Filters are always enabled now.
- `resvg::FitTo`
- `usvg::utils::view_box_to_transform_with_clip`
- `usvg::Size::to_screen_size`. Use `resvg::IntSize::from_usvg` instead.
- `usvg::Rect::to_screen_size`. Use `resvg::IntSize::from_usvg(rect.size())` instead.
- `usvg::Rect::to_screen_rect`. Use `resvg::IntRect::from_usvg` instead.
- (c-api) `resvg_fit_to`
- (c-api) `resvg_fit_to_type`
### Fixed
- Double quotes parsing in `font-family`.
## [0.32.0] - 2023-04-23
### Added
- Clipping and masking is up to 20% faster.
- `mask-type` property support. SVG2
- `usvg_tree::MaskType`
- `usvg_tree::Mask::kind`
- (rosvgtree) New SVG 2 mask attributes.
### Changed
- `BackgroundImage` and `BackgroundAlpha` filter inputs will produce the same output
as `SourceGraphic` and `SourceAlpha` respectively.
### Removed
- `enable-background` support. This feature was never supported by browsers
and was deprecated in SVG 2. To my knowledge, only Batik has a good support of it.
Also, it's a performance nightmare, which caused multiple issues in resvg already.
- `usvg_tree::EnableBackground`
- `usvg_tree::Group::enable_background`
- `usvg_tree::NodeExt::filter_background_start_node`
### Fixed
- Improve rectangular clipping anti-aliasing quality.
- Mask's RGB to Luminance converter was ignoring premultiplied alpha.
## [0.31.1] - 2023-04-22
### Fixed
- Use the latest `tiny-skia` to fix SVGs with large masks rendering.
## [0.31.0] - 2023-04-10
### Added
- `usvg::Tree::paint_servers`
- `usvg::Tree::clip_paths`
- `usvg::Tree::masks`
- `usvg::Tree::filters`
- `usvg::Node::subroots`
- (usvg) `--coordinates-precision` and `--transforms-precision` writing options.
Thanks to [@flxzt](https://github.com/flxzt).
### Fixed
- `fill-opacity` and `stroke-opacity` resolving.
- Double `transform` when resolving `symbol`.
- `symbol` clipping when its viewbox is the same as the document one.
- (usvg) Deeply nested gradients, patterns, clip paths, masks and filters
were ignored during SVG writing.
- Missing text in nested clip paths and mask, text decoration patterns, filter inputs and feImage.
## [0.30.0] - 2023-03-25
### Added
- Readd `usvg` CLI tool. Can be installed via cargo as before.
### Changed
- Extract most `usvg` internals into new `usvg-tree` and `usvg-parser` crates.
`usvg-tree` contains just the SVG tree and all the types.
`usvg-parser` parsers SVG into `usvg-tree`.
And `usvg` is just an umbrella crate now.
- To use `usvg::Tree::from*` methods one should import the `usvg::TreeParsing` trait now.
- No need to import `usvg-text-layout` manually anymore. It is part of `usvg` now.
- `rosvgtree` no longer reexports `svgtypes`.
- `rosvgtree::Node::attribute` returns just a string now.
- `rosvgtree::Node::find_attribute` returns just a `rosvgtree::Node` now.
- Rename `usvg::Stretch` into `usvg::FontStretch`.
- Rename `usvg::Style` into `usvg::FontStyle`.
- `usvg::FitTo` moved to `resvg::FitTo`.
- `usvg::IsDefault` trait is private now.
### Removed
- `rosvgtree::FromValue`. Due to Rust's orphan rules this trait is pretty useless.
### Fixed
- Recursive markers detection.
- Skip malformed `transform` attributes without skipping the whole element.
- Clipping path rectangle calculation for nested `svg` elements.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- Panic when applying `text-decoration` on text with only one cluster.
Thanks to [@LaurenzV](https://github.com/LaurenzV).
- (Qt API) Image size wasn't initialized. Thanks to [@missdeer](https://github.com/missdeer).
- `resvg` CLI allows files with XML DTD again.
- (svgtypes) Handle implicit MoveTo after ClosePath segments.
## [0.29.0] - 2023-02-04
### Added
- `resvg` CLI loads system fonts only when an input SVG has text nodes now.
Fonts loading is an IO-heavy operation and by avoiding it we can speed up `resvg` execution.
- `usvg::Group::should_isolate`
- `usvg::Tree::has_text_nodes`
### Changed
- Some `usvg` internals were moved into the new `rosvgtree` crate.
- Dummy groups are no longer removed. Use `usvg::Group::should_isolate` to check
if a group affects rendering.
- `usvg-text-layout::TreeTextToPath::convert_text` no longer has the `keep_named_groups` argument.
- MSRV bumped to 1.65
- Update dependencies.
### Removed
- `usvg::Options::keep_named_groups`. Dummy groups are no longer removed.
- (c-api) `resvg_options_set_keep_named_groups`
- (Qt API) `ResvgOptions::setKeepNamedGroups`
### Fixed
- Missing `font-family` handling.
- `font-weight` resolving.
## [0.28.0] - 2022-12-03
### Added
- `usvg::Text` and `usvg::NodeKind::Text`.
### Changed
- `usvg` isn't converting text to paths by default now. A caller must call
`usvg::Tree::convert_text` or `usvg::Text::convert` from `usvg-text-layout` crate on demand.
- `usvg` text layout implementation moved into `usvg-text-layout` crate.
- During SVG size recovery, when no `width`, `height` and `viewBox` attributes have been set,
text nodes are no longer taken into an account. This is because a text node has no bbox
before conversion into path(s), which we no longer doing during parsing.
- `usvg` is purely an SVG parser now. It doesn't convert text to paths
and doesn't write SVG anymore.
- `usvg::filter::ConvolveMatrixData` methods are fields now.
### Removed
- `usvg` CLI binary. No alternatives for now.
- All `usvg` build features.
- `filter`. Filter elements are always parsed by `usvg` now.
- `text`. Text elements are always parsed by `usvg` now.
- `export`. `usvg` cannot write an SVG anymore.
- `usvg::Tree::to_string`. `usvg` cannot write an SVG anymore.
- `usvg::TransformFromBBox` trait. This is just a regular `usvg::Transform` method now.
- `usvg::OptionsRef`. `usvg::Options` is enough from now.
- `usvg::Options::fontdb`. Used only by `usvg-text-layout` now.
- `--dump-svg` from `resvg`.
## [0.27.0] - 2022-11-27
### Added
- `lengthAdjust` and `textLength` attributes support.
- Support automatic `image` size detection.
`width` and `height` attributes can be omitted or set to `auto` on `image` now. SVG2
### Fixed
- `--query-all` flag in `resvg` CLI.
- Percentage values resolving.
## [0.26.1] - 2022-11-21
### Fixed
- Allow `dominant-baseline` and `alignment-baseline` to be set via CSS.
## [0.26.0] - 2022-11-20
### Added
- Minimal `dominant-baseline` and `alignment-baseline` support.
- `mix-blend-mode` and `isolation` support. SVG2
- Allow writing resvg output to stdout.
- Allow disabling text kerning using `kerning="0"` and `style="font-kerning:none"`. SVG2
- Allow `<percentage>` values for `opacity`, `fill-opacity`, `stroke-opacity`,
`flood-opacity` and `stop-opacity` attributes.<br>
You can write `opacity="50%"` now. SVG2
### Changed
- Disable focal point correction on radial gradients to conform with SVG 2. SVG2
- Update `feMorphology` radius value resolving.
### Fixed
- Do not clip nested `svg` when only the `viewBox` attribute is present.
## [0.25.0] - 2022-10-30
### Added
- Partial `paint-order` attribute support.
Markers can only be under or above the shape.
### Fixed
- Compilation issues caused by `rustybuzz` update.
## [0.24.0] - 2022-10-22
### Added
- CSS3 `writing-mode` variants `vertical-rl` and `vertical-lr`.
Thanks to [yisibl](https://github.com/yisibl).
- (tiny-skia) AArch64 Neon SIMD support. Up to 3x faster on Apple M1.
### Changed
- `usvg::Tree` stores only `Group`, `Path` and `Image` nodes now.
Instead of emulating an SVG file structure, where gradients, patterns, filters, clips and masks
are part of the nodes tree (usually inside the `defs` element), we reference them using `Rc`
from now.
This change makes `usvg` a bit simpler. Makes `usvg` API way easier, since instead of
looking for a node via `usvg::Tree::defs_by_id` the caller can access the type directly via `Rc`.
And makes creation of custom `usvg::Tree`s way easier.
- `clip_path`, `mask` and `filters` `usvg::Group` fields store `Rc` instead of `String` now.
- `usvg::NodeExt::units` was moved to `usvg::Paint::units`.
- `usvg::filter::ImageKind::Use` stores `usvg::Node` instead of `String`.
- `usvg::PathData` stores commands and points separately now to reduce overall memory usage.
- `usvg::PathData` segments should be accessed via `segments()` now.
- Most numeric types have been moved to the `strict-num` crate.
- Rename `NormalizedValue` into `NormalizedF64`.
- Rename `PositiveNumber` into `PositiveF64`.
- Raw number of numeric types should be accessed via `get()` method instead of `value()` now.
- `usvg::TextSpan::font_size` is `NonZeroPositiveF64` instead of `f64` now.
- Re-export `usvg` and `tiny-skia` dependencies in `resvg`.
- Re-export `roxmltree` dependency in `usvg`.
- (usvg) Output float precision is reduced from 11 to 8 digits.
### Removed
- `usvg::Tree::create`. `usvg::Tree` is an open struct now.
- `usvg::Tree::root`. It's a public field now.
- `usvg::Tree::svg_node`. Replaced with `usvg::Tree` public fields.
- `defs`, `is_in_defs`, `append_to_defs` and `defs_by_id` from `usvg::Tree`.
We no longer emulate SVG structure. No alternative.
- `usvg::Tree::is_in_defs`. There are no `defs` anymore.
- `usvg::Paint::Link`. We store gradient and patterns directly in `usvg::Paint` now.
- `usvg::Svg`. No longer needed. `size` and `view_box` are `usvg::Tree` fields now.
- `usvg::SubPathIter` and `usvg::PathData::subpaths`. No longer used.
### Fixed
- Path bbox calculation scales stroke width too.
Thanks to [growler](https://github.com/growler).
- (tiny-skia) Round caps roundness.
- (xmlparser) Stack overflow on specific files.
- (c-api) `resvg_is_image_empty` output was inverted.
## [0.23.0] - 2022-06-11
### Added
- `#RRGGBBAA` and `#RGBA` color notation support.
Thanks to [demurgos](https://github.com/demurgos).
### Fixed
- Panic during recursive `pattern` resolving.
Thanks to [FylmTM](https://github.com/FylmTM).
- Spurious warning when using `--export-id`.
Thanks to [benoit-pierre](https://github.com/benoit-pierre).
## [0.22.0] - 2022-02-20
### Added
- Support `svg` referenced by `use`. External SVG files are still not supported.
### Changed
- `ttf-parser`, `fontdb` and `rustybuzz` have been updated.
## [0.21.0] - 2022-02-13
### Added
- `usvg::ImageHrefResolver` that allows a custom `xlink:href` handling.
Thanks to [antmelnyk](https://github.com/antmelnyk).
- `usvg::Options::image_href_resolver`
- Support for GIF images inside the `<image>` element.
- (fontdb) Support for loading user fonts on Windows.
- (fontdb) Support for parsing fontconfig config files on Linux.
For now, only to retrieve a list of font dirs.
### Changed
- MSRV bumped to 1.51
- `usvg::ImageKind` stores data as `Arc<Vec<u8>>` and not just `Vec<u8>` now.
### Fixed
- Every nested `svg` element defines a new viewBox now. Previously, we were always using the root one.
- Correctly handle SVG size calculation when SVG doesn't have a size and any elements.
- Improve groups ungrouping speed.
## [0.20.0] - 2021-12-29
### Changed
- `resvg::render` and `resvg::render_node` accept a transform now.
- (c-api) `resvg_render` and `resvg_render_node` accept a transform now.
- `usvg::Color` is a custom type and not a `svgtypes::Color` reexport now.
- `usvg::Color` doesn't contain alpha anymore, which have been added in v0.16
Alpha would be automatically flattened.
This makes [Micro SVG](https://github.com/linebender/resvg/blob/main/crates/usvg/docs/spec.adoc)
compatible with SVG 1.1 again.
- (c-api) Rename `RESVG_FIT_TO_*` into `RESVG_FIT_TO_TYPE_*`.
### Fixed
- The `--background` argument in `resvg` correctly handles alpha now.
- Fix building usvg without filter feature but with export.
## [0.19.0] - 2021-10-04
### Added
- Better text-on-path converter accuracy by accounting the current transform.
### Changed
- `usvg::NodeExt::abs_transform` includes current node transform now.
- Improved turbulence filter performance. Thanks to [akindle](https://github.com/akindle).
- Multiple dependencies updated.
## [0.18.0] - 2021-09-12
### Added
- `filter` build feature. Enabled by default.
- `usvg::PathBbox` and `resvg_path_bbox` (to C API).
### Changed
- (usvg) All filter related types are under the `filter` module now.
- (usvg) Remove `Fe` prefix from all filter types.
- (c-api) `resvg_get_node_bbox` returns `resvg_path_bbox` now.
### Fixed
- Horizontal and vertical lines processing.
- C API building without the `text` feature.
## [0.17.0] - 2021-09-04
### Added
- `tiny-skia` updated with support of images larger than 8000x8000 pixels.
- `feDropShadow` support. SVG2
- [`<filter-value-list>`](https://www.w3.org/TR/filter-effects-1/#typedef-filter-value-list) support.
Meaning that the `filter` attribute can have multiple values now.
Like `url(#filter1) blur(2)`. SVG2
- All [filter functions](https://www.w3.org/TR/filter-effects-1/#filter-functions). SVG2
- Support all [new](https://www.w3.org/TR/compositing-1/#ltblendmodegt) `feBlend` modes. SVG2
- Automatic SVG size detection when `width`/`height`/`viewBox` is not set.
Thanks to [reknih](https://github.com/reknih).
- `usvg::Options::default_size`
- `--default-width` and `--default-height` to usvg.
### Changed
- `usvg::Group::filter` is a list of filter IDs now.
- `usvg::FeColorMatrixKind::Saturate` accepts any positive `f64` value now.
- `svgfilters::ColorMatrix::Saturate` accepts any positive `f64` value now.
- Fonts memory mapping was split into a separate build feature: `memmap-fonts`.
Now you can build resvg/usvg with `system-fonts`, but without `memmap-fonts`.
Enabled by default.
- The `--dump-svg` argument in resvg CLI tool should be enabled using `--features dump-svg` now.
No enabled by default.
- `usvg::Tree::to_string` is behind the `export` build feature now.
### Fixed
- When writing SVG, `usvg` will use `rgba()` notations for colors instead of `#RRGGBB`.
## [0.16.0] - 2021-08-22
### Added
- CSS3 colors support. Specifically `rgba`, `hsl`, `hsla` and `transparent`. SVG2
- Allow missing `rx`/`ry` attributes on `ellipse`. SVG2
- Allow markers on all shapes. SVG2
- `textPath` can reference basic shapes now. SVG2
- `usvg::OptionsRef`, which is a non-owned `usvg::Options` variant.
- `simplecss` updated with CSS specificity support.
- `turn` angle unit support. SVG2
- Basic `font-variant=small-caps` support. No font fallback.
- `--export-area-page` to resvg.
- `--export-area-drawing` to resvg.
### Changed
- `resvg::render_node` requires `usvg::Tree` now.
- `usvg::Color` gained an `alpha` field.
### Removed
- `usvg::Node::tree`. Cannot be implemented efficiently anymore.
- `usvg::SystemFontDB`. No longer needed.
### Fixed
- `pattern` scaling.
- Greatly improve `symbol` resolving speed in `usvg`.
- Whitespaces trimming on nested `tspan`.
## [0.15.0] - 2021-06-13
### Added
- Allow reading SVG from stdin in `resvg` binary.
- `--id-prefix` to `usvg`.
- `FitTo::Size`
- `resvg` binary accepts `--width` and `--height` args together now.
Previously, only `--width` or `--height` were allowed.
- `usvg::Path::text_bbox`
- The maximum number of SVG elements is limited by 1_000_000 now.
Mainly to prevent a billion laugh style attacks.
- The maximum SVG elements nesting is limited by 1024 now.
- `usvg::Error::ElementsLimitReached`
### Changed
- Improve clipping and masking performance on large images.
- Remove layers caching. This was a pointless optimization.
- Split _Preprocessing_ into _Reading_ and _Parsing_ in `resvg --perf`.
- `usvg::XmlOptions` rewritten.
- `usvg::Tree::to_string` requires a reference to `XmlOptions` now.
### Removed
- `usvg::Tree::from_file`. Use `from_data` or `from_str` instead.
- `usvg::Error::InvalidFileSuffix`
- `usvg::Error::FileOpenFailed`
- (c-api) `RESVG_ERROR_INVALID_FILE_SUFFIX`
### Fixed
- Ignore tiny blur values. It could lead to a transparent image.
- `use` style propagation when used with `symbol`.
- Vertical text layout with relative offsets.
- Text bbox calculation. `usvg` uses font metrics instead of path bbox now.
## [0.14.1] - 2021-04-18
### Added
- Allow `href` without the `xlink` namespace.
This feature is part of SVG 2 (which we do not support),
but there are more and more files like this in the wild.
### Changed
- (usvg) Do not write `usvg:version` to the output SVG.
### Fixed
- (usvg) `overflow='inherit'` resolving.
- (usvg) SVG Path length calculation that affects `startOffset` property in `textPath`.
- (usvg) Fix `feImage` resolving when the linked element has
`opacity`, `clip-path`, `mask` and/or `filter` attributes.
- (usvg) Fix chained `feImage` resolving.
- CLI arguments processing.
## [0.14.0] - 2021-03-06
### Fixed
- Multiple critical bugs in `tiny-skia`.
## [0.13.1] - 2021-01-20
### Fixed
- `image` with float size scaling.
- Critical bug in `tiny-skia`.
## [0.13.0] - 2020-12-21
### Added
- `--resources-dir` option to CLI tools.
- (usvg) `Tree::from_xmltree`
### Changed
- Remove the `Image` struct. `render()` and `render_node()` methods now accept `tiny_skia::PixmapMut`.
- Update `fontdb`.
- Update `tiny-skia`.
- (c-api) `resvg_size` uses `double` instead of `uint32_t` now.
- (qt-api) `defaultSize()` and `defaultSizeF()` methods now return SVG size
and not SVG viewbox size.
- (usvg) `Options::path` changed to `Options::resources_dir` and requires a directory now.
- (c-api) `resvg_options_set_file_path` changed to `resvg_options_set_resources_dir`
and requires a directory now.
- (qt-api) `ResvgOptions::setFilePath` changed to `ResvgOptions::setResourcesDir`
and requires a directory now.
### Fixed
- Support multiple values inside a `text-decoration` attribute.
### Removed
- `Image`. Use `tiny_skia::PixmapMut` instead.
- (c-api) `resvg_image` struct and `resvg_image_*` methods. `resvg` renders onto
the provided buffer now.
- (c-api) `resvg_color`, because unused.
## [0.12.0] - 2020-12-05
### Changed
- resvg no longer requires a C++ compiler!
- `tiny-skia` was updated to a pure Rust version, which means that `resvg` no longer
depends on `clang` and should work on 32bit targets.
- `rustybuzz` was updated to a pure Rust version.
- `tools/explorer-thumbnailer` is back and written in Rust now.
Thanks to [gentoo90](https://github.com/gentoo90).
### Fixed
- (usvg) Do not panic when a font has a zero-sized underline thickness.
- (usvg) Multiple `textPath` processing fixes by [chubei-oppen](https://github.com/chubei-oppen).
- (qt-api) `boundsOnElement` and `boundingBox` were returning transposed bounds.
## [0.11.0] - 2020-07-04
### Highlights
- All backends except Skia were removed. Skia is the only official one from now.
- New C API implementation.
### Added
- Support for user-defined fonts in usvg, resvg and C API.
- `--serif-family`, `--sans-serif-family`, `--cursive-family`, `--fantasy-family`
`--monospace-family`, `--use-font-file`, `--use-fonts-dir`, `--skip-system-fonts` and `--list-fonts`
options to all CLI tools.
- New tests suite. Instead of testing against the previous build, now we're testing against
prerendered PNG images. Which is way faster.<br>
And you can test resvg without the internet connection now.<br>
And all you need is just `cargo test`.
### Changed
- Library uses an embedded Skia by default now.
- Switch `harfbuzz_rs` with `rustybuzz`.
- Rendering doesn't require `usvg::Options` now.
- (usvg) The `fontdb` module moved into its own crate.
- (usvg) `fontconfig` is no longer used for matching
[generic fonts](https://www.w3.org/TR/2018/REC-css-fonts-3-20180920/#generic-family-value)
on Linux. Mainly because it's very slow.
- (usvg) When an `image` element contains a file path, the file will be loaded into memory now,
instead of simply storing a file path. And will be dumped as base64 on SVG save.
In case of an SVG image, it will be loaded as a `Tree` and saved as base64 encoded XML on save.
- (usvg) `ImageData` replaced with `ImageKind`.
- (usvg) Fonts database is empty by default now and should be filled manually.
- (c-api) Almost a complete rewrite.
### Removed
- All backends except the Skia one.
- `Options` from all backends. We don't use it anymore.
- (usvg) `ImageFormat`.
- (c-api) Rendering on a backends canvas no longer supported. Was constantly misused.
## [0.10.0] - 2020-06-19
### Changed
- The `resvg` crate has been split into four: resvg-cairo, resvg-qt, resvg-skia and resvg-raqote.<br/>
So from now, instead of enabling a required backend via cargo features,
you should select a required backend-specific crate.<br/>
This allows us to have a better integration with a selected 2D library.<br/>
And we also have separated C API implementations now.<br/>
And each backend has its own vendored archive too.
- (qt-backend) Use `QImage` instead of Rust libraries for raster images loading.
### Removed
- The `resvg` crate. Use backend-specific crates.
- `tools/rendersvg`. Each backend has its own CLI tool now.
- `tools/usvg`. `usvg` implements CLI by default now.
- (c-api) `resvg_*_render_to_file` methods.
- (qt-backend) `jpeg-decoder` and `png` dependencies.
## [0.9.1] - 2020-06-03
### Fixed
- Stack overflow when `enable-background` and `filter` are set on the same element.
- Grayscale PNG loading.
- Allow building on BSD.
- (usvg) Font fallback when shaping produces a different amount of glyphs.
- (usvg) Ignore a space after the last character during `letter-spacing` processing.
- (usvg) `marker-end` rendering when the last segment is a curve with the second control point
that coincides with end point.
- (usvg) Accept embedded `image` data without mime.
- (usvg) Fonts search in a home directory on Linux.
- (usvg) `dy` calculation for `textPath` thanks to [Stoeoef](https://github.com/Stoeoef)
- (usvg) `textPath` resolving when a referenced path has a transform.<br/>
Thanks to [Stoeoef](https://github.com/Stoeoef).
- (usvg) Load user fonts on macOS too.
- (xmlparser) Parsing comment before DTD.
## [0.9.0] - 2020-01-18
### Added
- `feConvolveMatrix`, `feMorphology`, `feDisplacementMap`, `feTurbulence`,
`feDiffuseLighting` and `feSpecularLighting` support.
- `BackgroundImage`, `BackgroundAlpha`, `FillPaint` and `StrokePaint` support as a filter input.
- Load grayscale raster images.
- `enable-background` support.
- resvg/usvg can be built without text rendering support now.
- `OutputImage::make_vec` and `OutputImage::make_rgba_vec`.
- `feImage` with a reference to an internal element.
### Changed
- `feComposite` k1-4 coefficients can have any number now.
This matches browsers behaviour.
- Use `flate2` instead of `libflate` for GZip decoding.
- (usvg) `fill` and `stroke` attributes will always be set for `path` now.
- (usvg) `g`, `path` and `image` can now be set inside `defs`. Required by `feImage`.
- (c-api) Rename `resvg_*_render_to_image` into `resvg_*_render_to_file`.
### Fixed
- (usvg) Transform processing during text-to-path conversion.
- `feComposite` with fully transparent region was producing an invalid result.
- Fallback to `matrix` in `feColorMatrix` when `type` is not set or invalid.
- ID preserving for `use` elements.
- `feFlood` with subregion and `primitiveUnits=objectBoundingBox`.
- (harfbuzz_rs) Memory leak.
## [0.8.0] - 2019-08-17
### Added
- A [Skia](https://skia.org/) backend thanks to
[JaFenix](https://github.com/JaFenix).
- `feComponentTransfer` support.
- `feColorMatrix` support.
- A better CSS support.
- An `*.otf` fonts support.
- (usvg) `dx`, `dy` are supported inside `textPath` now.
- Use a box blur for `feGaussianBlur` with `stdDeviation`>=2.
This is 4-8 times faster than IIR blur.
Thanks to [Shnatsel](https://github.com/Shnatsel).
### Changed
- All backends are using Rust crates for raster images loading now.
- Use `pico-args` instead of `gumdrop` to reduced the build time of `tools/rendersvg`
and `tools/usvg`.
- (usvg) The `xmlwriter` is used for SVG generation now.
Almost 2x faster than generating an `svgdom`.
- (usvg) Optimize font database initialization. Almost 50% faster.
- Use a lower PNG compression ratio to speed up PNG generation.
Depending on a backend and image can be 2-4x faster.
- `OutputImage::save` -> `OutputImage::save_png`.
- (usvg) `Path::segments` -> `Path::data`.
- Cairo backend compilation is 2x faster now due to overall changes.
- Performance improvements (Oxygen Icon theme SVG-to-PNG):
- cairo-backend: 22% faster
- qt-backend: 20% faster
- raqote-backend: 34% faster
### Fixed
- (qt-api) A default font resolving.
- (usvg) `baseline-shift` processing inside `textPath`.
- (usvg) Remove all `tref` element children.
- (usvg) `tref` with `xml:space` resolving.
- (usvg) Ignore nested `tref`.
- (usvg) Ignore invalid `clipPath` children that were referenced via `use`.
- (usvg) `currentColor` will always fallback to black now.
Previously, `stroke` was set to `none` which is incorrect.
- (usvg) `use` can reference an element inside a non-SVG element now.
- (usvg) Collect all styles for generic fonts and not only *Regular*.
- (usvg) Parse only presentation attributes from the `style` element and attribute.
### Removed
- (cairo-backend) `gdk-pixbuf` dependency.
- (qt-backend) JPEG image format plugin dependency.
- `svgdom` dependency.
## [0.7.0] - 2019-06-19
### Added
- New text layout implementation:
- `textPath` support.
- `writing-mode` support, aka vertical text.
- [Text BIDI reordering](http://www.unicode.org/reports/tr9/).
- Better text shaping.
- `word-spacing` is supported for all backends now.
- [`harfbuzz`](https://github.com/harfbuzz/harfbuzz) dependency.
- Subscript, superscript offsets are extracted from font and not hardcoded now.
- `shape-rendering`, `text-rendering` and `image-rendering` support.
- The `arithmetic` operator for `feComposite`.
- (usvg) `--quiet` argument.
- (c-api) `resvg_get_image_bbox`.
- (qt-api) `ResvgRenderer::boundingBox`.
- (resvg) A [raqote](https://github.com/jrmuizel/raqote) backend thanks to
[jrmuizel](https://github.com/jrmuizel). Still experimental.
### Changed
- Text will be converted into paths on the `usvg` side now.
- (resvg) Do not rescale images before rendering. This is faster and better.
- (usvg) An `image` element with a zero or negative size will be skipped now.
Previously, a linked image size was used, which is incorrect.
- Geometry primitives (`Rect`, `Size`, etc) are immutable and always valid now.
- (usvg) The default `color-interpolation-filters` attribute will not be exported now.
### Removed
- (usvg) All text related structures and enums. Text will be converted into `Path` now.
- `InitObject` and `init()` because they are no longer needed.
- (c-api) `resvg_handle`, `resvg_init`, `resvg_destroy`.
- (c-api) `resvg_cairo_get_node_bbox` and `resvg_qt_get_node_bbox`.
Use backend-independent `resvg_get_node_bbox` instead.
- (cairo-backend) `pango` dependency.
- (resvg) `Backend::calc_node_bbox`. Use `Node::calculate_bbox()` instead.
### Fixed
- `letter-spacing` on cursive scripts (like Arabic).
- (rctree) Prevent stack overflow on a huge, deeply nested SVG.
- (c-api) `resvg_is_image_empty` was always returning `false`.
- (resvg) Panic when `filter` with `objectBoundingBox` was set on an empty group.
- (usvg) `mask` with `objectBoundingBox` resolving.
- (usvg) `pattern`'s `viewBox` attribute resolving via `href`.
- (roxmltree) Namespace resolving.
## [0.6.1] - 2019-03-16
### Fixed
- (usvg) `transform` multiplication.
- (usvg) `use` inside `clipPath` resolving.
## [0.6.0] - 2019-03-16
### Added
- Nested `baseline-shift` support.
- (qt-api) `renderToImage`.
- (usvg) A better algorithm for unused defs (`defs` element children, like gradients) removal.
- (usvg) `Error::InvalidSize`.
- (c-api) `RESVG_ERROR_INVALID_SIZE`.
### Changed
- (usvg) A major rewrite.
- `baseline-shift` with `sub`, `super` and percent values calculation.
- Marker resolving moved completely to `usvg`.
- If an SVG doesn't have a valid size than an error will occur.
Previously, an empty tree was produced.
- (qt-api) `render` methods are `const` now.
- (usvg) Disable default attributes exporting.
### Removed
- (usvg) Marker element and attributes. Markers will be resolved just like `use` now.
### Fixed
- (resvg) During the `tspan` rendering, the `text` bbox will be used instead
of the `tspan` bbox itself. This is the correct behaviour by the SVG spec.
- (cairo-backend) `font-family` parsing.
- (usvg) `filter:none` processing.
- (usvg) `text` inside `text` processing.
- (usvg) Endless loop during `use` resolving.
- (usvg) Endless loop when SVG has indirect recursive `xlink:href` links.
- (usvg) Endless loop when SVG has recursive `marker-*` links.
- (usvg) Panic during `use` resolving.
- (usvg) Panic during inherited attributes resolving.
- (usvg) Groups regrouping.
- (usvg) `dx`/`dy` processing on `text`.
- (usvg) `textAnchor` resolving.
- (usvg) Ignore `fill-rule` on `text`.
- (svgtypes) Style with comments parsing.
- (roxmltree) Namespaces resolving.
## [0.5.0] - 2019-01-04
### Added
- `marker` support.
- Partial `baseline-shift` support.
- `letter-spacing` support.
- (qt-backend) `word-spacing` support.
Does not work on the cairo backend.
- tools/explorer-thumbnailer
- tools/kde-dolphin-thumbnailer
### Fixed
- Object bounding box calculation.
- Pattern scaling.
- Nested `objectBoundingBox` support.
- (usvg) `color` on `use` resolving.
- (usvg) `offset` attribute resolving inside the `stop` element.
- (usvg) Ungrouping of groups with non-inheritable attributes.
- (usvg) `rotate` attribute resolving.
- (usvg) Paths without stroke and fill will no longer be removed.
Required for a proper bbox resolving.
- (usvg) Coordinates resolving when units are `userSpaceOnUse`.
- (usvg) Groups regrouping. Caused an incorrect rendering of `clipPath`
that had `filter` on a child.
- (usvg) Style attributes resolving on the root `svg` element.
- (usvg) `SmoothCurveTo` and `SmoothQuadratic` conversion.
- (usvg) `symbol` resolving.
- (cairo-backend) Font ascent calculation.
- (qt-backend) Stroking of LineTo specified as CurveTo.
- (svgdom) `stroke-miterlimit` attribute parsing.
- (svgdom) `length` and `number` attribute types parsing.
- (svgdom) `offset` attribute parsing.
- (svgdom) IRI resolving order when SVG has duplicated ID's.
## [0.4.0] - 2018-12-13
### Added
- (resvg) Initial filters support.
- (resvg) Nested `clipPath` and `mask` support.
- (resvg) MSVC support.
- (rendersvg) `font-family`, `font-size` and `languages` to args.
- (usvg) `systemLanguage` attribute support.
- (usvg) Default font family and size is configurable now.
- (c-api) `RESVG_ERROR_PARSING_FAILED`.
- (c-api) `font_family`, `font_size` and `languages` to `resvg_options`.
- (qt-api) `ResvgRenderer::setDevicePixelRatio`.
### Changed
- (rendersvg) Use `gumdrop` instead of `getopts`.
- (c-api) Qt wrapper is header-only now.
### Fixed
- (cairo-backend) Text layout.
- (cairo-backend) Rendering of a zero length subpath with a square cap.
- (qt-backend) Transform retrieving via Qt bindings.
- (resvg) Recursive SVG images via `image` tag.
- (resvg) Bbox calculation of the text with rotate.
- (resvg) Invisible elements processing.
- (qt-api) SVG from QByteArray loading when data is invalid.
- (usvg) `display` attribute processing.
- (usvg) Recursive `mask` resolving.
- (usvg) `inherit` attribute value resolving.
- (svgdom) XML namespaces resolving.
### Removed
- (rendersvg) `failure` dependency.
## [0.3.0] - 2018-05-23
### Added
- (c-api) `resvg_is_image_empty`.
- (c-api) `resvg_error` enum.
- (c-api) Qt wrapper.
- (resvg) Advanced text layout support (lists of x, y, dx, dy and rotate).
- (resvg) SVG support for `image` element.
- (usvg) `symbol` element support.
- (usvg) Nested `svg` elements support.
- (usvg) Paint fallback resolving.
- (usvg) Bbox validation for shapes that use painting servers.
- (svgdom) Elements from ENTITY resolving.
### Changed
- (c-api) `resvg_parse_tree_from_file`, `resvg_parse_tree_from_data`
`resvg_cairo_render_to_image` and `resvg_qt_render_to_image`
will return an error code now.
- (cairo-backend) Use `gdk-pixbuf` crate instead of `image`.
- (resvg) `Render::render_to_image` and `Render::render_node_to_image` will return
`Option` and not `Result` now.
- (resvg) New geometry primitives implementation.
- (resvg) Rename `render_*` modules to `backend_`.
- (rendersvg) Use `getopts` instead of `clap` to reduce the executable size.
- (svgtypes) `StreamExt::parse_iri` and `StreamExt::parse_func_iri` will parse
not only well-formed data now.
### Fixed
- (qt-backend) Gradient with `objectBoundingBox` rendering.
- (qt-backend) Text bounding box detection during the rendering.
- (cairo-backend) `image` element clipping.
- (cairo-backend) Layers management.
- (c-api) `resvg_get_node_transform` will return a correct transform now.
- (resvg) `text-decoration` thickness.
- (resvg) `pattern` scaling.
- (resvg) `image` without size rendering.
- (usvg) Panic during `visibility` resolving.
- (usvg) Gradients with one stop resolving.
- (usvg) `use` attributes resolving.
- (usvg) `clipPath` and `mask` attributes resolving.
- (usvg) `offset` attribute in `stop` element resolving.
- (usvg) Incorrect `font-size` attribute resolving.
- (usvg) Gradient stops resolving.
- (usvg) `switch` element resolving.
- (svgdom) Mixed `xml:space` processing.
- (svgtypes) `Paint::from_span` poor performance.
### Removed
- (c-api) `resvg_error_msg_destroy`.
- (resvg) `parse_rtree_*` methods. Use `usvg::Tree::from_` instead.
- (resvg) `Error`.
## [0.2.0] - 2018-04-24
### Added
- (svg) Partial `clipPath` support.
- (svg) Partial `mask` support.
- (svg) Partial `pattern` support.
- (svg) `preserveAspectRatio` support.
- (svg) Check that an external image is PNG or JPEG.
- (rendersvg) Added `--query-all` and `--export-id` arguments to render SVG items by ID.
- (rendersvg) Added `--perf` argument for a simple performance stats.
### Changed
- (resvg) API is completely new.
### Fixed
- `font-size` attribute inheritance during `use` resolving.
[Linebender]: https://github.com/linebender
[@DJMcNab]: https://github.com/DJMcNab
[@michabay05]: https://github.com/michabay05
[@Shnatsel]: https://github.com/Shnatsel
[@JosefKuchar]: https://github.com/JosefKuchar
[@tovrstra]: https://github.com/tovrstra
[@newinnovations]: https://github.com/newinnovations
[@LaurenzV]: https://github.com/LaurenzV
[@HaHa421]: https://github.com/HaHa421
[@Dabble63]: https://github.com/Dabble63
[@Daaiid]: https://github.com/Daaiid
[@arnaud-secondlayer]: https://github.com/arnaud-secondlayer
[@Its-Just-Nans]: https://github.com/Its-Just-Nans
[#897]: https://github.com/linebender/resvg/pull/897
[Unreleased]: https://github.com/linebender/resvg/compare/v0.47.0...HEAD
[0.47.0]: https://github.com/linebender/resvg/compare/v0.46.0...v0.47.0
[0.46.0]: https://github.com/linebender/resvg/compare/v0.45.1...v0.46.0
[0.45.1]: https://github.com/linebender/resvg/compare/v0.45.0...v0.45.1
[0.45.0]: https://github.com/linebender/resvg/compare/v0.44.0...v0.45.0
[0.44.0]: https://github.com/linebender/resvg/compare/v0.43.0...v0.44.0
[0.43.0]: https://github.com/linebender/resvg/compare/v0.42.0...v0.43.0
[0.42.0]: https://github.com/linebender/resvg/compare/v0.41.0...v0.42.0
[0.41.0]: https://github.com/linebender/resvg/compare/v0.40.0...v0.41.0
[0.40.0]: https://github.com/linebender/resvg/compare/v0.39.0...v0.40.0
[0.39.0]: https://github.com/linebender/resvg/compare/v0.38.0...v0.39.0
[0.38.0]: https://github.com/linebender/resvg/compare/v0.37.0...v0.38.0
[0.37.0]: https://github.com/linebender/resvg/compare/v0.36.0...v0.37.0
[0.36.0]: https://github.com/linebender/resvg/compare/v0.35.0...v0.36.0
[0.35.0]: https://github.com/linebender/resvg/compare/v0.34.1...v0.35.0
[0.34.1]: https://github.com/linebender/resvg/compare/v0.34.0...v0.34.1
[0.34.0]: https://github.com/linebender/resvg/compare/v0.33.0...v0.34.0
[0.33.0]: https://github.com/linebender/resvg/compare/v0.32.0...v0.33.0
[0.32.0]: https://github.com/linebender/resvg/compare/v0.31.1...v0.32.0
[0.31.1]: https://github.com/linebender/resvg/compare/v0.31.0...v0.31.1
[0.31.0]: https://github.com/linebender/resvg/compare/v0.30.0...v0.31.0
[0.30.0]: https://github.com/linebender/resvg/compare/v0.29.0...v0.30.0
[0.29.0]: https://github.com/linebender/resvg/compare/v0.28.0...v0.29.0
[0.28.0]: https://github.com/linebender/resvg/compare/v0.27.0...v0.28.0
[0.27.0]: https://github.com/linebender/resvg/compare/v0.26.1...v0.27.0
[0.26.1]: https://github.com/linebender/resvg/compare/v0.26.0...v0.26.1
[0.26.0]: https://github.com/linebender/resvg/compare/v0.25.0...v0.26.0
[0.25.0]: https://github.com/linebender/resvg/compare/v0.24.0...v0.25.0
[0.24.0]: https://github.com/linebender/resvg/compare/v0.23.0...v0.24.0
[0.23.0]: https://github.com/linebender/resvg/compare/v0.22.0...v0.23.0
[0.22.0]: https://github.com/linebender/resvg/compare/v0.21.0...v0.22.0
[0.21.0]: https://github.com/linebender/resvg/compare/v0.20.0...v0.21.0
[0.20.0]: https://github.com/linebender/resvg/compare/v0.19.0...v0.20.0
[0.19.0]: https://github.com/linebender/resvg/compare/v0.18.0...v0.19.0
[0.18.0]: https://github.com/linebender/resvg/compare/v0.17.0...v0.18.0
[0.17.0]: https://github.com/linebender/resvg/compare/v0.16.0...v0.17.0
[0.16.0]: https://github.com/linebender/resvg/compare/v0.15.0...v0.16.0
[0.15.0]: https://github.com/linebender/resvg/compare/v0.14.1...v0.15.0
[0.14.1]: https://github.com/linebender/resvg/compare/v0.14.0...v0.14.1
[0.14.0]: https://github.com/linebender/resvg/compare/v0.13.1...v0.14.0
[0.13.1]: https://github.com/linebender/resvg/compare/v0.13.0...v0.13.1
[0.13.0]: https://github.com/linebender/resvg/compare/v0.12.0...v0.13.0
[0.12.0]: https://github.com/linebender/resvg/compare/v0.11.0...v0.12.0
[0.11.0]: https://github.com/linebender/resvg/compare/v0.10.0...v0.11.0
[0.10.0]: https://github.com/linebender/resvg/compare/v0.9.1...v0.10.0
[0.9.1]: https://github.com/linebender/resvg/compare/v0.9.0...v0.9.1
[0.9.0]: https://github.com/linebender/resvg/compare/v0.8.0...v0.9.0
[0.8.0]: https://github.com/linebender/resvg/compare/v0.7.0...v0.8.0
[0.7.0]: https://github.com/linebender/resvg/compare/v0.6.1...v0.7.0
[0.6.1]: https://github.com/linebender/resvg/compare/v0.6.0...v0.6.1
[0.6.0]: https://github.com/linebender/resvg/compare/v0.5.0...v0.6.0
[0.5.0]: https://github.com/linebender/resvg/compare/v0.4.0...v0.5.0
[0.4.0]: https://github.com/linebender/resvg/compare/v0.3.0...v0.4.0
[0.3.0]: https://github.com/linebender/resvg/compare/v0.2.0...v0.3.0
[0.2.0]: https://github.com/linebender/resvg/compare/v0.1.0...v0.2.0
================================================
FILE: Cargo.toml
================================================
[workspace]
members = [
"crates/c-api",
"crates/resvg",
"crates/usvg",
"crates/usvg/codegen",
#"tools/explorer-thumbnailer",
]
default-members = ["crates/resvg"]
resolver = "2"
[workspace.package]
license = "Apache-2.0 OR MIT"
================================================
FILE: LICENSE-APACHE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: LICENSE-MIT
================================================
Copyright 2017 the Resvg Authors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
================================================
FILE: README.md
================================================
## resvg

[](https://crates.io/crates/resvg)
[](https://docs.rs/resvg)
[](https://www.rust-lang.org)
*resvg* is an [SVG](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) rendering library.
It can be used as a Rust library, as a C library, and as a CLI application to render static SVG files.
The core idea is to make a fast, small, portable SVG library with the goal to support the whole SVG spec.
## Features
### Designed for edge-cases
SVG is a very complicated format with a large specification (SVG 1.1 is almost 900 pages).
You basically need a web browser to handle all of it. But the truth is that even browsers
fail at this (see [SVG support](https://github.com/linebender/resvg#svg-support)).
Yes, unlike `resvg`, browsers do support dynamic SVG features like animations and scripting.
But using a browser to render SVG _correctly_ is sadly not an option.
To prove its correctness, `resvg` has a vast test suite that includes around 1600 tests.
And those are only SVG-to-PNG regression tests. This doesn't include tests in `resvg` dependencies.
And the best thing is that `resvg` test suite is available to everyone. It's not tied to `resvg`
in any way. Which should help people who plan to develop their own SVG libraries.
### Safety
It's hard not to mention safety when we talk about Rust and processing of a random input.
And we're talking not only about SVG/XML, but also about CSS, TTF, PNG, JPEG, GIF, and GZIP.
While `resvg` is not the only SVG library written in Rust, it's the only one that
is written completely in Rust. There is no non-Rust code in the final binary.
Moreover, there is almost no `unsafe` code either. Still, some dependencies have some `unsafe` code
and font memory-mapping is inherently `unsafe`, but it's best you can get in terms of memory safety.
However, this doesn't stop at memory safety. `resvg` has extensive checks to prevent endless loops (freezes)
and stack overflows (via recursion).
### Zero bloat
Right now, the `resvg` CLI application is less than 3MB in size and doesn't require any external dependencies.
The binary contains nothing that isn't needed for rendering SVG files.
### Portable
`resvg` is guaranteed to work everywhere where you can compile the Rust itself,
including WASM. There are some rough edges with obscure CPU architectures and
mobile OSs (mainly system fonts loading), but it should be pretty painless otherwise.
### SVG preprocessing
Another major difference from other SVG rendering libraries is that in `resvg`
SVG parsing and rendering are two completely separate steps.
Those steps are also split into two separate libraries: `resvg` and [usvg].
Meaning you can easily write your own renderer on top of `usvg` using any 2D library of your liking.
### Performance
Comparing performance between different SVG rendering libraries is like comparing apples and oranges.
Everyone has a very different set of supported features, languages, build flags, etc...
Anyhow, as `resvg` is written in Rust and uses [tiny-skia] for rendering - it's pretty fast.
There should also still be quite a lot of room for improvement.
### Reproducibility
Since `resvg` doesn't rely on any system libraries it allows us to have reproducible results
on all supported platforms. Meaning if you render an SVG file on x86 Windows and then render it
on ARM macOS - the produced image will be identical. Each pixel would have the same value.
## Limitations
- No animations<br>
There are no plans on implementing them either.
- No native text rendering<br>
`resvg` doesn't rely on any system libraries, which implies that we cannot use native text rendering.
Nevertheless, native text rendering is optimized for small horizontal text, which is not
that common in SVG.
- Unicode-only<br>
It's the 21st century. Text files that aren't UTF-8 encoded are no longer relevant.
## SVG support
`resvg` aims to only support the [static](http://www.w3.org/TR/SVG11/feature#SVG-static)
SVG subset; i.e. no `a`, `script`, `view` or `cursor` elements, no events and no animations.
[SVG 2](https://www.w3.org/TR/SVG2/) support is being worked on.
You can search for relevant issues with the
[svg2 tag](https://github.com/linebender/resvg/issues?q=is%3Aissue+is%3Aopen+label%3Asvg2)
or our [SVG 2 changelog](https://github.com/linebender/resvg/blob/main/docs/svg2-changelog.md).
[SVG Tiny 1.2](https://www.w3.org/TR/SVGTiny12/) is not supported and support is also not planned.
Results of the [resvg test suite](https://github.com/linebender/resvg-test-suite):

SVG 2 only results:

You can find a complete table of supported features
[here](https://linebender.org/resvg-test-suite/svg-support-table.html).
It also includes some alternative libraries.
We're not testing against all SVG libraries since many of them are pretty bad.
Some libraries are not on the list because they don't pass the 25% mark.
Such libraries are: wxSvg, LunaSVG and nanosvg.
## resvg project
There is a subtle difference between resvg as a _library_ and resvg as a _project_.
While most users will interact only with the resvg library, it's just a tip of an iceberg.
There are a lot of libraries that I had to write to make resvg possible.
Here are some of them:
- resvg - the actual SVG renderer
- [usvg] - an SVG preprocessor/simplifier
- [tiny-skia] - a [Skia](https://github.com/google/skia) subset ported to Rust
- [rustybuzz] - a [harfbuzz](https://github.com/harfbuzz/harfbuzz) subset ported to Rust
- [ttf-parser] - a TrueType/OpenType font parser
- [fontdb] - a simple, in-memory font database with CSS-like queries
- [roxmltree] - an XML parsing library
- [simplecss] - a pretty decent CSS 2 parser and selector
- [pico-args] - an absolutely minimal, but surprisingly popular command-line arguments parser
So while the resvg _library_ is deceptively small (around 2500 LOC), the resvg _project_
is nearing 75'000 LOC. Which is not that much considering how much resvg does.
It's definitely the smallest option out there.
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
at your option.
## Contribution
Contributions are welcome by pull request.
The [Rust code of conduct] applies.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.
[usvg]: https://github.com/linebender/resvg/tree/main/crates/usvg
[rustybuzz]: https://github.com/harfbuzz/rustybuzz
[tiny-skia]: https://github.com/linebender/tiny-skia
[ttf-parser]: https://github.com/harfbuzz/ttf-parser
[roxmltree]: https://github.com/RazrFalcon/roxmltree
[simplecss]: https://github.com/linebender/simplecss
[fontdb]: https://github.com/RazrFalcon/fontdb
[pico-args]: https://github.com/RazrFalcon/pico-args
[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
================================================
FILE: crates/c-api/Cargo.toml
================================================
[package]
name = "resvg-capi"
version = "0.47.0"
keywords = ["svg", "render", "raster", "c-api"]
license.workspace = true
edition = "2024"
rust-version = "1.87.0"
workspace = "../.."
[lib]
name = "resvg"
path = "lib.rs"
crate-type = ["cdylib", "staticlib"]
[dependencies]
log = "0.4"
resvg = { path = "../resvg", default-features = false }
[features]
default = ["text", "system-fonts", "memmap-fonts", "raster-images"]
# enables SVG Text support
# adds around 500KiB to your binary
text = ["resvg/text"]
# enables system fonts loading (only for `text`)
system-fonts = ["resvg/system-fonts"]
# enables font files memmaping for faster loading (only for `text`)
memmap-fonts = ["resvg/memmap-fonts"]
raster-images = ["resvg/raster-images"]
capi = []
[package.metadata.capi.header]
generation = false
[package.metadata.capi.install.include]
asset = [{ from="resvg.h" }]
================================================
FILE: crates/c-api/LICENSE-APACHE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: crates/c-api/LICENSE-MIT
================================================
Copyright 2017 the Resvg Authors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
================================================
FILE: crates/c-api/README.md
================================================
# C API for resvg
## Build
```sh
cargo build --release
```
This will produce dynamic and static C libraries that can be found at `../target/release`.
## Header generation
The `resvg.h` is generated via [cbindgen](https://github.com/eqrion/cbindgen)
and then manually edited a bit.
## License
Licensed under either of
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or <http://www.apache.org/licenses/LICENSE-2.0>)
- MIT license ([LICENSE-MIT](LICENSE-MIT) or <http://opensource.org/licenses/MIT>)
at your option.
## Contribution
Contributions are welcome by pull request.
The [Rust code of conduct] applies.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.
[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
================================================
FILE: crates/c-api/ResvgQt.h
================================================
// Copyright 2018 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
/**
* @file ResvgQt.h
*
* An idiomatic Qt API for resvg.
*/
#ifndef RESVG_QT_H
#define RESVG_QT_H
#define RESVG_QT_MAJOR_VERSION 0
#define RESVG_QT_MINOR_VERSION 47
#define RESVG_QT_PATCH_VERSION 0
#define RESVG_QT_VERSION "0.47.0"
#include <cmath>
#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QGuiApplication>
#include <QImage>
#include <QRectF>
#include <QScopedPointer>
#include <QScreen>
#include <QString>
#include <QTransform>
#include <resvg.h>
namespace ResvgPrivate {
class Data
{
public:
~Data()
{
clear();
}
void reset()
{
clear();
}
resvg_render_tree *tree = nullptr;
QSizeF size;
QString errMsg;
private:
void clear()
{
// No need to deallocate opt.font_family, because it is a constant.
if (tree) {
resvg_tree_destroy(tree);
tree = nullptr;
}
size = QSizeF();
errMsg = QString();
}
};
static QString errorToString(const int err)
{
switch (err) {
case RESVG_OK :
return QString();
case RESVG_ERROR_NOT_AN_UTF8_STR :
return QLatin1String("The SVG content has not an UTF-8 encoding.");
case RESVG_ERROR_FILE_OPEN_FAILED :
return QLatin1String("Failed to read the file.");
case RESVG_ERROR_MALFORMED_GZIP :
return QLatin1String("Not a GZip compressed data.");
case RESVG_ERROR_ELEMENTS_LIMIT_REACHED :
return QLatin1String("Too many elements.");
case RESVG_ERROR_INVALID_SIZE :
return QLatin1String("SVG doesn't have a valid size.");
case RESVG_ERROR_PARSING_FAILED :
return QLatin1String("Failed to parse an SVG data.");
}
Q_UNREACHABLE();
}
} //ResvgPrivate
/**
* @brief SVG parsing options.
*/
class ResvgOptions {
public:
/**
* @brief Constructs a new options set.
*/
ResvgOptions()
: d(resvg_options_create())
{
// Do not set the default font via QFont::family()
// because it will return a dummy one on Windows.
// See https://github.com/linebender/resvg/issues/159
setLanguages({ QLocale().bcp47Name() });
}
/**
* @brief Sets a directory that will be used during relative paths resolving.
*
* Expected to be the same as the directory that contains the SVG file,
* but can be set to any.
*
* Default: not set
*/
void setResourcesDir(const QString &path)
{
Q_ASSERT(QFileInfo(path).isDir());
if (path.isEmpty()) {
resvg_options_set_resources_dir(d, nullptr);
} else {
auto pathC = path.toUtf8();
pathC.append('\0');
resvg_options_set_resources_dir(d, pathC.constData());
}
}
/**
* @brief Sets the target DPI.
*
* Impact units conversion.
*
* Default: 96
*/
void setDpi(const float dpi)
{
resvg_options_set_dpi(d, dpi);
}
/**
* @brief Sets the default font family.
*
* Will be used when no `font-family` attribute is set in the SVG.
*
* Default: Times New Roman
*/
void setFontFamily(const QString &family)
{
if (family.isEmpty()) {
return;
}
auto familyC = family.toUtf8();
familyC.append('\0');
resvg_options_set_font_family(d, familyC.constData());
}
/**
* @brief Sets the default font size.
*
* Will be used when no `font-size` attribute is set in the SVG.
*
* Default: 12
*/
void setFontSize(const float size)
{
resvg_options_set_font_size(d, size);
}
/**
* @brief Sets a list of languages.
*
* Will be used to resolve a `systemLanguage` conditional attribute.
*
* Example: en, en-US.
*
* Default: en
*/
void setLanguages(const QStringList &languages)
{
if (languages.isEmpty()) {
resvg_options_set_languages(d, nullptr);
} else {
auto languagesC = languages.join(',').toUtf8();
languagesC.append('\0');
resvg_options_set_languages(d, languagesC.constData());
}
}
/**
* @brief Sets the default shape rendering method.
*
* Will be used when an SVG element's `shape-rendering` property is set to `auto`.
*
* Default: `RESVG_SHAPE_RENDERING_GEOMETRIC_PRECISION`
*/
void setShapeRenderingMode(const resvg_shape_rendering mode)
{
resvg_options_set_shape_rendering_mode(d, mode);
}
/**
* @brief Sets the default text rendering method.
*
* Will be used when an SVG element's `text-rendering` property is set to `auto`.
*
* Default: `RESVG_TEXT_RENDERING_OPTIMIZE_LEGIBILITY`
*/
void setTextRenderingMode(const resvg_text_rendering mode)
{
resvg_options_set_text_rendering_mode(d, mode);
}
/**
* @brief Sets the default image rendering method.
*
* Will be used when an SVG element's `image-rendering` property is set to `auto`.
*
* Default: `RESVG_IMAGE_RENDERING_OPTIMIZE_QUALITY`
*/
void setImageRenderingMode(const resvg_image_rendering mode)
{
resvg_options_set_image_rendering_mode(d, mode);
}
/**
* @brief Loads a font data into the internal fonts database.
*
* Prints a warning into the log when the data is not a valid TrueType font.
*/
void loadFontData(const QByteArray &data)
{
resvg_options_load_font_data(d, data.constData(), data.size());
}
/**
* @brief Loads a font file into the internal fonts database.
*
* Prints a warning into the log when the data is not a valid TrueType font.
*/
bool loadFontFile(const QString &path)
{
auto pathC = path.toUtf8();
pathC.append('\0');
return resvg_options_load_font_file(d, pathC.constData());
}
/**
* @brief Loads system fonts into the internal fonts database.
*
* This method is very IO intensive.
*
* This method should be executed only once per #resvg_options.
*
* The system scanning is not perfect, so some fonts may be omitted.
* Please send a bug report in this case.
*
* Prints warnings into the log.
*/
void loadSystemFonts()
{
resvg_options_load_system_fonts(d);
}
/**
* @brief Destructs options.
*/
~ResvgOptions()
{
resvg_options_destroy(d);
}
friend class ResvgRenderer;
private:
resvg_options * const d;
};
/**
* @brief QSvgRenderer-like wrapper for resvg.
*/
class ResvgRenderer {
public:
/**
* @brief Constructs a new renderer.
*/
ResvgRenderer()
: d(new ResvgPrivate::Data())
{
}
/**
* @brief Constructs a new renderer and loads the contents of the SVG(Z) file.
*/
ResvgRenderer(const QString &filePath, const ResvgOptions &opt)
: d(new ResvgPrivate::Data())
{
load(filePath, opt);
}
/**
* @brief Constructs a new renderer and loads the SVG data.
*/
ResvgRenderer(const QByteArray &data, const ResvgOptions &opt)
: d(new ResvgPrivate::Data())
{
load(data, opt);
}
/**
* @brief Loads the contents of the SVG(Z) file.
*/
bool load(const QString &filePath, const ResvgOptions &opt)
{
// Check for Qt resource path.
if (filePath.startsWith(QLatin1String(":/"))) {
QFile file(filePath);
if (file.open(QFile::ReadOnly))
return load(file.readAll(), opt);
else
return false;
}
d->reset();
auto filePathC = filePath.toUtf8();
filePathC.append('\0');
const auto err = resvg_parse_tree_from_file(filePathC.constData(), opt.d, &d->tree);
if (err != RESVG_OK) {
d->errMsg = ResvgPrivate::errorToString(err);
return false;
}
const auto s = resvg_get_image_size(d->tree);
d->size = QSizeF(s.width, s.height);
return true;
}
/**
* @brief Loads the SVG data.
*/
bool load(const QByteArray &data, const ResvgOptions &opt)
{
d->reset();
const auto err = resvg_parse_tree_from_data(data.constData(), data.size(), opt.d, &d->tree);
if (err != RESVG_OK) {
d->errMsg = ResvgPrivate::errorToString(err);
return false;
}
const auto s = resvg_get_image_size(d->tree);
d->size = QSizeF(s.width, s.height);
return true;
}
/**
* @brief Returns \b true if the file or data were loaded successful.
*/
bool isValid() const
{
return d->tree;
}
/**
* @brief Returns an underling error when #isValid is \b false.
*/
QString errorString() const
{
return d->errMsg;
}
/**
* @brief Checks that underling tree has any nodes.
*
* #ResvgRenderer and #ResvgRenderer constructors
* will set an error only if a file does not exist or it has a non-UTF-8 encoding.
* All other errors will result in an empty tree with a 100x100px size.
*
* @return Returns \b true if tree has no nodes.
*/
bool isEmpty() const
{
if (d->tree)
return resvg_is_image_empty(d->tree);
else
return true;
}
/**
* @brief Returns an SVG size.
*
* The `width` and `height` attributes in SVG.
*/
QSize defaultSize() const
{
return defaultSizeF().toSize();
}
/**
* @brief Returns an SVG size.
*
* The `width` and `height` attributes in SVG.
*/
QSizeF defaultSizeF() const
{
if (d->tree)
return d->size.toSize();
else
return QSizeF();
}
/**
* @brief Returns an SVG viewbox.
*
* `resvg` flattens the `viewbox`, therefore this method returns
* the same value as \b size.
*/
QRect viewBox() const
{
return QRect(0, 0, d->size.width(), d->size.height());
}
/**
* @brief Returns an SVG viewbox.
*
* `resvg` flattens the `viewbox`, therefore this method returns
* the same value as \b size.
*/
QRectF viewBoxF() const
{
return QRectF(0, 0, d->size.width(), d->size.height());
}
/**
* @brief Returns bounding rectangle of the item with the given \b id.
* The transformation matrix of parent elements is not affecting
* the bounds of the element.
*/
QRectF boundsOnElement(const QString &id) const
{
if (!d->tree)
return QRectF();
const auto utf8Str = id.toUtf8();
const auto rawId = utf8Str.constData();
resvg_rect bbox;
if (resvg_get_node_bbox(d->tree, rawId, &bbox))
return QRectF(bbox.x, bbox.y, bbox.width, bbox.height);
return QRectF();
}
/**
* @brief Returns bounding rectangle of a whole image.
*/
QRectF boundingBox() const
{
if (!d->tree)
return QRectF();
resvg_rect bbox;
if (resvg_get_object_bbox(d->tree, &bbox))
return QRectF(bbox.x, bbox.y, bbox.width, bbox.height);
return QRectF();
}
/**
* @brief Returns \b true if element with such an ID exists.
*/
bool elementExists(const QString &id) const
{
if (!d->tree)
return false;
const auto utf8Str = id.toUtf8();
const auto rawId = utf8Str.constData();
return resvg_node_exists(d->tree, rawId);
}
/**
* @brief Returns element's transform.
*/
QTransform transformForElement(const QString &id) const
{
if (!d->tree)
return QTransform();
const auto utf8Str = id.toUtf8();
const auto rawId = utf8Str.constData();
resvg_transform ts;
if (resvg_get_node_transform(d->tree, rawId, &ts))
return QTransform(ts.a, ts.b, ts.c, ts.d, ts.e, ts.f);
return QTransform();
}
// TODO: render node
/**
* @brief Renders the SVG data to \b QImage with a specified \b size.
*
* If \b size is not set, the \b defaultSize() will be used.
*/
QImage renderToImage(const QSize &size = QSize()) const
{
resvg_transform ts = resvg_transform_identity();
if (size.isValid()) {
// TODO: support height too.
auto sizef = defaultSizeF();
const auto newHeight = std::ceil(double(size.width()) * sizef.height() / sizef.width());
ts.a = double(size.width()) / sizef.width();
ts.d = newHeight / sizef.height();
}
auto svgSize = size;
if (svgSize.isEmpty())
svgSize = defaultSize();
QImage qImg(svgSize.width(), svgSize.height(), QImage::Format_ARGB32_Premultiplied);
qImg.fill(Qt::transparent);
resvg_render(d->tree, ts, qImg.width(), qImg.height(), (char*)qImg.bits());
// resvg renders onto the RGBA canvas, while QImage is ARGB.
// std::move is required to call inplace version of rgbSwapped().
return std::move(qImg).rgbSwapped();
}
/**
* @brief Initializes the library log.
*
* Use it if you want to see any warnings.
*
* Must be called only once.
*
* All warnings will be printed to the \b stderr.
*/
static void initLog()
{
resvg_init_log();
}
private:
QScopedPointer<ResvgPrivate::Data> d;
};
#endif // RESVG_QT_H
================================================
FILE: crates/c-api/cbindgen.toml
================================================
language = "C"
include_guard = "RESVG_H"
braces = "SameLine"
tab_width = 4
documentation_style = "doxy"
header = """// Copyright 2021 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
/**
* @file resvg.h
*
* resvg C API
*/"""
cpp_compat = true
no_includes = true
sys_includes = ["stdbool.h", "stdint.h"]
style = "type"
[fn]
sort_by = "None"
[enum]
rename_variants = "ScreamingSnakeCase"
prefix_with_name = true
[export]
include = [
"resvg_error",
"resvg_shape_rendering",
"resvg_text_rendering",
"resvg_image_rendering",
]
================================================
FILE: crates/c-api/examples/cairo/Makefile
================================================
TARGET = example
LIBS = -lm -L../../../../target/debug -lresvg `pkg-config --libs cairo`
CC = gcc
CFLAGS = -g -Wall `pkg-config --cflags cairo` -I../../
.PHONY: default all clean
default: $(TARGET)
all: default
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c))
%.o: %.c $(CC) $(CFLAGS) -c $< -o $@
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -Wall $(LIBS) -o $@
clean:
-rm -f *.o
-rm -f $(TARGET)
================================================
FILE: crates/c-api/examples/cairo/README.md
================================================
A simple example that shows how to use *resvg* through C API to render on a Cairo context.
## Run
```bash
cargo build --manifest-path ../../Cargo.toml
make
LD_LIBRARY_PATH=../../../../target/debug ./example image.svg image.png
```
================================================
FILE: crates/c-api/examples/cairo/example.c
================================================
// Copyright 2020 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <cairo.h>
#include <resvg.h>
int main(int argc, char **argv)
{
if (argc != 3)
{
printf("Usage:\n\texample in.svg out.png");
abort();
}
// Initialize resvg's library logging system
resvg_init_log();
resvg_options *opt = resvg_options_create();
resvg_options_load_system_fonts(opt);
// Optionally, you can add some CSS to control the SVG rendering.
resvg_options_set_stylesheet(opt, "svg { fill: black; }");
resvg_render_tree *tree;
// Construct a tree from the svg file and pass in some options
int err = resvg_parse_tree_from_file(argv[1], opt, &tree);
resvg_options_destroy(opt);
if (err != RESVG_OK)
{
printf("Error id: %i\n", err);
abort();
}
resvg_size size = resvg_get_image_size(tree);
int width = (int)size.width;
int height = (int)size.height;
// Using the dimension info, allocate enough pixels to account for the entire image
cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
/* resvg doesn't support stride, so cairo_surface_t should have no padding */
assert(cairo_image_surface_get_stride(surface) == (int)size.width * 4);
unsigned char *surface_data = cairo_image_surface_get_data(surface);
resvg_render(tree, resvg_transform_identity(), width, height, (char*)surface_data);
/* RGBA -> BGRA */
for (int i = 0; i < width * height * 4; i += 4)
{
unsigned char r = surface_data[i + 0];
surface_data[i + 0] = surface_data[i + 2];
surface_data[i + 2] = r;
}
// Save image
cairo_surface_write_to_png(surface, argv[2]);
// De-initialize the allocated memory
cairo_surface_destroy(surface);
resvg_tree_destroy(tree);
return 0;
}
================================================
FILE: crates/c-api/lib.rs
================================================
// Copyright 2020 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! C bindings.
#![allow(non_camel_case_types)]
#![warn(missing_docs)]
#![warn(missing_copy_implementations)]
use std::ffi::CStr;
use std::os::raw::c_char;
use std::slice;
use resvg::tiny_skia;
use resvg::usvg;
/// @brief List of possible errors.
#[repr(C)]
#[derive(Copy, Clone)]
pub enum resvg_error {
/// Everything is ok.
OK = 0,
/// Only UTF-8 content are supported.
NOT_AN_UTF8_STR,
/// Failed to open the provided file.
FILE_OPEN_FAILED,
/// Compressed SVG must use the GZip algorithm.
MALFORMED_GZIP,
/// We do not allow SVG with more than 1_000_000 elements for security reasons.
ELEMENTS_LIMIT_REACHED,
/// SVG doesn't have a valid size.
///
/// Occurs when width and/or height are <= 0.
///
/// Also occurs if width, height and viewBox are not set.
INVALID_SIZE,
/// Failed to parse an SVG data.
PARSING_FAILED,
}
/// @brief A rectangle representation.
#[repr(C)]
#[allow(missing_docs)]
#[derive(Copy, Clone)]
pub struct resvg_rect {
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}
/// @brief A size representation.
#[repr(C)]
#[allow(missing_docs)]
#[derive(Copy, Clone)]
pub struct resvg_size {
pub width: f32,
pub height: f32,
}
/// @brief A 2D transform representation.
#[repr(C)]
#[allow(missing_docs)]
#[derive(Copy, Clone)]
pub struct resvg_transform {
pub a: f32,
pub b: f32,
pub c: f32,
pub d: f32,
pub e: f32,
pub f: f32,
}
impl resvg_transform {
#[inline]
fn to_tiny_skia(&self) -> tiny_skia::Transform {
tiny_skia::Transform::from_row(self.a, self.b, self.c, self.d, self.e, self.f)
}
}
/// @brief Creates an identity transform.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_transform_identity() -> resvg_transform {
resvg_transform {
a: 1.0,
b: 0.0,
c: 0.0,
d: 1.0,
e: 0.0,
f: 0.0,
}
}
/// @brief Initializes the library log.
///
/// Use it if you want to see any warnings.
///
/// Must be called only once.
///
/// All warnings will be printed to the `stderr`.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_init_log() {
if let Ok(()) = log::set_logger(&LOGGER) {
log::set_max_level(log::LevelFilter::Warn);
}
}
/// @brief An SVG to #resvg_render_tree conversion options.
///
/// Also, contains a fonts database used during text to path conversion.
/// The database is empty by default.
pub struct resvg_options {
options: usvg::Options<'static>,
}
/// @brief Creates a new #resvg_options object.
///
/// Should be destroyed via #resvg_options_destroy.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_create() -> *mut resvg_options {
Box::into_raw(Box::new(resvg_options {
options: usvg::Options::default(),
}))
}
#[inline]
fn cast_opt(opt: *mut resvg_options) -> &'static mut usvg::Options<'static> {
unsafe {
assert!(!opt.is_null());
&mut (*opt).options
}
}
/// @brief Sets a directory that will be used during relative paths resolving.
///
/// Expected to be the same as the directory that contains the SVG file,
/// but can be set to any.
///
/// Must be UTF-8. Can be set to NULL.
///
/// Default: NULL
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_resources_dir(opt: *mut resvg_options, path: *const c_char) {
if path.is_null() {
cast_opt(opt).resources_dir = None;
} else {
cast_opt(opt).resources_dir = Some(cstr_to_str(path).unwrap().into());
}
}
/// @brief Sets the target DPI.
///
/// Impact units conversion.
///
/// Default: 96
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_dpi(opt: *mut resvg_options, dpi: f32) {
cast_opt(opt).dpi = dpi;
}
/// @brief Provides the content of a stylesheet that will be used when resolving CSS attributes.
///
/// Must be UTF-8. Can be set to NULL.
///
/// Default: NULL
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_stylesheet(opt: *mut resvg_options, content: *const c_char) {
if content.is_null() {
cast_opt(opt).style_sheet = None;
} else {
cast_opt(opt).style_sheet = Some(cstr_to_str(content).unwrap().into());
}
}
/// @brief Sets the default font family.
///
/// Will be used when no `font-family` attribute is set in the SVG.
///
/// Must be UTF-8. NULL is not allowed.
///
/// Default: Times New Roman
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_font_family(opt: *mut resvg_options, family: *const c_char) {
cast_opt(opt).font_family = cstr_to_str(family).unwrap().to_string();
}
/// @brief Sets the default font size.
///
/// Will be used when no `font-size` attribute is set in the SVG.
///
/// Default: 12
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_font_size(opt: *mut resvg_options, size: f32) {
cast_opt(opt).font_size = size;
}
/// @brief Sets the `serif` font family.
///
/// Must be UTF-8. NULL is not allowed.
///
/// Has no effect when the `text` feature is not enabled.
///
/// Default: Times New Roman
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_set_serif_family(opt: *mut resvg_options, family: *const c_char) {
#[cfg(feature = "text")]
{
cast_opt(opt)
.fontdb_mut()
.set_serif_family(cstr_to_str(family).unwrap().to_string());
}
}
/// @brief Sets the `sans-serif` font family.
///
/// Must be UTF-8. NULL is not allowed.
///
/// Has no effect when the `text` feature is not enabled.
///
/// Default: Arial
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_set_sans_serif_family(
opt: *mut resvg_options,
family: *const c_char,
) {
#[cfg(feature = "text")]
{
cast_opt(opt)
.fontdb_mut()
.set_sans_serif_family(cstr_to_str(family).unwrap().to_string());
}
}
/// @brief Sets the `cursive` font family.
///
/// Must be UTF-8. NULL is not allowed.
///
/// Has no effect when the `text` feature is not enabled.
///
/// Default: Comic Sans MS
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_set_cursive_family(opt: *mut resvg_options, family: *const c_char) {
#[cfg(feature = "text")]
{
cast_opt(opt)
.fontdb_mut()
.set_cursive_family(cstr_to_str(family).unwrap().to_string());
}
}
/// @brief Sets the `fantasy` font family.
///
/// Must be UTF-8. NULL is not allowed.
///
/// Has no effect when the `text` feature is not enabled.
///
/// Default: Papyrus on macOS, Impact on other OS'es
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_set_fantasy_family(opt: *mut resvg_options, family: *const c_char) {
#[cfg(feature = "text")]
{
cast_opt(opt)
.fontdb_mut()
.set_fantasy_family(cstr_to_str(family).unwrap().to_string());
}
}
/// @brief Sets the `monospace` font family.
///
/// Must be UTF-8. NULL is not allowed.
///
/// Has no effect when the `text` feature is not enabled.
///
/// Default: Courier New
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_set_monospace_family(
opt: *mut resvg_options,
family: *const c_char,
) {
#[cfg(feature = "text")]
{
cast_opt(opt)
.fontdb_mut()
.set_monospace_family(cstr_to_str(family).unwrap().to_string());
}
}
/// @brief Sets a comma-separated list of languages.
///
/// Will be used to resolve a `systemLanguage` conditional attribute.
///
/// Example: en,en-US.
///
/// Must be UTF-8. Can be NULL.
///
/// Default: en
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_languages(opt: *mut resvg_options, languages: *const c_char) {
if languages.is_null() {
cast_opt(opt).languages = Vec::new();
return;
}
let languages_str = match cstr_to_str(languages) {
Some(v) => v,
None => return,
};
let mut languages = Vec::new();
for lang in languages_str.split(',') {
languages.push(lang.trim().to_string());
}
cast_opt(opt).languages = languages;
}
/// @brief A shape rendering method.
#[repr(C)]
#[allow(missing_docs)]
#[derive(Copy, Clone)]
pub enum resvg_shape_rendering {
OPTIMIZE_SPEED,
CRISP_EDGES,
GEOMETRIC_PRECISION,
}
/// @brief Sets the default shape rendering method.
///
/// Will be used when an SVG element's `shape-rendering` property is set to `auto`.
///
/// Default: `RESVG_SHAPE_RENDERING_GEOMETRIC_PRECISION`
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_shape_rendering_mode(
opt: *mut resvg_options,
mode: resvg_shape_rendering,
) {
cast_opt(opt).shape_rendering = match mode as i32 {
0 => usvg::ShapeRendering::OptimizeSpeed,
1 => usvg::ShapeRendering::CrispEdges,
2 => usvg::ShapeRendering::GeometricPrecision,
_ => return,
}
}
/// @brief A text rendering method.
#[repr(C)]
#[allow(missing_docs)]
#[derive(Copy, Clone)]
pub enum resvg_text_rendering {
OPTIMIZE_SPEED,
OPTIMIZE_LEGIBILITY,
GEOMETRIC_PRECISION,
}
/// @brief Sets the default text rendering method.
///
/// Will be used when an SVG element's `text-rendering` property is set to `auto`.
///
/// Default: `RESVG_TEXT_RENDERING_OPTIMIZE_LEGIBILITY`
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_text_rendering_mode(
opt: *mut resvg_options,
mode: resvg_text_rendering,
) {
cast_opt(opt).text_rendering = match mode as i32 {
0 => usvg::TextRendering::OptimizeSpeed,
1 => usvg::TextRendering::OptimizeLegibility,
2 => usvg::TextRendering::GeometricPrecision,
_ => return,
}
}
/// @brief A image rendering method.
#[repr(C)]
#[allow(missing_docs)]
#[derive(Copy, Clone)]
pub enum resvg_image_rendering {
OPTIMIZE_QUALITY,
OPTIMIZE_SPEED,
}
/// @brief Sets the default image rendering method.
///
/// Will be used when an SVG element's `image-rendering` property is set to `auto`.
///
/// Default: `RESVG_IMAGE_RENDERING_OPTIMIZE_QUALITY`
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_set_image_rendering_mode(
opt: *mut resvg_options,
mode: resvg_image_rendering,
) {
cast_opt(opt).image_rendering = match mode as i32 {
0 => usvg::ImageRendering::OptimizeQuality,
1 => usvg::ImageRendering::OptimizeSpeed,
_ => return,
}
}
/// @brief Loads a font data into the internal fonts database.
///
/// Prints a warning into the log when the data is not a valid TrueType font.
///
/// Has no effect when the `text` feature is not enabled.
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_load_font_data(
opt: *mut resvg_options,
data: *const c_char,
len: usize,
) {
#[cfg(feature = "text")]
{
let data = unsafe { slice::from_raw_parts(data as *const u8, len) };
cast_opt(opt).fontdb_mut().load_font_data(data.to_vec())
}
}
/// @brief Loads a font file into the internal fonts database.
///
/// Prints a warning into the log when the data is not a valid TrueType font.
///
/// Has no effect when the `text` feature is not enabled.
///
/// @return #resvg_error with RESVG_OK, RESVG_ERROR_NOT_AN_UTF8_STR or RESVG_ERROR_FILE_OPEN_FAILED
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_load_font_file(
opt: *mut resvg_options,
file_path: *const c_char,
) -> i32 {
#[cfg(feature = "text")]
{
let file_path = match cstr_to_str(file_path) {
Some(v) => v,
None => return resvg_error::NOT_AN_UTF8_STR as i32,
};
if cast_opt(opt).fontdb_mut().load_font_file(file_path).is_ok() {
resvg_error::OK as i32
} else {
resvg_error::FILE_OPEN_FAILED as i32
}
}
#[cfg(not(feature = "text"))]
{
resvg_error::OK as i32
}
}
/// @brief Loads system fonts into the internal fonts database.
///
/// This method is very IO intensive.
///
/// This method should be executed only once per #resvg_options.
///
/// The system scanning is not perfect, so some fonts may be omitted.
/// Please send a bug report in this case.
///
/// Prints warnings into the log.
///
/// Has no effect when the `text` feature is not enabled.
#[unsafe(no_mangle)]
#[allow(unused_variables)]
pub extern "C" fn resvg_options_load_system_fonts(opt: *mut resvg_options) {
#[cfg(feature = "text")]
{
cast_opt(opt).fontdb_mut().load_system_fonts();
}
}
/// @brief Destroys the #resvg_options.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_options_destroy(opt: *mut resvg_options) {
unsafe {
assert!(!opt.is_null());
let _ = Box::from_raw(opt);
};
}
// TODO: use resvg::Tree
/// @brief An opaque pointer to the rendering tree.
pub struct resvg_render_tree(pub usvg::Tree);
/// @brief Creates #resvg_render_tree from file.
///
/// .svg and .svgz files are supported.
///
/// See #resvg_is_image_empty for details.
///
/// @param file_path UTF-8 file path.
/// @param opt Rendering options. Must not be NULL.
/// @param tree Parsed render tree. Should be destroyed via #resvg_tree_destroy.
/// @return #resvg_error
#[unsafe(no_mangle)]
pub extern "C" fn resvg_parse_tree_from_file(
file_path: *const c_char,
opt: *const resvg_options,
tree: *mut *mut resvg_render_tree,
) -> i32 {
let file_path = match cstr_to_str(file_path) {
Some(v) => v,
None => return resvg_error::NOT_AN_UTF8_STR as i32,
};
let raw_opt = unsafe {
assert!(!opt.is_null());
&*opt
};
let file_data = match std::fs::read(file_path) {
Ok(tree) => tree,
Err(_) => return resvg_error::FILE_OPEN_FAILED as i32,
};
let utree = usvg::Tree::from_data(&file_data, &raw_opt.options);
let utree = match utree {
Ok(tree) => tree,
Err(e) => return convert_error(e) as i32,
};
let tree_box = Box::new(resvg_render_tree(utree));
unsafe {
*tree = Box::into_raw(tree_box);
}
resvg_error::OK as i32
}
/// @brief Creates #resvg_render_tree from data.
///
/// See #resvg_is_image_empty for details.
///
/// @param data SVG data. Can contain SVG string or gzip compressed data. Must not be NULL.
/// @param len Data length.
/// @param opt Rendering options. Must not be NULL.
/// @param tree Parsed render tree. Should be destroyed via #resvg_tree_destroy.
/// @return #resvg_error
#[unsafe(no_mangle)]
pub extern "C" fn resvg_parse_tree_from_data(
data: *const c_char,
len: usize,
opt: *const resvg_options,
tree: *mut *mut resvg_render_tree,
) -> i32 {
let data = unsafe { slice::from_raw_parts(data as *const u8, len) };
let raw_opt = unsafe {
assert!(!opt.is_null());
&*opt
};
let utree = usvg::Tree::from_data(data, &raw_opt.options);
let utree = match utree {
Ok(tree) => tree,
Err(e) => return convert_error(e) as i32,
};
let tree_box = Box::new(resvg_render_tree(utree));
unsafe {
*tree = Box::into_raw(tree_box);
}
resvg_error::OK as i32
}
/// @brief Checks that tree has any nodes.
///
/// @param tree Render tree.
/// @return Returns `true` if tree has no nodes.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_is_image_empty(tree: *const resvg_render_tree) -> bool {
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
!tree.0.root().has_children()
}
/// @brief Returns an image size.
///
/// The size of an image that is required to render this SVG.
///
/// Note that elements outside the viewbox will be clipped. This is by design.
/// If you want to render the whole SVG content, use #resvg_get_image_bbox instead.
///
/// @param tree Render tree.
/// @return Image size.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_get_image_size(tree: *const resvg_render_tree) -> resvg_size {
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
let size = tree.0.size();
resvg_size {
width: size.width(),
height: size.height(),
}
}
/// @brief Returns an object bounding box.
///
/// This bounding box does not include objects stroke and filter regions.
/// This is what SVG calls "absolute object bonding box".
///
/// If you're looking for a "complete" bounding box see #resvg_get_image_bbox
///
/// @param tree Render tree.
/// @param bbox Image's object bounding box.
/// @return `false` if an image has no elements.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_get_object_bbox(
tree: *const resvg_render_tree,
bbox: *mut resvg_rect,
) -> bool {
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
if let Some(r) = tree.0.root().abs_bounding_box().to_non_zero_rect() {
unsafe {
*bbox = resvg_rect {
x: r.x(),
y: r.y(),
width: r.width(),
height: r.height(),
}
}
true
} else {
false
}
}
/// @brief Returns an image bounding box.
///
/// This bounding box contains the maximum SVG dimensions.
/// It's size can be bigger or smaller than #resvg_get_image_size
/// Use it when you want to avoid clipping of elements that are outside the SVG viewbox.
///
/// @param tree Render tree.
/// @param bbox Image's bounding box.
/// @return `false` if an image has no elements.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_get_image_bbox(
tree: *const resvg_render_tree,
bbox: *mut resvg_rect,
) -> bool {
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
// `abs_layer_bounding_box` returns 0x0x1x1 for empty groups, so we need additional checks.
if tree.0.root().has_children() || !tree.0.root().filters().is_empty() {
let r = tree.0.root().abs_layer_bounding_box();
unsafe {
*bbox = resvg_rect {
x: r.x(),
y: r.y(),
width: r.width(),
height: r.height(),
}
}
true
} else {
false
}
}
/// @brief Returns `true` if a renderable node with such an ID exists.
///
/// @param tree Render tree.
/// @param id Node's ID. UTF-8 string. Must not be NULL.
/// @return `true` if a node exists.
/// @return `false` if a node doesn't exist or ID isn't a UTF-8 string.
/// @return `false` if a node exists, but not renderable.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_node_exists(tree: *const resvg_render_tree, id: *const c_char) -> bool {
let id = match cstr_to_str(id) {
Some(v) => v,
None => {
log::warn!("Provided ID is not a UTF-8 string.");
return false;
}
};
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
tree.0.node_by_id(id).is_some()
}
/// @brief Returns node's transform by ID.
///
/// @param tree Render tree.
/// @param id Node's ID. UTF-8 string. Must not be NULL.
/// @param transform Node's transform.
/// @return `true` if a node exists.
/// @return `false` if a node doesn't exist or ID isn't a UTF-8 string.
/// @return `false` if a node exists, but not renderable.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_get_node_transform(
tree: *const resvg_render_tree,
id: *const c_char,
transform: *mut resvg_transform,
) -> bool {
let id = match cstr_to_str(id) {
Some(v) => v,
None => {
log::warn!("Provided ID is not a UTF-8 string.");
return false;
}
};
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
if let Some(node) = tree.0.node_by_id(id) {
let abs_ts = node.abs_transform();
unsafe {
*transform = resvg_transform {
a: abs_ts.sx,
b: abs_ts.ky,
c: abs_ts.kx,
d: abs_ts.sy,
e: abs_ts.tx,
f: abs_ts.ty,
}
}
return true;
}
false
}
/// @brief Returns node's bounding box in canvas coordinates by ID.
///
/// @param tree Render tree.
/// @param id Node's ID. Must not be NULL.
/// @param bbox Node's bounding box.
/// @return `false` if a node with such an ID does not exist
/// @return `false` if ID isn't a UTF-8 string.
/// @return `false` if ID is an empty string
#[unsafe(no_mangle)]
pub extern "C" fn resvg_get_node_bbox(
tree: *const resvg_render_tree,
id: *const c_char,
bbox: *mut resvg_rect,
) -> bool {
get_node_bbox(tree, id, bbox, &|node| node.abs_bounding_box())
}
/// @brief Returns node's bounding box, including stroke, in canvas coordinates by ID.
///
/// @param tree Render tree.
/// @param id Node's ID. Must not be NULL.
/// @param bbox Node's bounding box.
/// @return `false` if a node with such an ID does not exist
/// @return `false` if ID isn't a UTF-8 string.
/// @return `false` if ID is an empty string
#[unsafe(no_mangle)]
pub extern "C" fn resvg_get_node_stroke_bbox(
tree: *const resvg_render_tree,
id: *const c_char,
bbox: *mut resvg_rect,
) -> bool {
get_node_bbox(tree, id, bbox, &|node| node.abs_stroke_bounding_box())
}
fn get_node_bbox(
tree: *const resvg_render_tree,
id: *const c_char,
bbox: *mut resvg_rect,
f: &dyn Fn(&usvg::Node) -> usvg::Rect,
) -> bool {
let id = match cstr_to_str(id) {
Some(v) => v,
None => {
log::warn!("Provided ID is not a UTF-8 string.");
return false;
}
};
if id.is_empty() {
log::warn!("Node ID must not be empty.");
return false;
}
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
match tree.0.node_by_id(id) {
Some(node) => {
let r = f(node);
unsafe {
*bbox = resvg_rect {
x: r.x(),
y: r.y(),
width: r.width(),
height: r.height(),
}
}
true
}
None => {
log::warn!("No node with '{}' ID is in the tree.", id);
false
}
}
}
/// @brief Destroys the #resvg_render_tree.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_tree_destroy(tree: *mut resvg_render_tree) {
unsafe {
assert!(!tree.is_null());
let _ = Box::from_raw(tree);
};
}
fn cstr_to_str(text: *const c_char) -> Option<&'static str> {
let text = unsafe {
assert!(!text.is_null());
CStr::from_ptr(text)
};
text.to_str().ok()
}
fn convert_error(e: usvg::Error) -> resvg_error {
match e {
usvg::Error::NotAnUtf8Str => resvg_error::NOT_AN_UTF8_STR,
usvg::Error::MalformedGZip => resvg_error::MALFORMED_GZIP,
usvg::Error::ElementsLimitReached => resvg_error::ELEMENTS_LIMIT_REACHED,
usvg::Error::InvalidSize => resvg_error::INVALID_SIZE,
usvg::Error::ParsingFailed(_) => resvg_error::PARSING_FAILED,
}
}
/// @brief Renders the #resvg_render_tree onto the pixmap.
///
/// @param tree A render tree.
/// @param transform A root SVG transform. Can be used to position SVG inside the `pixmap`.
/// @param width Pixmap width.
/// @param height Pixmap height.
/// @param pixmap Pixmap data. Should have width*height*4 size and contain
/// premultiplied RGBA8888 pixels.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_render(
tree: *const resvg_render_tree,
transform: resvg_transform,
width: u32,
height: u32,
pixmap: *mut c_char,
) {
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
let pixmap_len = width as usize * height as usize * tiny_skia::BYTES_PER_PIXEL;
let pixmap: &mut [u8] =
unsafe { std::slice::from_raw_parts_mut(pixmap as *mut u8, pixmap_len) };
let mut pixmap = tiny_skia::PixmapMut::from_bytes(pixmap, width, height).unwrap();
resvg::render(&tree.0, transform.to_tiny_skia(), &mut pixmap)
}
/// @brief Renders a Node by ID onto the image.
///
/// @param tree A render tree.
/// @param id Node's ID. Must not be NULL.
/// @param transform A root SVG transform. Can be used to position SVG inside the `pixmap`.
/// @param width Pixmap width.
/// @param height Pixmap height.
/// @param pixmap Pixmap data. Should have width*height*4 size and contain
/// premultiplied RGBA8888 pixels.
/// @return `false` when `id` is not a non-empty UTF-8 string.
/// @return `false` when the selected `id` is not present.
/// @return `false` when an element has a zero bbox.
#[unsafe(no_mangle)]
pub extern "C" fn resvg_render_node(
tree: *const resvg_render_tree,
id: *const c_char,
transform: resvg_transform,
width: u32,
height: u32,
pixmap: *mut c_char,
) -> bool {
let tree = unsafe {
assert!(!tree.is_null());
&*tree
};
let id = match cstr_to_str(id) {
Some(v) => v,
None => return false,
};
if id.is_empty() {
log::warn!("Node with an empty ID cannot be rendered.");
return false;
}
if let Some(node) = tree.0.node_by_id(id) {
let pixmap_len = width as usize * height as usize * tiny_skia::BYTES_PER_PIXEL;
let pixmap: &mut [u8] =
unsafe { std::slice::from_raw_parts_mut(pixmap as *mut u8, pixmap_len) };
let mut pixmap = tiny_skia::PixmapMut::from_bytes(pixmap, width, height).unwrap();
resvg::render_node(node, transform.to_tiny_skia(), &mut pixmap).is_some()
} else {
log::warn!("A node with '{}' ID wasn't found.", id);
false
}
}
/// 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().len() > 0 {
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 => eprintln!("Error (in {}:{}): {}", target, line, args),
log::Level::Warn => eprintln!("Warning (in {}:{}): {}", target, line, args),
log::Level::Info => eprintln!("Info (in {}:{}): {}", target, line, args),
log::Level::Debug => eprintln!("Debug (in {}:{}): {}", target, line, args),
log::Level::Trace => eprintln!("Trace (in {}:{}): {}", target, line, args),
}
}
}
fn flush(&self) {}
}
================================================
FILE: crates/c-api/resvg.h
================================================
// Copyright 2021 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
/**
* @file resvg.h
*
* resvg C API
*/
#ifndef RESVG_H
#define RESVG_H
#include <stdbool.h>
#include <stdint.h>
#define RESVG_MAJOR_VERSION 0
#define RESVG_MINOR_VERSION 47
#define RESVG_PATCH_VERSION 0
#define RESVG_VERSION "0.47.0"
/**
* @brief List of possible errors.
*/
typedef enum {
/**
* Everything is ok.
*/
RESVG_OK = 0,
/**
* Only UTF-8 content are supported.
*/
RESVG_ERROR_NOT_AN_UTF8_STR,
/**
* Failed to open the provided file.
*/
RESVG_ERROR_FILE_OPEN_FAILED,
/**
* Compressed SVG must use the GZip algorithm.
*/
RESVG_ERROR_MALFORMED_GZIP,
/**
* We do not allow SVG with more than 1_000_000 elements for security reasons.
*/
RESVG_ERROR_ELEMENTS_LIMIT_REACHED,
/**
* SVG doesn't have a valid size.
*
* Occurs when width and/or height are <= 0.
*
* Also occurs if width, height and viewBox are not set.
*/
RESVG_ERROR_INVALID_SIZE,
/**
* Failed to parse an SVG data.
*/
RESVG_ERROR_PARSING_FAILED,
} resvg_error;
/**
* @brief A image rendering method.
*/
typedef enum {
RESVG_IMAGE_RENDERING_OPTIMIZE_QUALITY,
RESVG_IMAGE_RENDERING_OPTIMIZE_SPEED,
} resvg_image_rendering;
/**
* @brief A shape rendering method.
*/
typedef enum {
RESVG_SHAPE_RENDERING_OPTIMIZE_SPEED,
RESVG_SHAPE_RENDERING_CRISP_EDGES,
RESVG_SHAPE_RENDERING_GEOMETRIC_PRECISION,
} resvg_shape_rendering;
/**
* @brief A text rendering method.
*/
typedef enum {
RESVG_TEXT_RENDERING_OPTIMIZE_SPEED,
RESVG_TEXT_RENDERING_OPTIMIZE_LEGIBILITY,
RESVG_TEXT_RENDERING_GEOMETRIC_PRECISION,
} resvg_text_rendering;
/**
* @brief An SVG to #resvg_render_tree conversion options.
*
* Also, contains a fonts database used during text to path conversion.
* The database is empty by default.
*/
typedef struct resvg_options resvg_options;
/**
* @brief An opaque pointer to the rendering tree.
*/
typedef struct resvg_render_tree resvg_render_tree;
/**
* @brief A 2D transform representation.
*/
typedef struct {
float a;
float b;
float c;
float d;
float e;
float f;
} resvg_transform;
/**
* @brief A size representation.
*/
typedef struct {
float width;
float height;
} resvg_size;
/**
* @brief A rectangle representation.
*/
typedef struct {
float x;
float y;
float width;
float height;
} resvg_rect;
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/**
* @brief Creates an identity transform.
*/
resvg_transform resvg_transform_identity(void);
/**
* @brief Initializes the library log.
*
* Use it if you want to see any warnings.
*
* Must be called only once.
*
* All warnings will be printed to the `stderr`.
*/
void resvg_init_log(void);
/**
* @brief Creates a new #resvg_options object.
*
* Should be destroyed via #resvg_options_destroy.
*/
resvg_options *resvg_options_create(void);
/**
* @brief Sets a directory that will be used during relative paths resolving.
*
* Expected to be the same as the directory that contains the SVG file,
* but can be set to any.
*
* Must be UTF-8. Can be set to NULL.
*
* Default: NULL
*/
void resvg_options_set_resources_dir(resvg_options *opt, const char *path);
/**
* @brief Sets the target DPI.
*
* Impact units conversion.
*
* Default: 96
*/
void resvg_options_set_dpi(resvg_options *opt, float dpi);
/**
* @brief Provides the content of a stylesheet that will be used when resolving CSS attributes.
*
* Must be UTF-8. Can be set to NULL.
*
* Default: NULL
*/
void resvg_options_set_stylesheet(resvg_options *opt, const char *content);
/**
* @brief Sets the default font family.
*
* Will be used when no `font-family` attribute is set in the SVG.
*
* Must be UTF-8. NULL is not allowed.
*
* Default: Times New Roman
*/
void resvg_options_set_font_family(resvg_options *opt, const char *family);
/**
* @brief Sets the default font size.
*
* Will be used when no `font-size` attribute is set in the SVG.
*
* Default: 12
*/
void resvg_options_set_font_size(resvg_options *opt, float size);
/**
* @brief Sets the `serif` font family.
*
* Must be UTF-8. NULL is not allowed.
*
* Has no effect when the `text` feature is not enabled.
*
* Default: Times New Roman
*/
void resvg_options_set_serif_family(resvg_options *opt, const char *family);
/**
* @brief Sets the `sans-serif` font family.
*
* Must be UTF-8. NULL is not allowed.
*
* Has no effect when the `text` feature is not enabled.
*
* Default: Arial
*/
void resvg_options_set_sans_serif_family(resvg_options *opt, const char *family);
/**
* @brief Sets the `cursive` font family.
*
* Must be UTF-8. NULL is not allowed.
*
* Has no effect when the `text` feature is not enabled.
*
* Default: Comic Sans MS
*/
void resvg_options_set_cursive_family(resvg_options *opt, const char *family);
/**
* @brief Sets the `fantasy` font family.
*
* Must be UTF-8. NULL is not allowed.
*
* Has no effect when the `text` feature is not enabled.
*
* Default: Papyrus on macOS, Impact on other OS'es
*/
void resvg_options_set_fantasy_family(resvg_options *opt, const char *family);
/**
* @brief Sets the `monospace` font family.
*
* Must be UTF-8. NULL is not allowed.
*
* Has no effect when the `text` feature is not enabled.
*
* Default: Courier New
*/
void resvg_options_set_monospace_family(resvg_options *opt, const char *family);
/**
* @brief Sets a comma-separated list of languages.
*
* Will be used to resolve a `systemLanguage` conditional attribute.
*
* Example: en,en-US.
*
* Must be UTF-8. Can be NULL.
*
* Default: en
*/
void resvg_options_set_languages(resvg_options *opt, const char *languages);
/**
* @brief Sets the default shape rendering method.
*
* Will be used when an SVG element's `shape-rendering` property is set to `auto`.
*
* Default: `RESVG_SHAPE_RENDERING_GEOMETRIC_PRECISION`
*/
void resvg_options_set_shape_rendering_mode(resvg_options *opt, resvg_shape_rendering mode);
/**
* @brief Sets the default text rendering method.
*
* Will be used when an SVG element's `text-rendering` property is set to `auto`.
*
* Default: `RESVG_TEXT_RENDERING_OPTIMIZE_LEGIBILITY`
*/
void resvg_options_set_text_rendering_mode(resvg_options *opt, resvg_text_rendering mode);
/**
* @brief Sets the default image rendering method.
*
* Will be used when an SVG element's `image-rendering` property is set to `auto`.
*
* Default: `RESVG_IMAGE_RENDERING_OPTIMIZE_QUALITY`
*/
void resvg_options_set_image_rendering_mode(resvg_options *opt, resvg_image_rendering mode);
/**
* @brief Loads a font data into the internal fonts database.
*
* Prints a warning into the log when the data is not a valid TrueType font.
*
* Has no effect when the `text` feature is not enabled.
*/
void resvg_options_load_font_data(resvg_options *opt, const char *data, uintptr_t len);
/**
* @brief Loads a font file into the internal fonts database.
*
* Prints a warning into the log when the data is not a valid TrueType font.
*
* Has no effect when the `text` feature is not enabled.
*
* @return #resvg_error with RESVG_OK, RESVG_ERROR_NOT_AN_UTF8_STR or RESVG_ERROR_FILE_OPEN_FAILED
*/
int32_t resvg_options_load_font_file(resvg_options *opt, const char *file_path);
/**
* @brief Loads system fonts into the internal fonts database.
*
* This method is very IO intensive.
*
* This method should be executed only once per #resvg_options.
*
* The system scanning is not perfect, so some fonts may be omitted.
* Please send a bug report in this case.
*
* Prints warnings into the log.
*
* Has no effect when the `text` feature is not enabled.
*/
void resvg_options_load_system_fonts(resvg_options *opt);
/**
* @brief Destroys the #resvg_options.
*/
void resvg_options_destroy(resvg_options *opt);
/**
* @brief Creates #resvg_render_tree from file.
*
* .svg and .svgz files are supported.
*
* See #resvg_is_image_empty for details.
*
* @param file_path UTF-8 file path.
* @param opt Rendering options. Must not be NULL.
* @param tree Parsed render tree. Should be destroyed via #resvg_tree_destroy.
* @return #resvg_error
*/
int32_t resvg_parse_tree_from_file(const char *file_path,
const resvg_options *opt,
resvg_render_tree **tree);
/**
* @brief Creates #resvg_render_tree from data.
*
* See #resvg_is_image_empty for details.
*
* @param data SVG data. Can contain SVG string or gzip compressed data. Must not be NULL.
* @param len Data length.
* @param opt Rendering options. Must not be NULL.
* @param tree Parsed render tree. Should be destroyed via #resvg_tree_destroy.
* @return #resvg_error
*/
int32_t resvg_parse_tree_from_data(const char *data,
uintptr_t len,
const resvg_options *opt,
resvg_render_tree **tree);
/**
* @brief Checks that tree has any nodes.
*
* @param tree Render tree.
* @return Returns `true` if tree has no nodes.
*/
bool resvg_is_image_empty(const resvg_render_tree *tree);
/**
* @brief Returns an image size.
*
* The size of an image that is required to render this SVG.
*
* Note that elements outside the viewbox will be clipped. This is by design.
* If you want to render the whole SVG content, use #resvg_get_image_bbox instead.
*
* @param tree Render tree.
* @return Image size.
*/
resvg_size resvg_get_image_size(const resvg_render_tree *tree);
/**
* @brief Returns an object bounding box.
*
* This bounding box does not include objects stroke and filter regions.
* This is what SVG calls "absolute object bonding box".
*
* If you're looking for a "complete" bounding box see #resvg_get_image_bbox
*
* @param tree Render tree.
* @param bbox Image's object bounding box.
* @return `false` if an image has no elements.
*/
bool resvg_get_object_bbox(const resvg_render_tree *tree, resvg_rect *bbox);
/**
* @brief Returns an image bounding box.
*
* This bounding box contains the maximum SVG dimensions.
* It's size can be bigger or smaller than #resvg_get_image_size
* Use it when you want to avoid clipping of elements that are outside the SVG viewbox.
*
* @param tree Render tree.
* @param bbox Image's bounding box.
* @return `false` if an image has no elements.
*/
bool resvg_get_image_bbox(const resvg_render_tree *tree, resvg_rect *bbox);
/**
* @brief Returns `true` if a renderable node with such an ID exists.
*
* @param tree Render tree.
* @param id Node's ID. UTF-8 string. Must not be NULL.
* @return `true` if a node exists.
* @return `false` if a node doesn't exist or ID isn't a UTF-8 string.
* @return `false` if a node exists, but not renderable.
*/
bool resvg_node_exists(const resvg_render_tree *tree, const char *id);
/**
* @brief Returns node's transform by ID.
*
* @param tree Render tree.
* @param id Node's ID. UTF-8 string. Must not be NULL.
* @param transform Node's transform.
* @return `true` if a node exists.
* @return `false` if a node doesn't exist or ID isn't a UTF-8 string.
* @return `false` if a node exists, but not renderable.
*/
bool resvg_get_node_transform(const resvg_render_tree *tree,
const char *id,
resvg_transform *transform);
/**
* @brief Returns node's bounding box in canvas coordinates by ID.
*
* @param tree Render tree.
* @param id Node's ID. Must not be NULL.
* @param bbox Node's bounding box.
* @return `false` if a node with such an ID does not exist
* @return `false` if ID isn't a UTF-8 string.
* @return `false` if ID is an empty string
*/
bool resvg_get_node_bbox(const resvg_render_tree *tree, const char *id, resvg_rect *bbox);
/**
* @brief Returns node's bounding box, including stroke, in canvas coordinates by ID.
*
* @param tree Render tree.
* @param id Node's ID. Must not be NULL.
* @param bbox Node's bounding box.
* @return `false` if a node with such an ID does not exist
* @return `false` if ID isn't a UTF-8 string.
* @return `false` if ID is an empty string
*/
bool resvg_get_node_stroke_bbox(const resvg_render_tree *tree, const char *id, resvg_rect *bbox);
/**
* @brief Destroys the #resvg_render_tree.
*/
void resvg_tree_destroy(resvg_render_tree *tree);
/**
* @brief Renders the #resvg_render_tree onto the pixmap.
*
* @param tree A render tree.
* @param transform A root SVG transform. Can be used to position SVG inside the `pixmap`.
* @param width Pixmap width.
* @param height Pixmap height.
* @param pixmap Pixmap data. Should have width*height*4 size and contain
* premultiplied RGBA8888 pixels.
*/
void resvg_render(const resvg_render_tree *tree,
resvg_transform transform,
uint32_t width,
uint32_t height,
char *pixmap);
/**
* @brief Renders a Node by ID onto the image.
*
* @param tree A render tree.
* @param id Node's ID. Must not be NULL.
* @param transform A root SVG transform. Can be used to position SVG inside the `pixmap`.
* @param width Pixmap width.
* @param height Pixmap height.
* @param pixmap Pixmap data. Should have width*height*4 size and contain
* premultiplied RGBA8888 pixels.
* @return `false` when `id` is not a non-empty UTF-8 string.
* @return `false` when the selected `id` is not present.
* @return `false` when an element has a zero bbox.
*/
bool resvg_render_node(const resvg_render_tree *tree,
const char *id,
resvg_transform transform,
uint32_t width,
uint32_t height,
char *pixmap);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
#endif /* RESVG_H */
================================================
FILE: crates/resvg/Cargo.toml
================================================
[package]
name = "resvg"
version = "0.47.0"
keywords = ["svg", "render", "raster"]
license.workspace = true
edition = "2024"
rust-version = "1.87.0"
description = "An SVG rendering library."
repository = "https://github.com/linebender/resvg"
exclude = ["tests"]
workspace = "../.."
[[bin]]
name = "resvg"
required-features = ["text", "system-fonts", "memmap-fonts"]
[dependencies]
gif = { version = "0.14.1", optional = true }
image-webp = { version = "0.2.4", optional = true }
log = "0.4"
pico-args = { version = "0.5", features = ["eq-separator"] }
rgb = "0.8"
svgtypes = "0.16.1"
tiny-skia = "0.12.0"
usvg = { path = "../usvg", version = "0.47.0", default-features = false }
zune-jpeg = { version = "0.5.8", optional = true }
[dev-dependencies]
once_cell = "1.21"
png = "0.18.0"
[features]
default = ["text", "system-fonts", "memmap-fonts", "raster-images"]
# Enables SVG Text support.
# Adds around 400KiB to your binary.
text = ["usvg/text"]
# Enables system fonts loading (only for `text`).
system-fonts = ["usvg/system-fonts"]
# Enables font files memmaping for faster loading (only for `text`).
memmap-fonts = ["usvg/memmap-fonts"]
# Enables decoding and rendering of raster images.
# When disabled, `image` elements with SVG data will still be rendered.
# Adds around 200KiB to your binary.
raster-images = ["gif", "image-webp", "dep:zune-jpeg"]
================================================
FILE: crates/resvg/LICENSE-APACHE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
================================================
FILE: crates/resvg/LICENSE-MIT
================================================
Copyright 2017 the Resvg Authors
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
================================================
FILE: crates/resvg/examples/custom_href_resolver.rs
================================================
// Copyright 2022 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
fn main() {
let mut opt = usvg::Options::default();
let ferris_image = std::sync::Arc::new(std::fs::read("./examples/ferris.png").unwrap());
// We know that our SVG won't have DataUrl hrefs, just return None for such case.
let resolve_data = Box::new(|_: &str, _: std::sync::Arc<Vec<u8>>, _: &usvg::Options| None);
// Here we handle xlink:href attribute as string,
// let's use already loaded Ferris image to match that string.
let resolve_string = Box::new(move |href: &str, _: &usvg::Options| match href {
"ferris_image" => Some(usvg::ImageKind::PNG(ferris_image.clone())),
_ => None,
});
// Assign new ImageHrefResolver option using our closures.
opt.image_href_resolver = usvg::ImageHrefResolver {
resolve_data,
resolve_string,
};
let svg_data = std::fs::read("./examples/custom_href_resolver.svg").unwrap();
let tree = usvg::Tree::from_data(&svg_data, &opt).unwrap();
let pixmap_size = tree.size().to_int_size();
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
resvg::render(&tree, tiny_skia::Transform::default(), &mut pixmap.as_mut());
pixmap.save_png("custom_href_resolver.png").unwrap();
}
================================================
FILE: crates/resvg/examples/draw_bboxes.rs
================================================
// Copyright 2017 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
fn main() {
let args: Vec<String> = std::env::args().collect();
if !(args.len() == 3 || args.len() == 5) {
println!(
"Usage:\n\
\tdraw_bboxes <in-svg> <out-png>\n\
\tdraw_bboxes <in-svg> <out-png> -z ZOOM"
);
return;
}
let zoom = if args.len() == 5 {
args[4].parse::<f32>().expect("not a float")
} else {
1.0
};
let mut opt = usvg::Options {
// Get file's absolute directory.
resources_dir: std::fs::canonicalize(&args[1])
.ok()
.and_then(|p| p.parent().map(|p| p.to_path_buf())),
..usvg::Options::default()
};
opt.fontdb_mut().load_system_fonts();
let svg_data = std::fs::read(&args[1]).unwrap();
let tree = usvg::Tree::from_data(&svg_data, &opt).unwrap();
let mut bboxes = Vec::new();
let mut stroke_bboxes = Vec::new();
collect_bboxes(tree.root(), &mut bboxes, &mut stroke_bboxes);
let pixmap_size = tree.size().to_int_size().scale_by(zoom).unwrap();
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
let render_ts = tiny_skia::Transform::from_scale(zoom, zoom);
resvg::render(&tree, render_ts, &mut pixmap.as_mut());
let stroke = tiny_skia::Stroke {
width: 1.0 / zoom, // prevent stroke scaling as well
..tiny_skia::Stroke::default()
};
let mut paint1 = tiny_skia::Paint::default();
paint1.set_color_rgba8(255, 0, 0, 127);
let mut paint2 = tiny_skia::Paint::default();
paint2.set_color_rgba8(0, 200, 0, 127);
for bbox in bboxes {
let path = tiny_skia::PathBuilder::from_rect(bbox);
pixmap.stroke_path(&path, &paint1, &stroke, render_ts, None);
}
for bbox in stroke_bboxes {
let path = tiny_skia::PathBuilder::from_rect(bbox);
pixmap.stroke_path(&path, &paint2, &stroke, render_ts, None);
}
pixmap.save_png(&args[2]).unwrap();
}
fn collect_bboxes(
parent: &usvg::Group,
bboxes: &mut Vec<usvg::Rect>,
stroke_bboxes: &mut Vec<usvg::Rect>,
) {
for node in parent.children() {
if let usvg::Node::Group(group) = node {
collect_bboxes(group, bboxes, stroke_bboxes);
}
let bbox = node.abs_bounding_box();
bboxes.push(bbox);
let stroke_bbox = node.abs_stroke_bounding_box();
if bbox != stroke_bbox {
stroke_bboxes.push(stroke_bbox);
}
}
}
================================================
FILE: crates/resvg/examples/minimal.rs
================================================
// Copyright 2017 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
fn main() {
let args: Vec<String> = std::env::args().collect();
if args.len() != 3 {
println!("Usage:\n\tminimal <in-svg> <out-png>");
return;
}
let tree = {
let mut opt = usvg::Options {
// Get file's absolute directory.
resources_dir: std::fs::canonicalize(&args[1])
.ok()
.and_then(|p| p.parent().map(|p| p.to_path_buf())),
..usvg::Options::default()
};
opt.fontdb_mut().load_system_fonts();
let svg_data = std::fs::read(&args[1]).unwrap();
usvg::Tree::from_data(&svg_data, &opt).unwrap()
};
let pixmap_size = tree.size().to_int_size();
let mut pixmap = tiny_skia::Pixmap::new(pixmap_size.width(), pixmap_size.height()).unwrap();
resvg::render(&tree, tiny_skia::Transform::default(), &mut pixmap.as_mut());
pixmap.save_png(&args[2]).unwrap();
}
================================================
FILE: crates/resvg/src/clip.rs
================================================
// Copyright 2019 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
use crate::render::Context;
pub fn apply(
clip: &usvg::ClipPath,
transform: tiny_skia::Transform,
pixmap: &mut tiny_skia::Pixmap,
) {
let mut clip_pixmap = tiny_skia::Pixmap::new(pixmap.width(), pixmap.height()).unwrap();
clip_pixmap.fill(tiny_skia::Color::BLACK);
draw_children(
clip.root(),
tiny_skia::BlendMode::Clear,
transform.pre_concat(clip.transform()),
&mut clip_pixmap.as_mut(),
);
if let Some(clip) = clip.clip_path() {
apply(clip, transform, pixmap);
}
let mut mask = tiny_skia::Mask::from_pixmap(clip_pixmap.as_ref(), tiny_skia::MaskType::Alpha);
mask.invert();
pixmap.apply_mask(&mask);
}
fn draw_children(
parent: &usvg::Group,
mode: tiny_skia::BlendMode,
transform: tiny_skia::Transform,
pixmap: &mut tiny_skia::PixmapMut,
) {
for child in parent.children() {
match child {
usvg::Node::Path(path) => {
if !path.is_visible() {
continue;
}
// We could use any values here. They will not be used anyway.
let ctx = Context {
max_bbox: tiny_skia::IntRect::from_xywh(0, 0, 1, 1).unwrap(),
};
crate::path::fill_path(path, mode, &ctx, transform, pixmap);
}
usvg::Node::Text(text) => {
draw_children(text.flattened(), mode, transform, pixmap);
}
usvg::Node::Group(group) => {
let transform = transform.pre_concat(group.transform());
if let Some(clip) = group.clip_path() {
// If a `clipPath` child also has a `clip-path`
// then we should render this child on a new canvas,
// clip it, and only then draw it to the `clipPath`.
clip_group(group, clip, transform, pixmap);
} else {
draw_children(group, mode, transform, pixmap);
}
}
_ => {}
}
}
}
fn clip_group(
children: &usvg::Group,
clip: &usvg::ClipPath,
transform: tiny_skia::Transform,
pixmap: &mut tiny_skia::PixmapMut,
) -> Option<()> {
let mut clip_pixmap = tiny_skia::Pixmap::new(pixmap.width(), pixmap.height()).unwrap();
draw_children(
children,
tiny_skia::BlendMode::SourceOver,
transform,
&mut clip_pixmap.as_mut(),
);
apply(clip, transform, &mut clip_pixmap);
let mut paint = tiny_skia::PixmapPaint::default();
paint.blend_mode = tiny_skia::BlendMode::Xor;
pixmap.draw_pixmap(
0,
0,
clip_pixmap.as_ref(),
&paint,
tiny_skia::Transform::identity(),
None,
);
Some(())
}
================================================
FILE: crates/resvg/src/filter/box_blur.rs
================================================
// Copyright 2020 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
// Based on https://github.com/fschutt/fastblur
#![allow(clippy::needless_range_loop)]
use super::ImageRefMut;
use rgb::RGBA8;
use std::cmp;
const STEPS: usize = 5;
/// Applies a box blur.
///
/// Input image pixels should have a **premultiplied alpha**.
///
/// A negative or zero `sigma_x`/`sigma_y` will disable the blur along that axis.
///
/// # Allocations
///
/// This method will allocate a copy of the `src` image as a back buffer.
pub fn apply(sigma_x: f64, sigma_y: f64, mut src: ImageRefMut) {
let boxes_horz = create_box_gauss(sigma_x as f32);
let boxes_vert = create_box_gauss(sigma_y as f32);
let mut backbuf = src.data.to_vec();
let mut backbuf = ImageRefMut::new(src.width, src.height, &mut backbuf);
for (box_size_horz, box_size_vert) in boxes_horz.iter().zip(boxes_vert.iter()) {
let radius_horz = ((box_size_horz - 1) / 2) as usize;
let radius_vert = ((box_size_vert - 1) / 2) as usize;
box_blur_impl(radius_horz, radius_vert, &mut backbuf, &mut src);
}
}
#[inline(never)]
fn create_box_gauss(sigma: f32) -> [i32; STEPS] {
if sigma > 0.0 {
let n_float = STEPS as f32;
// Ideal averaging filter width
let w_ideal = (12.0 * sigma * sigma / n_float).sqrt() + 1.0;
let mut wl = w_ideal.floor() as i32;
if wl % 2 == 0 {
wl -= 1;
}
let wu = wl + 2;
let wl_float = wl as f32;
let m_ideal = (12.0 * sigma * sigma
- n_float * wl_float * wl_float
- 4.0 * n_float * wl_float
- 3.0 * n_float)
/ (-4.0 * wl_float - 4.0);
let m = m_ideal.round() as usize;
let mut sizes = [0; STEPS];
for i in 0..STEPS {
if i < m {
sizes[i] = wl;
} else {
sizes[i] = wu;
}
}
sizes
} else {
[1; STEPS]
}
}
#[inline]
fn box_blur_impl(
blur_radius_horz: usize,
blur_radius_vert: usize,
backbuf: &mut ImageRefMut,
frontbuf: &mut ImageRefMut,
) {
box_blur_vert(blur_radius_vert, frontbuf, backbuf);
box_blur_horz(blur_radius_horz, backbuf, frontbuf);
}
#[inline]
fn box_blur_vert(blur_radius: usize, backbuf: &ImageRefMut, frontbuf: &mut ImageRefMut) {
if blur_radius == 0 {
frontbuf.data.copy_from_slice(backbuf.data);
return;
}
let width = backbuf.width as usize;
let height = backbuf.height as usize;
let iarr = 1.0 / (blur_radius + blur_radius + 1) as f32;
let blur_radius_prev = blur_radius as isize - height as isize;
let blur_radius_next = blur_radius as isize + 1;
for i in 0..width {
let col_start = i; //inclusive
let col_end = i + width * (height - 1); //inclusive
let mut ti = i;
let mut li = ti;
let mut ri = ti + blur_radius * width;
let fv = RGBA8::default();
let lv = RGBA8::default();
let mut val_r = blur_radius_next * (fv.r as isize);
let mut val_g = blur_radius_next * (fv.g as isize);
let mut val_b = blur_radius_next * (fv.b as isize);
let mut val_a = blur_radius_next * (fv.a as isize);
// Get the pixel at the specified index, or the first pixel of the column
// if the index is beyond the top edge of the image
let get_top = |i| {
if i < col_start { fv } else { backbuf.data[i] }
};
// Get the pixel at the specified index, or the last pixel of the column
// if the index is beyond the bottom edge of the image
let get_bottom = |i| {
if i > col_end { lv } else { backbuf.data[i] }
};
for j in 0..cmp::min(blur_radius, height) {
let bb = backbuf.data[ti + j * width];
val_r += bb.r as isize;
val_g += bb.g as isize;
val_b += bb.b as isize;
val_a += bb.a as isize;
}
if blur_radius > height {
val_r += blur_radius_prev * (lv.r as isize);
val_g += blur_radius_prev * (lv.g as isize);
val_b += blur_radius_prev * (lv.b as isize);
val_a += blur_radius_prev * (lv.a as isize);
}
for _ in 0..cmp::min(height, blur_radius + 1) {
let bb = get_bottom(ri);
ri += width;
val_r += sub(bb.r, fv.r);
val_g += sub(bb.g, fv.g);
val_b += sub(bb.b, fv.b);
val_a += sub(bb.a, fv.a);
frontbuf.data[ti] = RGBA8 {
r: round(val_r as f32 * iarr) as u8,
g: round(val_g as f32 * iarr) as u8,
b: round(val_b as f32 * iarr) as u8,
a: round(val_a as f32 * iarr) as u8,
};
ti += width;
}
if height <= blur_radius {
// otherwise `(height - blur_radius)` will underflow
continue;
}
for _ in (blur_radius + 1)..(height - blur_radius) {
let bb1 = backbuf.data[ri];
ri += width;
let bb2 = backbuf.data[li];
li += width;
val_r += sub(bb1.r, bb2.r);
val_g += sub(bb1.g, bb2.g);
val_b += sub(bb1.b, bb2.b);
val_a += sub(bb1.a, bb2.a);
frontbuf.data[ti] = RGBA8 {
r: round(val_r as f32 * iarr) as u8,
g: round(val_g as f32 * iarr) as u8,
b: round(val_b as f32 * iarr) as u8,
a: round(val_a as f32 * iarr) as u8,
};
ti += width;
}
for _ in 0..cmp::min(height - blur_radius - 1, blur_radius) {
let bb = get_top(li);
li += width;
val_r += sub(lv.r, bb.r);
val_g += sub(lv.g, bb.g);
val_b += sub(lv.b, bb.b);
val_a += sub(lv.a, bb.a);
frontbuf.data[ti] = RGBA8 {
r: round(val_r as f32 * iarr) as u8,
g: round(val_g as f32 * iarr) as u8,
b: round(val_b as f32 * iarr) as u8,
a: round(val_a as f32 * iarr) as u8,
};
ti += width;
}
}
}
#[inline]
fn box_blur_horz(blur_radius: usize, backbuf: &ImageRefMut, frontbuf: &mut ImageRefMut) {
if blur_radius == 0 {
frontbuf.data.copy_from_slice(backbuf.data);
return;
}
let width = backbuf.width as usize;
let height = backbuf.height as usize;
let iarr = 1.0 / (blur_radius + blur_radius + 1) as f32;
let blur_radius_prev = blur_radius as isize - width as isize;
let blur_radius_next = blur_radius as isize + 1;
for i in 0..height {
let row_start = i * width; // inclusive
let row_end = (i + 1) * width - 1; // inclusive
let mut ti = i * width; // VERTICAL: $i;
let mut li = ti;
let mut ri = ti + blur_radius;
let fv = RGBA8::default();
let lv = RGBA8::default();
let mut val_r = blur_radius_next * (fv.r as isize);
let mut val_g = blur_radius_next * (fv.g as isize);
let mut val_b = blur_radius_next * (fv.b as isize);
let mut val_a = blur_radius_next * (fv.a as isize);
// Get the pixel at the specified index, or the first pixel of the row
// if the index is beyond the left edge of the image
let get_left = |i| {
if i < row_start { fv } else { backbuf.data[i] }
};
// Get the pixel at the specified index, or the last pixel of the row
// if the index is beyond the right edge of the image
let get_right = |i| {
if i > row_end { lv } else { backbuf.data[i] }
};
for j in 0..cmp::min(blur_radius, width) {
let bb = backbuf.data[ti + j]; // VERTICAL: ti + j * width
val_r += bb.r as isize;
val_g += bb.g as isize;
val_b += bb.b as isize;
val_a += bb.a as isize;
}
if blur_radius > width {
val_r += blur_radius_prev * (lv.r as isize);
val_g += blur_radius_prev * (lv.g as isize);
val_b += blur_radius_prev * (lv.b as isize);
val_a += blur_radius_prev * (lv.a as isize);
}
// Process the left side where we need pixels from beyond the left edge
for _ in 0..cmp::min(width, blur_radius + 1) {
let bb = get_right(ri);
ri += 1;
val_r += sub(bb.r, fv.r);
val_g += sub(bb.g, fv.g);
val_b += sub(bb.b, fv.b);
val_a += sub(bb.a, fv.a);
frontbuf.data[ti] = RGBA8 {
r: round(val_r as f32 * iarr) as u8,
g: round(val_g as f32 * iarr) as u8,
b: round(val_b as f32 * iarr) as u8,
a: round(val_a as f32 * iarr) as u8,
};
ti += 1; // VERTICAL : ti += width, same with the other areas
}
if width <= blur_radius {
// otherwise `(width - blur_radius)` will underflow
continue;
}
// Process the middle where we know we won't bump into borders
// without the extra indirection of get_left/get_right. This is faster.
for _ in (blur_radius + 1)..(width - blur_radius) {
let bb1 = backbuf.data[ri];
ri += 1;
let bb2 = backbuf.data[li];
li += 1;
val_r += sub(bb1.r, bb2.r);
val_g += sub(bb1.g, bb2.g);
val_b += sub(bb1.b, bb2.b);
val_a += sub(bb1.a, bb2.a);
frontbuf.data[ti] = RGBA8 {
r: round(val_r as f32 * iarr) as u8,
g: round(val_g as f32 * iarr) as u8,
b: round(val_b as f32 * iarr) as u8,
a: round(val_a as f32 * iarr) as u8,
};
ti += 1;
}
// Process the right side where we need pixels from beyond the right edge
for _ in 0..cmp::min(width - blur_radius - 1, blur_radius) {
let bb = get_left(li);
li += 1;
val_r += sub(lv.r, bb.r);
val_g += sub(lv.g, bb.g);
val_b += sub(lv.b, bb.b);
val_a += sub(lv.a, bb.a);
frontbuf.data[ti] = RGBA8 {
r: round(val_r as f32 * iarr) as u8,
g: round(val_g as f32 * iarr) as u8,
b: round(val_b as f32 * iarr) as u8,
a: round(val_a as f32 * iarr) as u8,
};
ti += 1;
}
}
}
/// Fast rounding for x <= 2^23.
/// This is orders of magnitude faster than built-in rounding intrinsic.
///
/// Source: https://stackoverflow.com/a/42386149/585725
#[inline]
fn round(mut x: f32) -> f32 {
x += 12582912.0;
x -= 12582912.0;
x
}
#[inline]
fn sub(c1: u8, c2: u8) -> isize {
c1 as isize - c2 as isize
}
================================================
FILE: crates/resvg/src/filter/color_matrix.rs
================================================
// Copyright 2020 the Resvg Authors
// SPDX-License-Identifier: Apache-2.0 OR MIT
use super::{ImageRefMut, f32_bound};
use rgb::RGBA8;
use usvg::filter::ColorMatrixKind as ColorMatrix;
/// Applies a color matrix filter.
///
/// Input image pixels should have an **unpremultiplied alpha**.
pub fn apply(matrix: &ColorMatrix, src: ImageRefMut) {
match matrix {
ColorMatrix::Matrix(m) => {
for pixel in src.data {
let (r, g, b, a) = to_normalized_components(*pixel);
let new_r = r * m[0] + g * m[1] + b * m[2] + a * m[3] + m[4];
let new_g = r * m[5] + g * m[6] + b * m[7] + a * m[8] + m[9];
let new_b = r * m[10] + g * m[11] + b * m[12] + a * m[13] + m[14];
let new_a = r * m[15] + g * m[16] + b * m[17] + a * m[18] + m[19];
pixel.r = from_normalized(new_r);
pixel.g = from_normalized(new_g);
pixel.b = from_normalized(new_b);
pixel.a = from_normalized(new_a);
}
}
ColorMatrix::Saturate(v) => {
let v = v.get().max(0.0);
let m = [
0.213 + 0.787 * v,
0.715 - 0.715 * v,
0.072 - 0.072 * v,
0.213 - 0.213 * v,
0.715 + 0.285 * v,
0.072 - 0.072 * v,
0.213 - 0.213 * v,
0.715 - 0.715 * v,
0.072 + 0.928 * v,
gitextract_vwl0jp28/ ├── .github/ │ ├── copyright.sh │ ├── pull_request_template.md │ └── workflows/ │ ├── main.yml │ └── tagged-release.yml ├── .gitignore ├── .typos.toml ├── AUTHORS ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── crates/ │ ├── c-api/ │ │ ├── Cargo.toml │ │ ├── LICENSE-APACHE │ │ ├── LICENSE-MIT │ │ ├── README.md │ │ ├── ResvgQt.h │ │ ├── cbindgen.toml │ │ ├── examples/ │ │ │ └── cairo/ │ │ │ ├── Makefile │ │ │ ├── README.md │ │ │ └── example.c │ │ ├── lib.rs │ │ └── resvg.h │ ├── resvg/ │ │ ├── Cargo.toml │ │ ├── LICENSE-APACHE │ │ ├── LICENSE-MIT │ │ ├── examples/ │ │ │ ├── custom_href_resolver.rs │ │ │ ├── draw_bboxes.rs │ │ │ └── minimal.rs │ │ ├── src/ │ │ │ ├── clip.rs │ │ │ ├── filter/ │ │ │ │ ├── box_blur.rs │ │ │ │ ├── color_matrix.rs │ │ │ │ ├── component_transfer.rs │ │ │ │ ├── composite.rs │ │ │ │ ├── convolve_matrix.rs │ │ │ │ ├── displacement_map.rs │ │ │ │ ├── iir_blur.rs │ │ │ │ ├── lighting.rs │ │ │ │ ├── mod.rs │ │ │ │ ├── morphology.rs │ │ │ │ └── turbulence.rs │ │ │ ├── geom.rs │ │ │ ├── image.rs │ │ │ ├── lib.rs │ │ │ ├── main.rs │ │ │ ├── mask.rs │ │ │ ├── path.rs │ │ │ └── render.rs │ │ └── tests/ │ │ ├── README.md │ │ ├── fonts/ │ │ │ ├── Amiri-LICENSE-OFL.txt │ │ │ ├── CFF-and-SBIX-LICENSE-APACHE.txt │ │ │ ├── CFF-and-SBIX.otf │ │ │ ├── MPLUS1p-LICENSE-OFL.txt │ │ │ ├── Noto-LICENSE-OFL.txt │ │ │ ├── NotoColorEmojiCBDT-LICENSE_APACHE.txt │ │ │ ├── NotoZnamennyMusicalNotation-OFL.txt │ │ │ ├── README.md │ │ │ ├── RobotoFlex-LICENSE-OFL.txt │ │ │ ├── SedgwickAveDisplay-LICENSE-OFL.txt │ │ │ ├── SourceSansPro-LICENSE-OFL.md │ │ │ ├── TwitterColorEmoji-LICENSE-MIT.txt │ │ │ └── Yellowtail-LICENSE-Apache2.txt │ │ ├── gen-tests.py │ │ ├── integration/ │ │ │ ├── extra.rs │ │ │ ├── main.rs │ │ │ └── render.rs │ │ └── resources/ │ │ ├── green.css │ │ └── image.svgz │ └── usvg/ │ ├── Cargo.toml │ ├── LICENSE-APACHE │ ├── LICENSE-MIT │ ├── README.md │ ├── codegen/ │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── attributes.txt │ │ ├── elements.txt │ │ └── main.rs │ ├── docs/ │ │ ├── post-processing.md │ │ └── spec.adoc │ ├── src/ │ │ ├── lib.rs │ │ ├── main.rs │ │ ├── parser/ │ │ │ ├── clippath.rs │ │ │ ├── converter.rs │ │ │ ├── filter.rs │ │ │ ├── image.rs │ │ │ ├── marker.rs │ │ │ ├── mask.rs │ │ │ ├── mod.rs │ │ │ ├── options.rs │ │ │ ├── paint_server.rs │ │ │ ├── shapes.rs │ │ │ ├── style.rs │ │ │ ├── svgtree/ │ │ │ │ ├── mod.rs │ │ │ │ ├── names.rs │ │ │ │ ├── parse.rs │ │ │ │ └── text.rs │ │ │ ├── switch.rs │ │ │ ├── text.rs │ │ │ ├── units.rs │ │ │ └── use_node.rs │ │ ├── text/ │ │ │ ├── colr.rs │ │ │ ├── flatten.rs │ │ │ ├── layout.rs │ │ │ └── mod.rs │ │ ├── tree/ │ │ │ ├── filter.rs │ │ │ ├── geom.rs │ │ │ ├── mod.rs │ │ │ └── text.rs │ │ └── writer.rs │ └── tests/ │ ├── parser.rs │ └── write.rs ├── docs/ │ ├── svg2-changelog.md │ └── unsupported.md ├── tools/ │ ├── explorer-thumbnailer/ │ │ ├── Cargo.toml │ │ ├── LICENSE-APACHE │ │ ├── LICENSE-MIT │ │ ├── LICENSE-SUMMARY.txt │ │ ├── install/ │ │ │ └── installer.iss │ │ └── src/ │ │ ├── error.rs │ │ ├── interfaces/ │ │ │ ├── iinitialize_with_stream.rs │ │ │ ├── ithumbnail_provider.rs │ │ │ └── mod.rs │ │ ├── lib.rs │ │ ├── thumbnail_provider.rs │ │ └── utils.rs │ └── viewsvg/ │ ├── .gitignore │ ├── README.md │ ├── main.cpp │ ├── mainwindow.cpp │ ├── mainwindow.h │ ├── mainwindow.ui │ ├── svgview.cpp │ ├── svgview.h │ └── viewsvg.pro └── version-bump.md
Showing preview only (350K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3097 symbols across 71 files)
FILE: crates/c-api/ResvgQt.h
function namespace (line 33) | namespace ResvgPrivate {
function class (line 94) | class ResvgOptions {
function class (line 283) | class ResvgRenderer {
function load (line 314) | bool load(const QString &filePath, const ResvgOptions &opt)
function load (line 345) | bool load(const QByteArray &data, const ResvgOptions &opt)
function QRectF (line 444) | QRectF boundsOnElement(const QString &id) const
function elementExists (line 476) | bool elementExists(const QString &id) const
function QTransform (line 489) | QTransform transformForElement(const QString &id) const
function initLog (line 543) | static void initLog()
FILE: crates/c-api/examples/cairo/example.c
function main (line 10) | int main(int argc, char **argv)
FILE: crates/c-api/lib.rs
type resvg_error (line 20) | pub enum resvg_error {
type resvg_rect (line 45) | pub struct resvg_rect {
type resvg_size (line 56) | pub struct resvg_size {
type resvg_transform (line 65) | pub struct resvg_transform {
method to_tiny_skia (line 76) | fn to_tiny_skia(&self) -> tiny_skia::Transform {
function resvg_transform_identity (line 83) | pub extern "C" fn resvg_transform_identity() -> resvg_transform {
function resvg_init_log (line 102) | pub extern "C" fn resvg_init_log() {
type resvg_options (line 112) | pub struct resvg_options {
function resvg_options_create (line 120) | pub extern "C" fn resvg_options_create() -> *mut resvg_options {
function cast_opt (line 127) | fn cast_opt(opt: *mut resvg_options) -> &'static mut usvg::Options<'stat...
function resvg_options_set_resources_dir (line 143) | pub extern "C" fn resvg_options_set_resources_dir(opt: *mut resvg_option...
function resvg_options_set_dpi (line 157) | pub extern "C" fn resvg_options_set_dpi(opt: *mut resvg_options, dpi: f3...
function resvg_options_set_stylesheet (line 167) | pub extern "C" fn resvg_options_set_stylesheet(opt: *mut resvg_options, ...
function resvg_options_set_font_family (line 183) | pub extern "C" fn resvg_options_set_font_family(opt: *mut resvg_options,...
function resvg_options_set_font_size (line 193) | pub extern "C" fn resvg_options_set_font_size(opt: *mut resvg_options, s...
function resvg_options_set_serif_family (line 206) | pub extern "C" fn resvg_options_set_serif_family(opt: *mut resvg_options...
function resvg_options_set_sans_serif_family (line 224) | pub extern "C" fn resvg_options_set_sans_serif_family(
function resvg_options_set_cursive_family (line 245) | pub extern "C" fn resvg_options_set_cursive_family(opt: *mut resvg_optio...
function resvg_options_set_fantasy_family (line 263) | pub extern "C" fn resvg_options_set_fantasy_family(opt: *mut resvg_optio...
function resvg_options_set_monospace_family (line 281) | pub extern "C" fn resvg_options_set_monospace_family(
function resvg_options_set_languages (line 303) | pub extern "C" fn resvg_options_set_languages(opt: *mut resvg_options, l...
type resvg_shape_rendering (line 326) | pub enum resvg_shape_rendering {
function resvg_options_set_shape_rendering_mode (line 338) | pub extern "C" fn resvg_options_set_shape_rendering_mode(
type resvg_text_rendering (line 354) | pub enum resvg_text_rendering {
function resvg_options_set_text_rendering_mode (line 366) | pub extern "C" fn resvg_options_set_text_rendering_mode(
type resvg_image_rendering (line 382) | pub enum resvg_image_rendering {
function resvg_options_set_image_rendering_mode (line 393) | pub extern "C" fn resvg_options_set_image_rendering_mode(
function resvg_options_load_font_data (line 411) | pub extern "C" fn resvg_options_load_font_data(
function resvg_options_load_font_file (line 432) | pub extern "C" fn resvg_options_load_font_file(
function resvg_options_load_system_fonts (line 470) | pub extern "C" fn resvg_options_load_system_fonts(opt: *mut resvg_option...
function resvg_options_destroy (line 479) | pub extern "C" fn resvg_options_destroy(opt: *mut resvg_options) {
type resvg_render_tree (line 488) | pub struct resvg_render_tree(pub usvg::Tree);
function resvg_parse_tree_from_file (line 501) | pub extern "C" fn resvg_parse_tree_from_file(
function resvg_parse_tree_from_data (line 546) | pub extern "C" fn resvg_parse_tree_from_data(
function resvg_is_image_empty (line 579) | pub extern "C" fn resvg_is_image_empty(tree: *const resvg_render_tree) -...
function resvg_get_image_size (line 598) | pub extern "C" fn resvg_get_image_size(tree: *const resvg_render_tree) -...
function resvg_get_object_bbox (line 623) | pub extern "C" fn resvg_get_object_bbox(
function resvg_get_image_bbox (line 658) | pub extern "C" fn resvg_get_image_bbox(
function resvg_node_exists (line 693) | pub extern "C" fn resvg_node_exists(tree: *const resvg_render_tree, id: ...
function resvg_get_node_transform (line 719) | pub extern "C" fn resvg_get_node_transform(
function resvg_get_node_bbox (line 766) | pub extern "C" fn resvg_get_node_bbox(
function resvg_get_node_stroke_bbox (line 783) | pub extern "C" fn resvg_get_node_stroke_bbox(
function get_node_bbox (line 791) | fn get_node_bbox(
function resvg_tree_destroy (line 837) | pub extern "C" fn resvg_tree_destroy(tree: *mut resvg_render_tree) {
function cstr_to_str (line 844) | fn cstr_to_str(text: *const c_char) -> Option<&'static str> {
function convert_error (line 853) | fn convert_error(e: usvg::Error) -> resvg_error {
function resvg_render (line 872) | pub extern "C" fn resvg_render(
function resvg_render_node (line 905) | pub extern "C" fn resvg_render_node(
type SimpleLogger (line 943) | struct SimpleLogger;
method enabled (line 945) | fn enabled(&self, metadata: &log::Metadata) -> bool {
method log (line 949) | fn log(&self, record: &log::Record) {
method flush (line 970) | fn flush(&self) {}
FILE: crates/c-api/resvg.h
type resvg_error (line 24) | typedef enum {
type resvg_image_rendering (line 62) | typedef enum {
type resvg_shape_rendering (line 70) | typedef enum {
type resvg_text_rendering (line 79) | typedef enum {
type resvg_options (line 91) | typedef struct resvg_options resvg_options;
type resvg_render_tree (line 96) | typedef struct resvg_render_tree resvg_render_tree;
type resvg_transform (line 101) | typedef struct {
type resvg_size (line 113) | typedef struct {
type resvg_rect (line 121) | typedef struct {
FILE: crates/resvg/examples/custom_href_resolver.rs
function main (line 4) | fn main() {
FILE: crates/resvg/examples/draw_bboxes.rs
function main (line 4) | fn main() {
function collect_bboxes (line 67) | fn collect_bboxes(
FILE: crates/resvg/examples/minimal.rs
function main (line 4) | fn main() {
FILE: crates/resvg/src/clip.rs
function apply (line 6) | pub fn apply(
function draw_children (line 30) | fn draw_children(
function clip_group (line 70) | fn clip_group(
FILE: crates/resvg/src/filter/box_blur.rs
constant STEPS (line 12) | const STEPS: usize = 5;
function apply (line 23) | pub fn apply(sigma_x: f64, sigma_y: f64, mut src: ImageRefMut) {
function create_box_gauss (line 37) | fn create_box_gauss(sigma: f32) -> [i32; STEPS] {
function box_blur_impl (line 74) | fn box_blur_impl(
function box_blur_vert (line 85) | fn box_blur_vert(blur_radius: usize, backbuf: &ImageRefMut, frontbuf: &m...
function box_blur_horz (line 202) | fn box_blur_horz(blur_radius: usize, backbuf: &ImageRefMut, frontbuf: &m...
function round (line 327) | fn round(mut x: f32) -> f32 {
function sub (line 334) | fn sub(c1: u8, c2: u8) -> isize {
FILE: crates/resvg/src/filter/color_matrix.rs
function apply (line 11) | pub fn apply(matrix: &ColorMatrix, src: ImageRefMut) {
function to_normalized_components (line 98) | fn to_normalized_components(pixel: RGBA8) -> (f32, f32, f32, f32) {
function from_normalized (line 108) | fn from_normalized(c: f32) -> u8 {
FILE: crates/resvg/src/filter/component_transfer.rs
function apply (line 10) | pub fn apply(fe: &ComponentTransfer, src: ImageRefMut) {
function is_dummy (line 30) | fn is_dummy(func: &TransferFunction) -> bool {
function transfer (line 40) | fn transfer(func: &TransferFunction, c: u8) -> u8 {
FILE: crates/resvg/src/filter/composite.rs
function arithmetic (line 16) | pub fn arithmetic(
FILE: crates/resvg/src/filter/convolve_matrix.rs
function apply (line 15) | pub fn apply(matrix: &ConvolveMatrix, src: ImageRefMut) {
FILE: crates/resvg/src/filter/displacement_map.rs
function apply (line 17) | pub fn apply(
FILE: crates/resvg/src/filter/iir_blur.rs
type BlurData (line 31) | struct BlurData {
function apply (line 48) | pub fn apply(sigma_x: f64, sigma_y: f64, src: ImageRefMut) {
function gaussian_channel (line 68) | fn gaussian_channel(data: &mut [u8], d: &BlurData, channel: usize, buf: ...
function gaussianiir2d (line 80) | fn gaussianiir2d(d: &BlurData, buf: &mut [f64]) {
function gen_coefficients (line 143) | fn gen_coefficients(sigma: f64, steps: usize) -> (f64, f64) {
FILE: crates/resvg/src/filter/lighting.rs
constant FACTOR_1_2 (line 9) | const FACTOR_1_2: f32 = 1.0 / 2.0;
constant FACTOR_1_3 (line 10) | const FACTOR_1_3: f32 = 1.0 / 3.0;
constant FACTOR_1_4 (line 11) | const FACTOR_1_4: f32 = 1.0 / 4.0;
constant FACTOR_2_3 (line 12) | const FACTOR_2_3: f32 = 2.0 / 3.0;
type Vector2 (line 15) | struct Vector2 {
method new (line 22) | fn new(x: f32, y: f32) -> Self {
method approx_zero (line 27) | fn approx_zero(&self) -> bool {
type Output (line 33) | type Output = Self;
method mul (line 36) | fn mul(self, c: f32) -> Self::Output {
type Vector3 (line 45) | struct Vector3 {
method new (line 53) | fn new(x: f32, y: f32, z: f32) -> Self {
method dot (line 58) | fn dot(&self, other: &Self) -> f32 {
method length (line 63) | fn length(&self) -> f32 {
method normalized (line 68) | fn normalized(&self) -> Option<Self> {
type Output (line 83) | type Output = Self;
method add (line 86) | fn add(self, rhs: Vector3) -> Self::Output {
type Output (line 96) | type Output = Self;
method sub (line 99) | fn sub(self, rhs: Vector3) -> Self::Output {
type Normal (line 109) | struct Normal {
method new (line 116) | fn new(factor_x: f32, factor_y: f32, nx: i16, ny: i16) -> Self {
function diffuse_lighting (line 134) | pub fn diffuse_lighting(
function specular_lighting (line 179) | pub fn specular_lighting(
function apply (line 231) | fn apply(
function light_color (line 313) | fn light_color(light: &LightSource, lighting_color: Color, light_vector:...
function top_left_normal (line 344) | fn top_left_normal(img: ImageRef) -> Normal {
function top_right_normal (line 358) | fn top_right_normal(img: ImageRef) -> Normal {
function bottom_left_normal (line 372) | fn bottom_left_normal(img: ImageRef) -> Normal {
function bottom_right_normal (line 386) | fn bottom_right_normal(img: ImageRef) -> Normal {
function top_row_normal (line 400) | fn top_row_normal(img: ImageRef, x: u32) -> Normal {
function bottom_row_normal (line 416) | fn bottom_row_normal(img: ImageRef, x: u32) -> Normal {
function left_column_normal (line 432) | fn left_column_normal(img: ImageRef, y: u32) -> Normal {
function right_column_normal (line 448) | fn right_column_normal(img: ImageRef, y: u32) -> Normal {
function interior_normal (line 464) | fn interior_normal(img: ImageRef, x: u32, y: u32) -> Normal {
function calc_diffuse_alpha (line 482) | fn calc_diffuse_alpha(_: u8, _: u8, _: u8) -> u8 {
function calc_specular_alpha (line 486) | fn calc_specular_alpha(r: u8, g: u8, b: u8) -> u8 {
FILE: crates/resvg/src/filter/mod.rs
type ImageRef (line 30) | pub struct ImageRef<'a> {
function new (line 41) | pub fn new(width: u32, height: u32, data: &'a [RGBA8]) -> Self {
function alpha_at (line 50) | fn alpha_at(&self, x: u32, y: u32) -> i16 {
type ImageRefMut (line 56) | pub struct ImageRefMut<'a> {
function new (line 67) | pub fn new(width: u32, height: u32, data: &'a mut [RGBA8]) -> Self {
function pixel_at (line 76) | fn pixel_at(&self, x: u32, y: u32) -> RGBA8 {
function pixel_at_mut (line 81) | fn pixel_at_mut(&mut self, x: u32, y: u32) -> &mut RGBA8 {
type Error (line 87) | pub(crate) enum Error {
type PixmapExt (line 92) | trait PixmapExt: Sized {
method try_create (line 93) | fn try_create(width: u32, height: u32) -> Result<tiny_skia::Pixmap, Er...
method copy_region (line 94) | fn copy_region(&self, region: IntRect) -> Result<tiny_skia::Pixmap, Er...
method clear (line 95) | fn clear(&mut self);
method into_srgb (line 96) | fn into_srgb(&mut self);
method into_linear_rgb (line 97) | fn into_linear_rgb(&mut self);
method try_create (line 101) | fn try_create(width: u32, height: u32) -> Result<tiny_skia::Pixmap, Er...
method copy_region (line 105) | fn copy_region(&self, region: IntRect) -> Result<tiny_skia::Pixmap, Er...
method clear (line 111) | fn clear(&mut self) {
method into_srgb (line 115) | fn into_srgb(&mut self) {
method into_linear_rgb (line 121) | fn into_linear_rgb(&mut self) {
function multiply_alpha (line 129) | fn multiply_alpha(data: &mut [RGBA8]) {
function demultiply_alpha (line 139) | fn demultiply_alpha(data: &mut [RGBA8]) {
constant SRGB_TO_LINEAR_RGB_TABLE (line 162) | const SRGB_TO_LINEAR_RGB_TABLE: &[u8; 256] = &[
constant LINEAR_RGB_TO_SRGB_TABLE (line 195) | const LINEAR_RGB_TO_SRGB_TABLE: &[u8; 256] = &[
function into_linear_rgb (line 219) | fn into_linear_rgb(data: &mut [RGBA8]) {
function from_linear_rgb (line 232) | fn from_linear_rgb(data: &mut [RGBA8]) {
function f32_bound (line 242) | fn f32_bound(min: f32, val: f32, max: f32) -> f32 {
type Image (line 257) | struct Image {
method from_image (line 277) | fn from_image(image: tiny_skia::Pixmap, color_space: usvg::filter::Col...
method into_color_space (line 286) | fn into_color_space(
method take (line 310) | fn take(self) -> Result<tiny_skia::Pixmap, Error> {
method width (line 317) | fn width(&self) -> u32 {
method height (line 321) | fn height(&self) -> u32 {
method as_ref (line 325) | fn as_ref(&self) -> &tiny_skia::Pixmap {
type FilterResult (line 330) | struct FilterResult {
function apply (line 335) | pub fn apply(
function apply_inner (line 357) | fn apply_inner(
function get_input (line 516) | fn get_input(
type PixmapToImageRef (line 559) | trait PixmapToImageRef<'a> {
method as_image_ref (line 560) | fn as_image_ref(&'a self) -> ImageRef<'a>;
method as_image_ref_mut (line 561) | fn as_image_ref_mut(&'a mut self) -> ImageRefMut<'a>;
function as_image_ref (line 565) | fn as_image_ref(&'a self) -> ImageRef<'a> {
function as_image_ref_mut (line 569) | fn as_image_ref_mut(&'a mut self) -> ImageRefMut<'a> {
function apply_drop_shadow (line 574) | fn apply_drop_shadow(
function apply_blur (line 638) | fn apply_blur(
function apply_offset (line 661) | fn apply_offset(
function apply_blend (line 688) | fn apply_blend(
function apply_composite (line 724) | fn apply_composite(
function apply_merge (line 788) | fn apply_merge(
function apply_flood (line 813) | fn apply_flood(fe: &usvg::filter::Flood, region: IntRect) -> Result<Imag...
function apply_tile (line 830) | fn apply_tile(input: Image, region: IntRect) -> Result<Image, Error> {
function apply_image (line 854) | fn apply_image(
function apply_component_transfer (line 884) | fn apply_component_transfer(
function apply_color_matrix (line 898) | fn apply_color_matrix(
function apply_convolve_matrix (line 912) | fn apply_convolve_matrix(
function apply_morphology (line 928) | fn apply_morphology(
function apply_displacement_map (line 951) | fn apply_displacement_map(
function apply_turbulence (line 981) | fn apply_turbulence(
function apply_diffuse_lighting (line 1013) | fn apply_diffuse_lighting(
function apply_specular_lighting (line 1034) | fn apply_specular_lighting(
function transform_light_source (line 1056) | fn transform_light_source(
function apply_to_canvas (line 1093) | fn apply_to_canvas(input: Image, pixmap: &mut tiny_skia::Pixmap) -> Resu...
function resolve_std_dev (line 1112) | fn resolve_std_dev(std_dx: f32, std_dy: f32, ts: usvg::Transform) -> Opt...
function scale_coordinates (line 1137) | fn scale_coordinates(x: f32, y: f32, ts: usvg::Transform) -> Option<(f32...
FILE: crates/resvg/src/filter/morphology.rs
function apply (line 15) | pub fn apply(operator: MorphologyOperator, rx: f32, ry: f32, src: ImageR...
FILE: crates/resvg/src/filter/turbulence.rs
constant RAND_M (line 9) | const RAND_M: i32 = 2147483647;
constant RAND_A (line 10) | const RAND_A: i32 = 16807;
constant RAND_Q (line 11) | const RAND_Q: i32 = 127773;
constant RAND_R (line 12) | const RAND_R: i32 = 2836;
constant B_SIZE (line 13) | const B_SIZE: usize = 0x100;
constant B_SIZE_32 (line 14) | const B_SIZE_32: i32 = 0x100;
constant B_LEN (line 15) | const B_LEN: usize = B_SIZE + B_SIZE + 2;
constant BM (line 16) | const BM: i32 = 0xff;
constant PERLIN_N (line 17) | const PERLIN_N: i32 = 0x1000;
type StitchInfo (line 20) | struct StitchInfo {
function apply (line 33) | pub fn apply(
function init (line 93) | fn init(mut seed: i32) -> (Vec<usize>, Vec<Vec<Vec<f64>>>) {
function turbulence (line 142) | fn turbulence(
function noise2 (line 224) | fn noise2(
function random (line 287) | fn random(seed: i32) -> i32 {
function s_curve (line 297) | fn s_curve(t: f64) -> f64 {
function lerp (line 302) | fn lerp(t: f64, a: f64, b: f64) -> f64 {
FILE: crates/resvg/src/geom.rs
function fit_to_rect (line 5) | pub fn fit_to_rect(
FILE: crates/resvg/src/image.rs
function render (line 4) | pub fn render(
function render_inner (line 16) | pub fn render_inner(
function render_vector (line 37) | fn render_vector(
function decode_raster (line 62) | fn decode_raster(image: &usvg::ImageKind) -> Option<tiny_skia::Pixmap> {
function decode_png (line 80) | fn decode_png(data: &[u8]) -> Option<tiny_skia::Pixmap> {
function decode_jpeg (line 84) | fn decode_jpeg(data: &[u8]) -> Option<tiny_skia::Pixmap> {
function decode_gif (line 108) | fn decode_gif(data: &[u8]) -> Option<tiny_skia::Pixmap> {
function decode_webp (line 125) | fn decode_webp(data: &[u8]) -> Option<tiny_skia::Pixmap> {
function rgb_to_pixmap (line 142) | fn rgb_to_pixmap(data: &[u8], pixmap: &mut tiny_skia::Pixmap) {
function rgba_to_pixmap (line 157) | fn rgba_to_pixmap(data: &[u8], pixmap: &mut tiny_skia::Pixmap) {
function render_raster (line 173) | pub(crate) fn render_raster(
FILE: crates/resvg/src/lib.rs
function render (line 34) | pub fn render(
function render_node (line 62) | pub fn render_node(
type OptionLog (line 86) | pub(crate) trait OptionLog {
method log_none (line 87) | fn log_none<F: FnOnce()>(self, f: F) -> Self;
method log_none (line 92) | fn log_none<F: FnOnce()>(self, f: F) -> Self {
FILE: crates/resvg/src/main.rs
function main (line 11) | fn main() {
function timed (line 18) | fn timed<F, T>(perf: bool, name: &str, mut f: F) -> T
function process (line 32) | fn process() -> Result<(), String> {
constant HELP (line 121) | const HELP: &str = "\
type CliArgs (line 218) | struct CliArgs {
function collect_args (line 257) | fn collect_args() -> Result<CliArgs, pico_args::Error> {
function parse_dpi (line 322) | fn parse_dpi(s: &str) -> Result<u32, String> {
function parse_length (line 332) | fn parse_length(s: &str) -> Result<u32, String> {
function parse_zoom (line 342) | fn parse_zoom(s: &str) -> Result<f32, String> {
function parse_font_size (line 352) | fn parse_font_size(s: &str) -> Result<u32, String> {
function parse_languages (line 362) | fn parse_languages(s: &str) -> Result<Vec<String>, String> {
type InputFrom (line 376) | enum InputFrom {
type OutputTo (line 382) | enum OutputTo {
type FitTo (line 388) | enum FitTo {
method fit_to_size (line 402) | fn fit_to_size(&self, size: tiny_skia::IntSize) -> Option<tiny_skia::I...
method fit_to_transform (line 412) | fn fit_to_transform(&self, size: tiny_skia::IntSize) -> tiny_skia::Tra...
function list_fonts (line 425) | fn list_fonts(args: &CliArgs) {
type Args (line 457) | struct Args {
function parse_args (line 472) | fn parse_args() -> Result<Args, String> {
function load_fonts (line 599) | fn load_fonts(args: &CliArgs, fontdb: &mut fontdb::Database) {
function query_all (line 621) | fn query_all(tree: &usvg::Tree) -> Result<(), String> {
function query_all_impl (line 631) | fn query_all_impl(parent: &usvg::Group) -> usize {
function render_svg (line 669) | fn render_svg(args: &Args, tree: &usvg::Tree) -> Result<tiny_skia::Pixma...
function trim_pixmap (line 760) | fn trim_pixmap(
function fit_to_rect (line 782) | fn fit_to_rect(r: tiny_skia::IntRect, bounds: tiny_skia::IntRect) -> tin...
function svg_to_skia_color (line 806) | fn svg_to_skia_color(color: svgtypes::Color) -> tiny_skia::Color {
type SimpleLogger (line 812) | struct SimpleLogger;
method enabled (line 814) | fn enabled(&self, metadata: &log::Metadata) -> bool {
method log (line 818) | fn log(&self, record: &log::Record) {
method flush (line 839) | fn flush(&self) {}
FILE: crates/resvg/src/mask.rs
function apply (line 6) | pub fn apply(
FILE: crates/resvg/src/path.rs
function render (line 6) | pub fn render(
function fill_path (line 26) | pub fn fill_path(
function stroke_path (line 77) | fn stroke_path(
function convert_linear_gradient (line 118) | fn convert_linear_gradient(
function convert_radial_gradient (line 135) | fn convert_radial_gradient(
function convert_base_gradient (line 154) | fn convert_base_gradient(
function render_pattern_pixmap (line 179) | fn render_pattern_pixmap(
FILE: crates/resvg/src/render.rs
type Context (line 6) | pub struct Context {
function render_nodes (line 10) | pub fn render_nodes(
function render_node (line 21) | pub fn render_node(
function render_group (line 49) | fn render_group(
function convert_blend_mode (line 140) | pub fn convert_blend_mode(mode: usvg::BlendMode) -> tiny_skia::BlendMode {
FILE: crates/resvg/tests/integration/extra.rs
function group_with_only_transform (line 7) | fn group_with_only_transform() {
function subpixel_rect_position (line 12) | fn subpixel_rect_position() {
function transformed_rect (line 17) | fn transformed_rect() {
function hidden_element (line 22) | fn hidden_element() {
function simple_stroke (line 27) | fn simple_stroke() {
function fill_and_stroke (line 32) | fn fill_and_stroke() {
function paint_order_stroke (line 37) | fn paint_order_stroke() {
function stroke_linecap_square (line 42) | fn stroke_linecap_square() {
function miter_join_with_acute_angle (line 47) | fn miter_join_with_acute_angle() {
function horizontal_line (line 52) | fn horizontal_line() {
function horizontal_line_no_stroke (line 57) | fn horizontal_line_no_stroke() {
function filter_region_precision (line 62) | fn filter_region_precision() {
function translate_outside_viewbox (line 70) | fn translate_outside_viewbox() {
function render_node_filter_on_empty_group (line 75) | fn render_node_filter_on_empty_group() {
function render_node_filter_with_transform_on_shape (line 80) | fn render_node_filter_with_transform_on_shape() {
FILE: crates/resvg/tests/integration/main.rs
constant IMAGE_SIZE (line 19) | const IMAGE_SIZE: u32 = 300;
function render (line 36) | pub fn render(name: &str) -> usize {
function render_extra_with_scale (line 40) | pub fn render_extra_with_scale(name: &str, scale: f32) -> usize {
function render_extra (line 44) | pub fn render_extra(name: &str) -> usize {
function render_node (line 48) | pub fn render_node(name: &str, id: &str) -> usize {
function render_inner (line 52) | pub fn render_inner(name: &str, test_mode: TestMode) -> usize {
function get_diff (line 151) | fn get_diff(expected_image: &TestImage, actual_image: &TestImage) -> Opt...
function demultiply_alpha (line 204) | fn demultiply_alpha(data: &mut [RGBA8]) {
function is_pix_diff (line 213) | fn is_pix_diff(pixel1: &Rgba<u8>, pixel2: &Rgba<u8>, threshold: u8) -> b...
function load_png (line 228) | fn load_png(data: Vec<u8>) -> TestImage {
type TestImage (line 272) | struct TestImage {
method new (line 279) | fn new(width: u32, height: u32) -> Self {
method new_with (line 287) | fn new_with(data: Vec<u8>, width: u32, height: u32) -> Self {
method get_pixel (line 295) | fn get_pixel(&self, x: u32, y: u32) -> Option<Rgba<u8>> {
method set_pixel (line 305) | fn set_pixel(&mut self, x: u32, y: u32, val: Rgba<u8>) {
method save_png (line 311) | fn save_png(&self, path: &str) {
type TestMode (line 326) | pub enum TestMode<'a> {
type SimpleLogger (line 337) | struct SimpleLogger;
method enabled (line 339) | fn enabled(&self, metadata: &log::Metadata) -> bool {
method log (line 343) | fn log(&self, record: &log::Record) {
method flush (line 364) | fn flush(&self) {}
FILE: crates/resvg/tests/integration/render.rs
function filters_enable_background_accumulate_with_new (line 10) | fn filters_enable_background_accumulate_with_new() { assert_eq!(render("...
function filters_enable_background_accumulate (line 11) | fn filters_enable_background_accumulate() { assert_eq!(render("tests/fil...
function filters_enable_background_filter_on_shape (line 12) | fn filters_enable_background_filter_on_shape() { assert_eq!(render("test...
function filters_enable_background_inherit (line 13) | fn filters_enable_background_inherit() { assert_eq!(render("tests/filter...
function filters_enable_background_new_with_invalid_region_1 (line 14) | fn filters_enable_background_new_with_invalid_region_1() { assert_eq!(re...
function filters_enable_background_new_with_invalid_region_2 (line 15) | fn filters_enable_background_new_with_invalid_region_2() { assert_eq!(re...
function filters_enable_background_new_with_invalid_region_3 (line 16) | fn filters_enable_background_new_with_invalid_region_3() { assert_eq!(re...
function filters_enable_background_new_with_region (line 17) | fn filters_enable_background_new_with_region() { assert_eq!(render("test...
function filters_enable_background_new (line 18) | fn filters_enable_background_new() { assert_eq!(render("tests/filters/en...
function filters_enable_background_shapes_after_filter (line 19) | fn filters_enable_background_shapes_after_filter() { assert_eq!(render("...
function filters_enable_background_stop_on_the_first_new_1 (line 20) | fn filters_enable_background_stop_on_the_first_new_1() { assert_eq!(rend...
function filters_enable_background_stop_on_the_first_new_2 (line 21) | fn filters_enable_background_stop_on_the_first_new_2() { assert_eq!(rend...
function filters_enable_background_with_clip_path (line 22) | fn filters_enable_background_with_clip_path() { assert_eq!(render("tests...
function filters_enable_background_with_filter_on_the_same_element (line 23) | fn filters_enable_background_with_filter_on_the_same_element() { assert_...
function filters_enable_background_with_filter (line 24) | fn filters_enable_background_with_filter() { assert_eq!(render("tests/fi...
function filters_enable_background_with_mask (line 25) | fn filters_enable_background_with_mask() { assert_eq!(render("tests/filt...
function filters_enable_background_with_opacity_1 (line 26) | fn filters_enable_background_with_opacity_1() { assert_eq!(render("tests...
function filters_enable_background_with_opacity_2 (line 27) | fn filters_enable_background_with_opacity_2() { assert_eq!(render("tests...
function filters_enable_background_with_opacity_3 (line 28) | fn filters_enable_background_with_opacity_3() { assert_eq!(render("tests...
function filters_enable_background_with_opacity_4 (line 29) | fn filters_enable_background_with_opacity_4() { assert_eq!(render("tests...
function filters_enable_background_with_transform (line 30) | fn filters_enable_background_with_transform() { assert_eq!(render("tests...
function filters_feBlend_empty (line 31) | fn filters_feBlend_empty() { assert_eq!(render("tests/filters/feBlend/em...
function filters_feBlend_mode_eq_color_burn (line 32) | fn filters_feBlend_mode_eq_color_burn() { assert_eq!(render("tests/filte...
function filters_feBlend_mode_eq_darken (line 33) | fn filters_feBlend_mode_eq_darken() { assert_eq!(render("tests/filters/f...
function filters_feBlend_mode_eq_hue (line 34) | fn filters_feBlend_mode_eq_hue() { assert_eq!(render("tests/filters/feBl...
function filters_feBlend_mode_eq_lighten (line 35) | fn filters_feBlend_mode_eq_lighten() { assert_eq!(render("tests/filters/...
function filters_feBlend_mode_eq_multiply (line 36) | fn filters_feBlend_mode_eq_multiply() { assert_eq!(render("tests/filters...
function filters_feBlend_mode_eq_normal (line 37) | fn filters_feBlend_mode_eq_normal() { assert_eq!(render("tests/filters/f...
function filters_feBlend_mode_eq_screen (line 38) | fn filters_feBlend_mode_eq_screen() { assert_eq!(render("tests/filters/f...
function filters_feBlend_with_subregion_on_input_1 (line 39) | fn filters_feBlend_with_subregion_on_input_1() { assert_eq!(render("test...
function filters_feBlend_with_subregion_on_input_2 (line 40) | fn filters_feBlend_with_subregion_on_input_2() { assert_eq!(render("test...
function filters_feColorMatrix_invalid_type (line 41) | fn filters_feColorMatrix_invalid_type() { assert_eq!(render("tests/filte...
function filters_feColorMatrix_type_eq_hueRotate_without_an_angle (line 42) | fn filters_feColorMatrix_type_eq_hueRotate_without_an_angle() { assert_e...
function filters_feColorMatrix_type_eq_hueRotate (line 43) | fn filters_feColorMatrix_type_eq_hueRotate() { assert_eq!(render("tests/...
function filters_feColorMatrix_type_eq_luminanceToAlpha (line 44) | fn filters_feColorMatrix_type_eq_luminanceToAlpha() { assert_eq!(render(...
function filters_feColorMatrix_type_eq_matrix_with_empty_values (line 45) | fn filters_feColorMatrix_type_eq_matrix_with_empty_values() { assert_eq!...
function filters_feColorMatrix_type_eq_matrix_with_non_normalized_values (line 46) | fn filters_feColorMatrix_type_eq_matrix_with_non_normalized_values() { a...
function filters_feColorMatrix_type_eq_matrix_with_not_enough_values (line 47) | fn filters_feColorMatrix_type_eq_matrix_with_not_enough_values() { asser...
function filters_feColorMatrix_type_eq_matrix_with_too_many_values (line 48) | fn filters_feColorMatrix_type_eq_matrix_with_too_many_values() { assert_...
function filters_feColorMatrix_type_eq_matrix_without_values (line 49) | fn filters_feColorMatrix_type_eq_matrix_without_values() { assert_eq!(re...
function filters_feColorMatrix_type_eq_matrix (line 50) | fn filters_feColorMatrix_type_eq_matrix() { assert_eq!(render("tests/fil...
function filters_feColorMatrix_type_eq_saturate_with_a_large_coefficient (line 51) | fn filters_feColorMatrix_type_eq_saturate_with_a_large_coefficient() { a...
function filters_feColorMatrix_type_eq_saturate_with_negative_coefficient (line 52) | fn filters_feColorMatrix_type_eq_saturate_with_negative_coefficient() { ...
function filters_feColorMatrix_type_eq_saturate_without_a_coefficient (line 53) | fn filters_feColorMatrix_type_eq_saturate_without_a_coefficient() { asse...
function filters_feColorMatrix_type_eq_saturate (line 54) | fn filters_feColorMatrix_type_eq_saturate() { assert_eq!(render("tests/f...
function filters_feColorMatrix_without_a_type (line 55) | fn filters_feColorMatrix_without_a_type() { assert_eq!(render("tests/fil...
function filters_feColorMatrix_without_attributes (line 56) | fn filters_feColorMatrix_without_attributes() { assert_eq!(render("tests...
function filters_feComponentTransfer_invalid_type (line 57) | fn filters_feComponentTransfer_invalid_type() { assert_eq!(render("tests...
function filters_feComponentTransfer_mixed_types (line 58) | fn filters_feComponentTransfer_mixed_types() { assert_eq!(render("tests/...
function filters_feComponentTransfer_no_children (line 59) | fn filters_feComponentTransfer_no_children() { assert_eq!(render("tests/...
function filters_feComponentTransfer_type_eq_discrete_on_blue (line 60) | fn filters_feComponentTransfer_type_eq_discrete_on_blue() { assert_eq!(r...
function filters_feComponentTransfer_type_eq_gamma_on_blue (line 61) | fn filters_feComponentTransfer_type_eq_gamma_on_blue() { assert_eq!(rend...
function filters_feComponentTransfer_type_eq_gamma_with_an_invalid_offset (line 62) | fn filters_feComponentTransfer_type_eq_gamma_with_an_invalid_offset() { ...
function filters_feComponentTransfer_type_eq_gamma_with_invalid_values (line 63) | fn filters_feComponentTransfer_type_eq_gamma_with_invalid_values() { ass...
function filters_feComponentTransfer_type_eq_identity_on_all (line 64) | fn filters_feComponentTransfer_type_eq_identity_on_all() { assert_eq!(re...
function filters_feComponentTransfer_type_eq_linear_on_blue (line 65) | fn filters_feComponentTransfer_type_eq_linear_on_blue() { assert_eq!(ren...
function filters_feComponentTransfer_type_eq_linear_with_invalid_values (line 66) | fn filters_feComponentTransfer_type_eq_linear_with_invalid_values() { as...
function filters_feComponentTransfer_type_eq_linear_with_large_values (line 67) | fn filters_feComponentTransfer_type_eq_linear_with_large_values() { asse...
function filters_feComponentTransfer_type_eq_table_and_tableValues_eq_1_0_1 (line 68) | fn filters_feComponentTransfer_type_eq_table_and_tableValues_eq_1_0_1() ...
function filters_feComponentTransfer_type_eq_table_and_tableValues_eq_1 (line 69) | fn filters_feComponentTransfer_type_eq_table_and_tableValues_eq_1() { as...
function filters_feComponentTransfer_type_eq_table_and_tableValues_eq_100__100 (line 70) | fn filters_feComponentTransfer_type_eq_table_and_tableValues_eq_100__100...
function filters_feComponentTransfer_type_eq_table_and_tableValues_eq_1px (line 71) | fn filters_feComponentTransfer_type_eq_table_and_tableValues_eq_1px() { ...
function filters_feComponentTransfer_type_eq_table_on_alpha (line 72) | fn filters_feComponentTransfer_type_eq_table_on_alpha() { assert_eq!(ren...
function filters_feComponentTransfer_type_eq_table_on_blue_twice (line 73) | fn filters_feComponentTransfer_type_eq_table_on_blue_twice() { assert_eq...
function filters_feComponentTransfer_type_eq_table_on_blue_with_sRGB_interpolation (line 74) | fn filters_feComponentTransfer_type_eq_table_on_blue_with_sRGB_interpola...
function filters_feComponentTransfer_type_eq_table_on_blue (line 75) | fn filters_feComponentTransfer_type_eq_table_on_blue() { assert_eq!(rend...
function filters_feComponentTransfer_type_eq_table_with_an_empty_tableValues (line 76) | fn filters_feComponentTransfer_type_eq_table_with_an_empty_tableValues()...
function filters_feComponentTransfer_type_eq_table_with_large_values (line 77) | fn filters_feComponentTransfer_type_eq_table_with_large_values() { asser...
function filters_feComponentTransfer_type_eq_table_without_tableValues (line 78) | fn filters_feComponentTransfer_type_eq_table_without_tableValues() { ass...
function filters_feComposite_default_operator (line 79) | fn filters_feComposite_default_operator() { assert_eq!(render("tests/fil...
function filters_feComposite_empty (line 80) | fn filters_feComposite_empty() { assert_eq!(render("tests/filters/feComp...
function filters_feComposite_invalid_operator (line 81) | fn filters_feComposite_invalid_operator() { assert_eq!(render("tests/fil...
function filters_feComposite_operator_eq_arithmetic_and_invalid_k1_4 (line 82) | fn filters_feComposite_operator_eq_arithmetic_and_invalid_k1_4() { asser...
function filters_feComposite_operator_eq_arithmetic_on_sRGB (line 83) | fn filters_feComposite_operator_eq_arithmetic_on_sRGB() { assert_eq!(ren...
function filters_feComposite_operator_eq_arithmetic_with_large_k1_4 (line 84) | fn filters_feComposite_operator_eq_arithmetic_with_large_k1_4() { assert...
function filters_feComposite_operator_eq_arithmetic_with_opacity_on_sRGB (line 85) | fn filters_feComposite_operator_eq_arithmetic_with_opacity_on_sRGB() { a...
function filters_feComposite_operator_eq_arithmetic_with_opacity (line 86) | fn filters_feComposite_operator_eq_arithmetic_with_opacity() { assert_eq...
function filters_feComposite_operator_eq_arithmetic_with_some_k1_4 (line 87) | fn filters_feComposite_operator_eq_arithmetic_with_some_k1_4() { assert_...
function filters_feComposite_operator_eq_arithmetic_without_k1_4 (line 88) | fn filters_feComposite_operator_eq_arithmetic_without_k1_4() { assert_eq...
function filters_feComposite_operator_eq_arithmetic (line 89) | fn filters_feComposite_operator_eq_arithmetic() { assert_eq!(render("tes...
function filters_feComposite_operator_eq_atop (line 90) | fn filters_feComposite_operator_eq_atop() { assert_eq!(render("tests/fil...
function filters_feComposite_operator_eq_in (line 91) | fn filters_feComposite_operator_eq_in() { assert_eq!(render("tests/filte...
function filters_feComposite_operator_eq_out (line 92) | fn filters_feComposite_operator_eq_out() { assert_eq!(render("tests/filt...
function filters_feComposite_operator_eq_over (line 93) | fn filters_feComposite_operator_eq_over() { assert_eq!(render("tests/fil...
function filters_feComposite_operator_eq_xor (line 94) | fn filters_feComposite_operator_eq_xor() { assert_eq!(render("tests/filt...
function filters_feComposite_with_subregion_on_input_1 (line 95) | fn filters_feComposite_with_subregion_on_input_1() { assert_eq!(render("...
function filters_feComposite_with_subregion_on_input_2 (line 96) | fn filters_feComposite_with_subregion_on_input_2() { assert_eq!(render("...
function filters_feConvolveMatrix_bias_eq__0_5 (line 97) | fn filters_feConvolveMatrix_bias_eq__0_5() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_bias_eq_0_5 (line 98) | fn filters_feConvolveMatrix_bias_eq_0_5() { assert_eq!(render("tests/fil...
function filters_feConvolveMatrix_bias_eq_9999 (line 99) | fn filters_feConvolveMatrix_bias_eq_9999() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_custom_divisor (line 100) | fn filters_feConvolveMatrix_custom_divisor() { assert_eq!(render("tests/...
function filters_feConvolveMatrix_divisor_eq_0 (line 101) | fn filters_feConvolveMatrix_divisor_eq_0() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_edgeMode_eq_none (line 102) | fn filters_feConvolveMatrix_edgeMode_eq_none() { assert_eq!(render("test...
function filters_feConvolveMatrix_edgeMode_eq_wrap_with_matrix_larger_than_target (line 103) | fn filters_feConvolveMatrix_edgeMode_eq_wrap_with_matrix_larger_than_tar...
function filters_feConvolveMatrix_edgeMode_eq_wrap (line 104) | fn filters_feConvolveMatrix_edgeMode_eq_wrap() { assert_eq!(render("test...
function filters_feConvolveMatrix_empty_kernelMatrix (line 105) | fn filters_feConvolveMatrix_empty_kernelMatrix() { assert_eq!(render("te...
function filters_feConvolveMatrix_kernelMatrix_with_not_enough_values (line 106) | fn filters_feConvolveMatrix_kernelMatrix_with_not_enough_values() { asse...
function filters_feConvolveMatrix_kernelMatrix_with_too_many_values (line 107) | fn filters_feConvolveMatrix_kernelMatrix_with_too_many_values() { assert...
function filters_feConvolveMatrix_kernelMatrix_with_zero_sum_and_no_divisor (line 108) | fn filters_feConvolveMatrix_kernelMatrix_with_zero_sum_and_no_divisor() ...
function filters_feConvolveMatrix_no_kernelMatrix (line 109) | fn filters_feConvolveMatrix_no_kernelMatrix() { assert_eq!(render("tests...
function filters_feConvolveMatrix_order_with_a_negative_value_1 (line 110) | fn filters_feConvolveMatrix_order_with_a_negative_value_1() { assert_eq!...
function filters_feConvolveMatrix_order_with_a_negative_value_2 (line 111) | fn filters_feConvolveMatrix_order_with_a_negative_value_2() { assert_eq!...
function filters_feConvolveMatrix_order_eq_0 (line 112) | fn filters_feConvolveMatrix_order_eq_0() { assert_eq!(render("tests/filt...
function filters_feConvolveMatrix_order_eq_4_2 (line 113) | fn filters_feConvolveMatrix_order_eq_4_2() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_order_eq_4_4 (line 114) | fn filters_feConvolveMatrix_order_eq_4_4() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_order_eq_4 (line 115) | fn filters_feConvolveMatrix_order_eq_4() { assert_eq!(render("tests/filt...
function filters_feConvolveMatrix_preserveAlpha_eq_true (line 116) | fn filters_feConvolveMatrix_preserveAlpha_eq_true() { assert_eq!(render(...
function filters_feConvolveMatrix_targetX_eq__1 (line 117) | fn filters_feConvolveMatrix_targetX_eq__1() { assert_eq!(render("tests/f...
function filters_feConvolveMatrix_targetX_eq_0 (line 118) | fn filters_feConvolveMatrix_targetX_eq_0() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_targetX_eq_2 (line 119) | fn filters_feConvolveMatrix_targetX_eq_2() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_targetX_eq_3 (line 120) | fn filters_feConvolveMatrix_targetX_eq_3() { assert_eq!(render("tests/fi...
function filters_feConvolveMatrix_unset_order (line 121) | fn filters_feConvolveMatrix_unset_order() { assert_eq!(render("tests/fil...
function filters_feDiffuseLighting_complex_transform (line 122) | fn filters_feDiffuseLighting_complex_transform() { assert_eq!(render("te...
function filters_feDiffuseLighting_diffuseConstant_eq__1 (line 123) | fn filters_feDiffuseLighting_diffuseConstant_eq__1() { assert_eq!(render...
function filters_feDiffuseLighting_diffuseConstant_eq_0 (line 124) | fn filters_feDiffuseLighting_diffuseConstant_eq_0() { assert_eq!(render(...
function filters_feDiffuseLighting_diffuseConstant_eq_5 (line 125) | fn filters_feDiffuseLighting_diffuseConstant_eq_5() { assert_eq!(render(...
function filters_feDiffuseLighting_lighting_color_eq_currentColor_without_color (line 126) | fn filters_feDiffuseLighting_lighting_color_eq_currentColor_without_colo...
function filters_feDiffuseLighting_lighting_color_eq_currentColor (line 127) | fn filters_feDiffuseLighting_lighting_color_eq_currentColor() { assert_e...
function filters_feDiffuseLighting_lighting_color_eq_hsla (line 128) | fn filters_feDiffuseLighting_lighting_color_eq_hsla() { assert_eq!(rende...
function filters_feDiffuseLighting_lighting_color_eq_inherit (line 129) | fn filters_feDiffuseLighting_lighting_color_eq_inherit() { assert_eq!(re...
function filters_feDiffuseLighting_lighting_color_eq_seagreen (line 130) | fn filters_feDiffuseLighting_lighting_color_eq_seagreen() { assert_eq!(r...
function filters_feDiffuseLighting_linearRGB_color_interpolation (line 131) | fn filters_feDiffuseLighting_linearRGB_color_interpolation() { assert_eq...
function filters_feDiffuseLighting_multiple_light_sources (line 132) | fn filters_feDiffuseLighting_multiple_light_sources() { assert_eq!(rende...
function filters_feDiffuseLighting_no_light_source (line 133) | fn filters_feDiffuseLighting_no_light_source() { assert_eq!(render("test...
function filters_feDiffuseLighting_single_light_source_with_comment (line 134) | fn filters_feDiffuseLighting_single_light_source_with_comment() { assert...
function filters_feDiffuseLighting_single_light_source_with_desc (line 135) | fn filters_feDiffuseLighting_single_light_source_with_desc() { assert_eq...
function filters_feDiffuseLighting_single_light_source_with_invalid_child (line 136) | fn filters_feDiffuseLighting_single_light_source_with_invalid_child() { ...
function filters_feDiffuseLighting_single_light_source_with_title_and_desc (line 137) | fn filters_feDiffuseLighting_single_light_source_with_title_and_desc() {...
function filters_feDiffuseLighting_single_light_source_with_title (line 138) | fn filters_feDiffuseLighting_single_light_source_with_title() { assert_e...
function filters_feDiffuseLighting_single_light_source (line 139) | fn filters_feDiffuseLighting_single_light_source() { assert_eq!(render("...
function filters_feDiffuseLighting_surfaceScale_eq__10 (line 140) | fn filters_feDiffuseLighting_surfaceScale_eq__10() { assert_eq!(render("...
function filters_feDiffuseLighting_surfaceScale_eq_0 (line 141) | fn filters_feDiffuseLighting_surfaceScale_eq_0() { assert_eq!(render("te...
function filters_feDiffuseLighting_surfaceScale_eq_1_33 (line 142) | fn filters_feDiffuseLighting_surfaceScale_eq_1_33() { assert_eq!(render(...
function filters_feDiffuseLighting_surfaceScale_eq_5 (line 143) | fn filters_feDiffuseLighting_surfaceScale_eq_5() { assert_eq!(render("te...
function filters_feDisplacementMap_simple_case (line 144) | fn filters_feDisplacementMap_simple_case() { assert_eq!(render("tests/fi...
function filters_feDistantLight_default_attributes (line 145) | fn filters_feDistantLight_default_attributes() { assert_eq!(render("test...
function filters_feDistantLight_negative_azimuth_and_elevation (line 146) | fn filters_feDistantLight_negative_azimuth_and_elevation() { assert_eq!(...
function filters_feDistantLight_only_azimuth (line 147) | fn filters_feDistantLight_only_azimuth() { assert_eq!(render("tests/filt...
function filters_feDistantLight_only_elevation (line 148) | fn filters_feDistantLight_only_elevation() { assert_eq!(render("tests/fi...
function filters_feDropShadow_hsla_color (line 149) | fn filters_feDropShadow_hsla_color() { assert_eq!(render("tests/filters/...
function filters_feDropShadow_only_stdDeviation (line 150) | fn filters_feDropShadow_only_stdDeviation() { assert_eq!(render("tests/f...
function filters_feDropShadow_stdDeviation_eq_0 (line 151) | fn filters_feDropShadow_stdDeviation_eq_0() { assert_eq!(render("tests/f...
function filters_feDropShadow_with_flood_color (line 152) | fn filters_feDropShadow_with_flood_color() { assert_eq!(render("tests/fi...
function filters_feDropShadow_with_flood_opacity (line 153) | fn filters_feDropShadow_with_flood_opacity() { assert_eq!(render("tests/...
function filters_feDropShadow_with_offset_clipped (line 154) | fn filters_feDropShadow_with_offset_clipped() { assert_eq!(render("tests...
function filters_feDropShadow_with_offset (line 155) | fn filters_feDropShadow_with_offset() { assert_eq!(render("tests/filters...
function filters_feDropShadow_with_percent_offset (line 156) | fn filters_feDropShadow_with_percent_offset() { assert_eq!(render("tests...
function filters_feFlood_complex_transform (line 157) | fn filters_feFlood_complex_transform() { assert_eq!(render("tests/filter...
function filters_feFlood_default_values (line 158) | fn filters_feFlood_default_values() { assert_eq!(render("tests/filters/f...
function filters_feFlood_partial_subregion (line 159) | fn filters_feFlood_partial_subregion() { assert_eq!(render("tests/filter...
function filters_feFlood_seagreen (line 160) | fn filters_feFlood_seagreen() { assert_eq!(render("tests/filters/feFlood...
function filters_feFlood_subregion_inheritance (line 161) | fn filters_feFlood_subregion_inheritance() { assert_eq!(render("tests/fi...
function filters_feFlood_subregion_with_primitiveUnits_eq_objectBoundingBox (line 162) | fn filters_feFlood_subregion_with_primitiveUnits_eq_objectBoundingBox() ...
function filters_feFlood_with_opacity_on_target_element (line 163) | fn filters_feFlood_with_opacity_on_target_element() { assert_eq!(render(...
function filters_feFlood_with_opacity (line 164) | fn filters_feFlood_with_opacity() { assert_eq!(render("tests/filters/feF...
function filters_feGaussianBlur_complex_transform (line 165) | fn filters_feGaussianBlur_complex_transform() { assert_eq!(render("tests...
function filters_feGaussianBlur_empty_stdDeviation (line 166) | fn filters_feGaussianBlur_empty_stdDeviation() { assert_eq!(render("test...
function filters_feGaussianBlur_huge_stdDeviation (line 167) | fn filters_feGaussianBlur_huge_stdDeviation() { assert_eq!(render("tests...
function filters_feGaussianBlur_negative_stdDeviation (line 168) | fn filters_feGaussianBlur_negative_stdDeviation() { assert_eq!(render("t...
function filters_feGaussianBlur_no_stdDeviation (line 169) | fn filters_feGaussianBlur_no_stdDeviation() { assert_eq!(render("tests/f...
function filters_feGaussianBlur_simple_case (line 170) | fn filters_feGaussianBlur_simple_case() { assert_eq!(render("tests/filte...
function filters_feGaussianBlur_small_stdDeviation (line 171) | fn filters_feGaussianBlur_small_stdDeviation() { assert_eq!(render("test...
function filters_feGaussianBlur_stdDeviation_with_multiple_values (line 172) | fn filters_feGaussianBlur_stdDeviation_with_multiple_values() { assert_e...
function filters_feGaussianBlur_stdDeviation_with_two_different_values (line 173) | fn filters_feGaussianBlur_stdDeviation_with_two_different_values() { ass...
function filters_feGaussianBlur_stdDeviation_with_two_values (line 174) | fn filters_feGaussianBlur_stdDeviation_with_two_values() { assert_eq!(re...
function filters_feGaussianBlur_stdDeviation_eq_0_5 (line 175) | fn filters_feGaussianBlur_stdDeviation_eq_0_5() { assert_eq!(render("tes...
function filters_feGaussianBlur_stdDeviation_eq_5_0 (line 176) | fn filters_feGaussianBlur_stdDeviation_eq_5_0() { assert_eq!(render("tes...
function filters_feGaussianBlur_tiny_stdDeviation (line 177) | fn filters_feGaussianBlur_tiny_stdDeviation() { assert_eq!(render("tests...
function filters_feImage_chained_feImage (line 178) | fn filters_feImage_chained_feImage() { assert_eq!(render("tests/filters/...
function filters_feImage_embedded_png (line 179) | fn filters_feImage_embedded_png() { assert_eq!(render("tests/filters/feI...
function filters_feImage_empty (line 180) | fn filters_feImage_empty() { assert_eq!(render("tests/filters/feImage/em...
function filters_feImage_link_on_an_element_with_complex_transform (line 181) | fn filters_feImage_link_on_an_element_with_complex_transform() { assert_...
function filters_feImage_link_on_an_element_with_transform (line 182) | fn filters_feImage_link_on_an_element_with_transform() { assert_eq!(rend...
function filters_feImage_link_to_an_element_outside_defs_1 (line 183) | fn filters_feImage_link_to_an_element_outside_defs_1() { assert_eq!(rend...
function filters_feImage_link_to_an_element_outside_defs_2 (line 184) | fn filters_feImage_link_to_an_element_outside_defs_2() { assert_eq!(rend...
function filters_feImage_link_to_an_element_with_opacity (line 185) | fn filters_feImage_link_to_an_element_with_opacity() { assert_eq!(render...
function filters_feImage_link_to_an_element_with_transform (line 186) | fn filters_feImage_link_to_an_element_with_transform() { assert_eq!(rend...
function filters_feImage_link_to_an_element (line 187) | fn filters_feImage_link_to_an_element() { assert_eq!(render("tests/filte...
function filters_feImage_link_to_an_invalid_element (line 188) | fn filters_feImage_link_to_an_invalid_element() { assert_eq!(render("tes...
function filters_feImage_link_to_g (line 189) | fn filters_feImage_link_to_g() { assert_eq!(render("tests/filters/feImag...
function filters_feImage_link_to_use (line 190) | fn filters_feImage_link_to_use() { assert_eq!(render("tests/filters/feIm...
function filters_feImage_preserveAspectRatio_eq_none (line 191) | fn filters_feImage_preserveAspectRatio_eq_none() { assert_eq!(render("te...
function filters_feImage_recursive_links_1 (line 192) | fn filters_feImage_recursive_links_1() { assert_eq!(render("tests/filter...
function filters_feImage_recursive_links_2 (line 193) | fn filters_feImage_recursive_links_2() { assert_eq!(render("tests/filter...
function filters_feImage_self_recursive (line 194) | fn filters_feImage_self_recursive() { assert_eq!(render("tests/filters/f...
function filters_feImage_simple_case (line 195) | fn filters_feImage_simple_case() { assert_eq!(render("tests/filters/feIm...
function filters_feImage_svg (line 196) | fn filters_feImage_svg() { assert_eq!(render("tests/filters/feImage/svg"...
function filters_feImage_with_subregion_1 (line 197) | fn filters_feImage_with_subregion_1() { assert_eq!(render("tests/filters...
function filters_feImage_with_subregion_2 (line 198) | fn filters_feImage_with_subregion_2() { assert_eq!(render("tests/filters...
function filters_feImage_with_subregion_3 (line 199) | fn filters_feImage_with_subregion_3() { assert_eq!(render("tests/filters...
function filters_feImage_with_subregion_4 (line 200) | fn filters_feImage_with_subregion_4() { assert_eq!(render("tests/filters...
function filters_feImage_with_subregion_5 (line 201) | fn filters_feImage_with_subregion_5() { assert_eq!(render("tests/filters...
function filters_feImage_with_x_y_and_protruding_subregion_1 (line 202) | fn filters_feImage_with_x_y_and_protruding_subregion_1() { assert_eq!(re...
function filters_feImage_with_x_y_and_protruding_subregion_2 (line 203) | fn filters_feImage_with_x_y_and_protruding_subregion_2() { assert_eq!(re...
function filters_feImage_with_x_y (line 204) | fn filters_feImage_with_x_y() { assert_eq!(render("tests/filters/feImage...
function filters_feMerge_color_interpolation_filters_eq_linearRGB (line 205) | fn filters_feMerge_color_interpolation_filters_eq_linearRGB() { assert_e...
function filters_feMerge_color_interpolation_filters_eq_sRGB (line 206) | fn filters_feMerge_color_interpolation_filters_eq_sRGB() { assert_eq!(re...
function filters_feMerge_complex_transform (line 207) | fn filters_feMerge_complex_transform() { assert_eq!(render("tests/filter...
function filters_feMorphology_empty_radius (line 208) | fn filters_feMorphology_empty_radius() { assert_eq!(render("tests/filter...
function filters_feMorphology_negative_radius (line 209) | fn filters_feMorphology_negative_radius() { assert_eq!(render("tests/fil...
function filters_feMorphology_no_radius (line 210) | fn filters_feMorphology_no_radius() { assert_eq!(render("tests/filters/f...
function filters_feMorphology_operator_eq_dilate (line 211) | fn filters_feMorphology_operator_eq_dilate() { assert_eq!(render("tests/...
function filters_feMorphology_radius_with_too_many_values (line 212) | fn filters_feMorphology_radius_with_too_many_values() { assert_eq!(rende...
function filters_feMorphology_radius_eq_0_5_with_objectBoundingBox (line 213) | fn filters_feMorphology_radius_eq_0_5_with_objectBoundingBox() { assert_...
function filters_feMorphology_radius_eq_0_5 (line 214) | fn filters_feMorphology_radius_eq_0_5() { assert_eq!(render("tests/filte...
function filters_feMorphology_radius_eq_1_10 (line 215) | fn filters_feMorphology_radius_eq_1_10() { assert_eq!(render("tests/filt...
function filters_feMorphology_radius_eq_10_0 (line 216) | fn filters_feMorphology_radius_eq_10_0() { assert_eq!(render("tests/filt...
function filters_feMorphology_radius_eq_10_1 (line 217) | fn filters_feMorphology_radius_eq_10_1() { assert_eq!(render("tests/filt...
function filters_feMorphology_simple_case (line 218) | fn filters_feMorphology_simple_case() { assert_eq!(render("tests/filters...
function filters_feMorphology_source_with_opacity (line 219) | fn filters_feMorphology_source_with_opacity() { assert_eq!(render("tests...
function filters_feMorphology_zero_radius (line 220) | fn filters_feMorphology_zero_radius() { assert_eq!(render("tests/filters...
function filters_feOffset_complex_transform (line 221) | fn filters_feOffset_complex_transform() { assert_eq!(render("tests/filte...
function filters_feOffset_fractional_offset (line 222) | fn filters_feOffset_fractional_offset() { assert_eq!(render("tests/filte...
function filters_feOffset_negative_offset (line 223) | fn filters_feOffset_negative_offset() { assert_eq!(render("tests/filters...
function filters_feOffset_no_offset (line 224) | fn filters_feOffset_no_offset() { assert_eq!(render("tests/filters/feOff...
function filters_feOffset_only_dx (line 225) | fn filters_feOffset_only_dx() { assert_eq!(render("tests/filters/feOffse...
function filters_feOffset_only_dy (line 226) | fn filters_feOffset_only_dy() { assert_eq!(render("tests/filters/feOffse...
function filters_feOffset_percentage_values (line 227) | fn filters_feOffset_percentage_values() { assert_eq!(render("tests/filte...
function filters_feOffset_simple_case (line 228) | fn filters_feOffset_simple_case() { assert_eq!(render("tests/filters/feO...
function filters_feOffset_with_primitiveUnits_eq_objectBoundingBox (line 229) | fn filters_feOffset_with_primitiveUnits_eq_objectBoundingBox() { assert_...
function filters_fePointLight_complex_transform (line 230) | fn filters_fePointLight_complex_transform() { assert_eq!(render("tests/f...
function filters_fePointLight_custom_attributes (line 231) | fn filters_fePointLight_custom_attributes() { assert_eq!(render("tests/f...
function filters_fePointLight_default_attributes (line 232) | fn filters_fePointLight_default_attributes() { assert_eq!(render("tests/...
function filters_fePointLight_primitiveUnits_eq_objectBoundingBox (line 233) | fn filters_fePointLight_primitiveUnits_eq_objectBoundingBox() { assert_e...
function filters_feSpecularLighting_lighting_color_eq_hsla (line 234) | fn filters_feSpecularLighting_lighting_color_eq_hsla() { assert_eq!(rend...
function filters_feSpecularLighting_specularExponent_eq_0 (line 235) | fn filters_feSpecularLighting_specularExponent_eq_0() { assert_eq!(rende...
function filters_feSpecularLighting_specularExponent_eq_256 (line 236) | fn filters_feSpecularLighting_specularExponent_eq_256() { assert_eq!(ren...
function filters_feSpecularLighting_with_feDistantLight (line 237) | fn filters_feSpecularLighting_with_feDistantLight() { assert_eq!(render(...
function filters_feSpecularLighting_with_fePointLight (line 238) | fn filters_feSpecularLighting_with_fePointLight() { assert_eq!(render("t...
function filters_feSpecularLighting_with_feSpotLight_and_specular_and_exponent (line 239) | fn filters_feSpecularLighting_with_feSpotLight_and_specular_and_exponent...
function filters_feSpecularLighting_with_feSpotLight_and_specularConstant_eq_5 (line 240) | fn filters_feSpecularLighting_with_feSpotLight_and_specularConstant_eq_5...
function filters_feSpecularLighting_with_feSpotLight (line 241) | fn filters_feSpecularLighting_with_feSpotLight() { assert_eq!(render("te...
function filters_feSpotLight_complex_transform (line 242) | fn filters_feSpotLight_complex_transform() { assert_eq!(render("tests/fi...
function filters_feSpotLight_custom_attributes (line 243) | fn filters_feSpotLight_custom_attributes() { assert_eq!(render("tests/fi...
function filters_feSpotLight_default_attributes (line 244) | fn filters_feSpotLight_default_attributes() { assert_eq!(render("tests/f...
function filters_feSpotLight_limitingConeAngle_anti_aliasing (line 245) | fn filters_feSpotLight_limitingConeAngle_anti_aliasing() { assert_eq!(re...
function filters_feSpotLight_limitingConeAngle_eq__30 (line 246) | fn filters_feSpotLight_limitingConeAngle_eq__30() { assert_eq!(render("t...
function filters_feSpotLight_limitingConeAngle_eq_0 (line 247) | fn filters_feSpotLight_limitingConeAngle_eq_0() { assert_eq!(render("tes...
function filters_feSpotLight_limitingConeAngle_eq_30 (line 248) | fn filters_feSpotLight_limitingConeAngle_eq_30() { assert_eq!(render("te...
function filters_feSpotLight_primitiveUnits_eq_objectBoundingBox (line 249) | fn filters_feSpotLight_primitiveUnits_eq_objectBoundingBox() { assert_eq...
function filters_feSpotLight_specularExponent_eq__10 (line 250) | fn filters_feSpotLight_specularExponent_eq__10() { assert_eq!(render("te...
function filters_feSpotLight_specularExponent_eq_0_5 (line 251) | fn filters_feSpotLight_specularExponent_eq_0_5() { assert_eq!(render("te...
function filters_feSpotLight_specularExponent_eq_10 (line 252) | fn filters_feSpotLight_specularExponent_eq_10() { assert_eq!(render("tes...
function filters_feSpotLight_with_all_pointsAt (line 253) | fn filters_feSpotLight_with_all_pointsAt() { assert_eq!(render("tests/fi...
function filters_feTile_complex_transform (line 254) | fn filters_feTile_complex_transform() { assert_eq!(render("tests/filters...
function filters_feTile_empty_region (line 255) | fn filters_feTile_empty_region() { assert_eq!(render("tests/filters/feTi...
function filters_feTile_simple_case (line 256) | fn filters_feTile_simple_case() { assert_eq!(render("tests/filters/feTil...
function filters_feTile_with_region (line 257) | fn filters_feTile_with_region() { assert_eq!(render("tests/filters/feTil...
function filters_feTile_with_subregion_1 (line 258) | fn filters_feTile_with_subregion_1() { assert_eq!(render("tests/filters/...
function filters_feTile_with_subregion_2 (line 259) | fn filters_feTile_with_subregion_2() { assert_eq!(render("tests/filters/...
function filters_feTile_with_subregion_3 (line 260) | fn filters_feTile_with_subregion_3() { assert_eq!(render("tests/filters/...
function filters_feTurbulence_baseFrequency_eq__0_05 (line 261) | fn filters_feTurbulence_baseFrequency_eq__0_05() { assert_eq!(render("te...
function filters_feTurbulence_baseFrequency_eq_0_01 (line 262) | fn filters_feTurbulence_baseFrequency_eq_0_01() { assert_eq!(render("tes...
function filters_feTurbulence_baseFrequency_eq_0_05__0_01 (line 263) | fn filters_feTurbulence_baseFrequency_eq_0_05__0_01() { assert_eq!(rende...
function filters_feTurbulence_baseFrequency_eq_0_05_0_01 (line 264) | fn filters_feTurbulence_baseFrequency_eq_0_05_0_01() { assert_eq!(render...
function filters_feTurbulence_baseFrequency_eq_0_05_0_05 (line 265) | fn filters_feTurbulence_baseFrequency_eq_0_05_0_05() { assert_eq!(render...
function filters_feTurbulence_baseFrequency_eq_0_05_0 (line 266) | fn filters_feTurbulence_baseFrequency_eq_0_05_0() { assert_eq!(render("t...
function filters_feTurbulence_color_interpolation_filters_eq_sRGB (line 267) | fn filters_feTurbulence_color_interpolation_filters_eq_sRGB() { assert_e...
function filters_feTurbulence_complex_transform (line 268) | fn filters_feTurbulence_complex_transform() { assert_eq!(render("tests/f...
function filters_feTurbulence_no_attributes (line 269) | fn filters_feTurbulence_no_attributes() { assert_eq!(render("tests/filte...
function filters_feTurbulence_numOctaves_eq__1 (line 270) | fn filters_feTurbulence_numOctaves_eq__1() { assert_eq!(render("tests/fi...
function filters_feTurbulence_numOctaves_eq_0 (line 271) | fn filters_feTurbulence_numOctaves_eq_0() { assert_eq!(render("tests/fil...
function filters_feTurbulence_numOctaves_eq_5 (line 272) | fn filters_feTurbulence_numOctaves_eq_5() { assert_eq!(render("tests/fil...
function filters_feTurbulence_primitiveUnits_eq_objectBoundingBox (line 273) | fn filters_feTurbulence_primitiveUnits_eq_objectBoundingBox() { assert_e...
function filters_feTurbulence_seed_eq__20 (line 274) | fn filters_feTurbulence_seed_eq__20() { assert_eq!(render("tests/filters...
function filters_feTurbulence_seed_eq_1_5 (line 275) | fn filters_feTurbulence_seed_eq_1_5() { assert_eq!(render("tests/filters...
function filters_feTurbulence_seed_eq_20 (line 276) | fn filters_feTurbulence_seed_eq_20() { assert_eq!(render("tests/filters/...
function filters_feTurbulence_stitchTiles_eq_stitch (line 277) | fn filters_feTurbulence_stitchTiles_eq_stitch() { assert_eq!(render("tes...
function filters_feTurbulence_type_eq_fractalNoise (line 278) | fn filters_feTurbulence_type_eq_fractalNoise() { assert_eq!(render("test...
function filters_feTurbulence_type_eq_invalid (line 279) | fn filters_feTurbulence_type_eq_invalid() { assert_eq!(render("tests/fil...
function filters_filter_color_interpolation_filters_eq_sRGB (line 280) | fn filters_filter_color_interpolation_filters_eq_sRGB() { assert_eq!(ren...
function filters_filter_complex_order_and_xlink_href (line 281) | fn filters_filter_complex_order_and_xlink_href() { assert_eq!(render("te...
function filters_filter_content_outside_the_canvas_2 (line 282) | fn filters_filter_content_outside_the_canvas_2() { assert_eq!(render("te...
function filters_filter_content_outside_the_canvas (line 283) | fn filters_filter_content_outside_the_canvas() { assert_eq!(render("test...
function filters_filter_default_color_interpolation_filters (line 284) | fn filters_filter_default_color_interpolation_filters() { assert_eq!(ren...
function filters_filter_everything_via_xlink_href (line 285) | fn filters_filter_everything_via_xlink_href() { assert_eq!(render("tests...
function filters_filter_global_transform (line 286) | fn filters_filter_global_transform() { assert_eq!(render("tests/filters/...
function filters_filter_huge_region (line 287) | fn filters_filter_huge_region() { assert_eq!(render("tests/filters/filte...
function filters_filter_in_to_invalid_1 (line 288) | fn filters_filter_in_to_invalid_1() { assert_eq!(render("tests/filters/f...
function filters_filter_in_to_invalid_2 (line 289) | fn filters_filter_in_to_invalid_2() { assert_eq!(render("tests/filters/f...
function filters_filter_in_eq_BackgroundAlpha_with_enable_background (line 290) | fn filters_filter_in_eq_BackgroundAlpha_with_enable_background() { asser...
function filters_filter_in_eq_BackgroundAlpha (line 291) | fn filters_filter_in_eq_BackgroundAlpha() { assert_eq!(render("tests/fil...
function filters_filter_in_eq_BackgroundImage_with_enable_background (line 292) | fn filters_filter_in_eq_BackgroundImage_with_enable_background() { asser...
function filters_filter_in_eq_BackgroundImage (line 293) | fn filters_filter_in_eq_BackgroundImage() { assert_eq!(render("tests/fil...
function filters_filter_in_eq_FillPaint_on_g_without_children (line 294) | fn filters_filter_in_eq_FillPaint_on_g_without_children() { assert_eq!(r...
function filters_filter_in_eq_FillPaint_with_gradient (line 295) | fn filters_filter_in_eq_FillPaint_with_gradient() { assert_eq!(render("t...
function filters_filter_in_eq_FillPaint_with_pattern (line 296) | fn filters_filter_in_eq_FillPaint_with_pattern() { assert_eq!(render("te...
function filters_filter_in_eq_FillPaint_with_target_on_g (line 297) | fn filters_filter_in_eq_FillPaint_with_target_on_g() { assert_eq!(render...
function filters_filter_in_eq_FillPaint (line 298) | fn filters_filter_in_eq_FillPaint() { assert_eq!(render("tests/filters/f...
function filters_filter_in_eq_SourceAlpha (line 299) | fn filters_filter_in_eq_SourceAlpha() { assert_eq!(render("tests/filters...
function filters_filter_in_eq_StrokePaint (line 300) | fn filters_filter_in_eq_StrokePaint() { assert_eq!(render("tests/filters...
function filters_filter_initial_transform (line 301) | fn filters_filter_initial_transform() { assert_eq!(render("tests/filters...
function filters_filter_invalid_FuncIRI (line 302) | fn filters_filter_invalid_FuncIRI() { assert_eq!(render("tests/filters/f...
function filters_filter_invalid_filterUnits (line 303) | fn filters_filter_invalid_filterUnits() { assert_eq!(render("tests/filte...
function filters_filter_invalid_primitive_1 (line 304) | fn filters_filter_invalid_primitive_1() { assert_eq!(render("tests/filte...
function filters_filter_invalid_primitive_2 (line 305) | fn filters_filter_invalid_primitive_2() { assert_eq!(render("tests/filte...
function filters_filter_invalid_region (line 306) | fn filters_filter_invalid_region() { assert_eq!(render("tests/filters/fi...
function filters_filter_invalid_subregion (line 307) | fn filters_filter_invalid_subregion() { assert_eq!(render("tests/filters...
function filters_filter_invalid_xlink_href (line 308) | fn filters_filter_invalid_xlink_href() { assert_eq!(render("tests/filter...
function filters_filter_multiple_primitives_1 (line 309) | fn filters_filter_multiple_primitives_1() { assert_eq!(render("tests/fil...
function filters_filter_multiple_primitives_2 (line 310) | fn filters_filter_multiple_primitives_2() { assert_eq!(render("tests/fil...
function filters_filter_multiple_primitives_3 (line 311) | fn filters_filter_multiple_primitives_3() { assert_eq!(render("tests/fil...
function filters_filter_multiple_primitives_4 (line 312) | fn filters_filter_multiple_primitives_4() { assert_eq!(render("tests/fil...
function filters_filter_negative_subregion (line 313) | fn filters_filter_negative_subregion() { assert_eq!(render("tests/filter...
function filters_filter_no_children (line 314) | fn filters_filter_no_children() { assert_eq!(render("tests/filters/filte...
function filters_filter_none (line 315) | fn filters_filter_none() { assert_eq!(render("tests/filters/filter/none"...
function filters_filter_on_a_thin_rect (line 316) | fn filters_filter_on_a_thin_rect() { assert_eq!(render("tests/filters/fi...
function filters_filter_on_a_vertical_line (line 317) | fn filters_filter_on_a_vertical_line() { assert_eq!(render("tests/filter...
function filters_filter_on_an_empty_group_1 (line 318) | fn filters_filter_on_an_empty_group_1() { assert_eq!(render("tests/filte...
function filters_filter_on_an_empty_group_2 (line 319) | fn filters_filter_on_an_empty_group_2() { assert_eq!(render("tests/filte...
function filters_filter_on_group_with_child_outside_of_canvas (line 320) | fn filters_filter_on_group_with_child_outside_of_canvas() { assert_eq!(r...
function filters_filter_on_the_root_svg (line 321) | fn filters_filter_on_the_root_svg() { assert_eq!(render("tests/filters/f...
function filters_filter_on_zero_sized_shape (line 322) | fn filters_filter_on_zero_sized_shape() { assert_eq!(render("tests/filte...
function filters_filter_path_bbox (line 323) | fn filters_filter_path_bbox() { assert_eq!(render("tests/filters/filter/...
function filters_filter_primitiveUnits_eq_objectBoundingBox (line 324) | fn filters_filter_primitiveUnits_eq_objectBoundingBox() { assert_eq!(ren...
function filters_filter_recursive_xlink_href (line 325) | fn filters_filter_recursive_xlink_href() { assert_eq!(render("tests/filt...
function filters_filter_region_with_stroke (line 326) | fn filters_filter_region_with_stroke() { assert_eq!(render("tests/filter...
function filters_filter_self_recursive_xlink_href (line 327) | fn filters_filter_self_recursive_xlink_href() { assert_eq!(render("tests...
function filters_filter_simple_case (line 328) | fn filters_filter_simple_case() { assert_eq!(render("tests/filters/filte...
function filters_filter_some_attributes_via_xlink_href (line 329) | fn filters_filter_some_attributes_via_xlink_href() { assert_eq!(render("...
function filters_filter_subregion_and_primitiveUnits_eq_objectBoundingBox_1 (line 330) | fn filters_filter_subregion_and_primitiveUnits_eq_objectBoundingBox_1() ...
function filters_filter_subregion_and_primitiveUnits_eq_objectBoundingBox_2 (line 331) | fn filters_filter_subregion_and_primitiveUnits_eq_objectBoundingBox_2() ...
function filters_filter_subregion_bigger_that_region (line 332) | fn filters_filter_subregion_bigger_that_region() { assert_eq!(render("te...
function filters_filter_transform_on_filter (line 333) | fn filters_filter_transform_on_filter() { assert_eq!(render("tests/filte...
function filters_filter_transform_on_shape_with_filter_region (line 334) | fn filters_filter_transform_on_shape_with_filter_region() { assert_eq!(r...
function filters_filter_transform_on_shape (line 335) | fn filters_filter_transform_on_shape() { assert_eq!(render("tests/filter...
function filters_filter_unresolved_xlink_href (line 336) | fn filters_filter_unresolved_xlink_href() { assert_eq!(render("tests/fil...
function filters_filter_with_clip_path_and_mask (line 337) | fn filters_filter_with_clip_path_and_mask() { assert_eq!(render("tests/f...
function filters_filter_with_clip_path (line 338) | fn filters_filter_with_clip_path() { assert_eq!(render("tests/filters/fi...
function filters_filter_with_mask_on_parent (line 339) | fn filters_filter_with_mask_on_parent() { assert_eq!(render("tests/filte...
function filters_filter_with_mask (line 340) | fn filters_filter_with_mask() { assert_eq!(render("tests/filters/filter/...
function filters_filter_with_multiple_transforms_1 (line 341) | fn filters_filter_with_multiple_transforms_1() { assert_eq!(render("test...
function filters_filter_with_multiple_transforms_2 (line 342) | fn filters_filter_with_multiple_transforms_2() { assert_eq!(render("test...
function filters_filter_with_region_and_filterUnits_eq_userSpaceOnUse (line 343) | fn filters_filter_with_region_and_filterUnits_eq_userSpaceOnUse() { asse...
function filters_filter_with_region_and_subregion (line 344) | fn filters_filter_with_region_and_subregion() { assert_eq!(render("tests...
function filters_filter_with_region_outside_the_canvas (line 345) | fn filters_filter_with_region_outside_the_canvas() { assert_eq!(render("...
function filters_filter_with_region_outside_the_viewbox (line 346) | fn filters_filter_with_region_outside_the_viewbox() { assert_eq!(render(...
function filters_filter_with_region (line 347) | fn filters_filter_with_region() { assert_eq!(render("tests/filters/filte...
function filters_filter_with_subregion_1 (line 348) | fn filters_filter_with_subregion_1() { assert_eq!(render("tests/filters/...
function filters_filter_with_subregion_2 (line 349) | fn filters_filter_with_subregion_2() { assert_eq!(render("tests/filters/...
function filters_filter_with_subregion_3 (line 350) | fn filters_filter_with_subregion_3() { assert_eq!(render("tests/filters/...
function filters_filter_with_transform_outside_of_canvas (line 351) | fn filters_filter_with_transform_outside_of_canvas() { assert_eq!(render...
function filters_filter_without_region_and_filterUnits_eq_userSpaceOnUse (line 352) | fn filters_filter_without_region_and_filterUnits_eq_userSpaceOnUse() { a...
function filters_filter_zero_sized_subregion (line 353) | fn filters_filter_zero_sized_subregion() { assert_eq!(render("tests/filt...
function filters_filter_functions_blur_function_mm_value (line 354) | fn filters_filter_functions_blur_function_mm_value() { assert_eq!(render...
function filters_filter_functions_blur_function_negative_value (line 355) | fn filters_filter_functions_blur_function_negative_value() { assert_eq!(...
function filters_filter_functions_blur_function_no_values (line 356) | fn filters_filter_functions_blur_function_no_values() { assert_eq!(rende...
function filters_filter_functions_blur_function_percent_value (line 357) | fn filters_filter_functions_blur_function_percent_value() { assert_eq!(r...
function filters_filter_functions_blur_function_two_values (line 358) | fn filters_filter_functions_blur_function_two_values() { assert_eq!(rend...
function filters_filter_functions_blur_function (line 359) | fn filters_filter_functions_blur_function() { assert_eq!(render("tests/f...
function filters_filter_functions_color_adjust_functions_0percent (line 360) | fn filters_filter_functions_color_adjust_functions_0percent() { assert_e...
function filters_filter_functions_color_adjust_functions_100percent (line 361) | fn filters_filter_functions_color_adjust_functions_100percent() { assert...
function filters_filter_functions_color_adjust_functions_2 (line 362) | fn filters_filter_functions_color_adjust_functions_2() { assert_eq!(rend...
function filters_filter_functions_color_adjust_functions_200percent (line 363) | fn filters_filter_functions_color_adjust_functions_200percent() { assert...
function filters_filter_functions_color_adjust_functions_50percent (line 364) | fn filters_filter_functions_color_adjust_functions_50percent() { assert_...
function filters_filter_functions_color_adjust_functions_default_value (line 365) | fn filters_filter_functions_color_adjust_functions_default_value() { ass...
function filters_filter_functions_color_adjust_functions_negative (line 366) | fn filters_filter_functions_color_adjust_functions_negative() { assert_e...
function filters_filter_functions_drop_shadow_function_color_as_attribute (line 367) | fn filters_filter_functions_drop_shadow_function_color_as_attribute() { ...
function filters_filter_functions_drop_shadow_function_color_last (line 368) | fn filters_filter_functions_drop_shadow_function_color_last() { assert_e...
function filters_filter_functions_drop_shadow_function_comma_separated (line 369) | fn filters_filter_functions_drop_shadow_function_comma_separated() { ass...
function filters_filter_functions_drop_shadow_function_currentColor (line 370) | fn filters_filter_functions_drop_shadow_function_currentColor() { assert...
function filters_filter_functions_drop_shadow_function_em_values (line 371) | fn filters_filter_functions_drop_shadow_function_em_values() { assert_eq...
function filters_filter_functions_drop_shadow_function_extra_value (line 372) | fn filters_filter_functions_drop_shadow_function_extra_value() { assert_...
function filters_filter_functions_drop_shadow_function_filter_region (line 373) | fn filters_filter_functions_drop_shadow_function_filter_region() { asser...
function filters_filter_functions_drop_shadow_function_mm_values (line 374) | fn filters_filter_functions_drop_shadow_function_mm_values() { assert_eq...
function filters_filter_functions_drop_shadow_function_no_color (line 375) | fn filters_filter_functions_drop_shadow_function_no_color() { assert_eq!...
function filters_filter_functions_drop_shadow_function_no_values (line 376) | fn filters_filter_functions_drop_shadow_function_no_values() { assert_eq...
function filters_filter_functions_drop_shadow_function_only_X_offset (line 377) | fn filters_filter_functions_drop_shadow_function_only_X_offset() { asser...
function filters_filter_functions_drop_shadow_function_only_offset (line 378) | fn filters_filter_functions_drop_shadow_function_only_offset() { assert_...
function filters_filter_functions_drop_shadow_function_percent_values (line 379) | fn filters_filter_functions_drop_shadow_function_percent_values() { asse...
function filters_filter_functions_drop_shadow_function (line 380) | fn filters_filter_functions_drop_shadow_function() { assert_eq!(render("...
function filters_filter_functions_grayscale_and_opacity (line 381) | fn filters_filter_functions_grayscale_and_opacity() { assert_eq!(render(...
function filters_filter_functions_hue_rotate_function_0_25turn (line 382) | fn filters_filter_functions_hue_rotate_function_0_25turn() { assert_eq!(...
function filters_filter_functions_hue_rotate_function_45 (line 383) | fn filters_filter_functions_hue_rotate_function_45() { assert_eq!(render...
function filters_filter_functions_hue_rotate_function_45deg (line 384) | fn filters_filter_functions_hue_rotate_function_45deg() { assert_eq!(ren...
function filters_filter_functions_hue_rotate_function_45grad (line 385) | fn filters_filter_functions_hue_rotate_function_45grad() { assert_eq!(re...
function filters_filter_functions_hue_rotate_function_45rad (line 386) | fn filters_filter_functions_hue_rotate_function_45rad() { assert_eq!(ren...
function filters_filter_functions_hue_rotate_function_999deg (line 387) | fn filters_filter_functions_hue_rotate_function_999deg() { assert_eq!(re...
function filters_filter_functions_hue_rotate_function_default_value (line 388) | fn filters_filter_functions_hue_rotate_function_default_value() { assert...
function filters_filter_functions_hue_rotate_function_zero (line 389) | fn filters_filter_functions_hue_rotate_function_zero() { assert_eq!(rend...
function filters_filter_functions_nested_filters (line 390) | fn filters_filter_functions_nested_filters() { assert_eq!(render("tests/...
function filters_filter_functions_one_invalid_function_in_list (line 391) | fn filters_filter_functions_one_invalid_function_in_list() { assert_eq!(...
function filters_filter_functions_one_invalid_url_in_list (line 392) | fn filters_filter_functions_one_invalid_url_in_list() { assert_eq!(rende...
function filters_filter_functions_two_drop_shadow_function (line 393) | fn filters_filter_functions_two_drop_shadow_function() { assert_eq!(rend...
function filters_filter_functions_two_exact_urls (line 394) | fn filters_filter_functions_two_exact_urls() { assert_eq!(render("tests/...
function filters_filter_functions_two_urls (line 395) | fn filters_filter_functions_two_urls() { assert_eq!(render("tests/filter...
function filters_filter_functions_url_and_grayscale (line 396) | fn filters_filter_functions_url_and_grayscale() { assert_eq!(render("tes...
function filters_flood_color_hsla_color (line 397) | fn filters_flood_color_hsla_color() { assert_eq!(render("tests/filters/f...
function filters_flood_color_inheritance_1 (line 398) | fn filters_flood_color_inheritance_1() { assert_eq!(render("tests/filter...
function filters_flood_color_inheritance_2 (line 399) | fn filters_flood_color_inheritance_2() { assert_eq!(render("tests/filter...
function filters_flood_color_inheritance_3 (line 400) | fn filters_flood_color_inheritance_3() { assert_eq!(render("tests/filter...
function filters_flood_color_inheritance_4 (line 401) | fn filters_flood_color_inheritance_4() { assert_eq!(render("tests/filter...
function filters_flood_color_inheritance_5 (line 402) | fn filters_flood_color_inheritance_5() { assert_eq!(render("tests/filter...
function filters_flood_color_simple_case (line 403) | fn filters_flood_color_simple_case() { assert_eq!(render("tests/filters/...
function filters_flood_opacity_50percent (line 404) | fn filters_flood_opacity_50percent() { assert_eq!(render("tests/filters/...
function filters_flood_opacity_simple_case (line 405) | fn filters_flood_opacity_simple_case() { assert_eq!(render("tests/filter...
function masking_clip_simple_case (line 406) | fn masking_clip_simple_case() { assert_eq!(render("tests/masking/clip/si...
function masking_clip_rule_clip_rule_eq_evenodd (line 407) | fn masking_clip_rule_clip_rule_eq_evenodd() { assert_eq!(render("tests/m...
function masking_clipPath_circle_shorthand_with_stroke_box (line 408) | fn masking_clipPath_circle_shorthand_with_stroke_box() { assert_eq!(rend...
function masking_clipPath_circle_shorthand_with_view_box (line 409) | fn masking_clipPath_circle_shorthand_with_view_box() { assert_eq!(render...
function masking_clipPath_circle_shorthand (line 410) | fn masking_clipPath_circle_shorthand() { assert_eq!(render("tests/maskin...
function masking_clipPath_clip_path_on_child_with_transform (line 411) | fn masking_clipPath_clip_path_on_child_with_transform() { assert_eq!(ren...
function masking_clipPath_clip_path_on_child (line 412) | fn masking_clipPath_clip_path_on_child() { assert_eq!(render("tests/mask...
function masking_clipPath_clip_path_on_children (line 413) | fn masking_clipPath_clip_path_on_children() { assert_eq!(render("tests/m...
function masking_clipPath_clip_path_on_self_2 (line 414) | fn masking_clipPath_clip_path_on_self_2() { assert_eq!(render("tests/mas...
function masking_clipPath_clip_path_on_self (line 415) | fn masking_clipPath_clip_path_on_self() { assert_eq!(render("tests/maski...
function masking_clipPath_clip_path_with_transform_on_text (line 416) | fn masking_clipPath_clip_path_with_transform_on_text() { assert_eq!(rend...
function masking_clipPath_clip_path_with_transform (line 417) | fn masking_clipPath_clip_path_with_transform() { assert_eq!(render("test...
function masking_clipPath_clip_rule_from_parent_node (line 418) | fn masking_clipPath_clip_rule_from_parent_node() { assert_eq!(render("te...
function masking_clipPath_clip_rule_eq_evenodd (line 419) | fn masking_clipPath_clip_rule_eq_evenodd() { assert_eq!(render("tests/ma...
function masking_clipPath_clipPathUnits_eq_objectBoundingBox (line 420) | fn masking_clipPath_clipPathUnits_eq_objectBoundingBox() { assert_eq!(re...
function masking_clipPath_clipping_with_complex_text_1 (line 421) | fn masking_clipPath_clipping_with_complex_text_1() { assert_eq!(render("...
function masking_clipPath_clipping_with_complex_text_2 (line 422) | fn masking_clipPath_clipping_with_complex_text_2() { assert_eq!(render("...
function masking_clipPath_clipping_with_complex_text_and_clip_rule (line 423) | fn masking_clipPath_clipping_with_complex_text_and_clip_rule() { assert_...
function masking_clipPath_clipping_with_text (line 424) | fn masking_clipPath_clipping_with_text() { assert_eq!(render("tests/mask...
function masking_clipPath_fill_has_no_effect (line 425) | fn masking_clipPath_fill_has_no_effect() { assert_eq!(render("tests/mask...
function masking_clipPath_filter_has_no_effect (line 426) | fn masking_clipPath_filter_has_no_effect() { assert_eq!(render("tests/ma...
function masking_clipPath_g_is_not_a_valid_child (line 427) | fn masking_clipPath_g_is_not_a_valid_child() { assert_eq!(render("tests/...
function masking_clipPath_image_is_not_a_valid_child (line 428) | fn masking_clipPath_image_is_not_a_valid_child() { assert_eq!(render("te...
function masking_clipPath_invalid_FuncIRI (line 429) | fn masking_clipPath_invalid_FuncIRI() { assert_eq!(render("tests/masking...
function masking_clipPath_invalid_clip_path_on_child (line 430) | fn masking_clipPath_invalid_clip_path_on_child() { assert_eq!(render("te...
function masking_clipPath_invalid_clip_path_on_self (line 431) | fn masking_clipPath_invalid_clip_path_on_self() { assert_eq!(render("tes...
function masking_clipPath_invalid_transform_on_clipPath (line 432) | fn masking_clipPath_invalid_transform_on_clipPath() { assert_eq!(render(...
function masking_clipPath_invisible_child_1 (line 433) | fn masking_clipPath_invisible_child_1() { assert_eq!(render("tests/maski...
function masking_clipPath_invisible_child_2 (line 434) | fn masking_clipPath_invisible_child_2() { assert_eq!(render("tests/maski...
function masking_clipPath_line_is_not_a_valid_child (line 435) | fn masking_clipPath_line_is_not_a_valid_child() { assert_eq!(render("tes...
function masking_clipPath_malformed_path_child (line 436) | fn masking_clipPath_malformed_path_child() { assert_eq!(render("tests/ma...
function masking_clipPath_mask_has_no_effect (line 437) | fn masking_clipPath_mask_has_no_effect() { assert_eq!(render("tests/mask...
function masking_clipPath_mixed_clip_rule (line 438) | fn masking_clipPath_mixed_clip_rule() { assert_eq!(render("tests/masking...
function masking_clipPath_multiple_children (line 439) | fn masking_clipPath_multiple_children() { assert_eq!(render("tests/maski...
function masking_clipPath_nested_clip_path (line 440) | fn masking_clipPath_nested_clip_path() { assert_eq!(render("tests/maskin...
function masking_clipPath_no_children (line 441) | fn masking_clipPath_no_children() { assert_eq!(render("tests/masking/cli...
function masking_clipPath_none (line 442) | fn masking_clipPath_none() { assert_eq!(render("tests/masking/clipPath/n...
function masking_clipPath_on_a_horizontal_line (line 443) | fn masking_clipPath_on_a_horizontal_line() { assert_eq!(render("tests/ma...
function masking_clipPath_on_the_root_svg_with_size (line 444) | fn masking_clipPath_on_the_root_svg_with_size() { assert_eq!(render("tes...
function masking_clipPath_on_the_root_svg_without_size (line 445) | fn masking_clipPath_on_the_root_svg_without_size() { assert_eq!(render("...
function masking_clipPath_opacity_has_no_effect (line 446) | fn masking_clipPath_opacity_has_no_effect() { assert_eq!(render("tests/m...
function masking_clipPath_overlapped_shapes_with_evenodd (line 447) | fn masking_clipPath_overlapped_shapes_with_evenodd() { assert_eq!(render...
function masking_clipPath_recursive_on_child (line 448) | fn masking_clipPath_recursive_on_child() { assert_eq!(render("tests/mask...
function masking_clipPath_recursive_on_self (line 449) | fn masking_clipPath_recursive_on_self() { assert_eq!(render("tests/maski...
function masking_clipPath_recursive (line 450) | fn masking_clipPath_recursive() { assert_eq!(render("tests/masking/clipP...
function masking_clipPath_self_recursive (line 451) | fn masking_clipPath_self_recursive() { assert_eq!(render("tests/masking/...
function masking_clipPath_simple_case (line 452) | fn masking_clipPath_simple_case() { assert_eq!(render("tests/masking/cli...
function masking_clipPath_stroke_has_no_effect (line 453) | fn masking_clipPath_stroke_has_no_effect() { assert_eq!(render("tests/ma...
function masking_clipPath_switch_is_not_a_valid_child (line 454) | fn masking_clipPath_switch_is_not_a_valid_child() { assert_eq!(render("t...
function masking_clipPath_symbol_via_use_is_not_a_valid_child (line 455) | fn masking_clipPath_symbol_via_use_is_not_a_valid_child() { assert_eq!(r...
function masking_clipPath_transform_on_clipPath (line 456) | fn masking_clipPath_transform_on_clipPath() { assert_eq!(render("tests/m...
function masking_clipPath_with_invalid_child_via_use (line 457) | fn masking_clipPath_with_invalid_child_via_use() { assert_eq!(render("te...
function masking_clipPath_with_marker_on_clip (line 458) | fn masking_clipPath_with_marker_on_clip() { assert_eq!(render("tests/mas...
function masking_clipPath_with_use_child (line 459) | fn masking_clipPath_with_use_child() { assert_eq!(render("tests/masking/...
function masking_mask_color_interpolation_eq_linearRGB (line 460) | fn masking_mask_color_interpolation_eq_linearRGB() { assert_eq!(render("...
function masking_mask_half_width_region_with_rotation (line 461) | fn masking_mask_half_width_region_with_rotation() { assert_eq!(render("t...
function masking_mask_invalid_FuncIRI (line 462) | fn masking_mask_invalid_FuncIRI() { assert_eq!(render("tests/masking/mas...
function masking_mask_invalid_child (line 463) | fn masking_mask_invalid_child() { assert_eq!(render("tests/masking/mask/...
function masking_mask_invisible_child_1 (line 464) | fn masking_mask_invisible_child_1() { assert_eq!(render("tests/masking/m...
function masking_mask_invisible_child_2 (line 465) | fn masking_mask_invisible_child_2() { assert_eq!(render("tests/masking/m...
function masking_mask_mask_on_child (line 466) | fn masking_mask_mask_on_child() { assert_eq!(render("tests/masking/mask/...
function masking_mask_mask_on_self_with_mask_type_eq_alpha (line 467) | fn masking_mask_mask_on_self_with_mask_type_eq_alpha() { assert_eq!(rend...
function masking_mask_mask_on_self_with_mixed_mask_type (line 468) | fn masking_mask_mask_on_self_with_mixed_mask_type() { assert_eq!(render(...
function masking_mask_mask_on_self (line 469) | fn masking_mask_mask_on_self() { assert_eq!(render("tests/masking/mask/m...
function masking_mask_mask_type_in_style (line 470) | fn masking_mask_mask_type_in_style() { assert_eq!(render("tests/masking/...
function masking_mask_mask_type_eq_alpha (line 471) | fn masking_mask_mask_type_eq_alpha() { assert_eq!(render("tests/masking/...
function masking_mask_mask_type_eq_invalid (line 472) | fn masking_mask_mask_type_eq_invalid() { assert_eq!(render("tests/maskin...
function masking_mask_mask_type_eq_luminance (line 473) | fn masking_mask_mask_type_eq_luminance() { assert_eq!(render("tests/mask...
function masking_mask_maskContentUnits_eq_objectBoundingBox (line 474) | fn masking_mask_maskContentUnits_eq_objectBoundingBox() { assert_eq!(ren...
function masking_mask_maskUnits_eq_objectBoundingBox_with_percent (line 475) | fn masking_mask_maskUnits_eq_objectBoundingBox_with_percent() { assert_e...
function masking_mask_maskUnits_eq_userSpaceOnUse_with_percent (line 476) | fn masking_mask_maskUnits_eq_userSpaceOnUse_with_percent() { assert_eq!(...
function masking_mask_maskUnits_eq_userSpaceOnUse_with_rect (line 477) | fn masking_mask_maskUnits_eq_userSpaceOnUse_with_rect() { assert_eq!(ren...
function masking_mask_maskUnits_eq_userSpaceOnUse_with_width_only (line 478) | fn masking_mask_maskUnits_eq_userSpaceOnUse_with_width_only() { assert_e...
function masking_mask_maskUnits_eq_userSpaceOnUse_without_rect (line 479) | fn masking_mask_maskUnits_eq_userSpaceOnUse_without_rect() { assert_eq!(...
function masking_mask_nested_objectBoundingBox (line 480) | fn masking_mask_nested_objectBoundingBox() { assert_eq!(render("tests/ma...
function masking_mask_no_children (line 481) | fn masking_mask_no_children() { assert_eq!(render("tests/masking/mask/no...
function masking_mask_none (line 482) | fn masking_mask_none() { assert_eq!(render("tests/masking/mask/none"), 0...
function masking_mask_on_a_horizontal_line (line 483) | fn masking_mask_on_a_horizontal_line() { assert_eq!(render("tests/maskin...
function masking_mask_on_a_small_object (line 484) | fn masking_mask_on_a_small_object() { assert_eq!(render("tests/masking/m...
function masking_mask_on_group_with_transform (line 485) | fn masking_mask_on_group_with_transform() { assert_eq!(render("tests/mas...
function masking_mask_recursive_on_child (line 486) | fn masking_mask_recursive_on_child() { assert_eq!(render("tests/masking/...
function masking_mask_recursive_on_self (line 487) | fn masking_mask_recursive_on_self() { assert_eq!(render("tests/masking/m...
function masking_mask_recursive (line 488) | fn masking_mask_recursive() { assert_eq!(render("tests/masking/mask/recu...
function masking_mask_self_recursive (line 489) | fn masking_mask_self_recursive() { assert_eq!(render("tests/masking/mask...
function masking_mask_simple_case (line 490) | fn masking_mask_simple_case() { assert_eq!(render("tests/masking/mask/si...
function masking_mask_transform_has_no_effect (line 491) | fn masking_mask_transform_has_no_effect() { assert_eq!(render("tests/mas...
function masking_mask_transform_on_shape (line 492) | fn masking_mask_transform_on_shape() { assert_eq!(render("tests/masking/...
function masking_mask_with_clip_path (line 493) | fn masking_mask_with_clip_path() { assert_eq!(render("tests/masking/mask...
function masking_mask_with_grayscale_image (line 494) | fn masking_mask_with_grayscale_image() { assert_eq!(render("tests/maskin...
function masking_mask_with_image (line 495) | fn masking_mask_with_image() { assert_eq!(render("tests/masking/mask/wit...
function masking_mask_with_opacity_1 (line 496) | fn masking_mask_with_opacity_1() { assert_eq!(render("tests/masking/mask...
function masking_mask_with_opacity_2 (line 497) | fn masking_mask_with_opacity_2() { assert_eq!(render("tests/masking/mask...
function masking_mask_with_opacity_3 (line 498) | fn masking_mask_with_opacity_3() { assert_eq!(render("tests/masking/mask...
function paint_servers_linearGradient_attributes_via_xlink_href_complex_order (line 499) | fn paint_servers_linearGradient_attributes_via_xlink_href_complex_order(...
function paint_servers_linearGradient_attributes_via_xlink_href_from_radialGradient (line 500) | fn paint_servers_linearGradient_attributes_via_xlink_href_from_radialGra...
function paint_servers_linearGradient_attributes_via_xlink_href_from_rect (line 501) | fn paint_servers_linearGradient_attributes_via_xlink_href_from_rect() { ...
function paint_servers_linearGradient_attributes_via_xlink_href_only_required (line 502) | fn paint_servers_linearGradient_attributes_via_xlink_href_only_required(...
function paint_servers_linearGradient_attributes_via_xlink_href (line 503) | fn paint_servers_linearGradient_attributes_via_xlink_href() { assert_eq!...
function paint_servers_linearGradient_default_attributes (line 504) | fn paint_servers_linearGradient_default_attributes() { assert_eq!(render...
function paint_servers_linearGradient_gradientTransform_and_transform (line 505) | fn paint_servers_linearGradient_gradientTransform_and_transform() { asse...
function paint_servers_linearGradient_gradientTransform (line 506) | fn paint_servers_linearGradient_gradientTransform() { assert_eq!(render(...
function paint_servers_linearGradient_gradientUnits_eq_objectBoundingBox_with_percent (line 507) | fn paint_servers_linearGradient_gradientUnits_eq_objectBoundingBox_with_...
function paint_servers_linearGradient_gradientUnits_eq_userSpaceOnUse_with_percent (line 508) | fn paint_servers_linearGradient_gradientUnits_eq_userSpaceOnUse_with_per...
function paint_servers_linearGradient_gradientUnits_eq_userSpaceOnUse (line 509) | fn paint_servers_linearGradient_gradientUnits_eq_userSpaceOnUse() { asse...
function paint_servers_linearGradient_hsla_color (line 510) | fn paint_servers_linearGradient_hsla_color() { assert_eq!(render("tests/...
function paint_servers_linearGradient_invalid_child_1 (line 511) | fn paint_servers_linearGradient_invalid_child_1() { assert_eq!(render("t...
function paint_servers_linearGradient_invalid_child_2 (line 512) | fn paint_servers_linearGradient_invalid_child_2() { assert_eq!(render("t...
function paint_servers_linearGradient_invalid_child_3 (line 513) | fn paint_servers_linearGradient_invalid_child_3() { assert_eq!(render("t...
function paint_servers_linearGradient_invalid_gradientTransform (line 514) | fn paint_servers_linearGradient_invalid_gradientTransform() { assert_eq!...
function paint_servers_linearGradient_invalid_gradientUnits (line 515) | fn paint_servers_linearGradient_invalid_gradientUnits() { assert_eq!(ren...
function paint_servers_linearGradient_invalid_spreadMethod (line 516) | fn paint_servers_linearGradient_invalid_spreadMethod() { assert_eq!(rend...
function paint_servers_linearGradient_invalid_xlink_href (line 517) | fn paint_servers_linearGradient_invalid_xlink_href() { assert_eq!(render...
function paint_servers_linearGradient_many_stops (line 518) | fn paint_servers_linearGradient_many_stops() { assert_eq!(render("tests/...
function paint_servers_linearGradient_no_stops (line 519) | fn paint_servers_linearGradient_no_stops() { assert_eq!(render("tests/pa...
function paint_servers_linearGradient_recursive_xlink_href_1 (line 520) | fn paint_servers_linearGradient_recursive_xlink_href_1() { assert_eq!(re...
function paint_servers_linearGradient_recursive_xlink_href_2 (line 521) | fn paint_servers_linearGradient_recursive_xlink_href_2() { assert_eq!(re...
function paint_servers_linearGradient_recursive_xlink_href_3 (line 522) | fn paint_servers_linearGradient_recursive_xlink_href_3() { assert_eq!(re...
function paint_servers_linearGradient_self_recursive_xlink_href (line 523) | fn paint_servers_linearGradient_self_recursive_xlink_href() { assert_eq!...
function paint_servers_linearGradient_single_stop_with_opacity_used_by_fill_and_stroke (line 524) | fn paint_servers_linearGradient_single_stop_with_opacity_used_by_fill_an...
function paint_servers_linearGradient_single_stop_with_opacity_used_by_fill (line 525) | fn paint_servers_linearGradient_single_stop_with_opacity_used_by_fill() ...
function paint_servers_linearGradient_single_stop_with_opacity_used_by_stroke (line 526) | fn paint_servers_linearGradient_single_stop_with_opacity_used_by_stroke(...
function paint_servers_linearGradient_single_stop (line 527) | fn paint_servers_linearGradient_single_stop() { assert_eq!(render("tests...
function paint_servers_linearGradient_spreadMethod_eq_pad (line 528) | fn paint_servers_linearGradient_spreadMethod_eq_pad() { assert_eq!(rende...
function paint_servers_linearGradient_spreadMethod_eq_reflect (line 529) | fn paint_servers_linearGradient_spreadMethod_eq_reflect() { assert_eq!(r...
function paint_servers_linearGradient_spreadMethod_eq_repeat (line 530) | fn paint_servers_linearGradient_spreadMethod_eq_repeat() { assert_eq!(re...
function paint_servers_linearGradient_stops_via_xlink_href_complex_order_1 (line 531) | fn paint_servers_linearGradient_stops_via_xlink_href_complex_order_1() {...
function paint_servers_linearGradient_stops_via_xlink_href_complex_order_2 (line 532) | fn paint_servers_linearGradient_stops_via_xlink_href_complex_order_2() {...
function paint_servers_linearGradient_stops_via_xlink_href_from_radialGradient (line 533) | fn paint_servers_linearGradient_stops_via_xlink_href_from_radialGradient...
function paint_servers_linearGradient_stops_via_xlink_href_from_rect (line 534) | fn paint_servers_linearGradient_stops_via_xlink_href_from_rect() { asser...
function paint_servers_linearGradient_stops_via_xlink_href (line 535) | fn paint_servers_linearGradient_stops_via_xlink_href() { assert_eq!(rend...
function paint_servers_linearGradient_unresolved_xlink_href (line 536) | fn paint_servers_linearGradient_unresolved_xlink_href() { assert_eq!(ren...
function paint_servers_pattern_attributes_via_xlink_href (line 537) | fn paint_servers_pattern_attributes_via_xlink_href() { assert_eq!(render...
function paint_servers_pattern_child_with_invalid_FuncIRI (line 538) | fn paint_servers_pattern_child_with_invalid_FuncIRI() { assert_eq!(rende...
function paint_servers_pattern_children_via_xlink_href (line 539) | fn paint_servers_pattern_children_via_xlink_href() { assert_eq!(render("...
function paint_servers_pattern_display_eq_none_on_child (line 540) | fn paint_servers_pattern_display_eq_none_on_child() { assert_eq!(render(...
function paint_servers_pattern_everything_via_xlink_href (line 541) | fn paint_servers_pattern_everything_via_xlink_href() { assert_eq!(render...
function paint_servers_pattern_invalid_patternTransform (line 542) | fn paint_servers_pattern_invalid_patternTransform() { assert_eq!(render(...
function paint_servers_pattern_invalid_patternUnits_and_patternContentUnits (line 543) | fn paint_servers_pattern_invalid_patternUnits_and_patternContentUnits() ...
function paint_servers_pattern_missing_height (line 544) | fn paint_servers_pattern_missing_height() { assert_eq!(render("tests/pai...
function paint_servers_pattern_missing_width (line 545) | fn paint_servers_pattern_missing_width() { assert_eq!(render("tests/pain...
function paint_servers_pattern_nested_objectBoundingBox (line 546) | fn paint_servers_pattern_nested_objectBoundingBox() { assert_eq!(render(...
function paint_servers_pattern_no_children (line 547) | fn paint_servers_pattern_no_children() { assert_eq!(render("tests/paint-...
function paint_servers_pattern_out_of_order_referencing (line 548) | fn paint_servers_pattern_out_of_order_referencing() { assert_eq!(render(...
function paint_servers_pattern_overflow_eq_visible (line 549) | fn paint_servers_pattern_overflow_eq_visible() { assert_eq!(render("test...
function paint_servers_pattern_pattern_on_child (line 550) | fn paint_servers_pattern_pattern_on_child() { assert_eq!(render("tests/p...
function paint_servers_pattern_patternContentUnits_with_viewBox (line 551) | fn paint_servers_pattern_patternContentUnits_with_viewBox() { assert_eq!...
function paint_servers_pattern_patternContentUnits_eq_objectBoundingBox (line 552) | fn paint_servers_pattern_patternContentUnits_eq_objectBoundingBox() { as...
function paint_servers_pattern_patternUnits_eq_objectBoundingBox_with_percent (line 553) | fn paint_servers_pattern_patternUnits_eq_objectBoundingBox_with_percent(...
function paint_servers_pattern_patternUnits_eq_objectBoundingBox (line 554) | fn paint_servers_pattern_patternUnits_eq_objectBoundingBox() { assert_eq...
function paint_servers_pattern_patternUnits_eq_userSpaceOnUse_with_percent (line 555) | fn paint_servers_pattern_patternUnits_eq_userSpaceOnUse_with_percent() {...
function paint_servers_pattern_preserveAspectRatio (line 556) | fn paint_servers_pattern_preserveAspectRatio() { assert_eq!(render("test...
function paint_servers_pattern_recursive_on_child (line 557) | fn paint_servers_pattern_recursive_on_child() { assert_eq!(render("tests...
function paint_servers_pattern_self_recursive_on_child (line 558) | fn paint_servers_pattern_self_recursive_on_child() { assert_eq!(render("...
function paint_servers_pattern_self_recursive (line 559) | fn paint_servers_pattern_self_recursive() { assert_eq!(render("tests/pai...
function paint_servers_pattern_simple_case (line 560) | fn paint_servers_pattern_simple_case() { assert_eq!(render("tests/paint-...
function paint_servers_pattern_text_child (line 561) | fn paint_servers_pattern_text_child() { assert_eq!(render("tests/paint-s...
function paint_servers_pattern_tiny_pattern_upscaled (line 562) | fn paint_servers_pattern_tiny_pattern_upscaled() { assert_eq!(render("te...
function paint_servers_pattern_transform_and_patternTransform (line 563) | fn paint_servers_pattern_transform_and_patternTransform() { assert_eq!(r...
function paint_servers_pattern_viewBox_via_xlink_href (line 564) | fn paint_servers_pattern_viewBox_via_xlink_href() { assert_eq!(render("t...
function paint_servers_pattern_with_patternTransform (line 565) | fn paint_servers_pattern_with_patternTransform() { assert_eq!(render("te...
function paint_servers_pattern_with_viewBox (line 566) | fn paint_servers_pattern_with_viewBox() { assert_eq!(render("tests/paint...
function paint_servers_pattern_with_x_and_y (line 567) | fn paint_servers_pattern_with_x_and_y() { assert_eq!(render("tests/paint...
function paint_servers_radialGradient_attributes_via_xlink_href_complex_order (line 568) | fn paint_servers_radialGradient_attributes_via_xlink_href_complex_order(...
function paint_servers_radialGradient_attributes_via_xlink_href_from_linearGradient (line 569) | fn paint_servers_radialGradient_attributes_via_xlink_href_from_linearGra...
function paint_servers_radialGradient_attributes_via_xlink_href_from_rect (line 570) | fn paint_servers_radialGradient_attributes_via_xlink_href_from_rect() { ...
function paint_servers_radialGradient_attributes_via_xlink_href_only_required (line 571) | fn paint_servers_radialGradient_attributes_via_xlink_href_only_required(...
function paint_servers_radialGradient_attributes_via_xlink_href (line 572) | fn paint_servers_radialGradient_attributes_via_xlink_href() { assert_eq!...
function paint_servers_radialGradient_default_attributes (line 573) | fn paint_servers_radialGradient_default_attributes() { assert_eq!(render...
function paint_servers_radialGradient_fr_eq__1 (line 574) | fn paint_servers_radialGradient_fr_eq__1() { assert_eq!(render("tests/pa...
function paint_servers_radialGradient_fr_eq_0_2 (line 575) | fn paint_servers_radialGradient_fr_eq_0_2() { assert_eq!(render("tests/p...
function paint_servers_radialGradient_fr_eq_0_5 (line 576) | fn paint_servers_radialGradient_fr_eq_0_5() { assert_eq!(render("tests/p...
function paint_servers_radialGradient_fr_eq_0_7 (line 577) | fn paint_servers_radialGradient_fr_eq_0_7() { assert_eq!(render("tests/p...
function paint_servers_radialGradient_fx_resolving_1 (line 578) | fn paint_servers_radialGradient_fx_resolving_1() { assert_eq!(render("te...
function paint_servers_radialGradient_fx_resolving_2 (line 579) | fn paint_servers_radialGradient_fx_resolving_2() { assert_eq!(render("te...
function paint_servers_radialGradient_fx_resolving_3 (line 580) | fn paint_servers_radialGradient_fx_resolving_3() { assert_eq!(render("te...
function paint_servers_radialGradient_fy_resolving_1 (line 581) | fn paint_servers_radialGradient_fy_resolving_1() { assert_eq!(render("te...
function paint_servers_radialGradient_fy_resolving_2 (line 582) | fn paint_servers_radialGradient_fy_resolving_2() { assert_eq!(render("te...
function paint_servers_radialGradient_fy_resolving_3 (line 583) | fn paint_servers_radialGradient_fy_resolving_3() { assert_eq!(render("te...
function paint_servers_radialGradient_gradientTransform_and_transform (line 584) | fn paint_servers_radialGradient_gradientTransform_and_transform() { asse...
function paint_servers_radialGradient_gradientTransform (line 585) | fn paint_servers_radialGradient_gradientTransform() { assert_eq!(render(...
function paint_servers_radialGradient_gradientUnits_eq_objectBoundingBox_with_percent (line 586) | fn paint_servers_radialGradient_gradientUnits_eq_objectBoundingBox_with_...
function paint_servers_radialGradient_gradientUnits_eq_userSpaceOnUse_with_percent (line 587) | fn paint_servers_radialGradient_gradientUnits_eq_userSpaceOnUse_with_per...
function paint_servers_radialGradient_gradientUnits_eq_userSpaceOnUse (line 588) | fn paint_servers_radialGradient_gradientUnits_eq_userSpaceOnUse() { asse...
function paint_servers_radialGradient_hsla_color (line 589) | fn paint_servers_radialGradient_hsla_color() { assert_eq!(render("tests/...
function paint_servers_radialGradient_invalid_gradientTransform (line 590) | fn paint_servers_radialGradient_invalid_gradientTransform() { assert_eq!...
function paint_servers_radialGradient_invalid_gradientUnits (line 591) | fn paint_servers_radialGradient_invalid_gradientUnits() { assert_eq!(ren...
function paint_servers_radialGradient_invalid_spreadMethod (line 592) | fn paint_servers_radialGradient_invalid_spreadMethod() { assert_eq!(rend...
function paint_servers_radialGradient_invalid_xlink_href (line 593) | fn paint_servers_radialGradient_invalid_xlink_href() { assert_eq!(render...
function paint_servers_radialGradient_many_stops (line 594) | fn paint_servers_radialGradient_many_stops() { assert_eq!(render("tests/...
function paint_servers_radialGradient_negative_r (line 595) | fn paint_servers_radialGradient_negative_r() { assert_eq!(render("tests/...
function paint_servers_radialGradient_no_stops (line 596) | fn paint_servers_radialGradient_no_stops() { assert_eq!(render("tests/pa...
function paint_servers_radialGradient_recursive_xlink_href (line 597) | fn paint_servers_radialGradient_recursive_xlink_href() { assert_eq!(rend...
function paint_servers_radialGradient_self_recursive_xlink_href (line 598) | fn paint_servers_radialGradient_self_recursive_xlink_href() { assert_eq!...
function paint_servers_radialGradient_single_stop (line 599) | fn paint_servers_radialGradient_single_stop() { assert_eq!(render("tests...
function paint_servers_radialGradient_spreadMethod_eq_pad (line 600) | fn paint_servers_radialGradient_spreadMethod_eq_pad() { assert_eq!(rende...
function paint_servers_radialGradient_spreadMethod_eq_reflect (line 601) | fn paint_servers_radialGradient_spreadMethod_eq_reflect() { assert_eq!(r...
function paint_servers_radialGradient_spreadMethod_eq_repeat (line 602) | fn paint_servers_radialGradient_spreadMethod_eq_repeat() { assert_eq!(re...
function paint_servers_radialGradient_stops_via_xlink_href_complex_order (line 603) | fn paint_servers_radialGradient_stops_via_xlink_href_complex_order() { a...
function paint_servers_radialGradient_stops_via_xlink_href_from_linearGradient (line 604) | fn paint_servers_radialGradient_stops_via_xlink_href_from_linearGradient...
function paint_servers_radialGradient_stops_via_xlink_href_from_rect (line 605) | fn paint_servers_radialGradient_stops_via_xlink_href_from_rect() { asser...
function paint_servers_radialGradient_stops_via_xlink_href (line 606) | fn paint_servers_radialGradient_stops_via_xlink_href() { assert_eq!(rend...
function paint_servers_radialGradient_unresolved_xlink_href (line 607) | fn paint_servers_radialGradient_unresolved_xlink_href() { assert_eq!(ren...
function paint_servers_radialGradient_xlink_href_not_to_gradient (line 608) | fn paint_servers_radialGradient_xlink_href_not_to_gradient() { assert_eq...
function paint_servers_radialGradient_zero_r_with_stop_opacity_1 (line 609) | fn paint_servers_radialGradient_zero_r_with_stop_opacity_1() { assert_eq...
function paint_servers_radialGradient_zero_r_with_stop_opacity_2 (line 610) | fn paint_servers_radialGradient_zero_r_with_stop_opacity_2() { assert_eq...
function paint_servers_radialGradient_zero_r (line 611) | fn paint_servers_radialGradient_zero_r() { assert_eq!(render("tests/pain...
function paint_servers_stop_equal_stop_color (line 612) | fn paint_servers_stop_equal_stop_color() { assert_eq!(render("tests/pain...
function paint_servers_stop_hsla_color (line 613) | fn paint_servers_stop_hsla_color() { assert_eq!(render("tests/paint-serv...
function paint_servers_stop_invalid_offset_1 (line 614) | fn paint_servers_stop_invalid_offset_1() { assert_eq!(render("tests/pain...
function paint_servers_stop_invalid_offset_2 (line 615) | fn paint_servers_stop_invalid_offset_2() { assert_eq!(render("tests/pain...
function paint_servers_stop_missing_offset_1 (line 616) | fn paint_servers_stop_missing_offset_1() { assert_eq!(render("tests/pain...
function paint_servers_stop_missing_offset_2 (line 617) | fn paint_servers_stop_missing_offset_2() { assert_eq!(render("tests/pain...
function paint_servers_stop_missing_offset_3 (line 618) | fn paint_servers_stop_missing_offset_3() { assert_eq!(render("tests/pain...
function paint_servers_stop_missing_offset_4 (line 619) | fn paint_servers_stop_missing_offset_4() { assert_eq!(render("tests/pain...
function paint_servers_stop_missing_offset_5 (line 620) | fn paint_servers_stop_missing_offset_5() { assert_eq!(render("tests/pain...
function paint_servers_stop_missing_offset_6 (line 621) | fn paint_servers_stop_missing_offset_6() { assert_eq!(render("tests/pain...
function paint_servers_stop_missing_offset_7 (line 622) | fn paint_servers_stop_missing_offset_7() { assert_eq!(render("tests/pain...
function paint_servers_stop_no_stop_color (line 623) | fn paint_servers_stop_no_stop_color() { assert_eq!(render("tests/paint-s...
function paint_servers_stop_offset_clamping_with_percent (line 624) | fn paint_servers_stop_offset_clamping_with_percent() { assert_eq!(render...
function paint_servers_stop_offset_clamping (line 625) | fn paint_servers_stop_offset_clamping() { assert_eq!(render("tests/paint...
function paint_servers_stop_offset_with_percent (line 626) | fn paint_servers_stop_offset_with_percent() { assert_eq!(render("tests/p...
function paint_servers_stop_stop_color_with_currentColor_1 (line 627) | fn paint_servers_stop_stop_color_with_currentColor_1() { assert_eq!(rend...
function paint_servers_stop_stop_color_with_currentColor_2 (line 628) | fn paint_servers_stop_stop_color_with_currentColor_2() { assert_eq!(rend...
function paint_servers_stop_stop_color_with_currentColor_3 (line 629) | fn paint_servers_stop_stop_color_with_currentColor_3() { assert_eq!(rend...
function paint_servers_stop_stop_color_with_currentColor_4 (line 630) | fn paint_servers_stop_stop_color_with_currentColor_4() { assert_eq!(rend...
function paint_servers_stop_stop_color_with_inherit_1 (line 631) | fn paint_servers_stop_stop_color_with_inherit_1() { assert_eq!(render("t...
function paint_servers_stop_stop_color_with_inherit_2 (line 632) | fn paint_servers_stop_stop_color_with_inherit_2() { assert_eq!(render("t...
function paint_servers_stop_stop_color_with_inherit_3 (line 633) | fn paint_servers_stop_stop_color_with_inherit_3() { assert_eq!(render("t...
function paint_servers_stop_stop_color_with_inherit_4 (line 634) | fn paint_servers_stop_stop_color_with_inherit_4() { assert_eq!(render("t...
function paint_servers_stop_stop_color_with_inherit_5 (line 635) | fn paint_servers_stop_stop_color_with_inherit_5() { assert_eq!(render("t...
function paint_servers_stop_stop_with_smaller_offset (line 636) | fn paint_servers_stop_stop_with_smaller_offset() { assert_eq!(render("te...
function paint_servers_stop_stops_with_equal_offset_1 (line 637) | fn paint_servers_stop_stops_with_equal_offset_1() { assert_eq!(render("t...
function paint_servers_stop_stops_with_equal_offset_2 (line 638) | fn paint_servers_stop_stops_with_equal_offset_2() { assert_eq!(render("t...
function paint_servers_stop_stops_with_equal_offset_3 (line 639) | fn paint_servers_stop_stops_with_equal_offset_3() { assert_eq!(render("t...
function paint_servers_stop_stops_with_equal_offset_4 (line 640) | fn paint_servers_stop_stops_with_equal_offset_4() { assert_eq!(render("t...
function paint_servers_stop_stops_with_equal_offset_5 (line 641) | fn paint_servers_stop_stops_with_equal_offset_5() { assert_eq!(render("t...
function paint_servers_stop_stops_with_equal_offset_6 (line 642) | fn paint_servers_stop_stops_with_equal_offset_6() { assert_eq!(render("t...
function paint_servers_stop_zero_offset_in_the_middle (line 643) | fn paint_servers_stop_zero_offset_in_the_middle() { assert_eq!(render("t...
function paint_servers_stop_color_simple_case (line 644) | fn paint_servers_stop_color_simple_case() { assert_eq!(render("tests/pai...
function paint_servers_stop_opacity_50percent (line 645) | fn paint_servers_stop_opacity_50percent() { assert_eq!(render("tests/pai...
function paint_servers_stop_opacity_simple_case (line 646) | fn paint_servers_stop_opacity_simple_case() { assert_eq!(render("tests/p...
function painting_color_inherit (line 647) | fn painting_color_inherit() { assert_eq!(render("tests/painting/color/in...
function painting_color_recursive_nested_context_without_color (line 648) | fn painting_color_recursive_nested_context_without_color() { assert_eq!(...
function painting_color_recursive_nested_context (line 649) | fn painting_color_recursive_nested_context() { assert_eq!(render("tests/...
function painting_color_simple_case (line 650) | fn painting_color_simple_case() { assert_eq!(render("tests/painting/colo...
function painting_context_in_marker (line 651) | fn painting_context_in_marker() { assert_eq!(render("tests/painting/cont...
function painting_context_in_nested_marker (line 652) | fn painting_context_in_nested_marker() { assert_eq!(render("tests/painti...
function painting_context_in_nested_use_and_marker (line 653) | fn painting_context_in_nested_use_and_marker() { assert_eq!(render("test...
function painting_context_in_nested_use (line 654) | fn painting_context_in_nested_use() { assert_eq!(render("tests/painting/...
function painting_context_in_use (line 655) | fn painting_context_in_use() { assert_eq!(render("tests/painting/context...
function painting_context_on_shape_with_zero_size_bbox (line 656) | fn painting_context_on_shape_with_zero_size_bbox() { assert_eq!(render("...
function painting_context_with_gradient_and_gradient_transform (line 657) | fn painting_context_with_gradient_and_gradient_transform() { assert_eq!(...
function painting_context_with_gradient_in_use (line 658) | fn painting_context_with_gradient_in_use() { assert_eq!(render("tests/pa...
function painting_context_with_gradient_on_marker (line 659) | fn painting_context_with_gradient_on_marker() { assert_eq!(render("tests...
function painting_context_with_pattern_and_transform_in_use (line 660) | fn painting_context_with_pattern_and_transform_in_use() { assert_eq!(ren...
function painting_context_with_pattern_in_use (line 661) | fn painting_context_with_pattern_in_use() { assert_eq!(render("tests/pai...
function painting_context_with_pattern_objectBoundingBox_in_use (line 662) | fn painting_context_with_pattern_objectBoundingBox_in_use() { assert_eq!...
function painting_context_with_pattern_on_marker (line 663) | fn painting_context_with_pattern_on_marker() { assert_eq!(render("tests/...
function painting_context_with_text (line 664) | fn painting_context_with_text() { assert_eq!(render("tests/painting/cont...
function painting_context_with_viewbox (line 665) | fn painting_context_with_viewbox() { assert_eq!(render("tests/painting/c...
function painting_context_without_context_element (line 666) | fn painting_context_without_context_element() { assert_eq!(render("tests...
function painting_display_bBox_impact (line 667) | fn painting_display_bBox_impact() { assert_eq!(render("tests/painting/di...
function painting_display_none_on_clipPath (line 668) | fn painting_display_none_on_clipPath() { assert_eq!(render("tests/painti...
function painting_display_none_on_defs (line 669) | fn painting_display_none_on_defs() { assert_eq!(render("tests/painting/d...
function painting_display_none_on_linearGradient (line 670) | fn painting_display_none_on_linearGradient() { assert_eq!(render("tests/...
function painting_display_none_on_rect (line 671) | fn painting_display_none_on_rect() { assert_eq!(render("tests/painting/d...
function painting_display_none_on_svg (line 672) | fn painting_display_none_on_svg() { assert_eq!(render("tests/painting/di...
function painting_display_none_on_tref (line 673) | fn painting_display_none_on_tref() { assert_eq!(render("tests/painting/d...
function painting_display_none_on_tspan_1 (line 674) | fn painting_display_none_on_tspan_1() { assert_eq!(render("tests/paintin...
function painting_display_none_on_tspan_2 (line 675) | fn painting_display_none_on_tspan_2() { assert_eq!(render("tests/paintin...
function painting_fill_RGB_color (line 676) | fn painting_fill_RGB_color() { assert_eq!(render("tests/painting/fill/#R...
function painting_fill_RGBA (line 677) | fn painting_fill_RGBA() { assert_eq!(render("tests/painting/fill/#RGBA")...
function painting_fill_RRGGBB_color (line 678) | fn painting_fill_RRGGBB_color() { assert_eq!(render("tests/painting/fill...
function painting_fill_RRGGBB_uppercase_color (line 679) | fn painting_fill_RRGGBB_uppercase_color() { assert_eq!(render("tests/pai...
function painting_fill_RRGGBBAA (line 680) | fn painting_fill_RRGGBBAA() { assert_eq!(render("tests/painting/fill/#RR...
function painting_fill_currentColor_without_parent (line 681) | fn painting_fill_currentColor_without_parent() { assert_eq!(render("test...
function painting_fill_currentColor (line 682) | fn painting_fill_currentColor() { assert_eq!(render("tests/painting/fill...
function painting_fill_double_inherit (line 683) | fn painting_fill_double_inherit() { assert_eq!(render("tests/painting/fi...
function painting_fill_funcIRI_to_a_missing_element_with_a_fallback_color (line 684) | fn painting_fill_funcIRI_to_a_missing_element_with_a_fallback_color() { ...
function painting_fill_funcIRI_to_a_missing_element_with_a_none_fallback (line 685) | fn painting_fill_funcIRI_to_a_missing_element_with_a_none_fallback() { a...
function painting_fill_funcIRI_to_an_invalid_element_with_a_none_fallback (line 686) | fn painting_fill_funcIRI_to_an_invalid_element_with_a_none_fallback() { ...
function painting_fill_funcIRI_to_an_unsupported_element (line 687) | fn painting_fill_funcIRI_to_an_unsupported_element() { assert_eq!(render...
function painting_fill_funcIRI_with_a_fallback_color (line 688) | fn painting_fill_funcIRI_with_a_fallback_color() { assert_eq!(render("te...
function painting_fill_hsl_120_100percent_25percent (line 689) | fn painting_fill_hsl_120_100percent_25percent() { assert_eq!(render("tes...
function painting_fill_hsl_120_200percent_25percent (line 690) | fn painting_fill_hsl_120_200percent_25percent() { assert_eq!(render("tes...
function painting_fill_hsl_360_100percent_25percent (line 691) | fn painting_fill_hsl_360_100percent_25percent() { assert_eq!(render("tes...
function painting_fill_hsl_999_100percent_25percent (line 692) | fn painting_fill_hsl_999_100percent_25percent() { assert_eq!(render("tes...
function painting_fill_hsl_with_alpha (line 693) | fn painting_fill_hsl_with_alpha() { assert_eq!(render("tests/painting/fi...
function painting_fill_hsla_with_percentage_s_and_l_values (line 694) | fn painting_fill_hsla_with_percentage_s_and_l_values() { assert_eq!(rend...
function painting_fill_icc_color (line 695) | fn painting_fill_icc_color() { assert_eq!(render("tests/painting/fill/ic...
function painting_fill_inherit_without_parent (line 696) | fn painting_fill_inherit_without_parent() { assert_eq!(render("tests/pai...
function painting_fill_inherit (line 697) | fn painting_fill_inherit() { assert_eq!(render("tests/painting/fill/inhe...
function painting_fill_invalid_RRGGBB_1 (line 698) | fn painting_fill_invalid_RRGGBB_1() { assert_eq!(render("tests/painting/...
function painting_fill_invalid_RRGGBB_2 (line 699) | fn painting_fill_invalid_RRGGBB_2() { assert_eq!(render("tests/painting/...
function painting_fill_invalid_RRGGBB_3 (line 700) | fn painting_fill_invalid_RRGGBB_3() { assert_eq!(render("tests/painting/...
function painting_fill_invalid_FuncIRI_with_a_currentColor_fallback (line 701) | fn painting_fill_invalid_FuncIRI_with_a_currentColor_fallback() { assert...
function painting_fill_invalid_FuncIRI_with_a_fallback_color (line 702) | fn painting_fill_invalid_FuncIRI_with_a_fallback_color() { assert_eq!(re...
function painting_fill_linear_gradient_on_shape (line 703) | fn painting_fill_linear_gradient_on_shape() { assert_eq!(render("tests/p...
function painting_fill_linear_gradient_on_text (line 704) | fn painting_fill_linear_gradient_on_text() { assert_eq!(render("tests/pa...
function painting_fill_missing_FuncIRI_with_a_currentColor_fallback (line 705) | fn painting_fill_missing_FuncIRI_with_a_currentColor_fallback() { assert...
function painting_fill_named_color_in_mixedcase (line 706) | fn painting_fill_named_color_in_mixedcase() { assert_eq!(render("tests/p...
function painting_fill_named_color_in_uppercase (line 707) | fn painting_fill_named_color_in_uppercase() { assert_eq!(render("tests/p...
function painting_fill_named_color (line 708) | fn painting_fill_named_color() { assert_eq!(render("tests/painting/fill/...
function painting_fill_none (line 709) | fn painting_fill_none() { assert_eq!(render("tests/painting/fill/none"),...
function painting_fill_not_trimmed_attribute_value (line 710) | fn painting_fill_not_trimmed_attribute_value() { assert_eq!(render("test...
function painting_fill_pattern_on_shape (line 711) | fn painting_fill_pattern_on_shape() { assert_eq!(render("tests/painting/...
function painting_fill_pattern_on_text (line 712) | fn painting_fill_pattern_on_text() { assert_eq!(render("tests/painting/f...
function painting_fill_radial_gradient_on_shape (line 713) | fn painting_fill_radial_gradient_on_shape() { assert_eq!(render("tests/p...
function painting_fill_radial_gradient_on_text (line 714) | fn painting_fill_radial_gradient_on_text() { assert_eq!(render("tests/pa...
function painting_fill_random_value (line 715) | fn painting_fill_random_value() { assert_eq!(render("tests/painting/fill...
function painting_fill_rgb_0_127_0_0_5 (line 716) | fn painting_fill_rgb_0_127_0_0_5() { assert_eq!(render("tests/painting/f...
function painting_fill_rgb_color_with_a_big_fraction_part (line 717) | fn painting_fill_rgb_color_with_a_big_fraction_part() { assert_eq!(rende...
function painting_fill_rgb_color_with_extra_spaces (line 718) | fn painting_fill_rgb_color_with_extra_spaces() { assert_eq!(render("test...
function painting_fill_rgb_color_with_float_percentage_values (line 719) | fn painting_fill_rgb_color_with_float_percentage_values() { assert_eq!(r...
function painting_fill_rgb_color_with_floats (line 720) | fn painting_fill_rgb_color_with_floats() { assert_eq!(render("tests/pain...
function painting_fill_rgb_color_with_percentage_overflow (line 721) | fn painting_fill_rgb_color_with_percentage_overflow() { assert_eq!(rende...
function painting_fill_rgb_color_with_percentage_values (line 722) | fn painting_fill_rgb_color_with_percentage_values() { assert_eq!(render(...
function painting_fill_rgb_color (line 723) | fn painting_fill_rgb_color() { assert_eq!(render("tests/painting/fill/rg...
function painting_fill_rgb_int_int_int (line 724) | fn painting_fill_rgb_int_int_int() { assert_eq!(render("tests/painting/f...
function painting_fill_rgba_0_127_0__1 (line 725) | fn painting_fill_rgba_0_127_0__1() { assert_eq!(render("tests/painting/f...
function painting_fill_rgba_0_127_0_0_5 (line 726) | fn painting_fill_rgba_0_127_0_0_5() { assert_eq!(render("tests/painting/...
function painting_fill_rgba_0_127_0_0 (line 727) | fn painting_fill_rgba_0_127_0_0() { assert_eq!(render("tests/painting/fi...
function painting_fill_rgba_0_127_0_1 (line 728) | fn painting_fill_rgba_0_127_0_1() { assert_eq!(render("tests/painting/fi...
function painting_fill_rgba_0_127_0_2 (line 729) | fn painting_fill_rgba_0_127_0_2() { assert_eq!(render("tests/painting/fi...
function painting_fill_rgba_0_127_0_50percent (line 730) | fn painting_fill_rgba_0_127_0_50percent() { assert_eq!(render("tests/pai...
function painting_fill_rgba_0_50percent_0_0_5 (line 731) | fn painting_fill_rgba_0_50percent_0_0_5() { assert_eq!(render("tests/pai...
function painting_fill_rgba_0percent_50percent_0percent_0_5 (line 732) | fn painting_fill_rgba_0percent_50percent_0percent_0_5() { assert_eq!(ren...
function painting_fill_transparent (line 733) | fn painting_fill_transparent() { assert_eq!(render("tests/painting/fill/...
function painting_fill_uppercase_rgb_color (line 734) | fn painting_fill_uppercase_rgb_color() { assert_eq!(render("tests/painti...
function painting_fill_valid_FuncIRI_with_a_fallback_ICC_color (line 735) | fn painting_fill_valid_FuncIRI_with_a_fallback_ICC_color() { assert_eq!(...
function painting_fill_opacity_50percent (line 736) | fn painting_fill_opacity_50percent() { assert_eq!(render("tests/painting...
function painting_fill_opacity_half_opacity (line 737) | fn painting_fill_opacity_half_opacity() { assert_eq!(render("tests/paint...
function painting_fill_opacity_nested (line 738) | fn painting_fill_opacity_nested() { assert_eq!(render("tests/painting/fi...
function painting_fill_opacity_on_parent (line 739) | fn painting_fill_opacity_on_parent() { assert_eq!(render("tests/painting...
function painting_fill_opacity_on_text (line 740) | fn painting_fill_opacity_on_text() { assert_eq!(render("tests/painting/f...
function painting_fill_opacity_with_linearGradient (line 741) | fn painting_fill_opacity_with_linearGradient() { assert_eq!(render("test...
function painting_fill_opacity_with_opacity (line 742) | fn painting_fill_opacity_with_opacity() { assert_eq!(render("tests/paint...
function painting_fill_opacity_with_pattern (line 743) | fn painting_fill_opacity_with_pattern() { assert_eq!(render("tests/paint...
function painting_fill_rule_evenodd (line 744) | fn painting_fill_rule_evenodd() { assert_eq!(render("tests/painting/fill...
function painting_fill_rule_nonzero (line 745) | fn painting_fill_rule_nonzero() { assert_eq!(render("tests/painting/fill...
function painting_image_rendering_high_quality (line 746) | fn painting_image_rendering_high_quality() { assert_eq!(render("tests/pa...
function painting_image_rendering_on_feImage (line 747) | fn painting_image_rendering_on_feImage() { assert_eq!(render("tests/pain...
function painting_image_rendering_optimizeSpeed_on_SVG (line 748) | fn painting_image_rendering_optimizeSpeed_on_SVG() { assert_eq!(render("...
function painting_image_rendering_optimizeSpeed (line 749) | fn painting_image_rendering_optimizeSpeed() { assert_eq!(render("tests/p...
function painting_isolation_as_property (line 750) | fn painting_isolation_as_property() { assert_eq!(render("tests/painting/...
function painting_isolation_isolate (line 751) | fn painting_isolation_isolate() { assert_eq!(render("tests/painting/isol...
function painting_marker_default_clip (line 752) | fn painting_marker_default_clip() { assert_eq!(render("tests/painting/ma...
function painting_marker_empty (line 753) | fn painting_marker_empty() { assert_eq!(render("tests/painting/marker/em...
function painting_marker_inheritance_1 (line 754) | fn painting_marker_inheritance_1() { assert_eq!(render("tests/painting/m...
function painting_marker_inheritance_2 (line 755) | fn painting_marker_inheritance_2() { assert_eq!(render("tests/painting/m...
function painting_marker_invalid_child (line 756) | fn painting_marker_invalid_child() { assert_eq!(render("tests/painting/m...
function painting_marker_marker_on_circle (line 757) | fn painting_marker_marker_on_circle() { assert_eq!(render("tests/paintin...
function painting_marker_marker_on_line (line 758) | fn painting_marker_marker_on_line() { assert_eq!(render("tests/painting/...
function painting_marker_marker_on_polygon (line 759) | fn painting_marker_marker_on_polygon() { assert_eq!(render("tests/painti...
function painting_marker_marker_on_polyline (line 760) | fn painting_marker_marker_on_polyline() { assert_eq!(render("tests/paint...
function painting_marker_marker_on_rect (line 761) | fn painting_marker_marker_on_rect() { assert_eq!(render("tests/painting/...
function painting_marker_marker_on_rounded_rect (line 762) | fn painting_marker_marker_on_rounded_rect() { assert_eq!(render("tests/p...
function painting_marker_marker_on_text (line 763) | fn painting_marker_marker_on_text() { assert_eq!(render("tests/painting/...
function painting_marker_marker_with_a_negative_size (line 764) | fn painting_marker_marker_with_a_negative_size() { assert_eq!(render("te...
function painting_marker_nested (line 765) | fn painting_marker_nested() { assert_eq!(render("tests/painting/marker/n...
function painting_marker_no_stroke_on_target (line 766) | fn painting_marker_no_stroke_on_target() { assert_eq!(render("tests/pain...
function painting_marker_on_ArcTo (line 767) | fn painting_marker_on_ArcTo() { assert_eq!(render("tests/painting/marker...
function painting_marker_only_marker_end (line 768) | fn painting_marker_only_marker_end() { assert_eq!(render("tests/painting...
function painting_marker_only_marker_mid (line 769) | fn painting_marker_only_marker_mid() { assert_eq!(render("tests/painting...
function painting_marker_only_marker_start (line 770) | fn painting_marker_only_marker_start() { assert_eq!(render("tests/painti...
function painting_marker_orient_eq__45 (line 771) | fn painting_marker_orient_eq__45() { assert_eq!(render("tests/painting/m...
function painting_marker_orient_eq_0_25turn (line 772) | fn painting_marker_orient_eq_0_25turn() { assert_eq!(render("tests/paint...
function painting_marker_orient_eq_1_5rad (line 773) | fn painting_marker_orient_eq_1_5rad() { assert_eq!(render("tests/paintin...
function painting_marker_orient_eq_30 (line 774) | fn painting_marker_orient_eq_30() { assert_eq!(render("tests/painting/ma...
function painting_marker_orient_eq_40grad (line 775) | fn painting_marker_orient_eq_40grad() { assert_eq!(render("tests/paintin...
function painting_marker_orient_eq_9999 (line 776) | fn painting_marker_orient_eq_9999() { assert_eq!(render("tests/painting/...
function painting_marker_orient_eq_auto_on_M_C_C_1 (line 777) | fn painting_marker_orient_eq_auto_on_M_C_C_1() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_C_2 (line 778) | fn painting_marker_orient_eq_auto_on_M_C_C_2() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_C_3 (line 779) | fn painting_marker_orient_eq_auto_on_M_C_C_3() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_C_4 (line 780) | fn painting_marker_orient_eq_auto_on_M_C_C_4() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_C_5 (line 781) | fn painting_marker_orient_eq_auto_on_M_C_C_5() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_C_6 (line 782) | fn painting_marker_orient_eq_auto_on_M_C_C_6() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_C_7 (line 783) | fn painting_marker_orient_eq_auto_on_M_C_C_7() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_C_8 (line 784) | fn painting_marker_orient_eq_auto_on_M_C_C_8() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_C_L (line 785) | fn painting_marker_orient_eq_auto_on_M_C_L() { assert_eq!(render("tests/...
function painting_marker_orient_eq_auto_on_M_C_M_L (line 786) | fn painting_marker_orient_eq_auto_on_M_C_M_L() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_L_C (line 787) | fn painting_marker_orient_eq_auto_on_M_L_C() { assert_eq!(render("tests/...
function painting_marker_orient_eq_auto_on_M_L_L_Z_Z_Z (line 788) | fn painting_marker_orient_eq_auto_on_M_L_L_Z_Z_Z() { assert_eq!(render("...
function painting_marker_orient_eq_auto_on_M_L_L (line 789) | fn painting_marker_orient_eq_auto_on_M_L_L() { assert_eq!(render("tests/...
function painting_marker_orient_eq_auto_on_M_L_M_C (line 790) | fn painting_marker_orient_eq_auto_on_M_L_M_C() { assert_eq!(render("test...
function painting_marker_orient_eq_auto_on_M_L_Z (line 791) | fn painting_marker_orient_eq_auto_on_M_L_Z() { assert_eq!(render("tests/...
function painting_marker_orient_eq_auto_on_M_L (line 792) | fn painting_marker_orient_eq_auto_on_M_L() { assert_eq!(render("tests/pa...
function painting_marker_orient_eq_auto_start_reverse (line 793) | fn painting_marker_orient_eq_auto_start_reverse() { assert_eq!(render("t...
function painting_marker_percent_values (line 794) | fn painting_marker_percent_values() { assert_eq!(render("tests/painting/...
function painting_marker_recursive_1 (line 795) | fn painting_marker_recursive_1() { assert_eq!(render("tests/painting/mar...
function painting_marker_recursive_2 (line 796) | fn painting_marker_recursive_2() { assert_eq!(render("tests/painting/mar...
function painting_marker_recursive_3 (line 797) | fn painting_marker_recursive_3() { assert_eq!(render("tests/painting/mar...
function painting_marker_recursive_4 (line 798) | fn painting_marker_recursive_4() { assert_eq!(render("tests/painting/mar...
function painting_marker_recursive_5 (line 799) | fn painting_marker_recursive_5() { assert_eq!(render("tests/painting/mar...
function painting_marker_target_with_subpaths_1 (line 800) | fn painting_marker_target_with_subpaths_1() { assert_eq!(render("tests/p...
function painting_marker_target_with_subpaths_2 (line 801) | fn painting_marker_target_with_subpaths_2() { assert_eq!(render("tests/p...
function painting_marker_the_marker_property_in_CSS (line 802) | fn painting_marker_the_marker_property_in_CSS() { assert_eq!(render("tes...
function painting_marker_the_marker_property (line 803) | fn painting_marker_the_marker_property() { assert_eq!(render("tests/pain...
function painting_marker_with_a_large_stroke (line 804) | fn painting_marker_with_a_large_stroke() { assert_eq!(render("tests/pain...
function painting_marker_with_a_text_child (line 805) | fn painting_marker_with_a_text_child() { assert_eq!(render("tests/painti...
function painting_marker_with_an_image_child (line 806) | fn painting_marker_with_an_image_child() { assert_eq!(render("tests/pain...
function painting_marker_with_invalid_markerUnits (line 807) | fn painting_marker_with_invalid_markerUnits() { assert_eq!(render("tests...
function painting_marker_with_markerUnits_eq_userSpaceOnUse (line 808) | fn painting_marker_with_markerUnits_eq_userSpaceOnUse() { assert_eq!(ren...
function painting_marker_with_viewBox_1 (line 809) | fn painting_marker_with_viewBox_1() { assert_eq!(render("tests/painting/...
function painting_marker_with_viewBox_2 (line 810) | fn painting_marker_with_viewBox_2() { assert_eq!(render("tests/painting/...
function painting_marker_zero_length_path_1 (line 811) | fn painting_marker_zero_length_path_1() { assert_eq!(render("tests/paint...
function painting_marker_zero_length_path_2 (line 812) | fn painting_marker_zero_length_path_2() { assert_eq!(render("tests/paint...
function painting_marker_zero_sized_stroke (line 813) | fn painting_marker_zero_sized_stroke() { assert_eq!(render("tests/painti...
function painting_marker_zero_sized (line 814) | fn painting_marker_zero_sized() { assert_eq!(render("tests/painting/mark...
function painting_mix_blend_mode_as_property (line 815) | fn painting_mix_blend_mode_as_property() { assert_eq!(render("tests/pain...
function painting_mix_blend_mode_color_burn (line 816) | fn painting_mix_blend_mode_color_burn() { assert_eq!(render("tests/paint...
function painting_mix_blend_mode_color_dodge (line 817) | fn painting_mix_blend_mode_color_dodge() { assert_eq!(render("tests/pain...
function painting_mix_blend_mode_color (line 818) | fn painting_mix_blend_mode_color() { assert_eq!(render("tests/painting/m...
function painting_mix_blend_mode_darken (line 819) | fn painting_mix_blend_mode_darken() { assert_eq!(render("tests/painting/...
function painting_mix_blend_mode_difference (line 820) | fn painting_mix_blend_mode_difference() { assert_eq!(render("tests/paint...
function painting_mix_blend_mode_exclusion (line 821) | fn painting_mix_blend_mode_exclusion() { assert_eq!(render("tests/painti...
function painting_mix_blend_mode_hard_light (line 822) | fn painting_mix_blend_mode_hard_light() { assert_eq!(render("tests/paint...
function painting_mix_blend_mode_hue (line 823) | fn painting_mix_blend_mode_hue() { assert_eq!(render("tests/painting/mix...
function painting_mix_blend_mode_lighten (line 824) | fn painting_mix_blend_mode_lighten() { assert_eq!(render("tests/painting...
function painting_mix_blend_mode_luminosity (line 825) | fn painting_mix_blend_mode_luminosity() { assert_eq!(render("tests/paint...
function painting_mix_blend_mode_multiply (line 826) | fn painting_mix_blend_mode_multiply() { assert_eq!(render("tests/paintin...
function painting_mix_blend_mode_normal (line 827) | fn painting_mix_blend_mode_normal() { assert_eq!(render("tests/painting/...
function painting_mix_blend_mode_opacity_on_element (line 828) | fn painting_mix_blend_mode_opacity_on_element() { assert_eq!(render("tes...
function painting_mix_blend_mode_opacity_on_group (line 829) | fn painting_mix_blend_mode_opacity_on_group() { assert_eq!(render("tests...
function painting_mix_blend_mode_overlay (line 830) | fn painting_mix_blend_mode_overlay() { assert_eq!(render("tests/painting...
function painting_mix_blend_mode_saturation (line 831) | fn painting_mix_blend_mode_saturation() { assert_eq!(render("tests/paint...
function painting_mix_blend_mode_screen (line 832) | fn painting_mix_blend_mode_screen() { assert_eq!(render("tests/painting/...
function painting_mix_blend_mode_soft_light (line 833) | fn painting_mix_blend_mode_soft_light() { assert_eq!(render("tests/paint...
function painting_mix_blend_mode_xor (line 834) | fn painting_mix_blend_mode_xor() { assert_eq!(render("tests/painting/mix...
function painting_opacity_50percent (line 835) | fn painting_opacity_50percent() { assert_eq!(render("tests/painting/opac...
function painting_opacity_bBox_impact (line 836) | fn painting_opacity_bBox_impact() { assert_eq!(render("tests/painting/op...
function painting_opacity_clamp_value_1 (line 837) | fn painting_opacity_clamp_value_1() { assert_eq!(render("tests/painting/...
function painting_opacity_clamp_value_2 (line 838) | fn painting_opacity_clamp_value_2() { assert_eq!(render("tests/painting/...
function painting_opacity_group_opacity (line 839) | fn painting_opacity_group_opacity() { assert_eq!(render("tests/painting/...
function painting_opacity_invalid_value_2 (line 840) | fn painting_opacity_invalid_value_2() { assert_eq!(render("tests/paintin...
function painting_opacity_mixed_group_opacity (line 841) | fn painting_opacity_mixed_group_opacity() { assert_eq!(render("tests/pai...
function painting_opacity_on_an_invalid_element (line 842) | fn painting_opacity_on_an_invalid_element() { assert_eq!(render("tests/p...
function painting_opacity_on_the_root_svg (line 843) | fn painting_opacity_on_the_root_svg() { assert_eq!(render("tests/paintin...
function painting_overflow_auto_on_marker (line 844) | fn painting_overflow_auto_on_marker() { assert_eq!(render("tests/paintin...
function painting_overflow_inherit_on_marker_without_parent (line 845) | fn painting_overflow_inherit_on_marker_without_parent() { assert_eq!(ren...
function painting_overflow_inherit_on_marker (line 846) | fn painting_overflow_inherit_on_marker() { assert_eq!(render("tests/pain...
function painting_overflow_scroll_on_marker (line 847) | fn painting_overflow_scroll_on_marker() { assert_eq!(render("tests/paint...
function painting_overflow_visible_on_marker (line 848) | fn painting_overflow_visible_on_marker() { assert_eq!(render("tests/pain...
function painting_paint_order_duplicates (line 849) | fn painting_paint_order_duplicates() { assert_eq!(render("tests/painting...
function painting_paint_order_fill_markers_stroke (line 850) | fn painting_paint_order_fill_markers_stroke() { assert_eq!(render("tests...
function painting_paint_order_fill (line 851) | fn painting_paint_order_fill() { assert_eq!(render("tests/painting/paint...
function painting_paint_order_invalid (line 852) | fn painting_paint_order_invalid() { assert_eq!(render("tests/painting/pa...
function painting_paint_order_markers_stroke (line 853) | fn painting_paint_order_markers_stroke() { assert_eq!(render("tests/pain...
function painting_paint_order_markers (line 854) | fn painting_paint_order_markers() { assert_eq!(render("tests/painting/pa...
function painting_paint_order_normal (line 855) | fn painting_paint_order_normal() { assert_eq!(render("tests/painting/pai...
function painting_paint_order_on_text (line 856) | fn painting_paint_order_on_text() { assert_eq!(render("tests/painting/pa...
function painting_paint_order_on_tspan (line 857) | fn painting_paint_order_on_tspan() { assert_eq!(render("tests/painting/p...
function painting_paint_order_stroke_invalid (line 858) | fn painting_paint_order_stroke_invalid() { assert_eq!(render("tests/pain...
function painting_paint_order_stroke_markers_fill (line 859) | fn painting_paint_order_stroke_markers_fill() { assert_eq!(render("tests...
function painting_paint_order_stroke_markers (line 860) | fn painting_paint_order_stroke_markers() { assert_eq!(render("tests/pain...
function painting_paint_order_stroke (line 861) | fn painting_paint_order_stroke() { assert_eq!(render("tests/painting/pai...
function painting_paint_order_trailing_data (line 862) | fn painting_paint_order_trailing_data() { assert_eq!(render("tests/paint...
function painting_shape_rendering_auto_on_circle (line 863) | fn painting_shape_rendering_auto_on_circle() { assert_eq!(render("tests/...
function painting_shape_rendering_crispEdges_on_circle (line 864) | fn painting_shape_rendering_crispEdges_on_circle() { assert_eq!(render("...
function painting_shape_rendering_geometricPrecision_on_circle (line 865) | fn painting_shape_rendering_geometricPrecision_on_circle() { assert_eq!(...
function painting_shape_rendering_inheritance (line 866) | fn painting_shape_rendering_inheritance() { assert_eq!(render("tests/pai...
function painting_shape_rendering_on_horizontal_line (line 867) | fn painting_shape_rendering_on_horizontal_line() { assert_eq!(render("te...
function painting_shape_rendering_optimizeSpeed_on_circle (line 868) | fn painting_shape_rendering_optimizeSpeed_on_circle() { assert_eq!(rende...
function painting_shape_rendering_optimizeSpeed_on_text (line 869) | fn painting_shape_rendering_optimizeSpeed_on_text() { assert_eq!(render(...
function painting_shape_rendering_path_with_marker (line 870) | fn painting_shape_rendering_path_with_marker() { assert_eq!(render("test...
function painting_stroke_control_points_clamping_1 (line 871) | fn painting_stroke_control_points_clamping_1() { assert_eq!(render("test...
function painting_stroke_control_points_clamping_2 (line 872) | fn painting_stroke_control_points_clamping_2() { assert_eq!(render("test...
function painting_stroke_currentColor_without_a_parent (line 873) | fn painting_stroke_currentColor_without_a_parent() { assert_eq!(render("...
function painting_stroke_funcIRI_to_unsupported_element (line 874) | fn painting_stroke_funcIRI_to_unsupported_element() { assert_eq!(render(...
function painting_stroke_gradient_with_objectBoundingBox_and_fallback_on_lines (line 875) | fn painting_stroke_gradient_with_objectBoundingBox_and_fallback_on_lines...
function painting_stroke_gradient_with_objectBoundingBox_on_path_without_a_bbox_1 (line 876) | fn painting_stroke_gradient_with_objectBoundingBox_on_path_without_a_bbo...
function painting_stroke_gradient_with_objectBoundingBox_on_path_without_a_bbox_2 (line 877) | fn painting_stroke_gradient_with_objectBoundingBox_on_path_without_a_bbo...
function painting_stroke_gradient_with_objectBoundingBox_on_shape_without_a_bbox (line 878) | fn painting_stroke_gradient_with_objectBoundingBox_on_shape_without_a_bb...
function painting_stroke_line_as_curve_1 (line 879) | fn painting_stroke_line_as_curve_1() { assert_eq!(render("tests/painting...
function painting_stroke_line_as_curve_2 (line 880) | fn painting_stroke_line_as_curve_2() { assert_eq!(render("tests/painting...
function painting_stroke_linear_gradient_on_text (line 881) | fn painting_stroke_linear_gradient_on_text() { assert_eq!(render("tests/...
function painting_stroke_linear_gradient (line 882) | fn painting_stroke_linear_gradient() { assert_eq!(render("tests/painting...
function painting_stroke_named_color (line 883) | fn painting_stroke_named_color() { assert_eq!(render("tests/painting/str...
function painting_stroke_none (line 884) | fn painting_stroke_none() { assert_eq!(render("tests/painting/stroke/non...
function painting_stroke_pattern_on_text (line 885) | fn painting_stroke_pattern_on_text() { assert_eq!(render("tests/painting...
function painting_stroke_pattern_with_objectBoundingBox_fallback_on_zero_bbox_shape (line 886) | fn painting_stroke_pattern_with_objectBoundingBox_fallback_on_zero_bbox_...
function painting_stroke_pattern_with_objectBoundingBox_on_zero_bbox_shape (line 887) | fn painting_stroke_pattern_with_objectBoundingBox_on_zero_bbox_shape() {...
function painting_stroke_pattern (line 888) | fn painting_stroke_pattern() { assert_eq!(render("tests/painting/stroke/...
function painting_stroke_radial_gradient_on_text (line 889) | fn painting_stroke_radial_gradient_on_text() { assert_eq!(render("tests/...
function painting_stroke_radial_gradient (line 890) | fn painting_stroke_radial_gradient() { assert_eq!(render("tests/painting...
function painting_stroke_dasharray_0_n_with_butt_caps (line 891) | fn painting_stroke_dasharray_0_n_with_butt_caps() { assert_eq!(render("t...
function painting_stroke_dasharray_0_n_with_round_caps (line 892) | fn painting_stroke_dasharray_0_n_with_round_caps() { assert_eq!(render("...
function painting_stroke_dasharray_0_n_with_square_caps (line 893) | fn painting_stroke_dasharray_0_n_with_square_caps() { assert_eq!(render(...
function painting_stroke_dasharray_comma_ws_separator (line 894) | fn painting_stroke_dasharray_comma_ws_separator() { assert_eq!(render("t...
function painting_stroke_dasharray_em_units (line 895) | fn painting_stroke_dasharray_em_units() { assert_eq!(render("tests/paint...
function painting_stroke_dasharray_even_count (line 896) | fn painting_stroke_dasharray_even_count() { assert_eq!(render("tests/pai...
function painting_stroke_dasharray_mm_units (line 897) | fn painting_stroke_dasharray_mm_units() { assert_eq!(render("tests/paint...
function painting_stroke_dasharray_multiple_subpaths (line 898) | fn painting_stroke_dasharray_multiple_subpaths() { assert_eq!(render("te...
function painting_stroke_dasharray_n_0 (line 899) | fn painting_stroke_dasharray_n_0() { assert_eq!(render("tests/painting/s...
function painting_stroke_dasharray_negative_sum (line 900) | fn painting_stroke_dasharray_negative_sum() { assert_eq!(render("tests/p...
function painting_stroke_dasharray_negative_values (line 901) | fn painting_stroke_dasharray_negative_values() { assert_eq!(render("test...
function painting_stroke_dasharray_none (line 902) | fn painting_stroke_dasharray_none() { assert_eq!(render("tests/painting/...
function painting_stroke_dasharray_odd_count (line 903) | fn painting_stroke_dasharray_odd_count() { assert_eq!(render("tests/pain...
function painting_stroke_dasharray_on_a_circle (line 904) | fn painting_stroke_dasharray_on_a_circle() { assert_eq!(render("tests/pa...
function painting_stroke_dasharray_percent_units (line 905) | fn painting_stroke_dasharray_percent_units() { assert_eq!(render("tests/...
function painting_stroke_dasharray_ws_separator (line 906) | fn painting_stroke_dasharray_ws_separator() { assert_eq!(render("tests/p...
function painting_stroke_dasharray_zero_sum (line 907) | fn painting_stroke_dasharray_zero_sum() { assert_eq!(render("tests/paint...
function painting_stroke_dashoffset_default (line 908) | fn painting_stroke_dashoffset_default() { assert_eq!(render("tests/paint...
function painting_stroke_dashoffset_em_units (line 909) | fn painting_stroke_dashoffset_em_units() { assert_eq!(render("tests/pain...
function painting_stroke_dashoffset_mm_units (line 910) | fn painting_stroke_dashoffset_mm_units() { assert_eq!(render("tests/pain...
function painting_stroke_dashoffset_negative_value (line 911) | fn painting_stroke_dashoffset_negative_value() { assert_eq!(render("test...
function painting_stroke_dashoffset_percent_units (line 912) | fn painting_stroke_dashoffset_percent_units() { assert_eq!(render("tests...
function painting_stroke_dashoffset_px_units (line 913) | fn painting_stroke_dashoffset_px_units() { assert_eq!(render("tests/pain...
function painting_stroke_linecap_butt (line 914) | fn painting_stroke_linecap_butt() { assert_eq!(render("tests/painting/st...
function painting_stroke_linecap_open_path_with_butt (line 915) | fn painting_stroke_linecap_open_path_with_butt() { assert_eq!(render("te...
function painting_stroke_linecap_open_path_with_round (line 916) | fn painting_stroke_linecap_open_path_with_round() { assert_eq!(render("t...
function painting_stroke_linecap_open_path_with_square (line 917) | fn painting_stroke_linecap_open_path_with_square() { assert_eq!(render("...
function painting_stroke_linecap_round (line 918) | fn painting_stroke_linecap_round() { assert_eq!(render("tests/painting/s...
function painting_stroke_linecap_square (line 919) | fn painting_stroke_linecap_square() { assert_eq!(render("tests/painting/...
function painting_stroke_linecap_zero_length_path_with_butt (line 920) | fn painting_stroke_linecap_zero_length_path_with_butt() { assert_eq!(ren...
function painting_stroke_linecap_zero_length_path_with_round (line 921) | fn painting_stroke_linecap_zero_length_path_with_round() { assert_eq!(re...
function painting_stroke_linecap_zero_length_path_with_square (line 922) | fn painting_stroke_linecap_zero_length_path_with_square() { assert_eq!(r...
function painting_stroke_linejoin_arcs (line 923) | fn painting_stroke_linejoin_arcs() { assert_eq!(render("tests/painting/s...
function painting_stroke_linejoin_bevel (line 924) | fn painting_stroke_linejoin_bevel() { assert_eq!(render("tests/painting/...
function painting_stroke_linejoin_miter_clip (line 925) | fn painting_stroke_linejoin_miter_clip() { assert_eq!(render("tests/pain...
function painting_stroke_linejoin_miter (line 926) | fn painting_stroke_linejoin_miter() { assert_eq!(render("tests/painting/...
function painting_stroke_linejoin_round (line 927) | fn painting_stroke_linejoin_round() { assert_eq!(render("tests/painting/...
function painting_stroke_miterlimit_default (line 928) | fn painting_stroke_miterlimit_default() { assert_eq!(render("tests/paint...
function painting_stroke_miterlimit_invalid_value (line 929) | fn painting_stroke_miterlimit_invalid_value() { assert_eq!(render("tests...
function painting_stroke_miterlimit_valid_value (line 930) | fn painting_stroke_miterlimit_valid_value() { assert_eq!(render("tests/p...
function painting_stroke_miterlimit_value_with_mm (line 931) | fn painting_stroke_miterlimit_value_with_mm() { assert_eq!(render("tests...
function painting_stroke_miterlimit_value_with_percent (line 932) | fn painting_stroke_miterlimit_value_with_percent() { assert_eq!(render("...
function painting_stroke_opacity_50percent (line 933) | fn painting_stroke_opacity_50percent() { assert_eq!(render("tests/painti...
function painting_stroke_opacity_half_opacity (line 934) | fn painting_stroke_opacity_half_opacity() { assert_eq!(render("tests/pai...
function painting_stroke_opacity_nested (line 935) | fn painting_stroke_opacity_nested() { assert_eq!(render("tests/painting/...
function painting_stroke_opacity_on_parent (line 936) | fn painting_stroke_opacity_on_parent() { assert_eq!(render("tests/painti...
function painting_stroke_opacity_on_text (line 937) | fn painting_stroke_opacity_on_text() { assert_eq!(render("tests/painting...
function painting_stroke_opacity_with_linearGradient (line 938) | fn painting_stroke_opacity_with_linearGradient() { assert_eq!(render("te...
function painting_stroke_opacity_with_opacity (line 939) | fn painting_stroke_opacity_with_opacity() { assert_eq!(render("tests/pai...
function painting_stroke_opacity_with_pattern (line 940) | fn painting_stroke_opacity_with_pattern() { assert_eq!(render("tests/pai...
function painting_stroke_width_bold (line 941) | fn painting_stroke_width_bold() { assert_eq!(render("tests/painting/stro...
function painting_stroke_width_default (line 942) | fn painting_stroke_width_default() { assert_eq!(render("tests/painting/s...
function painting_stroke_width_negative (line 943) | fn painting_stroke_width_negative() { assert_eq!(render("tests/painting/...
function painting_stroke_width_percentage (line 944) | fn painting_stroke_width_percentage() { assert_eq!(render("tests/paintin...
function painting_stroke_width_zero (line 945) | fn painting_stroke_width_zero() { assert_eq!(render("tests/painting/stro...
function painting_visibility_bbox_impact_1 (line 946) | fn painting_visibility_bbox_impact_1() { assert_eq!(render("tests/painti...
function painting_visibility_bbox_impact_2 (line 947) | fn painting_visibility_bbox_impact_2() { assert_eq!(render("tests/painti...
function painting_visibility_bbox_impact_3 (line 948) | fn painting_visibility_bbox_impact_3() { assert_eq!(render("tests/painti...
function painting_visibility_collapse_on_tspan (line 949) | fn painting_visibility_collapse_on_tspan() { assert_eq!(render("tests/pa...
function painting_visibility_hidden_on_group (line 950) | fn painting_visibility_hidden_on_group() { assert_eq!(render("tests/pain...
function painting_visibility_hidden_on_shape (line 951) | fn painting_visibility_hidden_on_shape() { assert_eq!(render("tests/pain...
function painting_visibility_hidden_on_tspan (line 952) | fn painting_visibility_hidden_on_tspan() { assert_eq!(render("tests/pain...
function shapes_circle_missing_cx_and_cy_attributes (line 953) | fn shapes_circle_missing_cx_and_cy_attributes() { assert_eq!(render("tes...
function shapes_circle_missing_cx_attribute (line 954) | fn shapes_circle_missing_cx_attribute() { assert_eq!(render("tests/shape...
function shapes_circle_missing_cy_attribute (line 955) | fn shapes_circle_missing_cy_attribute() { assert_eq!(render("tests/shape...
function shapes_circle_missing_r_attribute (line 956) | fn shapes_circle_missing_r_attribute() { assert_eq!(render("tests/shapes...
function shapes_circle_negative_r_attribute (line 957) | fn shapes_circle_negative_r_attribute() { assert_eq!(render("tests/shape...
function shapes_circle_simple_case (line 958) | fn shapes_circle_simple_case() { assert_eq!(render("tests/shapes/circle/...
function shapes_ellipse_missing_cx_and_cy_attributes (line 959) | fn shapes_ellipse_missing_cx_and_cy_attributes() { assert_eq!(render("te...
function shapes_ellipse_missing_cx_attribute (line 960) | fn shapes_ellipse_missing_cx_attribute() { assert_eq!(render("tests/shap...
function shapes_ellipse_missing_cy_attribute (line 961) | fn shapes_ellipse_missing_cy_attribute() { assert_eq!(render("tests/shap...
function shapes_ellipse_missing_rx_and_ry_attributes (line 962) | fn shapes_ellipse_missing_rx_and_ry_attributes() { assert_eq!(render("te...
function shapes_ellipse_missing_rx_attribute (line 963) | fn shapes_ellipse_missing_rx_attribute() { assert_eq!(render("tests/shap...
function shapes_ellipse_missing_ry_attribute (line 964) | fn shapes_ellipse_missing_ry_attribute() { assert_eq!(render("tests/shap...
function shapes_ellipse_negative_rx_and_ry_attributes (line 965) | fn shapes_ellipse_negative_rx_and_ry_attributes() { assert_eq!(render("t...
function shapes_ellipse_negative_rx_attribute (line 966) | fn shapes_ellipse_negative_rx_attribute() { assert_eq!(render("tests/sha...
function shapes_ellipse_negative_ry_attribute (line 967) | fn shapes_ellipse_negative_ry_attribute() { assert_eq!(render("tests/sha...
function shapes_ellipse_percent_values_missing_ry (line 968) | fn shapes_ellipse_percent_values_missing_ry() { assert_eq!(render("tests...
function shapes_ellipse_percent_values (line 969) | fn shapes_ellipse_percent_values() { assert_eq!(render("tests/shapes/ell...
function shapes_ellipse_simple_case (line 970) | fn shapes_ellipse_simple_case() { assert_eq!(render("tests/shapes/ellips...
function shapes_line_no_coordinates (line 971) | fn shapes_line_no_coordinates() { assert_eq!(render("tests/shapes/line/n...
function shapes_line_no_x1_and_y1_coordinates (line 972) | fn shapes_line_no_x1_and_y1_coordinates() { assert_eq!(render("tests/sha...
function shapes_line_no_x1_coordinate (line 973) | fn shapes_line_no_x1_coordinate() { assert_eq!(render("tests/shapes/line...
function shapes_line_no_x2_and_y2_coordinates (line 974) | fn shapes_line_no_x2_and_y2_coordinates() { assert_eq!(render("tests/sha...
function shapes_line_no_x2_coordinate (line 975) | fn shapes_line_no_x2_coordinate() { assert_eq!(render("tests/shapes/line...
function shapes_line_no_y1_coordinate (line 976) | fn shapes_line_no_y1_coordinate() { assert_eq!(render("tests/shapes/line...
function shapes_line_no_y2_coordinate (line 977) | fn shapes_line_no_y2_coordinate() { assert_eq!(render("tests/shapes/line...
function shapes_line_percent_units (line 978) | fn shapes_line_percent_units() { assert_eq!(render("tests/shapes/line/pe...
function shapes_line_simple_case (line 979) | fn shapes_line_simple_case() { assert_eq!(render("tests/shapes/line/simp...
function shapes_line_with_transform (line 980) | fn shapes_line_with_transform() { assert_eq!(render("tests/shapes/line/w...
function shapes_path_A (line 981) | fn shapes_path_A() { assert_eq!(render("tests/shapes/path/A"), 0); }
function shapes_path_M_A_s (line 982) | fn shapes_path_M_A_s() { assert_eq!(render("tests/shapes/path/M-A-s"), 0...
function shapes_path_M_A_t (line 983) | fn shapes_path_M_A_t() { assert_eq!(render("tests/shapes/path/M-A-t"), 0...
function shapes_path_M_A_trimmed (line 984) | fn shapes_path_M_A_trimmed() { assert_eq!(render("tests/shapes/path/M-A-...
function shapes_path_M_A (line 985) | fn shapes_path_M_A() { assert_eq!(render("tests/shapes/path/M-A"), 0); }
function shapes_path_M_C_S (line 986) | fn shapes_path_M_C_S() { assert_eq!(render("tests/shapes/path/M-C-S"), 0...
function shapes_path_M_C (line 987) | fn shapes_path_M_C() { assert_eq!(render("tests/shapes/path/M-C"), 0); }
function shapes_path_M_H_H_implicit (line 988) | fn shapes_path_M_H_H_implicit() { assert_eq!(render("tests/shapes/path/M...
function shapes_path_M_H_H (line 989) | fn shapes_path_M_H_H() { assert_eq!(render("tests/shapes/path/M-H-H"), 0...
function shapes_path_M_H (line 990) | fn shapes_path_M_H() { assert_eq!(render("tests/shapes/path/M-H"), 0); }
function shapes_path_M_L_L_Z_rel (line 991) | fn shapes_path_M_L_L_Z_rel() { assert_eq!(render("tests/shapes/path/M-L-...
function shapes_path_M_L_L_Z (line 992) | fn shapes_path_M_L_L_Z() { assert_eq!(render("tests/shapes/path/M-L-L-Z"...
function shapes_path_M_L_L_implicit (line 993) | fn shapes_path_M_L_L_implicit() { assert_eq!(render("tests/shapes/path/M...
function shapes_path_M_L_M_L (line 994) | fn shapes_path_M_L_M_L() { assert_eq!(render("tests/shapes/path/M-L-M-L"...
function shapes_path_M_L_M_Z (line 995) | fn shapes_path_M_L_M_Z() { assert_eq!(render("tests/shapes/path/M-L-M-Z"...
function shapes_path_M_L_M (line 996) | fn shapes_path_M_L_M() { assert_eq!(render("tests/shapes/path/M-L-M"), 0...
function shapes_path_M_L_Z_A (line 997) | fn shapes_path_M_L_Z_A() { assert_eq!(render("tests/shapes/path/M-L-Z-A"...
function shapes_path_M_L_Z_L_L (line 998) | fn shapes_path_M_L_Z_L_L() { assert_eq!(render("tests/shapes/path/M-L-Z-...
function shapes_path_M_L (line 999) | fn shapes_path_M_L() { assert_eq!(render("tests/shapes/path/M-L"), 0); }
function shapes_path_M_M_implicit_M_implicit (line 1000) | fn shapes_path_M_M_implicit_M_implicit() { assert_eq!(render("tests/shap...
function shapes_path_M_M_rel (line 1001) | fn shapes_path_M_M_rel() { assert_eq!(render("tests/shapes/path/M-M-rel"...
function shapes_path_M_M (line 1002) | fn shapes_path_M_M() { assert_eq!(render("tests/shapes/path/M-M"), 0); }
function shapes_path_M_Q_T_rel (line 1003) | fn shapes_path_M_Q_T_rel() { assert_eq!(render("tests/shapes/path/M-Q-T-...
function shapes_path_M_Q_T (line 1004) | fn shapes_path_M_Q_T() { assert_eq!(render("tests/shapes/path/M-Q-T"), 0...
function shapes_path_M_Q_rel_T_rel (line 1005) | fn shapes_path_M_Q_rel_T_rel() { assert_eq!(render("tests/shapes/path/M-...
function shapes_path_M_Q (line 1006) | fn shapes_path_M_Q() { assert_eq!(render("tests/shapes/path/M-Q"), 0); }
function shapes_path_M_S_S (line 1007) | fn shapes_path_M_S_S() { assert_eq!(render("tests/shapes/path/M-S-S"), 0...
function shapes_path_M_S (line 1008) | fn shapes_path_M_S() { assert_eq!(render("tests/shapes/path/M-S"), 0); }
function shapes_path_M_T_Q_rel (line 1009) | fn shapes_path_M_T_Q_rel() { assert_eq!(render("tests/shapes/path/M-T-Q-...
function shapes_path_M_T_Q (line 1010) | fn shapes_path_M_T_Q() { assert_eq!(render("tests/shapes/path/M-T-Q"), 0...
function shapes_path_M_T_S_rel (line 1011) | fn shapes_path_M_T_S_rel() { assert_eq!(render("tests/shapes/path/M-T-S-...
function shapes_path_M_T_S (line 1012) | fn shapes_path_M_T_S() { assert_eq!(render("tests/shapes/path/M-T-S"), 0...
function shapes_path_M_T_T_rel (line 1013) | fn shapes_path_M_T_T_rel() { assert_eq!(render("tests/shapes/path/M-T-T-...
function shapes_path_M_T_T (line 1014) | fn shapes_path_M_T_T() { assert_eq!(render("tests/shapes/path/M-T-T"), 0...
function shapes_path_M_T (line 1015) | fn shapes_path_M_T() { assert_eq!(render("tests/shapes/path/M-T"), 0); }
function shapes_path_M_V_V_implicit (line 1016) | fn shapes_path_M_V_V_implicit() { assert_eq!(render("tests/shapes/path/M...
function shapes_path_M_V_V (line 1017) | fn shapes_path_M_V_V() { assert_eq!(render("tests/shapes/path/M-V-V"), 0...
function shapes_path_M_V (line 1018) | fn shapes_path_M_V() { assert_eq!(render("tests/shapes/path/M-V"), 0); }
function shapes_path_M_Z (line 1019) | fn shapes_path_M_Z() { assert_eq!(render("tests/shapes/path/M-Z"), 0); }
function shapes_path_M_rel_M_rel_implicit_M_rel_implicit (line 1020) | fn shapes_path_M_rel_M_rel_implicit_M_rel_implicit() { assert_eq!(render...
function shapes_path_M_rel_M (line 1021) | fn shapes_path_M_rel_M() { assert_eq!(render("tests/shapes/path/M-rel-M"...
function shapes_path_M (line 1022) | fn shapes_path_M() { assert_eq!(render("tests/shapes/path/M"), 0); }
function shapes_path_empty (line 1023) | fn shapes_path_empty() { assert_eq!(render("tests/shapes/path/empty"), 0...
function shapes_path_extra_spaces (line 1024) | fn shapes_path_extra_spaces() { assert_eq!(render("tests/shapes/path/ext...
function shapes_path_invalid_data_in_L (line 1025) | fn shapes_path_invalid_data_in_L() { assert_eq!(render("tests/shapes/pat...
function shapes_path_invalid_transform (line 1026) | fn shapes_path_invalid_transform() { assert_eq!(render("tests/shapes/pat...
function shapes_path_missing_coordinate_in_L (line 1027) | fn shapes_path_missing_coordinate_in_L() { assert_eq!(render("tests/shap...
function shapes_path_multi_line_data (line 1028) | fn shapes_path_multi_line_data() { assert_eq!(render("tests/shapes/path/...
function shapes_path_negative_large_arc_flag_value (line 1029) | fn shapes_path_negative_large_arc_flag_value() { assert_eq!(render("test...
function shapes_path_negative_sweep_flag_value (line 1030) | fn shapes_path_negative_sweep_flag_value() { assert_eq!(render("tests/sh...
function shapes_path_no_commawsp_after_sweep_flag (line 1031) | fn shapes_path_no_commawsp_after_sweep_flag() { assert_eq!(render("tests...
function shapes_path_no_commawsp_before_arc_flags (line 1032) | fn shapes_path_no_commawsp_before_arc_flags() { assert_eq!(render("tests...
function shapes_path_no_commawsp_between_and_after_arc_flags (line 1033) | fn shapes_path_no_commawsp_between_and_after_arc_flags() { assert_eq!(re...
function shapes_path_no_commawsp_between_arc_flags (line 1034) | fn shapes_path_no_commawsp_between_arc_flags() { assert_eq!(render("test...
function shapes_path_numeric_character_references (line 1035) | fn shapes_path_numeric_character_references() { assert_eq!(render("tests...
function shapes_path_out_of_range_large_arc_flag_value (line 1036) | fn shapes_path_out_of_range_large_arc_flag_value() { assert_eq!(render("...
function shapes_path_out_of_range_sweep_flag_value (line 1037) | fn shapes_path_out_of_range_sweep_flag_value() { assert_eq!(render("test...
function shapes_polygon_ignore_odd_points (line 1038) | fn shapes_polygon_ignore_odd_points() { assert_eq!(render("tests/shapes/...
function shapes_polygon_missing_points_attribute (line 1039) | fn shapes_polygon_missing_points_attribute() { assert_eq!(render("tests/...
function shapes_polygon_not_enough_points (line 1040) | fn shapes_polygon_not_enough_points() { assert_eq!(render("tests/shapes/...
function shapes_polygon_simple_case (line 1041) | fn shapes_polygon_simple_case() { assert_eq!(render("tests/shapes/polygo...
function shapes_polygon_stop_processing_on_invalid_data (line 1042) | fn shapes_polygon_stop_processing_on_invalid_data() { assert_eq!(render(...
function shapes_polyline_ignore_odd_points (line 1043) | fn shapes_polyline_ignore_odd_points() { assert_eq!(render("tests/shapes...
function shapes_polyline_missing_points_attribute (line 1044) | fn shapes_polyline_missing_points_attribute() { assert_eq!(render("tests...
function shapes_polyline_not_enough_points (line 1045) | fn shapes_polyline_not_enough_points() { assert_eq!(render("tests/shapes...
function shapes_polyline_simple_case (line 1046) | fn shapes_polyline_simple_case() { assert_eq!(render("tests/shapes/polyl...
function shapes_polyline_stop_processing_on_invalid_data (line 1047) | fn shapes_polyline_stop_processing_on_invalid_data() { assert_eq!(render...
function shapes_rect_cap_values (line 1048) | fn shapes_rect_cap_values() { assert_eq!(render("tests/shapes/rect/cap-v...
function shapes_rect_ch_values (line 1049) | fn shapes_rect_ch_values() { assert_eq!(render("tests/shapes/rect/ch-val...
function shapes_rect_em_values (line 1050) | fn shapes_rect_em_values() { assert_eq!(render("tests/shapes/rect/em-val...
function shapes_rect_ex_values (line 1051) | fn shapes_rect_ex_values() { assert_eq!(render("tests/shapes/rect/ex-val...
function shapes_rect_ic_values (line 1052) | fn shapes_rect_ic_values() { assert_eq!(render("tests/shapes/rect/ic-val...
function shapes_rect_invalid_coordinates (line 1053) | fn shapes_rect_invalid_coordinates() { assert_eq!(render("tests/shapes/r...
function shapes_rect_invalid_length (line 1054) | fn shapes_rect_invalid_length() { assert_eq!(render("tests/shapes/rect/i...
function shapes_rect_lh_values (line 1055) | fn shapes_rect_lh_values() { assert_eq!(render("tests/shapes/rect/lh-val...
function shapes_rect_missing_height_attribute_processing (line 1056) | fn shapes_rect_missing_height_attribute_processing() { assert_eq!(render...
function shapes_rect_missing_width_attribute_processing (line 1057) | fn shapes_rect_missing_width_attribute_processing() { assert_eq!(render(...
function shapes_rect_mm_values (line 1058) | fn shapes_rect_mm_values() { assert_eq!(render("tests/shapes/rect/mm-val...
function shapes_rect_negative_height_attribute_processing (line 1059) | fn shapes_rect_negative_height_attribute_processing() { assert_eq!(rende...
function shapes_rect_negative_rx_and_ry_attributes_resolving (line 1060) | fn shapes_rect_negative_rx_and_ry_attributes_resolving() { assert_eq!(re...
function shapes_rect_negative_rx_attribute_resolving (line 1061) | fn shapes_rect_negative_rx_attribute_resolving() { assert_eq!(render("te...
function shapes_rect_negative_ry_attribute_resolving (line 1062) | fn shapes_rect_negative_ry_attribute_resolving() { assert_eq!(render("te...
function shapes_rect_negative_width_attribute_processing (line 1063) | fn shapes_rect_negative_width_attribute_processing() { assert_eq!(render...
function shapes_rect_percentage_values_1 (line 1064) | fn shapes_rect_percentage_values_1() { assert_eq!(render("tests/shapes/r...
function shapes_rect_percentage_values_2 (line 1065) | fn shapes_rect_percentage_values_2() { assert_eq!(render("tests/shapes/r...
function shapes_rect_q_values (line 1066) | fn shapes_rect_q_values() { assert_eq!(render("tests/shapes/rect/q-value...
function shapes_rect_rem_values (line 1067) | fn shapes_rect_rem_values() { assert_eq!(render("tests/shapes/rect/rem-v...
function shapes_rect_rlh_values (line 1068) | fn shapes_rect_rlh_values() { assert_eq!(render("tests/shapes/rect/rlh-v...
function shapes_rect_rounded_rect (line 1069) | fn shapes_rect_rounded_rect() { assert_eq!(render("tests/shapes/rect/rou...
function shapes_rect_rx_and_ry_attributes_clamping_order (line 1070) | fn shapes_rect_rx_and_ry_attributes_clamping_order() { assert_eq!(render...
function shapes_rect_rx_attribute_clamping (line 1071) | fn shapes_rect_rx_attribute_clamping() { assert_eq!(render("tests/shapes...
function shapes_rect_rx_attribute_resolving (line 1072) | fn shapes_rect_rx_attribute_resolving() { assert_eq!(render("tests/shape...
function shapes_rect_ry_attribute_clamping (line 1073) | fn shapes_rect_ry_attribute_clamping() { assert_eq!(render("tests/shapes...
function shapes_rect_ry_attribute_resolving (line 1074) | fn shapes_rect_ry_attribute_resolving() { assert_eq!(render("tests/shape...
function shapes_rect_simple_case (line 1075) | fn shapes_rect_simple_case() { assert_eq!(render("tests/shapes/rect/simp...
function shapes_rect_vi_and_vb_values (line 1076) | fn shapes_rect_vi_and_vb_values() { assert_eq!(render("tests/shapes/rect...
function shapes_rect_vmin_and_vmax_values (line 1077) | fn shapes_rect_vmin_and_vmax_values() { assert_eq!(render("tests/shapes/...
function shapes_rect_vw_and_vh_values (line 1078) | fn shapes_rect_vw_and_vh_values() { assert_eq!(render("tests/shapes/rect...
function shapes_rect_with_child (line 1079) | fn shapes_rect_with_child() { assert_eq!(render("tests/shapes/rect/with-...
function shapes_rect_x_attribute_resolving (line 1080) | fn shapes_rect_x_attribute_resolving() { assert_eq!(render("tests/shapes...
function shapes_rect_y_attribute_resolving (line 1081) | fn shapes_rect_y_attribute_resolving() { assert_eq!(render("tests/shapes...
function shapes_rect_zero_height_attribute_processing (line 1082) | fn shapes_rect_zero_height_attribute_processing() { assert_eq!(render("t...
function shapes_rect_zero_rx_attribute_resolving (line 1083) | fn shapes_rect_zero_rx_attribute_resolving() { assert_eq!(render("tests/...
function shapes_rect_zero_ry_attribute_resolving (line 1084) | fn shapes_rect_zero_ry_attribute_resolving() { assert_eq!(render("tests/...
function shapes_rect_zero_width_attribute_processing (line 1085) | fn shapes_rect_zero_width_attribute_processing() { assert_eq!(render("te...
function structure_a_inside_text (line 1086) | fn structure_a_inside_text() { assert_eq!(render("tests/structure/a/insi...
function structure_a_inside_tspan (line 1087) | fn structure_a_inside_tspan() { assert_eq!(render("tests/structure/a/ins...
function structure_a_on_shape (line 1088) | fn structure_a_on_shape() { assert_eq!(render("tests/structure/a/on-shap...
function structure_a_on_text (line 1089) | fn structure_a_on_text() { assert_eq!(render("tests/structure/a/on-text"...
function structure_a_on_tspan (line 1090) | fn structure_a_on_tspan() { assert_eq!(render("tests/structure/a/on-tspa...
function structure_defs_ignore_shapes_inside_defs (line 1091) | fn structure_defs_ignore_shapes_inside_defs() { assert_eq!(render("tests...
function structure_defs_multiple_defs (line 1092) | fn structure_defs_multiple_defs() { assert_eq!(render("tests/structure/d...
function structure_defs_nested_defs (line 1093) | fn structure_defs_nested_defs() { assert_eq!(render("tests/structure/def...
function structure_defs_out_of_order (line 1094) | fn structure_defs_out_of_order() { assert_eq!(render("tests/structure/de...
function structure_defs_simple_case (line 1095) | fn structure_defs_simple_case() { assert_eq!(render("tests/structure/def...
function structure_defs_style_inheritance_on_text (line 1096) | fn structure_defs_style_inheritance_on_text() { assert_eq!(render("tests...
function structure_defs_style_inheritance (line 1097) | fn structure_defs_style_inheritance() { assert_eq!(render("tests/structu...
function structure_g_deeply_nested_groups (line 1098) | fn structure_g_deeply_nested_groups() { assert_eq!(render("tests/structu...
function structure_g_recursive_inheritance (line 1099) | fn structure_g_recursive_inheritance() { assert_eq!(render("tests/struct...
function structure_image_embedded_16bit_png (line 1100) | fn structure_image_embedded_16bit_png() { assert_eq!(render("tests/struc...
function structure_image_embedded_gif (line 1101) | fn structure_image_embedded_gif() { assert_eq!(render("tests/structure/i...
function structure_image_embedded_jpeg_as_image_jpeg (line 1102) | fn structure_image_embedded_jpeg_as_image_jpeg() { assert_eq!(render("te...
function structure_image_embedded_jpeg_as_image_jpg (line 1103) | fn structure_image_embedded_jpeg_as_image_jpg() { assert_eq!(render("tes...
function structure_image_embedded_jpeg_luma (line 1104) | fn structure_image_embedded_jpeg_luma() { assert_eq!(render("tests/struc...
function structure_image_embedded_jpeg_without_mime (line 1105) | fn structure_image_embedded_jpeg_without_mime() { assert_eq!(render("tes...
function structure_image_embedded_png_luma (line 1106) | fn structure_image_embedded_png_luma() { assert_eq!(render("tests/struct...
function structure_image_embedded_png (line 1107) | fn structure_image_embedded_png() { assert_eq!(render("tests/structure/i...
function structure_image_embedded_svg_with_text (line 1108) | fn structure_image_embedded_svg_with_text() { assert_eq!(render("tests/s...
function structure_image_embedded_svg_without_mime (line 1109) | fn structure_image_embedded_svg_without_mime() { assert_eq!(render("test...
function structure_image_embedded_svg (line 1110) | fn structure_image_embedded_svg() { assert_eq!(render("tests/structure/i...
function structure_image_embedded_svgz (line 1111) | fn structure_image_embedded_svgz() { assert_eq!(render("tests/structure/...
function structure_image_embedded_webp (line 1112) | fn structure_image_embedded_webp() { assert_eq!(render("tests/structure/...
function structure_image_external_gif (line 1113) | fn structure_image_external_gif() { assert_eq!(render("tests/structure/i...
function structure_image_external_jpeg (line 1114) | fn structure_image_external_jpeg() { assert_eq!(render("tests/structure/...
function structure_image_external_png (line 1115) | fn structure_image_external_png() { assert_eq!(render("tests/structure/i...
function structure_image_external_svg_with_transform (line 1116) | fn structure_image_external_svg_with_transform() { assert_eq!(render("te...
function structure_image_external_svg (line 1117) | fn structure_image_external_svg() { assert_eq!(render("tests/structure/i...
function structure_image_external_svgz (line 1118) | fn structure_image_external_svgz() { assert_eq!(render("tests/structure/...
function structure_image_external_webp (line 1119) | fn structure_image_external_webp() { assert_eq!(render("tests/structure/...
function structure_image_float_size (line 1120) | fn structure_image_float_size() { assert_eq!(render("tests/structure/ima...
function structure_image_image_with_float_size_scaling (line 1121) | fn structure_image_image_with_float_size_scaling() { assert_eq!(render("...
function structure_image_nested_embedded_png (line 1122) | fn structure_image_nested_embedded_png() { assert_eq!(render("tests/stru...
function structure_image_nested_external_png (line 1123) | fn structure_image_nested_external_png() { assert_eq!(render("tests/stru...
function structure_image_no_height_non_square (line 1124) | fn structure_image_no_height_non_square() { assert_eq!(render("tests/str...
function structure_image_no_height_on_svg (line 1125) | fn structure_image_no_height_on_svg() { assert_eq!(render("tests/structu...
function structure_image_no_height (line 1126) | fn structure_image_no_height() { assert_eq!(render("tests/structure/imag...
function structure_image_no_width_and_height_on_svg (line 1127) | fn structure_image_no_width_and_height_on_svg() { assert_eq!(render("tes...
function structure_image_no_width_and_height (line 1128) | fn structure_image_no_width_and_height() { assert_eq!(render("tests/stru...
function structure_image_no_width_on_svg (line 1129) | fn structure_image_no_width_on_svg() { assert_eq!(render("tests/structur...
function structure_image_no_width (line 1130) | fn structure_image_no_width() { assert_eq!(render("tests/structure/image...
function structure_image_preserveAspectRatio_eq_none_on_svg (line 1131) | fn structure_image_preserveAspectRatio_eq_none_on_svg() { assert_eq!(ren...
function structure_image_preserveAspectRatio_eq_none (line 1132) | fn structure_image_preserveAspectRatio_eq_none() { assert_eq!(render("te...
function structure_image_preserveAspectRatio_eq_xMaxYMax_meet_on_svg (line 1133) | fn structure_image_preserveAspectRatio_eq_xMaxYMax_meet_on_svg() { asser...
function structure_image_preserveAspectRatio_eq_xMaxYMax_meet (line 1134) | fn structure_image_preserveAspectRatio_eq_xMaxYMax_meet() { assert_eq!(r...
function structure_image_preserveAspectRatio_eq_xMaxYMax_slice_on_svg (line 1135) | fn structure_image_preserveAspectRatio_eq_xMaxYMax_slice_on_svg() { asse...
function structure_image_preserveAspectRatio_eq_xMaxYMax_slice (line 1136) | fn structure_image_preserveAspectRatio_eq_xMaxYMax_slice() { assert_eq!(...
function structure_image_preserveAspectRatio_eq_xMidYMid_meet_on_svg (line 1137) | fn structure_image_preserveAspectRatio_eq_xMidYMid_meet_on_svg() { asser...
function structure_image_preserveAspectRatio_eq_xMidYMid_meet (line 1138) | fn structure_image_preserveAspectRatio_eq_xMidYMid_meet() { assert_eq!(r...
function structure_image_preserveAspectRatio_eq_xMidYMid_slice_on_svg (line 1139) | fn structure_image_preserveAspectRatio_eq_xMidYMid_slice_on_svg() { asse...
function structure_image_preserveAspectRatio_eq_xMidYMid_slice (line 1140) | fn structure_image_preserveAspectRatio_eq_xMidYMid_slice() { assert_eq!(...
function structure_image_preserveAspectRatio_eq_xMinYMin_meet_on_svg (line 1141) | fn structure_image_preserveAspectRatio_eq_xMinYMin_meet_on_svg() { asser...
function structure_image_preserveAspectRatio_eq_xMinYMin_meet (line 1142) | fn structure_image_preserveAspectRatio_eq_xMinYMin_meet() { assert_eq!(r...
function structure_image_preserveAspectRatio_eq_xMinYMin_slice_on_svg (line 1143) | fn structure_image_preserveAspectRatio_eq_xMinYMin_slice_on_svg() { asse...
function structure_image_preserveAspectRatio_eq_xMinYMin_slice (line 1144) | fn structure_image_preserveAspectRatio_eq_xMinYMin_slice() { assert_eq!(...
function structure_image_raster_image_and_size_with_odd_numbers (line 1145) | fn structure_image_raster_image_and_size_with_odd_numbers() { assert_eq!...
function structure_image_recursive_1 (line 1146) | fn structure_image_recursive_1() { assert_eq!(render("tests/structure/im...
function structure_image_recursive_2 (line 1147) | fn structure_image_recursive_2() { assert_eq!(render("tests/structure/im...
function structure_image_url_to_png (line 1148) | fn structure_image_url_to_png() { assert_eq!(render("tests/structure/ima...
function structure_image_url_to_svg (line 1149) | fn structure_image_url_to_svg() { assert_eq!(render("tests/structure/ima...
function structure_image_width_and_height_set_to_auto (line 1150) | fn structure_image_width_and_height_set_to_auto() { assert_eq!(render("t...
function structure_image_with_transform (line 1151) | fn structure_image_with_transform() { assert_eq!(render("tests/structure...
function structure_image_with_zero_width_and_height (line 1152) | fn structure_image_with_zero_width_and_height() { assert_eq!(render("tes...
function structure_image_zero_height (line 1153) | fn structure_image_zero_height() { assert_eq!(render("tests/structure/im...
function structure_image_zero_width (line 1154) | fn structure_image_zero_width() { assert_eq!(render("tests/structure/ima...
function structure_style_attribute_selector (line 1155) | fn structure_style_attribute_selector() { assert_eq!(render("tests/struc...
function structure_style_class_selector (line 1156) | fn structure_style_class_selector() { assert_eq!(render("tests/structure...
function structure_style_combined_selectors (line 1157) | fn structure_style_combined_selectors() { assert_eq!(render("tests/struc...
function structure_style_current_color_fill_before_color (line 1158) | fn structure_style_current_color_fill_before_color() { assert_eq!(render...
function structure_style_current_color_stroke_before_color (line 1159) | fn structure_style_current_color_stroke_before_color() { assert_eq!(rend...
function structure_style_external_CSS (line 1160) | fn structure_style_external_CSS() { assert_eq!(render("tests/structure/s...
function structure_style_iD_selector (line 1161) | fn structure_style_iD_selector() { assert_eq!(render("tests/structure/st...
function structure_style_important (line 1162) | fn structure_style_important() { assert_eq!(render("tests/structure/styl...
function structure_style_invalid_type (line 1163) | fn structure_style_invalid_type() { assert_eq!(render("tests/structure/s...
function structure_style_non_presentational_attribute (line 1164) | fn structure_style_non_presentational_attribute() { assert_eq!(render("t...
function structure_style_resolve_order (line 1165) | fn structure_style_resolve_order() { assert_eq!(render("tests/structure/...
function structure_style_rule_specificity (line 1166) | fn structure_style_rule_specificity() { assert_eq!(render("tests/structu...
function structure_style_style_after_usage (line 1167) | fn structure_style_style_after_usage() { assert_eq!(render("tests/struct...
function structure_style_style_inside_CDATA (line 1168) | fn structure_style_style_inside_CDATA() { assert_eq!(render("tests/struc...
function structure_style_transform (line 1169) | fn structure_style_transform() { assert_eq!(render("tests/structure/styl...
function structure_style_type_selector (line 1170) | fn structure_style_type_selector() { assert_eq!(render("tests/structure/...
function structure_style_universal_selector (line 1171) | fn structure_style_universal_selector() { assert_eq!(render("tests/struc...
function structure_style_unresolved_class_selector (line 1172) | fn structure_style_unresolved_class_selector() { assert_eq!(render("test...
function structure_style_attribute_comments (line 1173) | fn structure_style_attribute_comments() { assert_eq!(render("tests/struc...
function structure_style_attribute_non_presentational_attribute (line 1174) | fn structure_style_attribute_non_presentational_attribute() { assert_eq!...
function structure_style_attribute_simple_case (line 1175) | fn structure_style_attribute_simple_case() { assert_eq!(render("tests/st...
function structure_style_attribute_transform (line 1176) | fn structure_style_attribute_transform() { assert_eq!(render("tests/stru...
function structure_svg_attribute_value_via_ENTITY_reference (line 1177) | fn structure_svg_attribute_value_via_ENTITY_reference() { assert_eq!(ren...
function structure_svg_background_color_with_viewbox (line 1178) | fn structure_svg_background_color_with_viewbox() { assert_eq!(render("te...
function structure_svg_background_color (line 1179) | fn structure_svg_background_color() { assert_eq!(render("tests/structure...
function structure_svg_deeply_nested_svg (line 1180) | fn structure_svg_deeply_nested_svg() { assert_eq!(render("tests/structur...
function structure_svg_elements_via_ENTITY_reference_1 (line 1181) | fn structure_svg_elements_via_ENTITY_reference_1() { assert_eq!(render("...
function structure_svg_elements_via_ENTITY_reference_2 (line 1182) | fn structure_svg_elements_via_ENTITY_reference_2() { assert_eq!(render("...
function structure_svg_elements_via_ENTITY_reference_3 (line 1183) | fn structure_svg_elements_via_ENTITY_reference_3() { assert_eq!(render("...
function structure_svg_explicit_svg_namespace (line 1184) | fn structure_svg_explicit_svg_namespace() { assert_eq!(render("tests/str...
function structure_svg_funcIRI_parsing (line 1185) | fn structure_svg_funcIRI_parsing() { assert_eq!(render("tests/structure/...
function structure_svg_funcIRI_with_invalid_characters (line 1186) | fn structure_svg_funcIRI_with_invalid_characters() { assert_eq!(render("...
function structure_svg_funcIRI_with_quotes (line 1187) | fn structure_svg_funcIRI_with_quotes() { assert_eq!(render("tests/struct...
function structure_svg_invalid_id_attribute_1 (line 1188) | fn structure_svg_invalid_id_attribute_1() { assert_eq!(render("tests/str...
function structure_svg_invalid_id_attribute_2 (line 1189) | fn structure_svg_invalid_id_attribute_2() { assert_eq!(render("tests/str...
function structure_svg_mixed_namespaces (line 1190) | fn structure_svg_mixed_namespaces() { assert_eq!(render("tests/structure...
function structure_svg_nested_svg_one_with_rect_and_one_with_viewBox (line 1191) | fn structure_svg_nested_svg_one_with_rect_and_one_with_viewBox() { asser...
function structure_svg_nested_svg_with_overflow_auto (line 1192) | fn structure_svg_nested_svg_with_overflow_auto() { assert_eq!(render("te...
function structure_svg_nested_svg_with_overflow_visible (line 1193) | fn structure_svg_nested_svg_with_overflow_visible() { assert_eq!(render(...
function structure_svg_nested_svg_with_rect_and_percent_values (line 1194) | fn structure_svg_nested_svg_with_rect_and_percent_values() { assert_eq!(...
function structure_svg_nested_svg_with_rect_and_viewBox_1 (line 1195) | fn structure_svg_nested_svg_with_rect_and_viewBox_1() { assert_eq!(rende...
function structure_svg_nested_svg_with_rect_and_viewBox_2 (line 1196) | fn structure_svg_nested_svg_with_rect_and_viewBox_2() { assert_eq!(rende...
function structure_svg_nested_svg_with_rect_and_viewBox_3 (line 1197) | fn structure_svg_nested_svg_with_rect_and_viewBox_3() { assert_eq!(rende...
function structure_svg_nested_svg_with_rect_and_viewBox_and_percent_values (line 1198) | fn structure_svg_nested_svg_with_rect_and_viewBox_and_percent_values() {...
function structure_svg_nested_svg_with_rect (line 1199) | fn structure_svg_nested_svg_with_rect() { assert_eq!(render("tests/struc...
function structure_svg_nested_svg_with_relative_width_and_height (line 1200) | fn structure_svg_nested_svg_with_relative_width_and_height() { assert_eq...
function structure_svg_nested_svg_with_viewBox_and_percent_values (line 1201) | fn structure_svg_nested_svg_with_viewBox_and_percent_values() { assert_e...
function structure_svg_nested_svg_with_viewBox (line 1202) | fn structure_svg_nested_svg_with_viewBox() { assert_eq!(render("tests/st...
function structure_svg_nested_svg (line 1203) | fn structure_svg_nested_svg() { assert_eq!(render("tests/structure/svg/n...
function structure_svg_no_children (line 1204) | fn structure_svg_no_children() { assert_eq!(render("tests/structure/svg/...
function structure_svg_preserveAspectRatio_with_viewBox_not_at_zero_pos (line 1205) | fn structure_svg_preserveAspectRatio_with_viewBox_not_at_zero_pos() { as...
function structure_svg_preserveAspectRatio_eq_none (line 1206) | fn structure_svg_preserveAspectRatio_eq_none() { assert_eq!(render("test...
function structure_svg_preserveAspectRatio_eq_xMaxYMax_slice (line 1207) | fn structure_svg_preserveAspectRatio_eq_xMaxYMax_slice() { assert_eq!(re...
function structure_svg_preserveAspectRatio_eq_xMaxYMax (line 1208) | fn structure_svg_preserveAspectRatio_eq_xMaxYMax() { assert_eq!(render("...
function structure_svg_preserveAspectRatio_eq_xMidYMid_slice (line 1209) | fn structure_svg_preserveAspectRatio_eq_xMidYMid_slice() { assert_eq!(re...
function structure_svg_preserveAspectRatio_eq_xMidYMid (line 1210) | fn structure_svg_preserveAspectRatio_eq_xMidYMid() { assert_eq!(render("...
function structure_svg_preserveAspectRatio_eq_xMinYMin_slice (line 1211) | fn structure_svg_preserveAspectRatio_eq_xMinYMin_slice() { assert_eq!(re...
function structure_svg_preserveAspectRatio_eq_xMinYMin (line 1212) | fn structure_svg_preserveAspectRatio_eq_xMinYMin() { assert_eq!(render("...
function structure_svg_proportional_viewBox (line 1213) | fn structure_svg_proportional_viewBox() { assert_eq!(render("tests/struc...
function structure_svg_rect_inside_a_non_SVG_element (line 1214) | fn structure_svg_rect_inside_a_non_SVG_element() { assert_eq!(render("te...
function structure_svg_viewBox_not_at_zero_pos (line 1215) | fn structure_svg_viewBox_not_at_zero_pos() { assert_eq!(render("tests/st...
function structure_svg_xmlns_validation (line 1216) | fn structure_svg_xmlns_validation() { assert_eq!(render("tests/structure...
function structure_switch_comment_as_first_child (line 1217) | fn structure_switch_comment_as_first_child() { assert_eq!(render("tests/...
function structure_switch_display_none_on_child (line 1218) | fn structure_switch_display_none_on_child() { assert_eq!(render("tests/s...
function structure_switch_non_SVG_child (line 1219) | fn structure_switch_non_SVG_child() { assert_eq!(render("tests/structure...
function structure_switch_requiredFeatures (line 1220) | fn structure_switch_requiredFeatures() { assert_eq!(render("tests/struct...
function structure_switch_simple_case (line 1221) | fn structure_switch_simple_case() { assert_eq!(render("tests/structure/s...
function structure_switch_single_child (line 1222) | fn structure_switch_single_child() { assert_eq!(render("tests/structure/...
function structure_switch_systemLanguage (line 1223) | fn structure_switch_systemLanguage() { assert_eq!(render("tests/structur...
function structure_switch_systemLanguage_eq_en_GB (line 1224) | fn structure_switch_systemLanguage_eq_en_GB() { assert_eq!(render("tests...
function structure_switch_systemLanguage_eq_en_US (line 1225) | fn structure_switch_systemLanguage_eq_en_US() { assert_eq!(render("tests...
function structure_switch_systemLanguage_eq_en (line 1226) | fn structure_switch_systemLanguage_eq_en() { assert_eq!(render("tests/st...
function structure_switch_systemLanguage_eq_ru_Ru (line 1227) | fn structure_switch_systemLanguage_eq_ru_Ru() { assert_eq!(render("tests...
function structure_switch_systemLanguage_eq_ru_en (line 1228) | fn structure_switch_systemLanguage_eq_ru_en() { assert_eq!(render("tests...
function structure_switch_with_attributes (line 1229) | fn structure_switch_with_attributes() { assert_eq!(render("tests/structu...
function structure_symbol_content_outside_the_viewbox (line 1230) | fn structure_symbol_content_outside_the_viewbox() { assert_eq!(render("t...
function structure_symbol_indirect_symbol_reference (line 1231) | fn structure_symbol_indirect_symbol_reference() { assert_eq!(render("tes...
function structure_symbol_opacity_on_symbol_with_viewBox (line 1232) | fn structure_symbol_opacity_on_symbol_with_viewBox() { assert_eq!(render...
function structure_symbol_opacity_on_symbol (line 1233) | fn structure_symbol_opacity_on_symbol() { assert_eq!(render("tests/struc...
function structure_symbol_opacity_on_use_and_symbol (line 1234) | fn structure_symbol_opacity_on_use_and_symbol() { assert_eq!(render("tes...
function structure_symbol_opacity_on_use (line 1235) | fn structure_symbol_opacity_on_use() { assert_eq!(render("tests/structur...
function structure_symbol_simple_case (line 1236) | fn structure_symbol_simple_case() { assert_eq!(render("tests/structure/s...
function structure_symbol_unused_symbol (line 1237) | fn structure_symbol_unused_symbol() { assert_eq!(render("tests/structure...
function structure_symbol_with_custom_use_size (line 1238) | fn structure_symbol_with_custom_use_size() { assert_eq!(render("tests/st...
function structure_symbol_with_overflow_visible (line 1239) | fn structure_symbol_with_overflow_visible() { assert_eq!(render("tests/s...
function structure_symbol_with_size_on_use_and_relative_units (line 1240) | fn structure_symbol_with_size_on_use_and_relative_units() { assert_eq!(r...
function structure_symbol_with_transform_on_use_no_size (line 1241) | fn structure_symbol_with_transform_on_use_no_size() { assert_eq!(render(...
function structure_symbol_with_transform_on_use (line 1242) | fn structure_symbol_with_transform_on_use() { assert_eq!(render("tests/s...
function structure_symbol_with_transform (line 1243) | fn structure_symbol_with_transform() { assert_eq!(render("tests/structur...
function structure_symbol_with_viewBox_and_custom_use_rect (line 1244) | fn structure_symbol_with_viewBox_and_custom_use_rect() { assert_eq!(rend...
function structure_symbol_with_viewBox_and_custom_use_size (line 1245) | fn structure_symbol_with_viewBox_and_custom_use_size() { assert_eq!(rend...
function structure_symbol_with_viewBox (line 1246) | fn structure_symbol_with_viewBox() { assert_eq!(render("tests/structure/...
function structure_systemLanguage_en_GB (line 1247) | fn structure_systemLanguage_en_GB() { assert_eq!(render("tests/structure...
function structure_systemLanguage_en_US (line 1248) | fn structure_systemLanguage_en_US() { assert_eq!(render("tests/structure...
function structure_systemLanguage_en (line 1249) | fn structure_systemLanguage_en() { assert_eq!(render("tests/structure/sy...
function structure_systemLanguage_on_clipPath (line 1250) | fn structure_systemLanguage_on_clipPath() { assert_eq!(render("tests/str...
function structure_systemLanguage_on_defs (line 1251) | fn structure_systemLanguage_on_defs() { assert_eq!(render("tests/structu...
function structure_systemLanguage_on_linearGradient (line 1252) | fn structure_systemLanguage_on_linearGradient() { assert_eq!(render("tes...
function structure_systemLanguage_on_svg (line 1253) | fn structure_systemLanguage_on_svg() { assert_eq!(render("tests/structur...
function structure_systemLanguage_on_tspan (line 1254) | fn structure_systemLanguage_on_tspan() { assert_eq!(render("tests/struct...
function structure_systemLanguage_ru_Ru (line 1255) | fn structure_systemLanguage_ru_Ru() { assert_eq!(render("tests/structure...
function structure_systemLanguage_ru_en (line 1256) | fn structure_systemL
Condensed preview — 135 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,397K chars).
[
{
"path": ".github/copyright.sh",
"chars": 855,
"preview": "#!/bin/bash\n\n# If there are new files with headers that can't match the conditions here,\n# then the files can be ignored"
},
{
"path": ".github/pull_request_template.md",
"chars": 267,
"preview": "Pull requests that include:\n\n- dependencies updates\n- code formatting fixes\n- clippy fixes\n- compiler warnings fixes\n\nwi"
},
{
"path": ".github/workflows/main.yml",
"chars": 2527,
"preview": "name: Build\n\non: [push, pull_request]\n\nenv:\n CARGO_TERM_COLOR: always\n\njobs:\n fmt:\n name: formatting\n runs-on: u"
},
{
"path": ".github/workflows/tagged-release.yml",
"chars": 6657,
"preview": "name: \"Tagged Release\"\n\non:\n push:\n tags:\n - \"v*\"\n\nenv:\n CARGO_TERM_COLOR: always\n\njobs:\n create-release:\n "
},
{
"path": ".gitignore",
"chars": 59,
"preview": "target\n.directory\n.DS_Store\n.vscode\ntools/build-*\n**/diffs\n"
},
{
"path": ".typos.toml",
"chars": 802,
"preview": "# See the configuration reference at\n# https://github.com/crate-ci/typos/blob/master/docs/reference.md\n\n# Corrections ta"
},
{
"path": "AUTHORS",
"chars": 319,
"preview": "# This is the list of Resvg's significant contributors.\n#\n# This does not necessarily list everyone who has contributed "
},
{
"path": "CHANGELOG.md",
"chars": 61969,
"preview": "# Change Log\nAll notable changes to this project will be documented in this file.\n\nThe format is based on [Keep a Change"
},
{
"path": "Cargo.toml",
"chars": 248,
"preview": "[workspace]\nmembers = [\n \"crates/c-api\",\n \"crates/resvg\",\n \"crates/usvg\",\n \"crates/usvg/codegen\",\n #\"tool"
},
{
"path": "LICENSE-APACHE",
"chars": 10173,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "LICENSE-MIT",
"chars": 1057,
"preview": "Copyright 2017 the Resvg Authors\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this s"
},
{
"path": "README.md",
"chars": 7378,
"preview": "## resvg\n\n[ {\n let mut opt = usvg::O"
},
{
"path": "crates/resvg/examples/draw_bboxes.rs",
"chars": 2565,
"preview": "// Copyright 2017 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nfn main() {\n let args: Vec<String>"
},
{
"path": "crates/resvg/examples/minimal.rs",
"chars": 994,
"preview": "// Copyright 2017 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nfn main() {\n let args: Vec<String>"
},
{
"path": "crates/resvg/src/clip.rs",
"chars": 2892,
"preview": "// Copyright 2019 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse crate::render::Context;\n\npub fn a"
},
{
"path": "crates/resvg/src/filter/box_blur.rs",
"chars": 10915,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// Based on https://github.com/fschut"
},
{
"path": "crates/resvg/src/filter/color_matrix.rs",
"chars": 3736,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::{ImageRefMut, f32_bound};\n"
},
{
"path": "crates/resvg/src/filter/component_transfer.rs",
"chars": 2251,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::{ImageRefMut, f32_bound};\n"
},
{
"path": "crates/resvg/src/filter/composite.rs",
"chars": 1390,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::{ImageRef, ImageRefMut, f3"
},
{
"path": "crates/resvg/src/filter/convolve_matrix.rs",
"chars": 3598,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::{ImageRefMut, f32_bound};\n"
},
{
"path": "crates/resvg/src/filter/displacement_map.rs",
"chars": 1832,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::{ImageRef, ImageRefMut};\nu"
},
{
"path": "crates/resvg/src/filter/iir_blur.rs",
"chars": 4205,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// An IIR blur.\n//\n// Based on http:/"
},
{
"path": "crates/resvg/src/filter/lighting.rs",
"chars": 14017,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::{ImageRef, ImageRefMut, f3"
},
{
"path": "crates/resvg/src/filter/mod.rs",
"chars": 35507,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::rc::Rc;\n\nuse rgb::{FromSlice"
},
{
"path": "crates/resvg/src/filter/morphology.rs",
"chars": 2453,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::ImageRefMut;\nuse rgb::RGBA"
},
{
"path": "crates/resvg/src/filter/turbulence.rs",
"chars": 8299,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n# 2010-2016, Khaled Hosny (<khaledhosny@eglug.org>)\r\n\r\nThis Font Software is licensed under the SIL Open Fon"
},
{
"path": "crates/resvg/tests/fonts/CFF-and-SBIX-LICENSE-APACHE.txt",
"chars": 571,
"preview": "Copyright 2019 Simon Cozens. All rights reserved.\r\rLicensed under the Apache License, Version 2.0 (the “License”); you m"
},
{
"path": "crates/resvg/tests/fonts/MPLUS1p-LICENSE-OFL.txt",
"chars": 4393,
"preview": "This Font Software is licensed under the SIL Open Font License, Version 1.1.\r\nThis license is copied below, and is also "
},
{
"path": "crates/resvg/tests/fonts/Noto-LICENSE-OFL.txt",
"chars": 4301,
"preview": "This Font Software is licensed under the SIL Open Font License,\nVersion 1.1.\n\nThis license is copied below, and is also "
},
{
"path": "crates/resvg/tests/fonts/NotoColorEmojiCBDT-LICENSE_APACHE.txt",
"chars": 11356,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "crates/resvg/tests/fonts/NotoZnamennyMusicalNotation-OFL.txt",
"chars": 4384,
"preview": "Copyright 2023 The Noto Project Authors (https://github.com/notofonts/znamenny)\n\nThis Font Software is licensed under th"
},
{
"path": "crates/resvg/tests/fonts/README.md",
"chars": 1500,
"preview": "How fonts were subsetted:\n\nTwitter Color Emoji\n1. Download: https://github.com/13rac1/twemoji-color-font/releases/downlo"
},
{
"path": "crates/resvg/tests/fonts/RobotoFlex-LICENSE-OFL.txt",
"chars": 4395,
"preview": "Copyright 2011 The Roboto Flex Project Authors (https://github.com/googlefonts/roboto-flex)\n\nThis Font Software is licen"
},
{
"path": "crates/resvg/tests/fonts/SedgwickAveDisplay-LICENSE-OFL.txt",
"chars": 4489,
"preview": "Copyright 2017 The Sedgwick Ave Project Authors (https://github.com/googlefonts/sedgwickave)\r\n\r\nThis Font Software is li"
},
{
"path": "crates/resvg/tests/fonts/SourceSansPro-LICENSE-OFL.md",
"chars": 4579,
"preview": "Copyright 2010-2018 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a tr"
},
{
"path": "crates/resvg/tests/fonts/TwitterColorEmoji-LICENSE-MIT.txt",
"chars": 1102,
"preview": "Applies to \"EmojiOne SVGinOT Font\" code only\nCopyright (c) 2022 Brad Erickson\n\nPermission is hereby granted, free of cha"
},
{
"path": "crates/resvg/tests/fonts/Yellowtail-LICENSE-Apache2.txt",
"chars": 11560,
"preview": "\r\n Apache License\r\n Version 2.0, January 2004\r\n "
},
{
"path": "crates/resvg/tests/gen-tests.py",
"chars": 1263,
"preview": "#!/usr/bin/env python3\n\nimport os\nfrom pathlib import Path\n\nIGNORE = [\n 'tests/filters/feMorphology/huge-radius', # w"
},
{
"path": "crates/resvg/tests/integration/extra.rs",
"chars": 1771,
"preview": "// Copyright 2023 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse crate::{render_extra, render_extr"
},
{
"path": "crates/resvg/tests/integration/main.rs",
"chars": 11443,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse once_cell::sync::Lazy;\nuse png::{"
},
{
"path": "crates/resvg/tests/integration/render.rs",
"chars": 214571,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// This file is auto-generated by gen"
},
{
"path": "crates/resvg/tests/resources/green.css",
"chars": 23,
"preview": "#rect1 { fill:green; }\n"
},
{
"path": "crates/usvg/Cargo.toml",
"chars": 1951,
"preview": "[package]\nname = \"usvg\"\nversion = \"0.47.0\"\nkeywords = [\"svg\"]\nlicense.workspace = true\nedition = \"2024\"\nrust-version = \""
},
{
"path": "crates/usvg/LICENSE-APACHE",
"chars": 10173,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "crates/usvg/LICENSE-MIT",
"chars": 1057,
"preview": "Copyright 2017 the Resvg Authors\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this s"
},
{
"path": "crates/usvg/README.md",
"chars": 3011,
"preview": "# usvg\n[](https://crates.io/crates/usvg)\n[ is an [SVG] pa"
},
{
"path": "crates/usvg/src/main.rs",
"chars": 19168,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::fs::File;\nuse std::io::{self"
},
{
"path": "crates/usvg/src/parser/clippath.rs",
"chars": 3661,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::str::FromStr;\nuse std::sync:"
},
{
"path": "crates/usvg/src/parser/converter.rs",
"chars": 32911,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::collections::{HashMap, HashS"
},
{
"path": "crates/usvg/src/parser/filter.rs",
"chars": 42325,
"preview": "// Copyright 2022 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! A collection of SVG filters.\n\nuse"
},
{
"path": "crates/usvg/src/parser/image.rs",
"chars": 11960,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse svgtypes::{A"
},
{
"path": "crates/usvg/src/parser/marker.rs",
"chars": 15696,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse strict_num::"
},
{
"path": "crates/usvg/src/parser/mask.rs",
"chars": 4732,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse svgtypes::{L"
},
{
"path": "crates/usvg/src/parser/mod.rs",
"chars": 5828,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nmod clippath;\nmod converter;\nmod filt"
},
{
"path": "crates/usvg/src/parser/options.rs",
"chars": 4716,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#[cfg(feature = \"text\")]\nuse std::syn"
},
{
"path": "crates/usvg/src/parser/paint_server.rs",
"chars": 34956,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::str::FromStr;\nuse std::sync:"
},
{
"path": "crates/usvg/src/parser/shapes.rs",
"chars": 9991,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse svgtypes::Le"
},
{
"path": "crates/usvg/src/parser/style.rs",
"chars": 9682,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::converter::{self, SvgColor"
},
{
"path": "crates/usvg/src/parser/svgtree/mod.rs",
"chars": 32056,
"preview": "// Copyright 2021 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::collections::HashMap;\nuse st"
},
{
"path": "crates/usvg/src/parser/svgtree/names.rs",
"chars": 19081,
"preview": "// Copyright 2019 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n// This file is autogenerated. Do not"
},
{
"path": "crates/usvg/src/parser/svgtree/parse.rs",
"chars": 25274,
"preview": "// Copyright 2021 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::collections::HashMap;\n\nuse r"
},
{
"path": "crates/usvg/src/parser/svgtree/text.rs",
"chars": 12133,
"preview": "// Copyright 2021 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#![allow(clippy::comparison_chain)]\n\n"
},
{
"path": "crates/usvg/src/parser/switch.rs",
"chars": 4975,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse super::svgtree::{AId, SvgNode};\nu"
},
{
"path": "crates/usvg/src/parser/text.rs",
"chars": 33414,
"preview": "// Copyright 2019 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse kurbo::{Para"
},
{
"path": "crates/usvg/src/parser/units.rs",
"chars": 4543,
"preview": "// Copyright 2019 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse svgtypes::{Length, LengthUnit as "
},
{
"path": "crates/usvg/src/parser/use_node.rs",
"chars": 13025,
"preview": "// Copyright 2019 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse svgtypes::{L"
},
{
"path": "crates/usvg/src/text/colr.rs",
"chars": 12334,
"preview": "// Copyright 2024 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse crate::parser::OptionLog;\nuse rus"
},
{
"path": "crates/usvg/src/text/flatten.rs",
"chars": 15665,
"preview": "// Copyright 2022 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::mem;\nuse std::sync::Arc;\n\nus"
},
{
"path": "crates/usvg/src/text/layout.rs",
"chars": 62937,
"preview": "// Copyright 2022 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::collections::{HashMap, HashS"
},
{
"path": "crates/usvg/src/text/mod.rs",
"chars": 8643,
"preview": "// Copyright 2024 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse fontdb::{Dat"
},
{
"path": "crates/usvg/src/tree/filter.rs",
"chars": 24284,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n//! SVG filter types.\n\nuse strict_num"
},
{
"path": "crates/usvg/src/tree/geom.rs",
"chars": 4769,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse strict_num::ApproxEqUlps;\nuse svg"
},
{
"path": "crates/usvg/src/tree/mod.rs",
"chars": 51911,
"preview": "// Copyright 2019 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\npub mod filter;\nmod geom;\nmod text;\n\n"
},
{
"path": "crates/usvg/src/tree/text.rs",
"chars": 18978,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse strict_num::"
},
{
"path": "crates/usvg/src/writer.rs",
"chars": 59103,
"preview": "// Copyright 2023 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::fmt::Display;\nuse std::io::W"
},
{
"path": "crates/usvg/tests/parser.rs",
"chars": 17025,
"preview": "// Copyright 2018 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse tiny_skia_path::Rect;\nuse usvg::C"
},
{
"path": "crates/usvg/tests/write.rs",
"chars": 4875,
"preview": "// Copyright 2023 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse std::sync::Arc;\n\nuse once_cell::s"
},
{
"path": "docs/svg2-changelog.md",
"chars": 17435,
"preview": "# SVG 2 changelog\n\nAn attempt to list all changes between SVG 1.1 and SVG 2.\n\nSomewhat similar to [Changes from SVG 1.1]"
},
{
"path": "docs/unsupported.md",
"chars": 934,
"preview": "## A list of unsupported SVG 1.1 features\n\nFor the list of unsupported SVG 2 features see: [svg2-changelog.md](./svg2-ch"
},
{
"path": "tools/explorer-thumbnailer/Cargo.toml",
"chars": 593,
"preview": "[package]\nname = \"explorer-thumbnailer\"\nversion = \"0.47.0\"\nlicense.workspace = true\nedition = \"2021\"\npublish = false\n\n# "
},
{
"path": "tools/explorer-thumbnailer/LICENSE-APACHE",
"chars": 10173,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "tools/explorer-thumbnailer/LICENSE-MIT",
"chars": 1057,
"preview": "Copyright 2017 the Resvg Authors\n\nPermission is hereby granted, free of charge, to any\nperson obtaining a copy of this s"
},
{
"path": "tools/explorer-thumbnailer/LICENSE-SUMMARY.txt",
"chars": 253,
"preview": "Licensed under either of\n\n- Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)\n- MIT license (http"
},
{
"path": "tools/explorer-thumbnailer/install/installer.iss",
"chars": 1716,
"preview": "[Setup]\nAppName=\"resvg Explorer Extension\"\nAppVersion=\"0.47.0\"\nVersionInfoVersion=\"0.0.47.0\"\nAppVerName=\"resvg Explorer "
},
{
"path": "tools/explorer-thumbnailer/src/error.rs",
"chars": 1573,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse com::sys::{E_POINTER, HRESULT, S_"
},
{
"path": "tools/explorer-thumbnailer/src/interfaces/iinitialize_with_stream.rs",
"chars": 409,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse com::{com_interface, interfaces::"
},
{
"path": "tools/explorer-thumbnailer/src/interfaces/ithumbnail_provider.rs",
"chars": 446,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse com::com_interface;\nuse com::inte"
},
{
"path": "tools/explorer-thumbnailer/src/interfaces/mod.rs",
"chars": 251,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\npub mod iinitialize_with_stream;\npub "
},
{
"path": "tools/explorer-thumbnailer/src/lib.rs",
"chars": 3398,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse com::registration::{dll_register_"
},
{
"path": "tools/explorer-thumbnailer/src/thumbnail_provider.rs",
"chars": 2092,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse crate::interfaces::{IInitializeWi"
},
{
"path": "tools/explorer-thumbnailer/src/utils.rs",
"chars": 3116,
"preview": "// Copyright 2020 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\nuse crate::error::Error;\nuse com::sys"
},
{
"path": "tools/viewsvg/.gitignore",
"chars": 11,
"preview": "*.pro.user\n"
},
{
"path": "tools/viewsvg/README.md",
"chars": 279,
"preview": "# viewsvg\n\nA simple SVG viewer using resvg-qt.\n\n## Dependencies\n\n- Qt >= 5.6\n\n## Build\n\nNote: make sure you have read th"
},
{
"path": "tools/viewsvg/main.cpp",
"chars": 319,
"preview": "// Copyright 2017 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#include <QApplication>\n\n#include \"ma"
},
{
"path": "tools/viewsvg/mainwindow.cpp",
"chars": 1285,
"preview": "// Copyright 2017 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#include <QMessageBox>\n#include <QTim"
},
{
"path": "tools/viewsvg/mainwindow.h",
"chars": 510,
"preview": "// Copyright 2017 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#pragma once\n\n#include <QMainWindow>\n"
},
{
"path": "tools/viewsvg/mainwindow.ui",
"chars": 4354,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ui version=\"4.0\">\n <class>MainWindow</class>\n <widget class=\"QMainWindow\" name=\""
},
{
"path": "tools/viewsvg/svgview.cpp",
"chars": 7145,
"preview": "// Copyright 2017 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#include <QDropEvent>\n#include <QElap"
},
{
"path": "tools/viewsvg/svgview.h",
"chars": 1911,
"preview": "// Copyright 2017 the Resvg Authors\n// SPDX-License-Identifier: Apache-2.0 OR MIT\n\n#pragma once\n\n#include <QWidget>\n#inc"
},
{
"path": "tools/viewsvg/viewsvg.pro",
"chars": 517,
"preview": "QT += core gui widgets\n\nTARGET = viewsvg\nTEMPLATE = app\nCONFIG += c++11\n\nSOURCES += \\\n main.cpp \\\n mainwindow.cpp "
},
{
"path": "version-bump.md",
"chars": 276,
"preview": "- .github/chart.svg\n- .github/chart-svg2.svg\n- CHANGELOG.md\n- crates/usvg/Cargo.toml\n- crates/resvg/Cargo.toml\n- crates/"
}
]
// ... and 2 more files (download for full content)
About this extraction
This page contains the full source code of the linebender/resvg GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 135 files (1.3 MB), approximately 343.8k tokens, and a symbol index with 3097 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.