Skip to content

Commit 68e3403

Browse files
authored
Bump to resvg 0.40 (#62)
1 parent b583dfe commit 68e3403

31 files changed

+507
-671
lines changed

Diff for: Cargo.lock

+180-263
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: Cargo.toml

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,17 @@ svg2pdf = { path = ".", version = "0.9.1" }
1616
clap = { version = "4.4.2", features = ["derive"] }
1717
clap_complete = "4.4.3"
1818
clap_mangen = "0.2.14"
19-
fontdb = "0.16.0"
19+
fontdb = "0.16.1"
2020
image = { version = "0.24", default-features = false, features = ["jpeg", "png", "gif"] }
2121
miniz_oxide = "0.7"
2222
once_cell = "1.18.0"
2323
oxipng = { version = "9", default-features = false, features = ["filetime", "parallel", "zopfli"] }
2424
pdf-writer = "0.9"
2525
pdfium-render = "0.8.6"
2626
termcolor = "1.2"
27-
usvg = { version = "0.38.0", default-features = false, features = ["text"] }
28-
tiny-skia = "0.11.3"
29-
resvg = { version = "0.38.0" }
27+
usvg = { version = "0.40", default-features = false, features = ["text"] }
28+
tiny-skia = "0.11.4"
29+
resvg = "0.40"
3030

3131
[package]
3232
name = "svg2pdf"

Diff for: README.md

+3-40
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,9 @@ This crate allows to convert static (i.e. non-interactive) SVG files to
1010
either standalone PDF files or Form XObjects that can be embedded in another
1111
PDF file and used just like images.
1212

13-
Apart from groups with filters on them, the conversion will translate
14-
the SVG content to PDF without rasterizing it, so no quality is lost.
15-
16-
## Example
17-
18-
This example reads an SVG file and writes the corresponding PDF back to the disk.
19-
20-
```rust
21-
let path = "tests/svg/custom/integration/matplotlib/time_series.svg";
22-
let svg = std::fs::read_to_string(path)?;
23-
24-
// This can only fail if the SVG is malformed. This one is not.
25-
let pdf = svg2pdf::convert_str(&svg, svg2pdf::Options::default())?;
26-
27-
// ... and now you have a Vec<u8> which you could write to a file or
28-
// transmit over the network!
29-
std::fs::write("target/time_series.pdf", pdf)?;
30-
```
13+
See the [documentation](https://docs.rs/svg2pdf/latest/svg2pdf/) for a more detailed
14+
description, including which features are supported and which are not, as well as for
15+
examples on how to use this library.
3116

3217
## CLI
3318

@@ -44,28 +29,6 @@ You can then convert SVGs to PDFs by running commands like these:
4429
svg2pdf your.svg
4530
```
4631

47-
## Supported features
48-
In general, a large part of the SVG specification is supported, including
49-
features like:
50-
- Path drawing with fills and strokes
51-
- Gradients
52-
- Patterns
53-
- Clip paths
54-
- Masks
55-
- Filters
56-
- Transformation matrices
57-
- Respecting the `keepAspectRatio` attribute
58-
- Raster images and nested SVGs
59-
60-
## Unsupported features
61-
Among the unsupported features are currently:
62-
- The `spreadMethod` attribute of gradients
63-
- Text will be converted into shapes before converting to PDF. It is planned
64-
to add support for text preservation in a future update.
65-
- Raster images are not color managed but use PDF's DeviceRGB color space
66-
- A number of features that were added in SVG2
67-
(see [here](https://github.com/RazrFalcon/resvg/blob/master/docs/svg2-changelog.md))
68-
6932
## Contributing
7033
We are looking forward to receiving your bugs and feature requests in the Issues
7134
tab. We would also be very happy to accept PRs for bug fixes, features, or

Diff for: cli/src/convert.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use crate::args::ConvertCommand;
22
use std::path::{Path, PathBuf};
33
use svg2pdf::Options;
4-
use usvg::{PostProcessingSteps, TreeParsing, TreePostProc};
54

65
/// Execute a font listing command.
76
pub fn _convert(command: ConvertCommand) -> Result<(), String> {
@@ -31,8 +30,8 @@ pub fn convert_(
3130

3231
let options = usvg::Options::default();
3332

34-
let mut tree = usvg::Tree::from_str(&svg, &options).map_err(|err| err.to_string())?;
35-
tree.postprocess(PostProcessingSteps::default(), &fontdb);
33+
let tree =
34+
usvg::Tree::from_str(&svg, &options, &fontdb).map_err(|err| err.to_string())?;
3635

3736
let pdf = svg2pdf::convert_tree(&tree, Options { dpi, ..Options::default() });
3837

Diff for: src/lib.rs

+42-30
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,25 @@ This crate allows to convert static (i.e. non-interactive) SVG files to
44
either standalone PDF files or Form XObjects that can be embedded in another
55
PDF file and used just like images.
66
7-
The conversion will translate the SVG content to PDF without rasterizing them,
8-
so no quality is lost.
7+
The conversion will translate the SVG content to PDF without rasterizing them
8+
(the only exception being objects with filters on them, but in this case only
9+
this single group will be rasterized, while the remaining contents of the SVG
10+
will still be turned into a vector graphic), so no quality is lost.
911
1012
## Example
1113
This example reads an SVG file and writes the corresponding PDF back to the disk.
1214
1315
```
1416
# fn main() -> Result<(), Box<dyn std::error::Error>> {
17+
use svg2pdf::usvg::fontdb;
18+
1519
let path = "tests/svg/custom/integration/matplotlib/time_series.svg";
1620
let svg = std::fs::read_to_string(path)?;
21+
let mut db = fontdb::Database::new();
22+
db.load_system_fonts();
1723
1824
// This can only fail if the SVG is malformed. This one is not.
19-
let pdf = svg2pdf::convert_str(&svg, svg2pdf::Options::default())?;
25+
let pdf = svg2pdf::convert_str(&svg, svg2pdf::Options::default(), &db)?;
2026
2127
// ... and now you have a Vec<u8> which you could write to a file or
2228
// transmit over the network!
@@ -25,22 +31,26 @@ std::fs::write("target/time_series.pdf", pdf)?;
2531
```
2632
2733
## Supported features
28-
In general, a large part of the SVG specification is supported, including features like:
29-
- Path drawing with fills and strokes
34+
In general, a very large part of the SVG specification is supported, including
35+
but not limited to:
36+
- Paths with simple and complex fills
3037
- Gradients
3138
- Patterns
3239
- Clip paths
3340
- Masks
34-
- Transformation matrices
35-
- Respecting the `keepAspectRatio` attribute
41+
- Transformations
42+
- Viewbox
43+
- Text (although it will be converted into paths)
3644
- Raster images and nested SVGs
3745
3846
## Unsupported features
3947
Among the unsupported features are currently:
4048
- The `spreadMethod` attribute of gradients
4149
- Filters
4250
- Raster images are not color managed but use PDF's DeviceRGB color space
43-
- A number of features that were added in SVG2
51+
- A number of features that were added in SVG2, See
52+
[here](https://github.com/RazrFalcon/resvg/blob/master/docs/svg2-changelog.md) for a more
53+
comprehensive list.
4454
*/
4555

4656
mod render;
@@ -50,8 +60,7 @@ pub use usvg;
5060

5161
use once_cell::sync::Lazy;
5262
use pdf_writer::{Chunk, Content, Filter, Finish, Pdf, Rect, Ref, TextStr};
53-
use usvg::utils::view_box_to_transform;
54-
use usvg::{Align, AspectRatio, NonZeroRect, Size, Transform, Tree, TreeParsing};
63+
use usvg::{fontdb, Align, AspectRatio, NonZeroRect, Size, Transform, Tree, ViewBox};
5564

5665
use crate::render::tree_to_stream;
5766
use crate::util::context::Context;
@@ -134,19 +143,17 @@ impl Default for Options {
134143

135144
/// Convert an SVG source string to a standalone PDF buffer.
136145
///
137-
/// Does not load any fonts and consequently cannot convert `text` elements. To
138-
/// convert text, you should convert your source string to a
139-
/// [`usvg` tree](Tree) manually,
140-
/// [convert text with usvg](usvg::TreePostProc::postprocess) and then use
141-
/// [`convert_tree`].
142-
///
143146
/// Returns an error if the SVG string is malformed.
144-
pub fn convert_str(src: &str, options: Options) -> Result<Vec<u8>, usvg::Error> {
147+
pub fn convert_str(
148+
src: &str,
149+
options: Options,
150+
fontdb: &fontdb::Database,
151+
) -> Result<Vec<u8>, usvg::Error> {
145152
let mut usvg_options = usvg::Options::default();
146153
if let Some(size) = options.viewport {
147154
usvg_options.default_size = size;
148155
}
149-
let tree = Tree::from_str(src, &usvg_options)?;
156+
let tree = Tree::from_str(src, &usvg_options, fontdb)?;
150157
Ok(convert_tree(&tree, options))
151158
}
152159

@@ -158,19 +165,17 @@ pub fn convert_str(src: &str, options: Options) -> Result<Vec<u8>, usvg::Error>
158165
///
159166
/// ```
160167
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
161-
/// use svg2pdf::usvg::{fontdb, PostProcessingSteps, TreeParsing, TreePostProc};
168+
/// use svg2pdf::usvg::fontdb;
162169
/// use svg2pdf::Options;
163170
///
164171
/// let input = "tests/svg/custom/integration/matplotlib/step.svg";
165172
/// let output = "target/step.pdf";
166173
///
167174
/// let svg = std::fs::read_to_string(input)?;
168175
/// let options = svg2pdf::usvg::Options::default();
169-
/// let mut tree = svg2pdf::usvg::Tree::from_str(&svg, &options)?;
170-
///
171176
/// let mut db = fontdb::Database::new();
172177
/// db.load_system_fonts();
173-
/// tree.postprocess(PostProcessingSteps::default(), &db);
178+
/// let mut tree = svg2pdf::usvg::Tree::from_str(&svg, &options, &db)?;
174179
///
175180
///
176181
/// let pdf = svg2pdf::convert_tree(&tree, Options::default());
@@ -256,7 +261,7 @@ pub fn convert_tree(tree: &Tree, options: Options) -> Vec<u8> {
256261
/// # fn main() -> Result<(), Box<dyn std::error::Error>> {
257262
/// use svg2pdf;
258263
/// use pdf_writer::{Content, Finish, Name, Pdf, Rect, Ref, Str};
259-
/// use svg2pdf::usvg::TreeParsing;
264+
/// use svg2pdf::usvg::fontdb;
260265
///
261266
/// // Allocate the indirect reference IDs and names.
262267
/// let catalog_id = Ref::new(1);
@@ -294,7 +299,9 @@ pub fn convert_tree(tree: &Tree, options: Options) -> Vec<u8> {
294299
/// // We need to load its source first and manually parse it into a usvg Tree.
295300
/// let path = "tests/svg/custom/integration/matplotlib/step.svg";
296301
/// let svg = std::fs::read_to_string(path)?;
297-
/// let tree = svg2pdf::usvg::Tree::from_str(&svg, &svg2pdf::usvg::Options::default())?;
302+
/// let mut db = fontdb::Database::new();
303+
/// db.load_system_fonts();
304+
/// let tree = svg2pdf::usvg::Tree::from_str(&svg, &svg2pdf::usvg::Options::default(), &db)?;
298305
///
299306
/// // Then, we will write it to the page as the 6th indirect object.
300307
/// //
@@ -391,7 +398,7 @@ fn write_color_spaces(ctx: &mut Context, chunk: &mut Chunk) {
391398
/// Return the dimensions of the PDF page
392399
fn pdf_size(tree: &Tree, options: Options) -> Size {
393400
// If no custom viewport is defined, we use the size of the tree.
394-
let viewport_size = options.viewport.unwrap_or(tree.size);
401+
let viewport_size = options.viewport.unwrap_or(tree.size());
395402
Size::from_wh(
396403
// dpi_ratio is in dot per user unit so dividing by it gave user unit
397404
viewport_size.width() / dpi_ratio(options.dpi),
@@ -410,11 +417,16 @@ fn initial_transform(
410417
// Account for the custom viewport that has been passed in the Options struct. If nothing has
411418
// been passed, pdf_size should be the same as tree.size, so the transform will just be the
412419
// default transform.
413-
let custom_viewport_transform = view_box_to_transform(
414-
NonZeroRect::from_xywh(0.0, 0.0, tree.size.width(), tree.size.height()).unwrap(),
415-
aspect.unwrap_or(AspectRatio { defer: false, align: Align::None, slice: false }),
416-
pdf_size,
417-
);
420+
let view_box = ViewBox {
421+
rect: NonZeroRect::from_xywh(0.0, 0.0, tree.size().width(), tree.size().height())
422+
.unwrap(),
423+
aspect: aspect.unwrap_or(AspectRatio {
424+
defer: false,
425+
align: Align::None,
426+
slice: false,
427+
}),
428+
};
429+
let custom_viewport_transform = view_box.to_transform(pdf_size);
418430

419431
// Account for the direction of the y axis and the shift of the origin in the coordinate system.
420432
let pdf_transform = Transform::from_row(1.0, 0.0, 0.0, -1.0, 0.0, pdf_size.height());

0 commit comments

Comments
 (0)