svg2pdf/render/
pattern.rs1use std::sync::Arc;
2
3use pdf_writer::types::{PaintType, TilingType};
4use pdf_writer::{Chunk, Content, Filter, Ref};
5use usvg::{Opacity, Pattern, Transform};
6
7use super::group;
8use crate::util::context::Context;
9use crate::util::helper::TransformExt;
10use crate::util::resources::ResourceContainer;
11use crate::Result;
12
13pub fn create(
15 pattern: Arc<Pattern>,
16 chunk: &mut Chunk,
17 ctx: &mut Context,
18 matrix: Transform,
19 initial_opacity: Option<Opacity>,
20) -> Result<Ref> {
21 let pattern_ref = ctx.alloc_ref();
22 let mut rc = ResourceContainer::new();
23
24 let pattern_rect = pattern.rect();
25
26 let pattern_matrix = matrix.pre_concat(pattern.transform()).pre_concat(
27 Transform::from_row(1.0, 0.0, 0.0, 1.0, pattern_rect.x(), pattern_rect.y()),
28 );
29
30 let mut content = Content::new();
31 group::render(
32 pattern.root(),
33 chunk,
34 &mut content,
35 ctx,
36 Transform::default(),
37 initial_opacity,
38 &mut rc,
39 )?;
40
41 let content_stream = ctx.finish_content(content);
42
43 let mut tiling_pattern = chunk.tiling_pattern(pattern_ref, &content_stream);
44
45 if ctx.options.compress {
46 tiling_pattern.filter(Filter::FlateDecode);
47 }
48
49 rc.finish(&mut tiling_pattern.resources());
50
51 let final_bbox =
54 pdf_writer::Rect::new(0.0, 0.0, pattern_rect.width(), pattern_rect.height());
55
56 tiling_pattern
57 .tiling_type(TilingType::ConstantSpacing)
58 .paint_type(PaintType::Colored)
59 .bbox(final_bbox)
60 .matrix(pattern_matrix.to_pdf_transform())
61 .x_step(final_bbox.x2 - final_bbox.x1)
62 .y_step(final_bbox.y2 - final_bbox.y1);
63
64 Ok(pattern_ref)
65}