aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas
diff options
context:
space:
mode:
Diffstat (limited to 'components/canvas')
-rw-r--r--components/canvas/backend.rs63
-rw-r--r--components/canvas/canvas_data.rs14
-rw-r--r--components/canvas/raqote_backend.rs71
3 files changed, 71 insertions, 77 deletions
diff --git a/components/canvas/backend.rs b/components/canvas/backend.rs
index c83eebe3bee..53acbea8b8d 100644
--- a/components/canvas/backend.rs
+++ b/components/canvas/backend.rs
@@ -2,8 +2,12 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
-use canvas_traits::canvas::{FillOrStrokeStyle, LineCapStyle, LineJoinStyle};
+use canvas_traits::canvas::{
+ CompositionOrBlending, FillOrStrokeStyle, LineCapStyle, LineJoinStyle,
+};
+use euclid::Angle;
use euclid::default::{Point2D, Rect, Size2D, Transform2D, Vector2D};
+use lyon_geom::Arc;
use style::color::AbsoluteColor;
use crate::canvas_data::{CanvasPaintState, Filter, TextRun};
@@ -14,10 +18,10 @@ pub(crate) trait Backend: Clone + Sized {
type Color: Clone;
type DrawOptions: DrawOptionsHelpers + Clone;
type CompositionOp;
- type CompositionOrBlending;
type DrawTarget: GenericDrawTarget<Self>;
type PathBuilder: GenericPathBuilder<Self>;
type SourceSurface;
+ type Bytes<'a>: AsRef<[u8]>;
type Path: PathHelpers<Self> + Clone;
type GradientStop;
type GradientStops;
@@ -39,7 +43,7 @@ pub(crate) trait Backend: Clone + Sized {
);
fn set_global_composition(
&mut self,
- op: Self::CompositionOrBlending,
+ op: CompositionOrBlending,
state: &mut CanvasPaintState<'_, Self>,
);
fn create_drawtarget(&self, size: Size2D<u64>) -> Self::DrawTarget;
@@ -95,7 +99,6 @@ pub(crate) trait GenericDrawTarget<B: Backend> {
fn pop_clip(&mut self);
fn push_clip(&mut self, path: &B::Path);
fn set_transform(&mut self, matrix: &Transform2D<f32>);
- fn snapshot(&self) -> B::SourceSurface;
fn stroke(
&mut self,
path: &B::Path,
@@ -118,7 +121,8 @@ pub(crate) trait GenericDrawTarget<B: Backend> {
stroke_options: &B::StrokeOptions,
draw_options: &B::DrawOptions,
);
- fn snapshot_data(&self) -> &[u8];
+ fn surface(&self) -> B::SourceSurface;
+ fn bytes(&'_ self) -> B::Bytes<'_>;
}
/// A generic PathBuilder that abstracts the interface for azure's and raqote's PathBuilder.
@@ -148,7 +152,54 @@ pub(crate) trait GenericPathBuilder<B: Backend> {
start_angle: f32,
end_angle: f32,
anticlockwise: bool,
- );
+ ) {
+ let mut start = Angle::radians(start_angle);
+ let mut end = Angle::radians(end_angle);
+
+ // Wrap angles mod 2 * PI if necessary
+ if !anticlockwise && start > end + Angle::two_pi() ||
+ anticlockwise && end > start + Angle::two_pi()
+ {
+ start = start.positive();
+ end = end.positive();
+ }
+
+ // Calculate the total arc we're going to sweep.
+ let sweep = match anticlockwise {
+ true => {
+ if end - start == Angle::two_pi() {
+ -Angle::two_pi()
+ } else if end > start {
+ -(Angle::two_pi() - (end - start))
+ } else {
+ -(start - end)
+ }
+ },
+ false => {
+ if start - end == Angle::two_pi() {
+ Angle::two_pi()
+ } else if start > end {
+ Angle::two_pi() - (start - end)
+ } else {
+ end - start
+ }
+ },
+ };
+
+ let arc: Arc<f32> = Arc {
+ center: origin,
+ radii: Vector2D::new(radius_x, radius_y),
+ start_angle: start,
+ sweep_angle: sweep,
+ x_rotation: Angle::radians(rotation_angle),
+ };
+
+ self.line_to(arc.from());
+
+ arc.for_each_quadratic_bezier(&mut |q| {
+ self.quadratic_curve_to(&q.ctrl, &q.to);
+ });
+ }
fn get_current_point(&mut self) -> Option<Point2D<f32>>;
fn line_to(&mut self, point: Point2D<f32>);
fn move_to(&mut self, point: Point2D<f32>);
diff --git a/components/canvas/canvas_data.rs b/components/canvas/canvas_data.rs
index 7d8b4a9cdbc..ea30589d0af 100644
--- a/components/canvas/canvas_data.rs
+++ b/components/canvas/canvas_data.rs
@@ -426,7 +426,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
flags: ImageDescriptorFlags::empty(),
};
let data =
- SerializableImageData::Raw(IpcSharedMemory::from_bytes(draw_target.snapshot_data()));
+ SerializableImageData::Raw(IpcSharedMemory::from_bytes(draw_target.bytes().as_ref()));
compositor_api.update_images(vec![ImageUpdate::AddImage(image_key, descriptor, data)]);
CanvasData {
state: backend.new_paint_state(),
@@ -1183,7 +1183,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
self.state.draw_options.set_alpha(alpha);
}
- pub(crate) fn set_global_composition(&mut self, op: B::CompositionOrBlending) {
+ pub(crate) fn set_global_composition(&mut self, op: CompositionOrBlending) {
self.backend.set_global_composition(op, &mut self.state);
}
@@ -1209,7 +1209,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
flags: ImageDescriptorFlags::empty(),
};
let data = SerializableImageData::Raw(IpcSharedMemory::from_bytes(
- self.drawtarget.snapshot_data(),
+ self.drawtarget.bytes().as_ref(),
));
self.compositor_api
@@ -1292,7 +1292,7 @@ impl<'a, B: Backend> CanvasData<'a, B> {
let mut new_draw_target = self.create_draw_target_for_shadow(&shadow_src_rect);
draw_shadow_source(&mut new_draw_target);
self.drawtarget.draw_surface_with_shadow(
- new_draw_target.snapshot(),
+ new_draw_target.surface(),
&Point2D::new(shadow_src_rect.origin.x, shadow_src_rect.origin.y),
&self.state.shadow_color,
&Vector2D::new(
@@ -1323,11 +1323,11 @@ impl<'a, B: Backend> CanvasData<'a, B> {
{
vec![]
} else {
- let bytes = self.drawtarget.snapshot_data();
- pixels::rgba8_get_rect(bytes, canvas_size, read_rect).to_vec()
+ pixels::rgba8_get_rect(self.drawtarget.bytes().as_ref(), canvas_size, read_rect)
+ .to_vec()
}
} else {
- self.drawtarget.snapshot_data().to_vec()
+ self.drawtarget.bytes().as_ref().to_vec()
};
Snapshot::from_vec(
diff --git a/components/canvas/raqote_backend.rs b/components/canvas/raqote_backend.rs
index e88de701336..efe0ffd05b8 100644
--- a/components/canvas/raqote_backend.rs
+++ b/components/canvas/raqote_backend.rs
@@ -7,12 +7,10 @@ use std::collections::HashMap;
use canvas_traits::canvas::*;
use cssparser::color::clamp_unit_f32;
-use euclid::Angle;
use euclid::default::{Point2D, Rect, Size2D, Transform2D, Vector2D};
use font_kit::font::Font;
use fonts::{ByteIndex, FontIdentifier, FontTemplateRefMethods};
use log::warn;
-use lyon_geom::Arc;
use range::Range;
use raqote::PathOp;
use style::color::AbsoluteColor;
@@ -40,10 +38,10 @@ impl Backend for RaqoteBackend {
type Color = raqote::SolidSource;
type DrawOptions = raqote::DrawOptions;
type CompositionOp = raqote::BlendMode;
- type CompositionOrBlending = CompositionOrBlending;
type DrawTarget = raqote::DrawTarget;
type PathBuilder = PathBuilder;
type SourceSurface = Vec<u8>; // TODO: See if we can avoid the alloc (probably?)
+ type Bytes<'a> = &'a [u8];
type Path = raqote::Path;
type GradientStop = raqote::GradientStop;
type GradientStops = Vec<raqote::GradientStop>;
@@ -84,7 +82,7 @@ impl Backend for RaqoteBackend {
fn set_global_composition(
&mut self,
- op: Self::CompositionOrBlending,
+ op: CompositionOrBlending,
state: &mut CanvasPaintState<'_, Self>,
) {
state.draw_options.blend_mode = op.to_raqote_style();
@@ -598,8 +596,8 @@ impl GenericDrawTarget<RaqoteBackend> for raqote::DrawTarget {
fn set_transform(&mut self, matrix: &Transform2D<f32>) {
self.set_transform(matrix);
}
- fn snapshot(&self) -> <RaqoteBackend as Backend>::SourceSurface {
- self.snapshot_data().to_vec()
+ fn surface(&self) -> <RaqoteBackend as Backend>::SourceSurface {
+ self.bytes().to_vec()
}
fn stroke(
&mut self,
@@ -658,7 +656,7 @@ impl GenericDrawTarget<RaqoteBackend> for raqote::DrawTarget {
);
}
#[allow(unsafe_code)]
- fn snapshot_data(&self) -> &[u8] {
+ fn bytes(&self) -> &[u8] {
let v = self.get_data();
unsafe { std::slice::from_raw_parts(v.as_ptr() as *const u8, std::mem::size_of_val(v)) }
}
@@ -701,6 +699,7 @@ impl GenericPathBuilder<RaqoteBackend> for PathBuilder {
anticlockwise,
);
}
+
fn bezier_curve_to(
&mut self,
control_point1: &Point2D<f32>,
@@ -716,66 +715,10 @@ impl GenericPathBuilder<RaqoteBackend> for PathBuilder {
control_point3.y,
);
}
+
fn close(&mut self) {
self.0.as_mut().unwrap().close();
}
- fn ellipse(
- &mut self,
- origin: Point2D<f32>,
- radius_x: f32,
- radius_y: f32,
- rotation_angle: f32,
- start_angle: f32,
- end_angle: f32,
- anticlockwise: bool,
- ) {
- let mut start = Angle::radians(start_angle);
- let mut end = Angle::radians(end_angle);
-
- // Wrap angles mod 2 * PI if necessary
- if !anticlockwise && start > end + Angle::two_pi() ||
- anticlockwise && end > start + Angle::two_pi()
- {
- start = start.positive();
- end = end.positive();
- }
-
- // Calculate the total arc we're going to sweep.
- let sweep = match anticlockwise {
- true => {
- if end - start == Angle::two_pi() {
- -Angle::two_pi()
- } else if end > start {
- -(Angle::two_pi() - (end - start))
- } else {
- -(start - end)
- }
- },
- false => {
- if start - end == Angle::two_pi() {
- Angle::two_pi()
- } else if start > end {
- Angle::two_pi() - (start - end)
- } else {
- end - start
- }
- },
- };
-
- let arc: Arc<f32> = Arc {
- center: origin,
- radii: Vector2D::new(radius_x, radius_y),
- start_angle: start,
- sweep_angle: sweep,
- x_rotation: Angle::radians(rotation_angle),
- };
-
- self.line_to(arc.from());
-
- arc.for_each_quadratic_bezier(&mut |q| {
- self.quadratic_curve_to(&q.ctrl, &q.to);
- });
- }
fn svg_arc(
&mut self,