summaryrefslogtreecommitdiff
path: root/src/utils.rs
diff options
context:
space:
mode:
authorEvgeniy Reizner <razrfalcon@gmail.com>2019-05-26 23:45:22 +0300
committerGitHub <noreply@github.com>2019-05-26 23:45:22 +0300
commit01582324f464890976cacb1e4703c4a513f9f283 (patch)
tree88ba1d0399d96511ce3df78b1a2e69d6f9271be4 /src/utils.rs
parentd6c1553384964510c1e8225fb328762c35f2b89d (diff)
New text layout.
Closes #89, Closes #90, Closes #92, Closes #95, Closes #96, Closes #103, Closes #109, Closes #122
Diffstat (limited to 'src/utils.rs')
-rw-r--r--src/utils.rs230
1 files changed, 0 insertions, 230 deletions
diff --git a/src/utils.rs b/src/utils.rs
index bbc5d3c..46303d6 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -69,233 +69,3 @@ pub fn abs_transform(
root_ts
}
-
-/// Calculates path's bounding box.
-///
-/// Width and/or height can be zero.
-pub fn path_bbox(
- segments: &[usvg::PathSegment],
- stroke: Option<&usvg::Stroke>,
- ts: Option<usvg::Transform>,
-) -> Option<Rect> {
- debug_assert!(!segments.is_empty());
-
- let ts = match ts {
- Some(ts) => ts,
- None => usvg::Transform::default(),
- };
-
- use crate::lyon_geom;
-
- let mut prev_x = 0.0;
- let mut prev_y = 0.0;
- let mut minx = 0.0;
- let mut miny = 0.0;
- let mut maxx = 0.0;
- let mut maxy = 0.0;
-
- if let Some(usvg::PathSegment::MoveTo { x, y }) = TransformedPath::new(segments, ts).next() {
- let x = x as f32;
- let y = y as f32;
-
- prev_x = x;
- prev_y = y;
- minx = x;
- miny = y;
- maxx = x;
- maxy = y;
- }
-
- for seg in TransformedPath::new(segments, ts) {
- match seg {
- usvg::PathSegment::MoveTo { x, y }
- | usvg::PathSegment::LineTo { x, y } => {
- let x = x as f32;
- let y = y as f32;
- prev_x = x;
- prev_y = y;
-
- if x > maxx { maxx = x; }
- else if x < minx { minx = x; }
-
- if y > maxy { maxy = y; }
- else if y < miny { miny = y; }
- }
- usvg::PathSegment::CurveTo { x1, y1, x2, y2, x, y } => {
- let x = x as f32;
- let y = y as f32;
-
- let curve = lyon_geom::CubicBezierSegment {
- from: lyon_geom::math::Point::new(prev_x, prev_y),
- ctrl1: lyon_geom::math::Point::new(x1 as f32, y1 as f32),
- ctrl2: lyon_geom::math::Point::new(x2 as f32, y2 as f32),
- to: lyon_geom::math::Point::new(x, y),
- };
-
- prev_x = x;
- prev_y = y;
-
- let r = curve.bounding_rect();
-
- let right = r.max_x();
- let bottom = r.max_y();
- if r.min_x() < minx { minx = r.min_x(); }
- if right > maxx { maxx = right; }
- if r.min_y() < miny { miny = r.min_y(); }
- if bottom > maxy { maxy = bottom; }
- }
- usvg::PathSegment::ClosePath => {}
- }
- }
-
- // TODO: find a better way
- // It's an approximation, but it's better than nothing.
- if let Some(ref stroke) = stroke {
- let w = (stroke.width.value() / 2.0) as f32;
- minx -= w;
- miny -= w;
- maxx += w;
- maxy += w;
- }
-
- let width = maxx - minx;
- let height = maxy - miny;
-
- Rect::new(minx as f64, miny as f64, width as f64, height as f64)
-}
-
-/// Calculates path's length.
-///
-/// Length from the first segment to the first MoveTo, ClosePath or slice end.
-pub fn path_length(segments: &[usvg::PathSegment]) -> f64 {
- debug_assert!(!segments.is_empty());
-
- use crate::lyon_geom;
-
- let (mut prev_x, mut prev_y) = {
- if let usvg::PathSegment::MoveTo { x, y } = segments[0] {
- (x as f32, y as f32)
- } else {
- panic!("first segment must be MoveTo");
- }
- };
-
- let start_x = prev_x;
- let start_y = prev_y;
-
- let mut is_first_seg = true;
- let mut length = 0.0f64;
- for seg in segments {
- match *seg {
- usvg::PathSegment::MoveTo { .. } => {
- if !is_first_seg {
- break;
- }
- }
- usvg::PathSegment::LineTo { x, y } => {
- length += Line::new(prev_x as f64, prev_y as f64, x, y).length();
-
- prev_x = x as f32;
- prev_y = y as f32;
- }
- usvg::PathSegment::CurveTo { x1, y1, x2, y2, x, y } => {
- let x = x as f32;
- let y = y as f32;
-
- let curve = lyon_geom::CubicBezierSegment {
- from: lyon_geom::math::Point::new(prev_x, prev_y),
- ctrl1: lyon_geom::math::Point::new(x1 as f32, y1 as f32),
- ctrl2: lyon_geom::math::Point::new(x2 as f32, y2 as f32),
- to: lyon_geom::math::Point::new(x, y),
- };
-
- length += curve.approximate_length(1.0) as f64;
-
- prev_x = x;
- prev_y = y;
- }
- usvg::PathSegment::ClosePath => {
- length += Line::new(prev_x as f64, prev_y as f64,
- start_x as f64, start_y as f64).length();
- break;
- }
- }
-
- is_first_seg = false;
- }
-
- length
-}
-
-/// Applies the transform to the path segments.
-pub fn transform_path(segments: &mut [usvg::PathSegment], ts: &usvg::Transform) {
- for seg in segments {
- match *seg {
- usvg::PathSegment::MoveTo { ref mut x, ref mut y } => {
- ts.apply_to(x, y);
- }
- usvg::PathSegment::LineTo { ref mut x, ref mut y } => {
- ts.apply_to(x, y);
- }
- usvg::PathSegment::CurveTo { ref mut x1, ref mut y1, ref mut x2,
- ref mut y2, ref mut x, ref mut y } => {
- ts.apply_to(x1, y1);
- ts.apply_to(x2, y2);
- ts.apply_to(x, y);
- }
- usvg::PathSegment::ClosePath => {}
- }
- }
-}
-
-
-/// An iterator over transformed path segments.
-pub struct TransformedPath<'a> {
- segments: &'a [usvg::PathSegment],
- ts: usvg::Transform,
- idx: usize,
-}
-
-impl<'a> TransformedPath<'a> {
- /// Creates a new `TransformedPath` iterator.
- pub fn new(segments: &'a [usvg::PathSegment], ts: usvg::Transform) -> Self {
- TransformedPath { segments, ts, idx: 0 }
- }
-}
-
-impl<'a> Iterator for TransformedPath<'a> {
- type Item = usvg::PathSegment;
-
- fn next(&mut self) -> Option<Self::Item> {
- if self.idx == self.segments.len() {
- return None;
- }
-
- if self.ts.is_default() {
- self.idx += 1;
- return self.segments.get(self.idx - 1).cloned();
- }
-
- let seg = match self.segments[self.idx] {
- usvg::PathSegment::MoveTo { x, y } => {
- let (x, y) = self.ts.apply(x, y);
- usvg::PathSegment::MoveTo { x, y }
- }
- usvg::PathSegment::LineTo { x, y } => {
- let (x, y) = self.ts.apply(x, y);
- usvg::PathSegment::LineTo { x, y }
- }
- usvg::PathSegment::CurveTo { x1, y1, x2, y2, x, y } => {
- let (x1, y1) = self.ts.apply(x1, y1);
- let (x2, y2) = self.ts.apply(x2, y2);
- let (x, y) = self.ts.apply(x, y);
- usvg::PathSegment::CurveTo { x1, y1, x2, y2, x, y }
- }
- usvg::PathSegment::ClosePath => usvg::PathSegment::ClosePath,
- };
-
- self.idx += 1;
-
- Some(seg)
- }
-}