Add some implicit conversions between scalars and vectors where appropriate
This commit is contained in:
parent
40bd13aa5a
commit
794dd55038
|
@ -341,7 +341,7 @@ pub unsafe extern "C" fn PFCanvasSetLineDashOffset(canvas: PFCanvasRef, new_offs
|
||||||
pub unsafe extern "C" fn PFCanvasSetFontByPostScriptName(canvas: PFCanvasRef,
|
pub unsafe extern "C" fn PFCanvasSetFontByPostScriptName(canvas: PFCanvasRef,
|
||||||
postscript_name: *const c_char,
|
postscript_name: *const c_char,
|
||||||
postscript_name_len: usize) {
|
postscript_name_len: usize) {
|
||||||
(*canvas).set_font_by_postscript_name(to_rust_string(&postscript_name, postscript_name_len))
|
(*canvas).set_font(to_rust_string(&postscript_name, postscript_name_len))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
|
@ -23,7 +23,7 @@ use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
||||||
use pathfinder_geometry::line_segment::LineSegment2F;
|
use pathfinder_geometry::line_segment::LineSegment2F;
|
||||||
use pathfinder_geometry::rect::RectF;
|
use pathfinder_geometry::rect::RectF;
|
||||||
use pathfinder_geometry::transform2d::Transform2F;
|
use pathfinder_geometry::transform2d::Transform2F;
|
||||||
use pathfinder_geometry::vector::{Vector2F, vec2f};
|
use pathfinder_geometry::vector::{IntoVector2F, Vector2F, vec2f};
|
||||||
use pathfinder_renderer::paint::{Paint, PaintId};
|
use pathfinder_renderer::paint::{Paint, PaintId};
|
||||||
use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, RenderTarget, Scene};
|
use pathfinder_renderer::scene::{ClipPath, ClipPathId, DrawPath, RenderTarget, Scene};
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
@ -550,7 +550,7 @@ impl Path2D {
|
||||||
start_angle: f32,
|
start_angle: f32,
|
||||||
end_angle: f32,
|
end_angle: f32,
|
||||||
direction: ArcDirection) {
|
direction: ArcDirection) {
|
||||||
let transform = Transform2F::from_scale(Vector2F::splat(radius)).translate(center);
|
let transform = Transform2F::from_scale(radius).translate(center);
|
||||||
self.current_contour.push_arc(&transform, start_angle, end_angle, direction);
|
self.current_contour.push_arc(&transform, start_angle, end_angle, direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,12 +562,10 @@ impl Path2D {
|
||||||
let (vu0, vu1) = (v0.normalize(), v1.normalize());
|
let (vu0, vu1) = (v0.normalize(), v1.normalize());
|
||||||
let hypot = radius / f32::sqrt(0.5 * (1.0 - vu0.dot(vu1)));
|
let hypot = radius / f32::sqrt(0.5 * (1.0 - vu0.dot(vu1)));
|
||||||
let bisector = vu0 + vu1;
|
let bisector = vu0 + vu1;
|
||||||
let center = ctrl + bisector.scale(hypot / bisector.length());
|
let center = ctrl + bisector * (hypot / bisector.length());
|
||||||
|
|
||||||
let transform = Transform2F::from_scale(Vector2F::splat(radius)).translate(center);
|
let transform = Transform2F::from_scale(radius).translate(center);
|
||||||
|
let chord = LineSegment2F::new(vu0.yx() * vec2f(-1.0, 1.0), vu1.yx() * vec2f( 1.0, -1.0));
|
||||||
let chord = LineSegment2F::new(vu0.yx().scale_xy(vec2f(-1.0, 1.0)),
|
|
||||||
vu1.yx().scale_xy(vec2f( 1.0, -1.0)));
|
|
||||||
|
|
||||||
// FIXME(pcwalton): Is clockwise direction correct?
|
// FIXME(pcwalton): Is clockwise direction correct?
|
||||||
self.current_contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW);
|
self.current_contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW);
|
||||||
|
@ -582,12 +580,13 @@ impl Path2D {
|
||||||
self.current_contour.close();
|
self.current_contour.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ellipse(&mut self,
|
pub fn ellipse<A>(&mut self,
|
||||||
center: Vector2F,
|
center: Vector2F,
|
||||||
axes: Vector2F,
|
axes: A,
|
||||||
rotation: f32,
|
rotation: f32,
|
||||||
start_angle: f32,
|
start_angle: f32,
|
||||||
end_angle: f32) {
|
end_angle: f32)
|
||||||
|
where A: IntoVector2F {
|
||||||
self.flush_current_contour();
|
self.flush_current_contour();
|
||||||
|
|
||||||
let transform = Transform2F::from_scale(axes).rotate(rotation).translate(center);
|
let transform = Transform2F::from_scale(axes).rotate(rotation).translate(center);
|
||||||
|
|
|
@ -33,7 +33,7 @@ impl<'a> ContourDilator<'a> {
|
||||||
|
|
||||||
pub fn dilate(&mut self) {
|
pub fn dilate(&mut self) {
|
||||||
// Determine orientation.
|
// Determine orientation.
|
||||||
let scale = self.amount.scale_xy(match self.orientation {
|
let scale = self.amount * (match self.orientation {
|
||||||
Orientation::Ccw => vec2f( 1.0, -1.0),
|
Orientation::Ccw => vec2f( 1.0, -1.0),
|
||||||
Orientation::Cw => vec2f(-1.0, 1.0),
|
Orientation::Cw => vec2f(-1.0, 1.0),
|
||||||
});
|
});
|
||||||
|
@ -86,7 +86,7 @@ impl<'a> ContourDilator<'a> {
|
||||||
let scaled_bisector = if bisector_length == 0.0 {
|
let scaled_bisector = if bisector_length == 0.0 {
|
||||||
Vector2F::zero()
|
Vector2F::zero()
|
||||||
} else {
|
} else {
|
||||||
bisector.scale_xy(scale).scale(1.0 / bisector_length)
|
bisector * scale * (1.0 / bisector_length)
|
||||||
};
|
};
|
||||||
let new_position = position - scaled_bisector;
|
let new_position = position - scaled_bisector;
|
||||||
|
|
||||||
|
|
|
@ -420,7 +420,7 @@ impl Contour {
|
||||||
direction: ArcDirection) {
|
direction: ArcDirection) {
|
||||||
let mut direction_transform = Transform2F::default();
|
let mut direction_transform = Transform2F::default();
|
||||||
if direction == ArcDirection::CCW {
|
if direction == ArcDirection::CCW {
|
||||||
chord = chord.scale_xy(vec2f(1.0, -1.0));
|
chord *= vec2f(1.0, -1.0);
|
||||||
direction_transform = Transform2F::from_scale(vec2f(1.0, -1.0));
|
direction_transform = Transform2F::from_scale(vec2f(1.0, -1.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -103,7 +103,7 @@ impl Segment {
|
||||||
let p0 = Vector2F::splat(SQRT_2 * 0.5);
|
let p0 = Vector2F::splat(SQRT_2 * 0.5);
|
||||||
let p1 = vec2f(-SQRT_2 / 6.0 + 4.0 / 3.0, 7.0 * SQRT_2 / 6.0 - 4.0 / 3.0);
|
let p1 = vec2f(-SQRT_2 / 6.0 + 4.0 / 3.0, 7.0 * SQRT_2 / 6.0 - 4.0 / 3.0);
|
||||||
let flip = vec2f(1.0, -1.0);
|
let flip = vec2f(1.0, -1.0);
|
||||||
let (p2, p3) = (p1.scale_xy(flip), p0.scale_xy(flip));
|
let (p2, p3) = (p1 * flip, p0 * flip);
|
||||||
Segment::cubic(LineSegment2F::new(p3, p0), LineSegment2F::new(p2, p1))
|
Segment::cubic(LineSegment2F::new(p3, p0), LineSegment2F::new(p2, p1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +150,7 @@ impl Segment {
|
||||||
let mut new_segment = *self;
|
let mut new_segment = *self;
|
||||||
let p1_2 = self.ctrl.from() + self.ctrl.from();
|
let p1_2 = self.ctrl.from() + self.ctrl.from();
|
||||||
new_segment.ctrl = LineSegment2F::new(self.baseline.from() + p1_2,
|
new_segment.ctrl = LineSegment2F::new(self.baseline.from() + p1_2,
|
||||||
p1_2 + self.baseline.to()).scale(1.0 / 3.0);
|
p1_2 + self.baseline.to()) * (1.0 / 3.0);
|
||||||
new_segment.kind = SegmentKind::Cubic;
|
new_segment.kind = SegmentKind::Cubic;
|
||||||
new_segment
|
new_segment
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ use pathfinder_geometry::line_segment::LineSegment2F;
|
||||||
use pathfinder_geometry::rect::RectF;
|
use pathfinder_geometry::rect::RectF;
|
||||||
use pathfinder_geometry::transform2d::Transform2F;
|
use pathfinder_geometry::transform2d::Transform2F;
|
||||||
use pathfinder_geometry::util::EPSILON;
|
use pathfinder_geometry::util::EPSILON;
|
||||||
use pathfinder_geometry::vector::Vector2F;
|
use pathfinder_geometry::vector::{Vector2F, vec2f};
|
||||||
use std::f32;
|
use std::f32;
|
||||||
|
|
||||||
const TOLERANCE: f32 = 0.01;
|
const TOLERANCE: f32 = 0.01;
|
||||||
|
@ -139,10 +139,10 @@ impl<'a> OutlineStrokeToFill<'a> {
|
||||||
LineCap::Butt => unreachable!(),
|
LineCap::Butt => unreachable!(),
|
||||||
|
|
||||||
LineCap::Square => {
|
LineCap::Square => {
|
||||||
let offset = gradient.scale(width * 0.5);
|
let offset = gradient * (width * 0.5);
|
||||||
|
|
||||||
let p2 = p1 + offset;
|
let p2 = p1 + offset;
|
||||||
let p3 = p2 + gradient.yx().scale_xy(Vector2F::new(-width, width));
|
let p3 = p2 + gradient.yx() * vec2f(-width, width);
|
||||||
let p4 = p3 - offset;
|
let p4 = p3 - offset;
|
||||||
|
|
||||||
contour.push_endpoint(p2);
|
contour.push_endpoint(p2);
|
||||||
|
@ -151,9 +151,9 @@ impl<'a> OutlineStrokeToFill<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
LineCap::Round => {
|
LineCap::Round => {
|
||||||
let scale = Vector2F::splat(width * 0.5);
|
let scale = width * 0.5;
|
||||||
let offset = gradient.yx().scale_xy(Vector2F::new(-1.0, 1.0));
|
let offset = gradient.yx() * vec2f(-1.0, 1.0);
|
||||||
let translation = p1 + offset.scale(width * 0.5);
|
let translation = p1 + offset * (width * 0.5);
|
||||||
let transform = Transform2F::from_scale(scale).translate(translation);
|
let transform = Transform2F::from_scale(scale).translate(translation);
|
||||||
let chord = LineSegment2F::new(-offset, offset);
|
let chord = LineSegment2F::new(-offset, offset);
|
||||||
contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW);
|
contour.push_arc_from_unit_chord(&transform, chord, ArcDirection::CW);
|
||||||
|
@ -395,7 +395,7 @@ impl Contour {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LineJoin::Round => {
|
LineJoin::Round => {
|
||||||
let scale = Vector2F::splat(distance.abs());
|
let scale = distance.abs();
|
||||||
let transform = Transform2F::from_scale(scale).translate(join_point);
|
let transform = Transform2F::from_scale(scale).translate(join_point);
|
||||||
let chord_from = (prev_tangent.to() - join_point).normalize();
|
let chord_from = (prev_tangent.to() - join_point).normalize();
|
||||||
let chord_to = (next_tangent.to() - join_point).normalize();
|
let chord_to = (next_tangent.to() - join_point).normalize();
|
||||||
|
|
|
@ -53,10 +53,10 @@ impl Camera {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_2d(view_box: RectF, viewport_size: Vector2I) -> Camera {
|
fn new_2d(view_box: RectF, viewport_size: Vector2I) -> Camera {
|
||||||
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32
|
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 *
|
||||||
* scale_factor_for_view_box(view_box);
|
scale_factor_for_view_box(view_box);
|
||||||
let origin = viewport_size.to_f32().scale(0.5) - view_box.size().scale(scale * 0.5);
|
let origin = viewport_size.to_f32() * 0.5 - view_box.size() * (scale * 0.5);
|
||||||
Camera::TwoD(Transform2F::from_uniform_scale(scale).translate(origin))
|
Camera::TwoD(Transform2F::from_scale(scale).translate(origin))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_3d(mode: Mode, view_box: RectF, viewport_size: Vector2I) -> Camera {
|
fn new_3d(mode: Mode, view_box: RectF, viewport_size: Vector2I) -> Camera {
|
||||||
|
|
|
@ -255,8 +255,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
transform: self.render_transform.clone().unwrap(),
|
transform: self.render_transform.clone().unwrap(),
|
||||||
dilation: if self.ui_model.stem_darkening_effect_enabled {
|
dilation: if self.ui_model.stem_darkening_effect_enabled {
|
||||||
let font_size = APPROX_FONT_SIZE * self.window_size.backing_scale_factor;
|
let font_size = APPROX_FONT_SIZE * self.window_size.backing_scale_factor;
|
||||||
let (x, y) = (STEM_DARKENING_FACTORS[0], STEM_DARKENING_FACTORS[1]);
|
vec2f(STEM_DARKENING_FACTORS[0], STEM_DARKENING_FACTORS[1]) * font_size
|
||||||
vec2f(x, y).scale(font_size)
|
|
||||||
} else {
|
} else {
|
||||||
Vector2F::zero()
|
Vector2F::zero()
|
||||||
},
|
},
|
||||||
|
@ -290,15 +289,8 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
Event::MouseMoved(new_position) if self.mouselook_enabled => {
|
Event::MouseMoved(new_position) if self.mouselook_enabled => {
|
||||||
let mouse_position = self.process_mouse_position(new_position);
|
let mouse_position = self.process_mouse_position(new_position);
|
||||||
if let Camera::ThreeD {
|
if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera {
|
||||||
ref mut modelview_transform,
|
let rotation = mouse_position.relative.to_f32() * MOUSELOOK_ROTATION_SPEED;
|
||||||
..
|
|
||||||
} = self.camera
|
|
||||||
{
|
|
||||||
let rotation = mouse_position
|
|
||||||
.relative
|
|
||||||
.to_f32()
|
|
||||||
.scale(MOUSELOOK_ROTATION_SPEED);
|
|
||||||
modelview_transform.yaw += rotation.x();
|
modelview_transform.yaw += rotation.x();
|
||||||
modelview_transform.pitch += rotation.y();
|
modelview_transform.pitch += rotation.y();
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
@ -312,19 +304,15 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
Event::Zoom(d_dist, position) => {
|
Event::Zoom(d_dist, position) => {
|
||||||
if let Camera::TwoD(ref mut transform) = self.camera {
|
if let Camera::TwoD(ref mut transform) = self.camera {
|
||||||
let backing_scale_factor = self.window_size.backing_scale_factor;
|
let backing_scale_factor = self.window_size.backing_scale_factor;
|
||||||
let position = position.to_f32().scale(backing_scale_factor);
|
let position = position.to_f32() * backing_scale_factor;
|
||||||
let scale_delta = 1.0 + d_dist * CAMERA_SCALE_SPEED_2D;
|
let scale_delta = 1.0 + d_dist * CAMERA_SCALE_SPEED_2D;
|
||||||
*transform = transform.translate(-position)
|
*transform = transform.translate(-position)
|
||||||
.uniform_scale(scale_delta)
|
.scale(scale_delta)
|
||||||
.translate(position);
|
.translate(position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Event::Look { pitch, yaw } => {
|
Event::Look { pitch, yaw } => {
|
||||||
if let Camera::ThreeD {
|
if let Camera::ThreeD { ref mut modelview_transform, .. } = self.camera {
|
||||||
ref mut modelview_transform,
|
|
||||||
..
|
|
||||||
} = self.camera
|
|
||||||
{
|
|
||||||
modelview_transform.pitch += pitch;
|
modelview_transform.pitch += pitch;
|
||||||
modelview_transform.yaw += yaw;
|
modelview_transform.yaw += yaw;
|
||||||
}
|
}
|
||||||
|
@ -470,7 +458,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_mouse_position(&mut self, new_position: Vector2I) -> MousePosition {
|
fn process_mouse_position(&mut self, new_position: Vector2I) -> MousePosition {
|
||||||
let absolute = new_position.scale(self.window_size.backing_scale_factor as i32);
|
let absolute = new_position * self.window_size.backing_scale_factor as i32;
|
||||||
let relative = absolute - self.last_mouse_position;
|
let relative = absolute - self.last_mouse_position;
|
||||||
self.last_mouse_position = absolute;
|
self.last_mouse_position = absolute;
|
||||||
MousePosition { absolute, relative }
|
MousePosition { absolute, relative }
|
||||||
|
@ -487,10 +475,8 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
self.renderer.debug_ui_presenter.ui_presenter.event_queue.push(*ui_event);
|
self.renderer.debug_ui_presenter.ui_presenter.event_queue.push(*ui_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.renderer.debug_ui_presenter.ui_presenter.mouse_position = self
|
self.renderer.debug_ui_presenter.ui_presenter.mouse_position =
|
||||||
.last_mouse_position
|
self.last_mouse_position.to_f32() * self.window_size.backing_scale_factor;
|
||||||
.to_f32()
|
|
||||||
.scale(self.window_size.backing_scale_factor);
|
|
||||||
|
|
||||||
let mut ui_action = UIAction::None;
|
let mut ui_action = UIAction::None;
|
||||||
if self.options.ui == UIVisibility::All {
|
if self.options.ui == UIVisibility::All {
|
||||||
|
@ -605,7 +591,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
UIAction::ZoomIn => {
|
UIAction::ZoomIn => {
|
||||||
if let Camera::TwoD(ref mut transform) = self.camera {
|
if let Camera::TwoD(ref mut transform) = self.camera {
|
||||||
let scale = Vector2F::splat(1.0 + CAMERA_ZOOM_AMOUNT_2D);
|
let scale = 1.0 + CAMERA_ZOOM_AMOUNT_2D;
|
||||||
let center = center_of_window(&self.window_size);
|
let center = center_of_window(&self.window_size);
|
||||||
*transform = transform.translate(-center).scale(scale).translate(center);
|
*transform = transform.translate(-center).scale(scale).translate(center);
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
@ -613,7 +599,7 @@ impl<W> DemoApp<W> where W: Window {
|
||||||
}
|
}
|
||||||
UIAction::ZoomOut => {
|
UIAction::ZoomOut => {
|
||||||
if let Camera::TwoD(ref mut transform) = self.camera {
|
if let Camera::TwoD(ref mut transform) = self.camera {
|
||||||
let scale = Vector2F::splat(1.0 - CAMERA_ZOOM_AMOUNT_2D);
|
let scale = 1.0 - CAMERA_ZOOM_AMOUNT_2D;
|
||||||
let center = center_of_window(&self.window_size);
|
let center = center_of_window(&self.window_size);
|
||||||
*transform = transform.translate(-center).scale(scale).translate(center);
|
*transform = transform.translate(-center).scale(scale).translate(center);
|
||||||
self.dirty = true;
|
self.dirty = true;
|
||||||
|
@ -779,7 +765,7 @@ fn build_svg_tree(tree: &Tree, viewport_size: Vector2I, effects: Option<Effects>
|
||||||
_ => vec2i(1, 1),
|
_ => vec2i(1, 1),
|
||||||
};
|
};
|
||||||
let name = "Text".to_owned();
|
let name = "Text".to_owned();
|
||||||
let render_target = RenderTarget::new(viewport_size.scale_xy(scale), name);
|
let render_target = RenderTarget::new(viewport_size * scale, name);
|
||||||
Some(scene.push_render_target(render_target))
|
Some(scene.push_render_target(render_target))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -794,7 +780,7 @@ fn build_svg_tree(tree: &Tree, viewport_size: Vector2I, effects: Option<Effects>
|
||||||
}
|
}
|
||||||
|
|
||||||
fn center_of_window(window_size: &WindowSize) -> Vector2F {
|
fn center_of_window(window_size: &WindowSize) -> Vector2F {
|
||||||
window_size.device_size().to_f32().scale(0.5)
|
window_size.device_size().to_f32() * 0.5
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_svg_building_message(built_svg: &BuiltSVG) -> String {
|
fn get_svg_building_message(built_svg: &BuiltSVG) -> String {
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
//! A minimal cross-platform windowing layer.
|
//! A minimal cross-platform windowing layer.
|
||||||
|
|
||||||
use pathfinder_geometry::vector::Vector2I;
|
|
||||||
use pathfinder_geometry::rect::RectI;
|
use pathfinder_geometry::rect::RectI;
|
||||||
use pathfinder_geometry::transform3d::{Perspective, Transform4F};
|
use pathfinder_geometry::transform3d::{Perspective, Transform4F};
|
||||||
|
use pathfinder_geometry::vector::Vector2I;
|
||||||
use pathfinder_resources::ResourceLoader;
|
use pathfinder_resources::ResourceLoader;
|
||||||
use rayon::ThreadPoolBuilder;
|
use rayon::ThreadPoolBuilder;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -90,10 +90,7 @@ pub struct WindowSize {
|
||||||
impl WindowSize {
|
impl WindowSize {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn device_size(&self) -> Vector2I {
|
pub fn device_size(&self) -> Vector2I {
|
||||||
self.logical_size
|
(self.logical_size.to_f32() * self.backing_scale_factor).to_i32()
|
||||||
.to_f32()
|
|
||||||
.scale(self.backing_scale_factor)
|
|
||||||
.to_i32()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -218,7 +218,7 @@ pub unsafe extern "C" fn magicleap_pathfinder_render(pf: *mut c_void, options: *
|
||||||
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 /
|
let scale = i32::min(viewport_size.x(), viewport_size.y()) as f32 /
|
||||||
f32::max(svg.scene.bounds().size().x(), svg.scene.bounds().size().y());
|
f32::max(svg.scene.bounds().size().x(), svg.scene.bounds().size().y());
|
||||||
let transform = Transform2F::from_translation(svg.scene.bounds().size().scale(-0.5))
|
let transform = Transform2F::from_translation(svg.scene.bounds().size().scale(-0.5))
|
||||||
.post_mul(&Transform2F::from_scale(Vector2F::splat(scale)))
|
.post_mul(&Transform2F::from_scale(scale))
|
||||||
.post_mul(&Transform2F::from_translation(viewport_size.to_f32().scale(0.5)));
|
.post_mul(&Transform2F::from_translation(viewport_size.to_f32().scale(0.5)));
|
||||||
|
|
||||||
let render_options = RenderOptions {
|
let render_options = RenderOptions {
|
||||||
|
|
|
@ -18,7 +18,7 @@ use glutin::window::WindowBuilder;
|
||||||
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
|
use pathfinder_canvas::{CanvasFontContext, CanvasRenderingContext2D, Path2D};
|
||||||
use pathfinder_color::ColorF;
|
use pathfinder_color::ColorF;
|
||||||
use pathfinder_geometry::rect::RectF;
|
use pathfinder_geometry::rect::RectF;
|
||||||
use pathfinder_geometry::vector::{Vector2F, Vector2I, vec2f, vec2i};
|
use pathfinder_geometry::vector::{vec2f, vec2i};
|
||||||
use pathfinder_gl::{GLDevice, GLVersion};
|
use pathfinder_gl::{GLDevice, GLVersion};
|
||||||
use pathfinder_resources::fs::FilesystemResourceLoader;
|
use pathfinder_resources::fs::FilesystemResourceLoader;
|
||||||
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
use pathfinder_renderer::concurrent::rayon::RayonExecutor;
|
||||||
|
|
|
@ -119,9 +119,9 @@ impl MoireRenderer {
|
||||||
let foreground_color = self.colors.sample(color_time + 0.5);
|
let foreground_color = self.colors.sample(color_time + 0.5);
|
||||||
|
|
||||||
// Calculate outer and inner circle centers (circle and Leminscate of Gerono respectively).
|
// Calculate outer and inner circle centers (circle and Leminscate of Gerono respectively).
|
||||||
let window_center = self.window_size.to_f32().scale(0.5);
|
let window_center = self.window_size.to_f32() * 0.5;
|
||||||
let outer_center = window_center + vec2f(sin_time, cos_time).scale(OUTER_RADIUS);
|
let outer_center = window_center + vec2f(sin_time, cos_time) * OUTER_RADIUS;
|
||||||
let inner_center = window_center + vec2f(1.0, sin_time).scale(cos_time * INNER_RADIUS);
|
let inner_center = window_center + vec2f(1.0, sin_time) * (cos_time * INNER_RADIUS);
|
||||||
|
|
||||||
// Clear to background color.
|
// Clear to background color.
|
||||||
self.renderer.set_options(RendererOptions { background_color: Some(background_color) });
|
self.renderer.set_options(RendererOptions { background_color: Some(background_color) });
|
||||||
|
@ -144,12 +144,12 @@ impl MoireRenderer {
|
||||||
self.frame += 1;
|
self.frame += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_circles(&self, canvas: &mut CanvasRenderingContext2D, center: Vector2F) {
|
fn draw_circles(&self, canvas: &mut CanvasRenderingContext2D, mut center: Vector2F) {
|
||||||
let center = center.scale(self.device_pixel_ratio);
|
center *= self.device_pixel_ratio;
|
||||||
for index in 0..CIRCLE_COUNT {
|
for index in 0..CIRCLE_COUNT {
|
||||||
let radius = (index + 1) as f32 * CIRCLE_SPACING * self.device_pixel_ratio;
|
let radius = (index + 1) as f32 * CIRCLE_SPACING * self.device_pixel_ratio;
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
path.ellipse(center, Vector2F::splat(radius), 0.0, 0.0, PI * 2.0);
|
path.ellipse(center, radius, 0.0, 0.0, PI * 2.0);
|
||||||
canvas.stroke_path(path);
|
canvas.stroke_path(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,8 +66,7 @@ fn render_demo(canvas: &mut CanvasRenderingContext2D,
|
||||||
time);
|
time);
|
||||||
draw_paragraph(canvas, RectF::new(vec2f(window_size.x() - 450.0, 50.0), vec2f(150.0, 100.0)));
|
draw_paragraph(canvas, RectF::new(vec2f(window_size.x() - 450.0, 50.0), vec2f(150.0, 100.0)));
|
||||||
draw_graph(canvas,
|
draw_graph(canvas,
|
||||||
RectF::new(window_size.scale_xy(vec2f(0.0, 0.5)),
|
RectF::new(window_size * vec2f(0.0, 0.5), window_size * vec2f(1.0, 0.5)),
|
||||||
window_size.scale_xy(vec2f(1.0, 0.5))),
|
|
||||||
time);
|
time);
|
||||||
draw_color_wheel(canvas,
|
draw_color_wheel(canvas,
|
||||||
RectF::new(window_size - vec2f(300.0, 300.0), vec2f(250.0, 250.0)),
|
RectF::new(window_size - vec2f(300.0, 300.0), vec2f(250.0, 250.0)),
|
||||||
|
@ -130,7 +129,7 @@ fn draw_eyes(canvas: &mut CanvasRenderingContext2D,
|
||||||
rect: RectF,
|
rect: RectF,
|
||||||
mouse_position: Vector2F,
|
mouse_position: Vector2F,
|
||||||
time: f32) {
|
time: f32) {
|
||||||
let eyes_radii = rect.size().scale_xy(vec2f(0.23, 0.5));
|
let eyes_radii = rect.size() * vec2f(0.23, 0.5);
|
||||||
let eyes_left_position = rect.origin() + eyes_radii;
|
let eyes_left_position = rect.origin() + eyes_radii;
|
||||||
let eyes_right_position = rect.origin() + vec2f(rect.width() - eyes_radii.x(), eyes_radii.y());
|
let eyes_right_position = rect.origin() + vec2f(rect.width() - eyes_radii.x(), eyes_radii.y());
|
||||||
let eyes_center = f32::min(eyes_radii.x(), eyes_radii.y()) * 0.5;
|
let eyes_center = f32::min(eyes_radii.x(), eyes_radii.y()) * 0.5;
|
||||||
|
@ -138,7 +137,7 @@ fn draw_eyes(canvas: &mut CanvasRenderingContext2D,
|
||||||
|
|
||||||
let mut gradient = Gradient::linear(
|
let mut gradient = Gradient::linear(
|
||||||
LineSegment2F::new(vec2f(0.0, rect.height() * 0.5),
|
LineSegment2F::new(vec2f(0.0, rect.height() * 0.5),
|
||||||
rect.size().scale_xy(vec2f(0.1, 1.0))) + rect.origin());
|
rect.size() * vec2f(0.1, 1.0)) + rect.origin());
|
||||||
gradient.add_color_stop(rgbau(0, 0, 0, 32), 0.0);
|
gradient.add_color_stop(rgbau(0, 0, 0, 32), 0.0);
|
||||||
gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0);
|
gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0);
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
|
@ -147,9 +146,9 @@ fn draw_eyes(canvas: &mut CanvasRenderingContext2D,
|
||||||
canvas.set_fill_style(gradient);
|
canvas.set_fill_style(gradient);
|
||||||
canvas.fill_path(path, FillRule::Winding);
|
canvas.fill_path(path, FillRule::Winding);
|
||||||
|
|
||||||
let mut gradient = Gradient::linear(
|
let mut gradient =
|
||||||
LineSegment2F::new(vec2f(0.0, rect.height() * 0.25),
|
Gradient::linear(LineSegment2F::new(vec2f(0.0, rect.height() * 0.25),
|
||||||
rect.size().scale_xy(vec2f(0.1, 1.0))) + rect.origin());
|
rect.size() * vec2f(0.1, 1.0)) + rect.origin());
|
||||||
gradient.add_color_stop(rgbu(220, 220, 220), 0.0);
|
gradient.add_color_stop(rgbu(220, 220, 220), 0.0);
|
||||||
gradient.add_color_stop(rgbu(128, 128, 128), 1.0);
|
gradient.add_color_stop(rgbu(128, 128, 128), 1.0);
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
|
@ -158,12 +157,12 @@ fn draw_eyes(canvas: &mut CanvasRenderingContext2D,
|
||||||
canvas.set_fill_style(gradient);
|
canvas.set_fill_style(gradient);
|
||||||
canvas.fill_path(path, FillRule::Winding);
|
canvas.fill_path(path, FillRule::Winding);
|
||||||
|
|
||||||
let mut delta = (mouse_position - eyes_right_position) / eyes_radii.scale(10.0);
|
let mut delta = (mouse_position - eyes_right_position) / (eyes_radii * 10.0);
|
||||||
let distance = delta.length();
|
let distance = delta.length();
|
||||||
if distance > 1.0 {
|
if distance > 1.0 {
|
||||||
delta = delta.scale(1.0 / distance);
|
delta *= 1.0 / distance;
|
||||||
}
|
}
|
||||||
delta = delta.scale_xy(eyes_radii).scale_xy(vec2f(0.4, 0.5));
|
delta *= eyes_radii * vec2f(0.4, 0.5);
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
path.ellipse(eyes_left_position + delta + vec2f(0.0, eyes_radii.y() * 0.25 * (1.0 - blink)),
|
path.ellipse(eyes_left_position + delta + vec2f(0.0, eyes_radii.y() * 0.25 * (1.0 - blink)),
|
||||||
vec2f(eyes_center, eyes_center * blink),
|
vec2f(eyes_center, eyes_center * blink),
|
||||||
|
@ -178,7 +177,7 @@ fn draw_eyes(canvas: &mut CanvasRenderingContext2D,
|
||||||
canvas.set_fill_style(rgbu(32, 32, 32));
|
canvas.set_fill_style(rgbu(32, 32, 32));
|
||||||
canvas.fill_path(path, FillRule::Winding);
|
canvas.fill_path(path, FillRule::Winding);
|
||||||
|
|
||||||
let gloss_position = eyes_left_position - eyes_radii.scale_xy(vec2f(0.25, 0.5));
|
let gloss_position = eyes_left_position - eyes_radii * vec2f(0.25, 0.5);
|
||||||
let gloss_radii = F32x2::new(0.1, 0.75) * F32x2::splat(eyes_radii.x());
|
let gloss_radii = F32x2::new(0.1, 0.75) * F32x2::splat(eyes_radii.x());
|
||||||
let mut gloss = Gradient::radial(gloss_position, gloss_radii);
|
let mut gloss = Gradient::radial(gloss_position, gloss_radii);
|
||||||
gloss.add_color_stop(rgbau(255, 255, 255, 128), 0.0);
|
gloss.add_color_stop(rgbau(255, 255, 255, 128), 0.0);
|
||||||
|
@ -188,7 +187,7 @@ fn draw_eyes(canvas: &mut CanvasRenderingContext2D,
|
||||||
path.ellipse(eyes_left_position, eyes_radii, 0.0, 0.0, PI_2);
|
path.ellipse(eyes_left_position, eyes_radii, 0.0, 0.0, PI_2);
|
||||||
canvas.fill_path(path, FillRule::Winding);
|
canvas.fill_path(path, FillRule::Winding);
|
||||||
|
|
||||||
let gloss_position = eyes_right_position - eyes_radii.scale_xy(vec2f(0.25, 0.5));
|
let gloss_position = eyes_right_position - eyes_radii * vec2f(0.25, 0.5);
|
||||||
let mut gloss = Gradient::radial(gloss_position, gloss_radii);
|
let mut gloss = Gradient::radial(gloss_position, gloss_radii);
|
||||||
gloss.add_color_stop(rgbau(255, 255, 255, 128), 0.0);
|
gloss.add_color_stop(rgbau(255, 255, 255, 128), 0.0);
|
||||||
gloss.add_color_stop(rgbau(255, 255, 255, 0), 1.0);
|
gloss.add_color_stop(rgbau(255, 255, 255, 0), 1.0);
|
||||||
|
@ -263,7 +262,7 @@ fn draw_graph(canvas: &mut CanvasRenderingContext2D, rect: RectF, time: f32) {
|
||||||
let sample_points: ArrayVec<[Vector2F; 6]> = samples.iter()
|
let sample_points: ArrayVec<[Vector2F; 6]> = samples.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(index, &sample)| {
|
.map(|(index, &sample)| {
|
||||||
rect.origin() + vec2f(index as f32, sample).scale_xy(sample_scale)
|
rect.origin() + vec2f(index as f32, sample) * sample_scale
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
// Draw graph background.
|
// Draw graph background.
|
||||||
|
@ -336,7 +335,7 @@ fn draw_color_wheel(canvas: &mut CanvasRenderingContext2D, rect: RectF, time: f3
|
||||||
let line = LineSegment2F::new(vec2f(f32::cos(start_angle), f32::sin(start_angle)),
|
let line = LineSegment2F::new(vec2f(f32::cos(start_angle), f32::sin(start_angle)),
|
||||||
vec2f(f32::cos(end_angle), f32::sin(end_angle)));
|
vec2f(f32::cos(end_angle), f32::sin(end_angle)));
|
||||||
let scale = util::lerp(inner_radius, outer_radius, 0.5);
|
let scale = util::lerp(inner_radius, outer_radius, 0.5);
|
||||||
let mut gradient = Gradient::linear(line.scale(scale) + center);
|
let mut gradient = Gradient::linear(line * scale + center);
|
||||||
let start_color = ColorF::from_hsl(start_angle, 1.0, 0.55).to_u8();
|
let start_color = ColorF::from_hsl(start_angle, 1.0, 0.55).to_u8();
|
||||||
let end_color = ColorF::from_hsl(end_angle, 1.0, 0.55).to_u8();
|
let end_color = ColorF::from_hsl(end_angle, 1.0, 0.55).to_u8();
|
||||||
gradient.add_color_stop(start_color, 0.0);
|
gradient.add_color_stop(start_color, 0.0);
|
||||||
|
@ -353,8 +352,8 @@ fn draw_color_wheel(canvas: &mut CanvasRenderingContext2D, rect: RectF, time: f3
|
||||||
canvas.set_stroke_style(rgbau(0, 0, 0, 64));
|
canvas.set_stroke_style(rgbau(0, 0, 0, 64));
|
||||||
canvas.set_line_width(1.0);
|
canvas.set_line_width(1.0);
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
path.ellipse(center, Vector2F::splat(inner_radius - 0.5), 0.0, 0.0, PI_2);
|
path.ellipse(center, inner_radius - 0.5, 0.0, 0.0, PI_2);
|
||||||
path.ellipse(center, Vector2F::splat(outer_radius + 0.5), 0.0, 0.0, PI_2);
|
path.ellipse(center, outer_radius + 0.5, 0.0, 0.0, PI_2);
|
||||||
canvas.stroke_path(path);
|
canvas.stroke_path(path);
|
||||||
|
|
||||||
// Prepare to draw the selector.
|
// Prepare to draw the selector.
|
||||||
|
@ -374,9 +373,8 @@ fn draw_color_wheel(canvas: &mut CanvasRenderingContext2D, rect: RectF, time: f3
|
||||||
// Draw center triangle.
|
// Draw center triangle.
|
||||||
let triangle_radius = inner_radius - 6.0;
|
let triangle_radius = inner_radius - 6.0;
|
||||||
let triangle_vertex_a = vec2f(triangle_radius, 0.0);
|
let triangle_vertex_a = vec2f(triangle_radius, 0.0);
|
||||||
let triangle_vertex_b = vec2f(FRAC_PI_2_3.cos(), FRAC_PI_2_3.sin()).scale(triangle_radius);
|
let triangle_vertex_b = vec2f(FRAC_PI_2_3.cos(), FRAC_PI_2_3.sin()) * triangle_radius;
|
||||||
let triangle_vertex_c = vec2f((-FRAC_PI_2_3).cos(),
|
let triangle_vertex_c = vec2f((-FRAC_PI_2_3).cos(), (-FRAC_PI_2_3).sin()) * triangle_radius;
|
||||||
(-FRAC_PI_2_3).sin()).scale(triangle_radius);
|
|
||||||
let mut gradient_0 = Gradient::linear_from_points(triangle_vertex_a, triangle_vertex_b);
|
let mut gradient_0 = Gradient::linear_from_points(triangle_vertex_a, triangle_vertex_b);
|
||||||
gradient_0.add_color_stop(ColorF::from_hsl(hue, 1.0, 0.5).to_u8(), 0.0);
|
gradient_0.add_color_stop(ColorF::from_hsl(hue, 1.0, 0.5).to_u8(), 0.0);
|
||||||
gradient_0.add_color_stop(ColorU::white(), 1.0);
|
gradient_0.add_color_stop(ColorU::white(), 1.0);
|
||||||
|
@ -398,9 +396,8 @@ fn draw_color_wheel(canvas: &mut CanvasRenderingContext2D, rect: RectF, time: f3
|
||||||
canvas.stroke_path(path);
|
canvas.stroke_path(path);
|
||||||
|
|
||||||
// Stroke the selection circle on the triangle.
|
// Stroke the selection circle on the triangle.
|
||||||
let selection_circle_center =
|
let selection_circle_center = vec2f(FRAC_PI_2_3.cos(), FRAC_PI_2_3.sin()) * triangle_radius *
|
||||||
vec2f(FRAC_PI_2_3.cos(), FRAC_PI_2_3.sin()).scale(triangle_radius)
|
vec2f(0.3, 0.4);
|
||||||
.scale_xy(vec2f(0.3, 0.4));
|
|
||||||
canvas.set_stroke_style(rgbau(255, 255, 255, 192));
|
canvas.set_stroke_style(rgbau(255, 255, 255, 192));
|
||||||
canvas.set_line_width(2.0);
|
canvas.set_line_width(2.0);
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
|
@ -442,9 +439,9 @@ fn draw_lines(canvas: &mut CanvasRenderingContext2D, rect: RectF, time: f32) {
|
||||||
LineJoin::Miter, LineJoin::Round, LineJoin::Bevel
|
LineJoin::Miter, LineJoin::Round, LineJoin::Bevel
|
||||||
].iter().enumerate() {
|
].iter().enumerate() {
|
||||||
let origin = rect.origin() +
|
let origin = rect.origin() +
|
||||||
vec2f(spacing, -spacing).scale(0.5) +
|
vec2f(0.5, -0.5) * spacing +
|
||||||
vec2f((cap_index * 3 + join_index) as f32 / 9.0 * rect.width(), 0.0) +
|
vec2f((cap_index * 3 + join_index) as f32 / 9.0 * rect.width(), 0.0) +
|
||||||
vec2f(PADDING, PADDING);
|
PADDING;
|
||||||
|
|
||||||
canvas.set_line_cap(cap);
|
canvas.set_line_cap(cap);
|
||||||
canvas.set_line_join(join);
|
canvas.set_line_join(join);
|
||||||
|
@ -584,7 +581,7 @@ fn draw_search_box(canvas: &mut CanvasRenderingContext2D, text: &str, rect: Rect
|
||||||
canvas.set_fill_style(rgbau(255, 255, 255, 64));
|
canvas.set_fill_style(rgbau(255, 255, 255, 64));
|
||||||
canvas.set_text_align(TextAlign::Left);
|
canvas.set_text_align(TextAlign::Left);
|
||||||
canvas.set_text_baseline(TextBaseline::Middle);
|
canvas.set_text_baseline(TextBaseline::Middle);
|
||||||
canvas.fill_text(text, rect.origin() + Vector2F::splat(rect.height()) * vec2f(1.05, 0.5));
|
canvas.fill_text(text, rect.origin() + vec2f(1.05, 0.5) * rect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_dropdown(canvas: &mut CanvasRenderingContext2D, text: &str, rect: RectF) {
|
fn draw_dropdown(canvas: &mut CanvasRenderingContext2D, text: &str, rect: RectF) {
|
||||||
|
@ -606,7 +603,7 @@ fn draw_dropdown(canvas: &mut CanvasRenderingContext2D, text: &str, rect: RectF)
|
||||||
canvas.set_fill_style(rgbau(255, 255, 255, 160));
|
canvas.set_fill_style(rgbau(255, 255, 255, 160));
|
||||||
canvas.set_text_align(TextAlign::Left);
|
canvas.set_text_align(TextAlign::Left);
|
||||||
canvas.set_text_baseline(TextBaseline::Middle);
|
canvas.set_text_baseline(TextBaseline::Middle);
|
||||||
canvas.fill_text(text, rect.origin() + Vector2F::splat(rect.height()) * vec2f(0.3, 0.5));
|
canvas.fill_text(text, rect.origin() + vec2f(0.3, 0.5) * rect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_label(canvas: &mut CanvasRenderingContext2D, text: &str, rect: RectF) {
|
fn draw_label(canvas: &mut CanvasRenderingContext2D, text: &str, rect: RectF) {
|
||||||
|
@ -644,7 +641,7 @@ fn draw_text_edit_box(canvas: &mut CanvasRenderingContext2D, text: &str, rect: R
|
||||||
canvas.set_fill_style(rgbau(255, 255, 255, 64));
|
canvas.set_fill_style(rgbau(255, 255, 255, 64));
|
||||||
canvas.set_text_align(TextAlign::Left);
|
canvas.set_text_align(TextAlign::Left);
|
||||||
canvas.set_text_baseline(TextBaseline::Middle);
|
canvas.set_text_baseline(TextBaseline::Middle);
|
||||||
canvas.fill_text(text, rect.origin() + Vector2F::splat(rect.height()) * vec2f(0.3, 0.5));
|
canvas.fill_text(text, rect.origin() + vec2f(0.3, 0.5) * rect.height());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_numeric_edit_box(canvas: &mut CanvasRenderingContext2D,
|
fn draw_numeric_edit_box(canvas: &mut CanvasRenderingContext2D,
|
||||||
|
@ -660,7 +657,7 @@ fn draw_numeric_edit_box(canvas: &mut CanvasRenderingContext2D,
|
||||||
canvas.set_fill_style(rgbau(255, 255, 255, 64));
|
canvas.set_fill_style(rgbau(255, 255, 255, 64));
|
||||||
canvas.set_text_align(TextAlign::Right);
|
canvas.set_text_align(TextAlign::Right);
|
||||||
canvas.set_text_baseline(TextBaseline::Middle);
|
canvas.set_text_baseline(TextBaseline::Middle);
|
||||||
canvas.fill_text(unit, rect.upper_right() + vec2f(-0.3, 0.5) * Vector2F::splat(rect.height()));
|
canvas.fill_text(unit, rect.upper_right() + vec2f(-0.3, 0.5) * rect.height());
|
||||||
|
|
||||||
canvas.set_font_size(17.0);
|
canvas.set_font_size(17.0);
|
||||||
canvas.set_fill_style(rgbau(255, 255, 255, 128));
|
canvas.set_fill_style(rgbau(255, 255, 255, 128));
|
||||||
|
@ -681,7 +678,7 @@ fn draw_check_box(canvas: &mut CanvasRenderingContext2D, text: &str, rect: RectF
|
||||||
canvas.fill_text(text, rect.origin() + vec2f(28.0, rect.height() * 0.5));
|
canvas.fill_text(text, rect.origin() + vec2f(28.0, rect.height() * 0.5));
|
||||||
|
|
||||||
let check_box_rect = RectF::new(vec2f(rect.origin_x(), rect.center().y().floor() - 9.0),
|
let check_box_rect = RectF::new(vec2f(rect.origin_x(), rect.center().y().floor() - 9.0),
|
||||||
vec2f(20.0, 20.0)).contract(Vector2F::splat(1.0));
|
vec2f(20.0, 20.0)).contract(1.0);
|
||||||
fill_path_with_box_gradient(canvas,
|
fill_path_with_box_gradient(canvas,
|
||||||
create_rounded_rect_path(check_box_rect, CORNER_RADIUS),
|
create_rounded_rect_path(check_box_rect, CORNER_RADIUS),
|
||||||
FillRule::Winding,
|
FillRule::Winding,
|
||||||
|
@ -754,9 +751,8 @@ fn draw_slider(canvas: &mut CanvasRenderingContext2D, value: f32, rect: RectF) {
|
||||||
background_gradient.add_color_stop(rgbau(0, 0, 0, 0), 1.0);
|
background_gradient.add_color_stop(rgbau(0, 0, 0, 0), 1.0);
|
||||||
canvas.set_fill_style(background_gradient);
|
canvas.set_fill_style(background_gradient);
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
path.rect(RectF::new(knob_position,
|
path.rect(RectF::new(knob_position, Vector2F::zero()).dilate(knob_radius + 5.0));
|
||||||
Vector2F::zero()).dilate(Vector2F::splat(knob_radius + 5.0)));
|
path.ellipse(knob_position, knob_radius, 0.0, 0.0, PI_2);
|
||||||
path.ellipse(knob_position, Vector2F::splat(knob_radius), 0.0, 0.0, PI_2);
|
|
||||||
canvas.fill_path(path, FillRule::EvenOdd);
|
canvas.fill_path(path, FillRule::EvenOdd);
|
||||||
|
|
||||||
// Fill knob.
|
// Fill knob.
|
||||||
|
@ -766,7 +762,7 @@ fn draw_slider(canvas: &mut CanvasRenderingContext2D, value: f32, rect: RectF) {
|
||||||
background_gradient.add_color_stop(rgbau(255, 255, 255, 16), 0.0);
|
background_gradient.add_color_stop(rgbau(255, 255, 255, 16), 0.0);
|
||||||
background_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0);
|
background_gradient.add_color_stop(rgbau(0, 0, 0, 16), 1.0);
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
path.ellipse(knob_position, Vector2F::splat(knob_radius - 1.0), 0.0, 0.0, PI_2);
|
path.ellipse(knob_position, knob_radius - 1.0, 0.0, 0.0, PI_2);
|
||||||
canvas.set_fill_style(rgbu(40, 43, 48));
|
canvas.set_fill_style(rgbu(40, 43, 48));
|
||||||
canvas.fill_path(path.clone(), FillRule::Winding);
|
canvas.fill_path(path.clone(), FillRule::Winding);
|
||||||
canvas.set_fill_style(background_gradient);
|
canvas.set_fill_style(background_gradient);
|
||||||
|
@ -774,7 +770,7 @@ fn draw_slider(canvas: &mut CanvasRenderingContext2D, value: f32, rect: RectF) {
|
||||||
|
|
||||||
// Outline knob.
|
// Outline knob.
|
||||||
let mut path = Path2D::new();
|
let mut path = Path2D::new();
|
||||||
path.ellipse(knob_position, Vector2F::splat(knob_radius - 0.5), 0.0, 0.0, PI_2);
|
path.ellipse(knob_position, knob_radius - 0.5, 0.0, 0.0, PI_2);
|
||||||
canvas.set_stroke_style(rgbau(0, 0, 0, 92));
|
canvas.set_stroke_style(rgbau(0, 0, 0, 92));
|
||||||
canvas.stroke_path(path);
|
canvas.stroke_path(path);
|
||||||
|
|
||||||
|
@ -831,8 +827,7 @@ fn draw_thumbnails(canvas: &mut CanvasRenderingContext2D,
|
||||||
|
|
||||||
for image_index in 0..image_count {
|
for image_index in 0..image_count {
|
||||||
let image_origin = rect.origin() + vec2f(10.0, 10.0) +
|
let image_origin = rect.origin() + vec2f(10.0, 10.0) +
|
||||||
vec2i(image_index as i32 % 2, image_index as i32 / 2).to_f32()
|
vec2i(image_index as i32 % 2, image_index as i32 / 2).to_f32() * (THUMB_HEIGHT + 10.0);
|
||||||
.scale(THUMB_HEIGHT + 10.0);
|
|
||||||
let image_rect = RectF::new(image_origin, Vector2F::splat(THUMB_HEIGHT));
|
let image_rect = RectF::new(image_origin, Vector2F::splat(THUMB_HEIGHT));
|
||||||
|
|
||||||
let image_y = image_index as f32 * image_y_scale;
|
let image_y = image_index as f32 * image_y_scale;
|
||||||
|
@ -845,8 +840,8 @@ fn draw_thumbnails(canvas: &mut CanvasRenderingContext2D,
|
||||||
let pattern_transform = Transform2F::from_translation(
|
let pattern_transform = Transform2F::from_translation(
|
||||||
image_rect.origin() - vec2i(
|
image_rect.origin() - vec2i(
|
||||||
(image_index % IMAGES_ACROSS) as i32,
|
(image_index % IMAGES_ACROSS) as i32,
|
||||||
(image_index / IMAGES_ACROSS) as i32).to_f32().scale(THUMB_HEIGHT)) *
|
(image_index / IMAGES_ACROSS) as i32).to_f32() * THUMB_HEIGHT) *
|
||||||
Transform2F::from_scale(vec2f(0.5, 0.5));
|
Transform2F::from_scale(0.5);
|
||||||
let pattern = Pattern::new(PatternSource::Image((*image).clone()),
|
let pattern = Pattern::new(PatternSource::Image((*image).clone()),
|
||||||
pattern_transform,
|
pattern_transform,
|
||||||
PatternFlags::empty());
|
PatternFlags::empty());
|
||||||
|
@ -863,7 +858,7 @@ fn draw_thumbnails(canvas: &mut CanvasRenderingContext2D,
|
||||||
canvas,
|
canvas,
|
||||||
shadow_path,
|
shadow_path,
|
||||||
FillRule::EvenOdd,
|
FillRule::EvenOdd,
|
||||||
image_rect.dilate(Vector2F::splat(1.0)) + vec2f(0.0, 1.0),
|
image_rect.dilate(1.0) + vec2f(0.0, 1.0),
|
||||||
5.0,
|
5.0,
|
||||||
3.0,
|
3.0,
|
||||||
rgbau(0, 0, 0, 128),
|
rgbau(0, 0, 0, 128),
|
||||||
|
@ -871,7 +866,7 @@ fn draw_thumbnails(canvas: &mut CanvasRenderingContext2D,
|
||||||
*/
|
*/
|
||||||
|
|
||||||
canvas.set_stroke_style(rgbau(255, 255, 255, 192));
|
canvas.set_stroke_style(rgbau(255, 255, 255, 192));
|
||||||
canvas.stroke_path(create_rounded_rect_path(image_rect.dilate(Vector2F::splat(0.5)), 3.5));
|
canvas.stroke_path(create_rounded_rect_path(image_rect.dilate(0.5), 3.5));
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.restore();
|
canvas.restore();
|
||||||
|
@ -934,8 +929,8 @@ fn draw_spinner(canvas: &mut CanvasRenderingContext2D, center: Vector2F, radius:
|
||||||
path.close_path();
|
path.close_path();
|
||||||
set_linear_gradient_fill_style(
|
set_linear_gradient_fill_style(
|
||||||
canvas,
|
canvas,
|
||||||
center + vec2f(outer_radius.cos(), outer_radius.sin()).scale(average_radius),
|
center + vec2f(outer_radius.cos(), outer_radius.sin()) * average_radius,
|
||||||
center + vec2f(inner_radius.cos(), inner_radius.sin()).scale(average_radius),
|
center + vec2f(inner_radius.cos(), inner_radius.sin()) * average_radius,
|
||||||
rgbau(0, 0, 0, 0),
|
rgbau(0, 0, 0, 0),
|
||||||
rgbau(0, 0, 0, 128));
|
rgbau(0, 0, 0, 128));
|
||||||
canvas.fill_path(path, FillRule::Winding);
|
canvas.fill_path(path, FillRule::Winding);
|
||||||
|
@ -954,8 +949,7 @@ fn fill_path_with_box_gradient(canvas: &mut CanvasRenderingContext2D,
|
||||||
// TODO(pcwalton): Fill the corners with radial gradients.
|
// TODO(pcwalton): Fill the corners with radial gradients.
|
||||||
|
|
||||||
let window_rect = RectF::new(Vector2F::zero(), vec2i(WINDOW_WIDTH, WINDOW_HEIGHT).to_f32());
|
let window_rect = RectF::new(Vector2F::zero(), vec2i(WINDOW_WIDTH, WINDOW_HEIGHT).to_f32());
|
||||||
let inner_rect = rect.contract(Vector2F::splat(blur_radius));
|
let (inner_rect, outer_rect) = (rect.contract(blur_radius), rect.dilate(blur_radius));
|
||||||
let outer_rect = rect.dilate(Vector2F::splat(blur_radius));
|
|
||||||
|
|
||||||
canvas.save();
|
canvas.save();
|
||||||
|
|
||||||
|
|
|
@ -106,16 +106,15 @@ fn main() {
|
||||||
);
|
);
|
||||||
// Clear to swf stage background color.
|
// Clear to swf stage background color.
|
||||||
let mut scene = Scene::new();
|
let mut scene = Scene::new();
|
||||||
scene.set_view_box(RectF::new(
|
scene.set_view_box(RectF::new(Vector2F::zero(),
|
||||||
Vector2F::zero(),
|
vec2f(stage.width() as f32,
|
||||||
vec2f(stage.width() as f32, stage.height() as f32).scale(device_pixel_ratio)
|
stage.height() as f32) * device_pixel_ratio));
|
||||||
));
|
|
||||||
draw_paths_into_scene(&library, &mut scene);
|
draw_paths_into_scene(&library, &mut scene);
|
||||||
|
|
||||||
// Render the canvas to screen.
|
// Render the canvas to screen.
|
||||||
let scene = SceneProxy::from_scene(scene, RayonExecutor);
|
let scene = SceneProxy::from_scene(scene, RayonExecutor);
|
||||||
let mut build_options = BuildOptions::default();
|
let mut build_options = BuildOptions::default();
|
||||||
let scale_transform = Transform2F::from_scale(Vector2F::splat(device_pixel_ratio));
|
let scale_transform = Transform2F::from_scale(device_pixel_ratio);
|
||||||
build_options.transform = RenderTransform::Transform2D(scale_transform);
|
build_options.transform = RenderTransform::Transform2D(scale_transform);
|
||||||
scene.build_and_render(&mut renderer, build_options);
|
scene.build_and_render(&mut renderer, build_options);
|
||||||
|
|
||||||
|
|
|
@ -100,8 +100,8 @@ fn export_pdf<W: Write>(scene: &Scene, writer: &mut W) -> io::Result<()> {
|
||||||
let current = segment.baseline.from();
|
let current = segment.baseline.from();
|
||||||
let c = segment.ctrl.from();
|
let c = segment.ctrl.from();
|
||||||
let p = segment.baseline.to();
|
let p = segment.baseline.to();
|
||||||
let c1 = Vector2F::splat(2./3.) * c + Vector2F::splat(1./3.) * current;
|
let c1 = c * (2.0 / 3.0) + current * (1.0 / 3.0);
|
||||||
let c2 = Vector2F::splat(2./3.) * c + Vector2F::splat(1./3.) * p;
|
let c2 = c * (2.0 / 3.0) + p * (1.0 / 3.0);
|
||||||
pdf.cubic_to(c1, c2, p);
|
pdf.cubic_to(c1, c2, p);
|
||||||
}
|
}
|
||||||
SegmentKind::Cubic => {
|
SegmentKind::Cubic => {
|
||||||
|
@ -166,8 +166,8 @@ fn export_ps<W: Write>(scene: &Scene, writer: &mut W) -> io::Result<()> {
|
||||||
let current = segment.baseline.from();
|
let current = segment.baseline.from();
|
||||||
let c = segment.ctrl.from();
|
let c = segment.ctrl.from();
|
||||||
let p = segment.baseline.to();
|
let p = segment.baseline.to();
|
||||||
let c1 = Vector2F::splat(2. / 3.) * c + Vector2F::splat(1. / 3.) * current;
|
let c1 = c * (2.0 / 3.0) + current * (1.0 / 3.0);
|
||||||
let c2 = Vector2F::splat(2. / 3.) * c + Vector2F::splat(1. / 3.) * p;
|
let c2 = c * (2.0 / 3.0) + p * (1.0 / 3.0);
|
||||||
writeln!(writer, "{} {} {} curveto", P(c1), P(c2), P(p))?;
|
writeln!(writer, "{} {} {} curveto", P(c1), P(c2), P(p))?;
|
||||||
}
|
}
|
||||||
SegmentKind::Cubic => {
|
SegmentKind::Cubic => {
|
||||||
|
|
|
@ -11,10 +11,10 @@
|
||||||
//! Line segment types, optimized with SIMD.
|
//! Line segment types, optimized with SIMD.
|
||||||
|
|
||||||
use crate::transform2d::Matrix2x2F;
|
use crate::transform2d::Matrix2x2F;
|
||||||
use crate::vector::Vector2F;
|
use crate::vector::{Vector2F, vec2f};
|
||||||
use crate::util;
|
use crate::util;
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use std::ops::{Add, Sub};
|
use std::ops::{Add, Mul, MulAssign, Sub};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||||
pub struct LineSegment2F(pub F32x4);
|
pub struct LineSegment2F(pub F32x4);
|
||||||
|
@ -87,21 +87,6 @@ impl LineSegment2F {
|
||||||
self.0[3] = y
|
self.0[3] = y
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn translate(self, offset: Vector2F) -> LineSegment2F {
|
|
||||||
LineSegment2F(self.0 + offset.0.to_f32x4().xyxy())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale(self, factor: f32) -> LineSegment2F {
|
|
||||||
LineSegment2F(self.0 * F32x4::splat(factor))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale_xy(self, factors: Vector2F) -> LineSegment2F {
|
|
||||||
LineSegment2F(self.0 * factors.0.to_f32x4().xyxy())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn split(self, t: f32) -> (LineSegment2F, LineSegment2F) {
|
pub fn split(self, t: f32) -> (LineSegment2F, LineSegment2F) {
|
||||||
debug_assert!(t >= 0.0 && t <= 1.0);
|
debug_assert!(t >= 0.0 && t <= 1.0);
|
||||||
|
@ -239,7 +224,7 @@ impl LineSegment2F {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sample(self, t: f32) -> Vector2F {
|
pub fn sample(self, t: f32) -> Vector2F {
|
||||||
self.from() + self.vector().scale(t)
|
self.from() + self.vector() * t
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -252,7 +237,7 @@ impl LineSegment2F {
|
||||||
if self.is_zero_length() {
|
if self.is_zero_length() {
|
||||||
self
|
self
|
||||||
} else {
|
} else {
|
||||||
self + self.vector().yx().normalize().scale_xy(Vector2F::new(-distance, distance))
|
self + self.vector().yx().normalize() * vec2f(-distance, distance)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,6 +263,29 @@ impl Sub<Vector2F> for LineSegment2F {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Mul<Vector2F> for LineSegment2F {
|
||||||
|
type Output = LineSegment2F;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, factors: Vector2F) -> LineSegment2F {
|
||||||
|
LineSegment2F(self.0 * factors.0.to_f32x4().xyxy())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<f32> for LineSegment2F {
|
||||||
|
type Output = LineSegment2F;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, factor: f32) -> LineSegment2F {
|
||||||
|
LineSegment2F(self.0 * F32x4::splat(factor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MulAssign<Vector2F> for LineSegment2F {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, factors: Vector2F) {
|
||||||
|
*self = *self * factors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct LineSegmentU4 {
|
pub struct LineSegmentU4 {
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
|
|
||||||
//! 2D axis-aligned rectangles, optimized with SIMD.
|
//! 2D axis-aligned rectangles, optimized with SIMD.
|
||||||
|
|
||||||
use crate::vector::{Vector2F, Vector2I};
|
use crate::vector::{IntoVector2F, Vector2F, Vector2I};
|
||||||
use pathfinder_simd::default::{F32x4, I32x4};
|
use pathfinder_simd::default::{F32x4, I32x4};
|
||||||
use std::ops::Add;
|
use std::ops::{Add, Mul};
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||||
pub struct RectF(pub F32x4);
|
pub struct RectF(pub F32x4);
|
||||||
|
@ -158,17 +158,7 @@ impl RectF {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn center(self) -> Vector2F {
|
pub fn center(self) -> Vector2F {
|
||||||
self.origin() + self.size().scale(0.5)
|
self.origin() + self.size() * 0.5
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale(self, factor: f32) -> RectF {
|
|
||||||
RectF(self.0 * F32x4::splat(factor))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale_xy(self, factors: Vector2F) -> RectF {
|
|
||||||
RectF(self.0 * factors.0.concat_xy_xy(factors.0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Rounds all points to the nearest integer.
|
/// Rounds all points to the nearest integer.
|
||||||
|
@ -183,12 +173,14 @@ impl RectF {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dilate(self, amount: Vector2F) -> RectF {
|
pub fn dilate<A>(self, amount: A) -> RectF where A: IntoVector2F {
|
||||||
|
let amount = amount.into_vector_2f();
|
||||||
RectF::from_points(self.origin() - amount, self.lower_right() + amount)
|
RectF::from_points(self.origin() - amount, self.lower_right() + amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contract(self, amount: Vector2F) -> RectF {
|
pub fn contract<A>(self, amount: A) -> RectF where A: IntoVector2F {
|
||||||
|
let amount = amount.into_vector_2f();
|
||||||
RectF::from_points(self.origin() + amount, self.lower_right() - amount)
|
RectF::from_points(self.origin() + amount, self.lower_right() - amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,6 +198,22 @@ impl Add<Vector2F> for RectF {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Mul<Vector2F> for RectF {
|
||||||
|
type Output = RectF;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, factors: Vector2F) -> RectF {
|
||||||
|
RectF(self.0 * factors.0.concat_xy_xy(factors.0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<f32> for RectF {
|
||||||
|
type Output = RectF;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, factor: f32) -> RectF {
|
||||||
|
RectF(self.0 * F32x4::splat(factor))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// NB: The origin is inclusive, while the lower right point is exclusive.
|
/// NB: The origin is inclusive, while the lower right point is exclusive.
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
#[derive(Clone, Copy, Debug, PartialEq, Default)]
|
||||||
pub struct RectI(pub I32x4);
|
pub struct RectI(pub I32x4);
|
||||||
|
@ -319,7 +327,7 @@ impl RectI {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn contains_point(&self, point: Vector2I) -> bool {
|
pub fn contains_point(&self, point: Vector2I) -> bool {
|
||||||
// self.origin <= point && point <= self.lower_right - 1
|
// self.origin <= point && point <= self.lower_right - 1
|
||||||
let lower_right = self.lower_right() - Vector2I::splat(1);
|
let lower_right = self.lower_right() - 1;
|
||||||
self.origin()
|
self.origin()
|
||||||
.0
|
.0
|
||||||
.concat_xy_xy(point.0)
|
.concat_xy_xy(point.0)
|
||||||
|
|
|
@ -14,7 +14,7 @@ use crate::line_segment::LineSegment2F;
|
||||||
use crate::rect::RectF;
|
use crate::rect::RectF;
|
||||||
use crate::transform3d::Transform4F;
|
use crate::transform3d::Transform4F;
|
||||||
use crate::unit_vector::UnitVector;
|
use crate::unit_vector::UnitVector;
|
||||||
use crate::vector::{Vector2F, vec2f};
|
use crate::vector::{IntoVector2F, Vector2F, vec2f};
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use std::ops::{Mul, MulAssign, Sub};
|
use std::ops::{Mul, MulAssign, Sub};
|
||||||
|
|
||||||
|
@ -25,13 +25,14 @@ pub struct Matrix2x2F(pub F32x4);
|
||||||
impl Default for Matrix2x2F {
|
impl Default for Matrix2x2F {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Matrix2x2F {
|
fn default() -> Matrix2x2F {
|
||||||
Self::from_scale(vec2f(1.0, 1.0))
|
Self::from_scale(1.0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Matrix2x2F {
|
impl Matrix2x2F {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_scale(scale: Vector2F) -> Matrix2x2F {
|
pub fn from_scale<S>(scale: S) -> Matrix2x2F where S: IntoVector2F {
|
||||||
|
let scale = scale.into_vector_2f();
|
||||||
Matrix2x2F(F32x4::new(scale.x(), 0.0, 0.0, scale.y()))
|
Matrix2x2F(F32x4::new(scale.x(), 0.0, 0.0, scale.y()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,18 +138,14 @@ impl Default for Transform2F {
|
||||||
|
|
||||||
impl Transform2F {
|
impl Transform2F {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_scale(scale: Vector2F) -> Transform2F {
|
pub fn from_scale<S>(scale: S) -> Transform2F where S: IntoVector2F {
|
||||||
|
let scale = scale.into_vector_2f();
|
||||||
Transform2F {
|
Transform2F {
|
||||||
matrix: Matrix2x2F::from_scale(scale),
|
matrix: Matrix2x2F::from_scale(scale),
|
||||||
vector: Vector2F::zero(),
|
vector: Vector2F::zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn from_uniform_scale(scale: f32) -> Transform2F {
|
|
||||||
Transform2F::from_scale(Vector2F::splat(scale))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_rotation(theta: f32) -> Transform2F {
|
pub fn from_rotation(theta: f32) -> Transform2F {
|
||||||
Transform2F {
|
Transform2F {
|
||||||
|
@ -171,11 +168,9 @@ impl Transform2F {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn from_scale_rotation_translation(
|
pub fn from_scale_rotation_translation<S>(scale: S, theta: f32, translation: Vector2F)
|
||||||
scale: Vector2F,
|
-> Transform2F where S: IntoVector2F {
|
||||||
theta: f32,
|
let scale = scale.into_vector_2f();
|
||||||
translation: Vector2F,
|
|
||||||
) -> Transform2F {
|
|
||||||
let rotation = Transform2F::from_rotation(theta);
|
let rotation = Transform2F::from_rotation(theta);
|
||||||
let translation = Transform2F::from_translation(translation);
|
let translation = Transform2F::from_translation(translation);
|
||||||
Transform2F::from_scale(scale) * rotation * translation
|
Transform2F::from_scale(scale) * rotation * translation
|
||||||
|
@ -245,15 +240,11 @@ impl Transform2F {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn scale(&self, scale: Vector2F) -> Transform2F {
|
pub fn scale<S>(&self, scale: S) -> Transform2F where S: IntoVector2F {
|
||||||
|
let scale = scale.into_vector_2f();
|
||||||
Transform2F::from_scale(scale) * *self
|
Transform2F::from_scale(scale) * *self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn uniform_scale(&self, scale: f32) -> Transform2F {
|
|
||||||
self.scale(Vector2F::splat(scale))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the translation part of this matrix.
|
/// Returns the translation part of this matrix.
|
||||||
///
|
///
|
||||||
/// This decomposition assumes that scale, rotation, and translation are applied in that order.
|
/// This decomposition assumes that scale, rotation, and translation are applied in that order.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
use crate::rect::RectF;
|
use crate::rect::RectF;
|
||||||
use crate::transform2d::Matrix2x2F;
|
use crate::transform2d::Matrix2x2F;
|
||||||
use crate::vector::{Vector2F, Vector2I, Vector3F, Vector4F, vec2f};
|
use crate::vector::{Vector2F, Vector2I, Vector3F, Vector4F};
|
||||||
use pathfinder_simd::default::F32x4;
|
use pathfinder_simd::default::F32x4;
|
||||||
use std::ops::{Add, Mul, MulAssign, Neg};
|
use std::ops::{Add, Mul, MulAssign, Neg};
|
||||||
|
|
||||||
|
@ -407,7 +407,7 @@ impl Mul<Vector2F> for Perspective {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn mul(self, vector: Vector2F) -> Vector2F {
|
fn mul(self, vector: Vector2F) -> Vector2F {
|
||||||
let point = (self.transform * vector.to_4d()).to_2d() * Vector2F::new(1.0, -1.0);
|
let point = (self.transform * vector.to_4d()).to_2d() * Vector2F::new(1.0, -1.0);
|
||||||
(point + vec2f(1.0, 1.0)) * self.window_size.to_f32().scale(0.5)
|
(point + 1.0) * self.window_size.to_f32() * 0.5
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
use pathfinder_simd::default::{F32x2, F32x4, I32x2};
|
use pathfinder_simd::default::{F32x2, F32x4, I32x2};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
use std::ops::{Add, AddAssign, Div, Mul, Neg, Sub};
|
use std::ops::{Add, AddAssign, Div, Mul, MulAssign, Neg, Sub};
|
||||||
|
|
||||||
/// 2D points with 32-bit floating point coordinates.
|
/// 2D points with 32-bit floating point coordinates.
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
|
@ -90,16 +90,6 @@ impl Vector2F {
|
||||||
xy.x() + xy.y()
|
xy.x() + xy.y()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale(self, x: f32) -> Vector2F {
|
|
||||||
Vector2F(self.0 * F32x2::splat(x))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale_xy(self, factors: Vector2F) -> Vector2F {
|
|
||||||
Vector2F(self.0 * factors.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn floor(self) -> Vector2F {
|
pub fn floor(self) -> Vector2F {
|
||||||
Vector2F(self.0.floor())
|
Vector2F(self.0.floor())
|
||||||
|
@ -132,7 +122,7 @@ impl Vector2F {
|
||||||
/// Treats this point as a vector and normalizes it.
|
/// Treats this point as a vector and normalizes it.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn normalize(self) -> Vector2F {
|
pub fn normalize(self) -> Vector2F {
|
||||||
self.scale(1.0 / self.length())
|
self * (1.0 / self.length())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Swaps y and x.
|
/// Swaps y and x.
|
||||||
|
@ -157,7 +147,7 @@ impl Vector2F {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn lerp(self, other: Vector2F, t: f32) -> Vector2F {
|
pub fn lerp(self, other: Vector2F, t: f32) -> Vector2F {
|
||||||
self + (other - self).scale(t)
|
self + (other - self) * t
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -187,6 +177,14 @@ impl Add<Vector2F> for Vector2F {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Add<f32> for Vector2F {
|
||||||
|
type Output = Vector2F;
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: f32) -> Vector2F {
|
||||||
|
self + Vector2F::splat(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AddAssign<Vector2F> for Vector2F {
|
impl AddAssign<Vector2F> for Vector2F {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_assign(&mut self, other: Vector2F) {
|
fn add_assign(&mut self, other: Vector2F) {
|
||||||
|
@ -210,6 +208,28 @@ impl Mul<Vector2F> for Vector2F {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Mul<f32> for Vector2F {
|
||||||
|
type Output = Vector2F;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: f32) -> Vector2F {
|
||||||
|
self * Vector2F::splat(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MulAssign<Vector2F> for Vector2F {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, other: Vector2F) {
|
||||||
|
*self = *self * other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MulAssign<f32> for Vector2F {
|
||||||
|
#[inline]
|
||||||
|
fn mul_assign(&mut self, other: f32) {
|
||||||
|
*self = *self * other
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Div<Vector2F> for Vector2F {
|
impl Div<Vector2F> for Vector2F {
|
||||||
type Output = Vector2F;
|
type Output = Vector2F;
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -226,6 +246,30 @@ impl Neg for Vector2F {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Either a scalar or a `Vector2F`.
|
||||||
|
///
|
||||||
|
/// Scalars will be automatically splatted (i.e. `x` becomes `vec2f(x, x)`).
|
||||||
|
///
|
||||||
|
/// Be judicious with the use of this trait. Only use it if it will aid readability without the
|
||||||
|
/// potential to introduce bugs.
|
||||||
|
pub trait IntoVector2F {
|
||||||
|
fn into_vector_2f(self) -> Vector2F;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoVector2F for Vector2F {
|
||||||
|
#[inline]
|
||||||
|
fn into_vector_2f(self) -> Vector2F {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoVector2F for f32 {
|
||||||
|
#[inline]
|
||||||
|
fn into_vector_2f(self) -> Vector2F {
|
||||||
|
Vector2F::splat(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// 2D points with 32-bit signed integer coordinates.
|
/// 2D points with 32-bit signed integer coordinates.
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default)]
|
||||||
pub struct Vector2I(pub I32x2);
|
pub struct Vector2I(pub I32x2);
|
||||||
|
@ -276,16 +320,6 @@ impl Vector2I {
|
||||||
Vector2I(self.0.max(other.0))
|
Vector2I(self.0.max(other.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale(self, factor: i32) -> Vector2I {
|
|
||||||
Vector2I(self.0 * I32x2::splat(factor))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
pub fn scale_xy(self, factors: Vector2I) -> Vector2I {
|
|
||||||
Vector2I(self.0 * factors.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn to_f32(self) -> Vector2F {
|
pub fn to_f32(self) -> Vector2F {
|
||||||
Vector2F(self.0.to_f32x2())
|
Vector2F(self.0.to_f32x2())
|
||||||
|
@ -306,6 +340,14 @@ impl Add<Vector2I> for Vector2I {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Add<i32> for Vector2I {
|
||||||
|
type Output = Vector2I;
|
||||||
|
#[inline]
|
||||||
|
fn add(self, other: i32) -> Vector2I {
|
||||||
|
self + Vector2I::splat(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AddAssign<Vector2I> for Vector2I {
|
impl AddAssign<Vector2I> for Vector2I {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn add_assign(&mut self, other: Vector2I) {
|
fn add_assign(&mut self, other: Vector2I) {
|
||||||
|
@ -329,6 +371,30 @@ impl Sub<Vector2I> for Vector2I {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Sub<i32> for Vector2I {
|
||||||
|
type Output = Vector2I;
|
||||||
|
#[inline]
|
||||||
|
fn sub(self, other: i32) -> Vector2I {
|
||||||
|
self - Vector2I::splat(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<Vector2I> for Vector2I {
|
||||||
|
type Output = Vector2I;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: Vector2I) -> Vector2I {
|
||||||
|
Vector2I(self.0 * other.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul<i32> for Vector2I {
|
||||||
|
type Output = Vector2I;
|
||||||
|
#[inline]
|
||||||
|
fn mul(self, other: i32) -> Vector2I {
|
||||||
|
self * Vector2I::splat(other)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl PartialEq for Vector2I {
|
impl PartialEq for Vector2I {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn eq(&self, other: &Vector2I) -> bool {
|
fn eq(&self, other: &Vector2I) -> bool {
|
||||||
|
|
|
@ -189,10 +189,9 @@ impl TreeNode {
|
||||||
requested_size) {
|
requested_size) {
|
||||||
return Some(origin);
|
return Some(origin);
|
||||||
}
|
}
|
||||||
if let Some(origin) = kids[3].allocate(
|
if let Some(origin) = kids[3].allocate(this_origin + kid_size as i32,
|
||||||
this_origin + Vector2I::splat(kid_size as i32),
|
kid_size,
|
||||||
kid_size,
|
requested_size) {
|
||||||
requested_size) {
|
|
||||||
return Some(origin);
|
return Some(origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,7 +216,7 @@ impl TreeNode {
|
||||||
}
|
}
|
||||||
|
|
||||||
let child_size = this_size / 2;
|
let child_size = this_size / 2;
|
||||||
let this_center = this_origin + Vector2I::splat(child_size as i32);
|
let this_center = this_origin + child_size as i32;
|
||||||
|
|
||||||
let child_index;
|
let child_index;
|
||||||
let mut child_origin = this_origin;
|
let mut child_origin = this_origin;
|
||||||
|
|
|
@ -278,9 +278,7 @@ impl<'a> SceneBuilder<'a> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let uv_rect =
|
let uv_rect = RectI::new(tile_coords, vec2i(1, 1)).to_f32() * uv_scale;
|
||||||
RectI::new(tile_coords, Vector2I::splat(1)).to_f32()
|
|
||||||
.scale_xy(uv_scale);
|
|
||||||
tiles.push(Tile::new_solid_from_texture_rect(tile_coords, uv_rect));
|
tiles.push(Tile::new_solid_from_texture_rect(tile_coords, uv_rect));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -894,12 +892,12 @@ fn calculate_mask_uv(tile_index: u16, tile_offset: Vector2I) -> Vector2F {
|
||||||
let mask_u = tile_index as i32 % MASK_TILES_ACROSS as i32;
|
let mask_u = tile_index as i32 % MASK_TILES_ACROSS as i32;
|
||||||
let mask_v = tile_index as i32 / MASK_TILES_ACROSS as i32;
|
let mask_v = tile_index as i32 / MASK_TILES_ACROSS as i32;
|
||||||
let scale = vec2f(1.0 / MASK_TILES_ACROSS as f32, 1.0 / MASK_TILES_DOWN as f32);
|
let scale = vec2f(1.0 / MASK_TILES_ACROSS as f32, 1.0 / MASK_TILES_DOWN as f32);
|
||||||
(vec2i(mask_u, mask_v) + tile_offset).to_f32().scale_xy(scale)
|
(vec2i(mask_u, mask_v) + tile_offset).to_f32() * scale
|
||||||
}
|
}
|
||||||
|
|
||||||
fn calculate_opacity_uv(draw_tiling_path_info: &DrawTilingPathInfo) -> Vector2F {
|
fn calculate_opacity_uv(draw_tiling_path_info: &DrawTilingPathInfo) -> Vector2F {
|
||||||
let DrawTilingPathInfo { opacity_tile_transform, opacity, .. } = *draw_tiling_path_info;
|
let DrawTilingPathInfo { opacity_tile_transform, opacity, .. } = *draw_tiling_path_info;
|
||||||
let texel_coord = (vec2i((opacity % 16) as i32, (opacity / 16) as i32).to_f32() +
|
let texel_coord = (vec2i((opacity % 16) as i32, (opacity / 16) as i32).to_f32() +
|
||||||
vec2f(0.5, 0.5)).scale(1.0 / 16.0);
|
vec2f(0.5, 0.5)) * (1.0 / 16.0);
|
||||||
opacity_tile_transform * texel_coord
|
opacity_tile_transform * texel_coord
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,8 +297,7 @@ impl Palette {
|
||||||
Paint::Gradient(Gradient { radii: Some(_), .. }) => {
|
Paint::Gradient(Gradient { radii: Some(_), .. }) => {
|
||||||
let texture_origin_uv =
|
let texture_origin_uv =
|
||||||
rect_to_inset_uv(metadata.location.rect, texture_scale).origin();
|
rect_to_inset_uv(metadata.location.rect, texture_scale).origin();
|
||||||
let gradient_tile_scale =
|
let gradient_tile_scale = texture_scale * (GRADIENT_TILE_LENGTH - 1) as f32;
|
||||||
texture_scale.scale((GRADIENT_TILE_LENGTH - 1) as f32);
|
|
||||||
Transform2F {
|
Transform2F {
|
||||||
matrix: Matrix2x2F::from_scale(gradient_tile_scale),
|
matrix: Matrix2x2F::from_scale(gradient_tile_scale),
|
||||||
vector: texture_origin_uv,
|
vector: texture_origin_uv,
|
||||||
|
@ -320,7 +319,7 @@ impl Palette {
|
||||||
let texture_origin_uv = rect_to_uv(metadata.location.rect,
|
let texture_origin_uv = rect_to_uv(metadata.location.rect,
|
||||||
texture_scale).lower_left();
|
texture_scale).lower_left();
|
||||||
Transform2F::from_translation(texture_origin_uv) *
|
Transform2F::from_translation(texture_origin_uv) *
|
||||||
Transform2F::from_scale(texture_scale.scale_xy(vec2f(1.0, -1.0))) *
|
Transform2F::from_scale(texture_scale * vec2f(1.0, -1.0)) *
|
||||||
transform.inverse()
|
transform.inverse()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,7 +371,7 @@ impl PaintMetadata {
|
||||||
// TODO(pcwalton): Apply clamp/repeat to tile rect.
|
// TODO(pcwalton): Apply clamp/repeat to tile rect.
|
||||||
pub(crate) fn calculate_tex_coords(&self, tile_position: Vector2I) -> Vector2F {
|
pub(crate) fn calculate_tex_coords(&self, tile_position: Vector2I) -> Vector2F {
|
||||||
let tile_size = vec2i(TILE_WIDTH as i32, TILE_HEIGHT as i32);
|
let tile_size = vec2i(TILE_WIDTH as i32, TILE_HEIGHT as i32);
|
||||||
let position = tile_position.scale_xy(tile_size).to_f32();
|
let position = (tile_position * tile_size).to_f32();
|
||||||
let tex_coords = self.texture_transform * position;
|
let tex_coords = self.texture_transform * position;
|
||||||
tex_coords
|
tex_coords
|
||||||
}
|
}
|
||||||
|
@ -394,11 +393,11 @@ impl PaintMetadata {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rect_to_uv(rect: RectI, texture_scale: Vector2F) -> RectF {
|
fn rect_to_uv(rect: RectI, texture_scale: Vector2F) -> RectF {
|
||||||
rect.to_f32().scale_xy(texture_scale)
|
rect.to_f32() * texture_scale
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rect_to_inset_uv(rect: RectI, texture_scale: Vector2F) -> RectF {
|
fn rect_to_inset_uv(rect: RectI, texture_scale: Vector2F) -> RectF {
|
||||||
rect_to_uv(rect, texture_scale).contract(texture_scale.scale(0.5))
|
rect_to_uv(rect, texture_scale).contract(texture_scale * 0.5)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opacity allocation
|
// Opacity allocation
|
||||||
|
@ -424,7 +423,7 @@ impl OpacityTileBuilder {
|
||||||
|
|
||||||
fn tile_transform(&self, allocator: &TextureAllocator) -> Transform2F {
|
fn tile_transform(&self, allocator: &TextureAllocator) -> Transform2F {
|
||||||
let texture_scale = allocator.page_scale(self.tile_location.page);
|
let texture_scale = allocator.page_scale(self.tile_location.page);
|
||||||
let matrix = Matrix2x2F::from_scale(texture_scale.scale(16.0));
|
let matrix = Matrix2x2F::from_scale(texture_scale * 16.0);
|
||||||
let vector = rect_to_uv(self.tile_location.rect, texture_scale).origin();
|
let vector = rect_to_uv(self.tile_location.rect, texture_scale).origin();
|
||||||
Transform2F { matrix, vector }
|
Transform2F { matrix, vector }
|
||||||
}
|
}
|
||||||
|
@ -548,8 +547,7 @@ impl GradientTileBuilder {
|
||||||
render_commands.push(RenderCommand::UploadTexelData {
|
render_commands.push(RenderCommand::UploadTexelData {
|
||||||
texels: Arc::new(tile.texels),
|
texels: Arc::new(tile.texels),
|
||||||
location: TextureLocation {
|
location: TextureLocation {
|
||||||
rect: RectI::new(Vector2I::zero(),
|
rect: RectI::new(vec2i(0, 0), Vector2I::splat(GRADIENT_TILE_LENGTH as i32)),
|
||||||
Vector2I::splat(GRADIENT_TILE_LENGTH as i32)),
|
|
||||||
page: tile.page,
|
page: tile.page,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -177,7 +177,7 @@ impl Scene {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn effective_view_box(&self, render_options: &PreparedBuildOptions) -> RectF {
|
pub(crate) fn effective_view_box(&self, render_options: &PreparedBuildOptions) -> RectF {
|
||||||
if render_options.subpixel_aa_enabled {
|
if render_options.subpixel_aa_enabled {
|
||||||
self.view_box.scale_xy(vec2f(3.0, 1.0))
|
self.view_box * vec2f(3.0, 1.0)
|
||||||
} else {
|
} else {
|
||||||
self.view_box
|
self.view_box
|
||||||
}
|
}
|
||||||
|
|
|
@ -499,7 +499,7 @@ impl<'a> PackedTile<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn round_rect_out_to_tile_bounds(rect: RectF) -> RectI {
|
pub fn round_rect_out_to_tile_bounds(rect: RectF) -> RectI {
|
||||||
rect.scale_xy(vec2f(1.0 / TILE_WIDTH as f32, 1.0 / TILE_HEIGHT as f32)).round_out().to_i32()
|
(rect * vec2f(1.0 / TILE_WIDTH as f32, 1.0 / TILE_HEIGHT as f32)).round_out().to_i32()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_active_segment(
|
fn process_active_segment(
|
||||||
|
|
|
@ -13,7 +13,7 @@ use pathfinder_color::{ColorF, ColorU};
|
||||||
use pathfinder_content::fill::FillRule;
|
use pathfinder_content::fill::FillRule;
|
||||||
use pathfinder_content::outline::{Outline, Contour};
|
use pathfinder_content::outline::{Outline, Contour};
|
||||||
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
use pathfinder_content::stroke::{OutlineStrokeToFill, StrokeStyle};
|
||||||
use pathfinder_geometry::vector::{Vector2F, vec2f};
|
use pathfinder_geometry::vector::vec2f;
|
||||||
use pathfinder_renderer::scene::{DrawPath, Scene};
|
use pathfinder_renderer::scene::{DrawPath, Scene};
|
||||||
|
|
||||||
use swf_types::tags::SetBackgroundColor;
|
use swf_types::tags::SetBackgroundColor;
|
||||||
|
|
Loading…
Reference in New Issue