Add affine transform support to the canvas implementation
This commit is contained in:
parent
89ca998fa8
commit
c7382a8b2c
|
@ -94,10 +94,12 @@ impl CanvasRenderingContext2D {
|
||||||
pub fn fill_text(&mut self, string: &str, position: Point2DF32) {
|
pub fn fill_text(&mut self, string: &str, position: Point2DF32) {
|
||||||
// TODO(pcwalton): Report errors.
|
// TODO(pcwalton): Report errors.
|
||||||
let paint_id = self.scene.push_paint(&self.current_state.fill_paint);
|
let paint_id = self.scene.push_paint(&self.current_state.fill_paint);
|
||||||
|
let transform = Transform2DF32::from_translation(position).post_mul(&self.current_state
|
||||||
|
.transform);
|
||||||
drop(self.scene.push_text(string,
|
drop(self.scene.push_text(string,
|
||||||
&TextStyle { size: self.current_state.font_size },
|
&TextStyle { size: self.current_state.font_size },
|
||||||
&self.current_state.font_collection,
|
&self.current_state.font_collection,
|
||||||
&Transform2DF32::from_translation(position),
|
&transform,
|
||||||
TextRenderMode::Fill,
|
TextRenderMode::Fill,
|
||||||
HintingOptions::None,
|
HintingOptions::None,
|
||||||
paint_id));
|
paint_id));
|
||||||
|
@ -106,10 +108,12 @@ impl CanvasRenderingContext2D {
|
||||||
pub fn stroke_text(&mut self, string: &str, position: Point2DF32) {
|
pub fn stroke_text(&mut self, string: &str, position: Point2DF32) {
|
||||||
// TODO(pcwalton): Report errors.
|
// TODO(pcwalton): Report errors.
|
||||||
let paint_id = self.scene.push_paint(&self.current_state.stroke_paint);
|
let paint_id = self.scene.push_paint(&self.current_state.stroke_paint);
|
||||||
|
let transform = Transform2DF32::from_translation(position).post_mul(&self.current_state
|
||||||
|
.transform);
|
||||||
drop(self.scene.push_text(string,
|
drop(self.scene.push_text(string,
|
||||||
&TextStyle { size: self.current_state.font_size },
|
&TextStyle { size: self.current_state.font_size },
|
||||||
&self.current_state.font_collection,
|
&self.current_state.font_collection,
|
||||||
&Transform2DF32::from_translation(position),
|
&transform,
|
||||||
TextRenderMode::Stroke(self.current_state.line_width),
|
TextRenderMode::Stroke(self.current_state.line_width),
|
||||||
HintingOptions::None,
|
HintingOptions::None,
|
||||||
paint_id));
|
paint_id));
|
||||||
|
@ -139,12 +143,14 @@ impl CanvasRenderingContext2D {
|
||||||
self.current_state.font_size = new_font_size;
|
self.current_state.font_size = new_font_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paths
|
// Drawing paths
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn fill_path(&mut self, path: Path2D) {
|
pub fn fill_path(&mut self, path: Path2D) {
|
||||||
|
let mut outline = path.into_outline();
|
||||||
|
outline.transform(&self.current_state.transform);
|
||||||
let paint_id = self.scene.push_paint(&self.current_state.fill_paint);
|
let paint_id = self.scene.push_paint(&self.current_state.fill_paint);
|
||||||
self.scene.push_path(PathObject::new(path.into_outline(), paint_id, String::new()))
|
self.scene.push_path(PathObject::new(outline, paint_id, String::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -153,9 +159,29 @@ impl CanvasRenderingContext2D {
|
||||||
let stroke_width = f32::max(self.current_state.line_width, HAIRLINE_STROKE_WIDTH);
|
let stroke_width = f32::max(self.current_state.line_width, HAIRLINE_STROKE_WIDTH);
|
||||||
let mut stroke_to_fill = OutlineStrokeToFill::new(path.into_outline(), stroke_width);
|
let mut stroke_to_fill = OutlineStrokeToFill::new(path.into_outline(), stroke_width);
|
||||||
stroke_to_fill.offset();
|
stroke_to_fill.offset();
|
||||||
|
stroke_to_fill.outline.transform(&self.current_state.transform);
|
||||||
self.scene.push_path(PathObject::new(stroke_to_fill.outline, paint_id, String::new()))
|
self.scene.push_path(PathObject::new(stroke_to_fill.outline, paint_id, String::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Transformations
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn current_transform(&self) -> Transform2DF32 {
|
||||||
|
self.current_state.transform
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_current_transform(&mut self, new_transform: &Transform2DF32) {
|
||||||
|
self.current_state.transform = *new_transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn reset_transform(&mut self) {
|
||||||
|
self.current_state.transform = Transform2DF32::default();
|
||||||
|
}
|
||||||
|
|
||||||
|
// The canvas state
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn save(&mut self) {
|
pub fn save(&mut self) {
|
||||||
self.saved_states.push(self.current_state.clone());
|
self.saved_states.push(self.current_state.clone());
|
||||||
|
@ -171,6 +197,7 @@ impl CanvasRenderingContext2D {
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct State {
|
pub struct State {
|
||||||
|
transform: Transform2DF32,
|
||||||
font_collection: Arc<FontCollection>,
|
font_collection: Arc<FontCollection>,
|
||||||
font_size: f32,
|
font_size: f32,
|
||||||
fill_paint: Paint,
|
fill_paint: Paint,
|
||||||
|
@ -181,6 +208,7 @@ pub struct State {
|
||||||
impl State {
|
impl State {
|
||||||
fn default(default_font_collection: Arc<FontCollection>) -> State {
|
fn default(default_font_collection: Arc<FontCollection>) -> State {
|
||||||
State {
|
State {
|
||||||
|
transform: Transform2DF32::default(),
|
||||||
font_collection: default_font_collection,
|
font_collection: default_font_collection,
|
||||||
font_size: DEFAULT_FONT_SIZE,
|
font_size: DEFAULT_FONT_SIZE,
|
||||||
fill_paint: Paint { color: ColorU::black() },
|
fill_paint: Paint { color: ColorU::black() },
|
||||||
|
|
|
@ -127,6 +127,10 @@ impl Outline {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform(&mut self, transform: &Transform2DF32) {
|
pub fn transform(&mut self, transform: &Transform2DF32) {
|
||||||
|
if transform.is_identity() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let mut new_bounds = None;
|
let mut new_bounds = None;
|
||||||
for contour in &mut self.contours {
|
for contour in &mut self.contours {
|
||||||
contour.transform(transform);
|
contour.transform(transform);
|
||||||
|
@ -487,6 +491,10 @@ impl Contour {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn transform(&mut self, transform: &Transform2DF32) {
|
pub fn transform(&mut self, transform: &Transform2DF32) {
|
||||||
|
if transform.is_identity() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (point_index, point) in self.points.iter_mut().enumerate() {
|
for (point_index, point) in self.points.iter_mut().enumerate() {
|
||||||
*point = transform.transform_point(*point);
|
*point = transform.transform_point(*point);
|
||||||
union_rect(&mut self.bounds, *point, point_index == 0);
|
union_rect(&mut self.bounds, *point, point_index == 0);
|
||||||
|
|
Loading…
Reference in New Issue