pub struct Svg {
pub width: Px,
pub height: Px,
/* private fields */
}
Expand description
SVG - wrapper around an XObject
to allow for more
control within the library.
When placing multiple copies of the same SVG on the
same layer, it is better to use the into_xobject
method to get a reference, rather than a clone
Fields§
§width: Px
Width of the rendered SVG content
height: Px
Height of the rendered SVG content
Implementations§
source§impl Svg
impl Svg
sourcepub fn parse(svg_string: &str) -> Result<Self, SvgParseError>
pub fn parse(svg_string: &str) -> Result<Self, SvgParseError>
Internally parses the SVG string, converts it to a PDF document using the svg2pdf crate, parses the resulting PDF again (using lopdf), then extracts the SVG XObject.
I wish there was a more direct way, but handling SVG is very tricky.
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
fn main() {
let (doc, page1, layer1) =
PdfDocument::new("printpdf graphics test", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
let svg = Svg::parse(SVG).unwrap();
let rotation_center_x = Px((svg.width.0 as f32 / 2.0) as usize);
let rotation_center_y = Px((svg.height.0 as f32 / 2.0) as usize);
let reference = svg.into_xobject(¤t_layer);
for i in 0..10 {
reference.clone().add_to_layer(
¤t_layer,
SvgTransform {
rotate: Some(SvgRotation {
angle_ccw_degrees: i as f32 * 36.0,
rotation_center_x: rotation_center_x.into_pt(300.0),
rotation_center_y: rotation_center_y.into_pt(300.0),
}),
translate_x: Some(Mm(i as f32 * 20.0 % 50.0).into()),
translate_y: Some(Mm(i as f32 * 30.0).into()),
..Default::default()
},
);
}
let pdf_bytes = doc.save_to_bytes().unwrap();
std::fs::write("test_svg.pdf", &pdf_bytes).unwrap();
}
sourcepub fn into_xobject(self, layer: &PdfLayerReference) -> SvgXObjectRef
pub fn into_xobject(self, layer: &PdfLayerReference) -> SvgXObjectRef
Adds the SVG to the pages /Resources, returns the name of the reference to the SVG, so that one SVG can be used more than once on a page
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
fn main() {
let (doc, page1, layer1) =
PdfDocument::new("printpdf graphics test", Mm(210.0), Mm(297.0), "Layer 1");
let current_layer = doc.get_page(page1).get_layer(layer1);
let svg = Svg::parse(SVG).unwrap();
let rotation_center_x = Px((svg.width.0 as f32 / 2.0) as usize);
let rotation_center_y = Px((svg.height.0 as f32 / 2.0) as usize);
let reference = svg.into_xobject(¤t_layer);
for i in 0..10 {
reference.clone().add_to_layer(
¤t_layer,
SvgTransform {
rotate: Some(SvgRotation {
angle_ccw_degrees: i as f32 * 36.0,
rotation_center_x: rotation_center_x.into_pt(300.0),
rotation_center_y: rotation_center_y.into_pt(300.0),
}),
translate_x: Some(Mm(i as f32 * 20.0 % 50.0).into()),
translate_y: Some(Mm(i as f32 * 30.0).into()),
..Default::default()
},
);
}
let pdf_bytes = doc.save_to_bytes().unwrap();
std::fs::write("test_svg.pdf", &pdf_bytes).unwrap();
}
sourcepub fn add_to_layer(self, layer: &PdfLayerReference, transform: SvgTransform)
pub fn add_to_layer(self, layer: &PdfLayerReference, transform: SvgTransform)
Adds the image to a specific layer and consumes it.
This is due to a PDF weirdness - images are basically just “names” and you have to make sure that they are added to resources of the same page as they are used on.
You can use the “transform.dpi” parameter to specify a scaling - the default is 300dpi