Skip to content
Permalink
Browse files

Use kurbo instead of lyon.

Cause lyon is a pretty heavy dependency.
  • Loading branch information...
RazrFalcon committed Jun 16, 2019
1 parent 2fdccff commit 708d0fff2bf47939587e0d562085a65f6dbf794f
@@ -13,7 +13,6 @@ This changelog also contains important changes in dependencies.
- `writing-mode` support, aka vertical text.
- [Text BIDI reordering](http://www.unicode.org/reports/tr9/).
- Better text shaping.
- Text will be converted into paths on the `usvg` side now.
- `word-spacing` is supported for all backends now.
- [`harfbuzz`](https://github.com/harfbuzz/harfbuzz) dependency.
- Subscript, superscript offsets are extracted from font and not hardcoded now.
@@ -24,6 +23,7 @@ This changelog also contains important changes in dependencies.
- (qt-api) `ResvgRenderer::boundingBox`.

### Changed
- Text will be converted into paths on the `usvg` side now.
- (resvg) Do not rescale images before rendering. This is faster and better.
- (usvg) An `image` element with a zero or negative size will be skipped now.
Previously, a linked image size was used, which is incorrect.

Some generated files are not rendered by default. Learn more.

@@ -7,7 +7,7 @@
use std::{cmp, f64, fmt};

use usvg;
pub use usvg::{Line, Rect, Size};
pub use usvg::{Rect, Size};
pub(crate) use usvg::f64_bound;

use crate::utils;
@@ -1,3 +0,0 @@
e-filter-053.svg
e-filter-054.svg
e-mask-020.svg
@@ -1,3 +0,0 @@
e-filter-053.svg
e-filter-054.svg
e-mask-020.svg
@@ -21,9 +21,9 @@ travis-ci = { repository = "RazrFalcon/resvg" }
base64 = "0.10"
data-url = "0.1"
harfbuzz_rs = "1.0"
kurbo = { git = "https://github.com/linebender/kurbo", rev = "a006dd8" }
libflate = "0.1"
log = "0.4"
lyon_geom = "0.12"
memmap = "0.7"
rctree = "0.3"
svgdom = "0.17"
@@ -8,7 +8,7 @@ use std::rc::Rc;
use svgdom::{ElementType, FilterSvg, Length};
use log::warn;

use crate::{tree, tree::prelude::*, fontdb, Error};
use crate::{tree, tree::prelude::*, fontdb, utils, Error};
pub use self::preprocess::prepare_doc;


@@ -559,7 +559,7 @@ fn convert_path(
return;
}

let has_bbox = path::has_bbox(&segments);
let has_bbox = utils::path_has_bbox(&segments);
let attrs = node.attributes();
let fill = style::resolve_fill(node, has_bbox, state, tree);
let stroke = style::resolve_stroke(node, has_bbox, state, tree);
@@ -2,10 +2,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::f64;

use crate::tree;
use super::prelude::*;


pub fn convert(
@@ -93,24 +90,29 @@ pub fn convert(
}
}
svgdom::PathSegment::EllipticalArc { rx, ry, x_axis_rotation, large_arc, sweep, x, y, .. } => {
let arc = lyon_geom::SvgArc {
from: [px as f32, py as f32].into(),
to: [x as f32, y as f32].into(),
radii: [rx as f32, ry as f32].into(),
x_rotation: lyon_geom::math::Angle::degrees(x_axis_rotation as f32),
flags: lyon_geom::ArcFlags { large_arc, sweep },
let svg_arc = kurbo::SvgArc {
from: kurbo::Vec2::new(px, py),
to: kurbo::Vec2::new(x, y),
radii: kurbo::Vec2::new(rx, ry),
x_rotation: x_axis_rotation.to_radians(),
large_arc,
sweep,
};

arc.for_each_quadratic_bezier(&mut |quad| {
let cubic = quad.to_cubic();
let curve = tree::PathSegment::CurveTo {
x1: cubic.ctrl1.x as f64, y1: cubic.ctrl1.y as f64,
x2: cubic.ctrl2.x as f64, y2: cubic.ctrl2.y as f64,
x: cubic.to.x as f64, y: cubic.to.y as f64,
};

new_path.push(curve);
});
match kurbo::Arc::from_svg_arc(&svg_arc) {
Some(arc) => {
arc.to_cubic_beziers(0.1, |p1, p2, p| {
new_path.push(tree::PathSegment::CurveTo {
x1: p1.x, y1: p1.y,
x2: p2.x, y2: p2.y,
x: p.x, y: p.y,
});
});
}
None => {
new_path.push(tree::PathSegment::LineTo { x, y });
}
}
}
svgdom::PathSegment::ClosePath { .. } => {
if let Some(tree::PathSegment::ClosePath) = new_path.last() {
@@ -171,87 +173,15 @@ pub fn convert(
new_path
}

fn quad_to_curve(
px: f64,
py: f64,
x1: f64,
y1: f64,
x: f64,
y: f64,
) -> tree::PathSegment {
let quad = lyon_geom::QuadraticBezierSegment {
from: [px as f32, py as f32].into(),
ctrl: [x1 as f32, y1 as f32].into(),
to: [x as f32, y as f32].into(),
};

let cubic = quad.to_cubic();

tree::PathSegment::CurveTo {
x1: cubic.ctrl1.x as f64, y1: cubic.ctrl1.y as f64,
x2: cubic.ctrl2.x as f64, y2: cubic.ctrl2.y as f64,
x: cubic.to.x as f64, y: cubic.to.y as f64,
fn quad_to_curve(px: f64, py: f64, x1: f64, y1: f64, x: f64, y: f64) -> tree::PathSegment {
#[inline]
fn calc(n1: f64, n2: f64) -> f64 {
(n1 + n2 * 2.0) / 3.0
}
}

pub fn has_bbox(segments: &[tree::PathSegment]) -> bool {
debug_assert!(!segments.is_empty());

let (mut prev_x, mut prev_y, mut minx, mut miny, mut maxx, mut maxy) = {
if let tree::PathSegment::MoveTo { x, y } = segments[0] {
(x as f32, y as f32, x as f32, y as f32, x as f32, y as f32)
} else {
unreachable!();
}
};

for seg in segments {
match *seg {
tree::PathSegment::MoveTo { x, y }
| tree::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; }
}
tree::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; }
}
tree::PathSegment::ClosePath => {}
}

let width = (maxx - minx) as f64;
let height = (maxy - miny) as f64;
if !(width.is_fuzzy_zero() || height.is_fuzzy_zero()) {
return true;
}
tree::PathSegment::CurveTo {
x1: calc(px, x1), y1: calc(py, y1),
x2: calc(x, x1), y2: calc(y, y1),
x, y,
}

false
}

0 comments on commit 708d0ff

Please sign in to comment.
You can’t perform that action at this time.