1 | // This Source Code Form is subject to the terms of the Mozilla Public |
2 | // License, v. 2.0. If a copy of the MPL was not distributed with this |
3 | // file, You can obtain one at http://mozilla.org/MPL/2.0/. |
4 | |
5 | /// Fits the current rect into the specified bounds. |
6 | pub fn fit_to_rect( |
7 | r: tiny_skia::IntRect, |
8 | bounds: tiny_skia::IntRect, |
9 | ) -> Option<tiny_skia::IntRect> { |
10 | let mut left: i32 = r.left(); |
11 | if left < bounds.left() { |
12 | left = bounds.left(); |
13 | } |
14 | |
15 | let mut top: i32 = r.top(); |
16 | if top < bounds.top() { |
17 | top = bounds.top(); |
18 | } |
19 | |
20 | let mut right: i32 = r.right(); |
21 | if right > bounds.right() { |
22 | right = bounds.right(); |
23 | } |
24 | |
25 | let mut bottom: i32 = r.bottom(); |
26 | if bottom > bounds.bottom() { |
27 | bottom = bounds.bottom(); |
28 | } |
29 | |
30 | tiny_skia::IntRect::from_ltrb(left, top, right, bottom) |
31 | } |
32 | |
33 | /// Converts `viewBox` to `Transform` with an optional clip rectangle. |
34 | /// |
35 | /// Unlike `view_box_to_transform`, returns an optional clip rectangle |
36 | /// that should be applied before rendering the image. |
37 | pub fn view_box_to_transform_with_clip( |
38 | view_box: &usvg::ViewBox, |
39 | img_size: tiny_skia::IntSize, |
40 | ) -> (usvg::Transform, Option<tiny_skia::NonZeroRect>) { |
41 | let r = view_box.rect; |
42 | |
43 | let new_size = fit_view_box(img_size.to_size(), view_box); |
44 | |
45 | let (tx, ty, clip) = if view_box.aspect.slice { |
46 | let (dx, dy) = usvg::utils::aligned_pos( |
47 | view_box.aspect.align, |
48 | 0.0, |
49 | 0.0, |
50 | new_size.width() - r.width(), |
51 | new_size.height() - r.height(), |
52 | ); |
53 | |
54 | (r.x() - dx, r.y() - dy, Some(r)) |
55 | } else { |
56 | let (dx, dy) = usvg::utils::aligned_pos( |
57 | view_box.aspect.align, |
58 | r.x(), |
59 | r.y(), |
60 | r.width() - new_size.width(), |
61 | r.height() - new_size.height(), |
62 | ); |
63 | |
64 | (dx, dy, None) |
65 | }; |
66 | |
67 | let sx = new_size.width() / img_size.width() as f32; |
68 | let sy = new_size.height() / img_size.height() as f32; |
69 | let ts = usvg::Transform::from_row(sx, 0.0, 0.0, sy, tx, ty); |
70 | |
71 | (ts, clip) |
72 | } |
73 | |
74 | /// Fits size into a viewbox. |
75 | pub fn fit_view_box(size: usvg::Size, vb: &usvg::ViewBox) -> usvg::Size { |
76 | let s: Size = vb.rect.size(); |
77 | |
78 | if vb.aspect.align == usvg::Align::None { |
79 | s |
80 | } else if vb.aspect.slice { |
81 | size.expand_to(s) |
82 | } else { |
83 | size.scale_to(s) |
84 | } |
85 | } |
86 | |