aboutsummaryrefslogtreecommitdiffstats
path: root/components/canvas
diff options
context:
space:
mode:
Diffstat (limited to 'components/canvas')
-rw-r--r--components/canvas/Cargo.toml3
-rw-r--r--components/canvas/canvas_paint_thread.rs173
-rw-r--r--components/canvas/lib.rs3
-rw-r--r--components/canvas/webgl_paint_thread.rs14
4 files changed, 175 insertions, 18 deletions
diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml
index 41debc4a83a..4416e1cb0b3 100644
--- a/components/canvas/Cargo.toml
+++ b/components/canvas/Cargo.toml
@@ -12,6 +12,7 @@ path = "lib.rs"
[dependencies]
azure = {git = "https://github.com/servo/rust-azure", features = ["plugins"]}
canvas_traits = {path = "../canvas_traits"}
+cssparser = {version = "0.7", features = ["heap_size", "serde-serialization"]}
euclid = "0.10.1"
gleam = "0.2.8"
ipc-channel = "0.5"
@@ -19,7 +20,7 @@ log = "0.3.5"
num-traits = "0.1.32"
offscreen_gl_context = "0.5.0"
plugins = {path = "../plugins"}
-util = {path = "../util"}
+servo_config = {path = "../config"}
[dependencies.webrender_traits]
git = "https://github.com/servo/webrender"
diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs
index 26863482a99..f7c3fdfb6ae 100644
--- a/components/canvas/canvas_paint_thread.rs
+++ b/components/canvas/canvas_paint_thread.rs
@@ -6,7 +6,10 @@ use azure::azure::AzFloat;
use azure::azure_hl::{AntialiasMode, CapStyle, CompositionOp, JoinStyle};
use azure::azure_hl::{BackendType, DrawOptions, DrawTarget, Pattern, StrokeOptions, SurfaceFormat};
use azure::azure_hl::{Color, ColorPattern, DrawSurfaceOptions, Filter, PathBuilder};
+use azure::azure_hl::{ExtendMode, GradientStop, LinearGradientPattern, RadialGradientPattern};
+use azure::azure_hl::SurfacePattern;
use canvas_traits::*;
+use cssparser::RGBA;
use euclid::matrix2d::Matrix2D;
use euclid::point::Point2D;
use euclid::rect::Rect;
@@ -15,7 +18,7 @@ use ipc_channel::ipc::{self, IpcSender};
use num_traits::ToPrimitive;
use std::borrow::ToOwned;
use std::mem;
-use util::thread::spawn_named;
+use std::thread;
use webrender_traits;
impl<'a> CanvasPaintThread<'a> {
@@ -121,7 +124,7 @@ impl<'a> CanvasPaintThread<'a> {
antialias: bool)
-> IpcSender<CanvasMsg> {
let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap();
- spawn_named("CanvasThread".to_owned(), move || {
+ thread::Builder::new().name("CanvasThread".to_owned()).spawn(move || {
let mut painter = CanvasPaintThread::new(size, webrender_api_sender, antialias);
loop {
let msg = receiver.recv();
@@ -185,7 +188,7 @@ impl<'a> CanvasPaintThread<'a> {
Canvas2dMsg::SetShadowOffsetX(value) => painter.set_shadow_offset_x(value),
Canvas2dMsg::SetShadowOffsetY(value) => painter.set_shadow_offset_y(value),
Canvas2dMsg::SetShadowBlur(value) => painter.set_shadow_blur(value),
- Canvas2dMsg::SetShadowColor(ref color) => painter.set_shadow_color(color.to_azcolor()),
+ Canvas2dMsg::SetShadowColor(ref color) => painter.set_shadow_color(color.to_azure_style()),
}
},
CanvasMsg::Common(message) => {
@@ -211,7 +214,7 @@ impl<'a> CanvasPaintThread<'a> {
CanvasMsg::WebGL(_) => panic!("Wrong message sent to Canvas2D thread"),
}
}
- });
+ }).expect("Thread spawning failed");
sender
}
@@ -794,8 +797,8 @@ fn write_image(draw_target: &DrawTarget,
let draw_options = DrawOptions::new(global_alpha, composition_op, AntialiasMode::None);
draw_target.draw_surface(source_surface,
- dest_rect.to_azfloat(),
- image_rect.to_azfloat(),
+ dest_rect.to_azure_style(),
+ image_rect.to_azure_style(),
draw_surface_options,
draw_options);
}
@@ -854,13 +857,163 @@ impl RectToi32 for Rect<f64> {
}
-pub trait ToAzFloat {
- fn to_azfloat(&self) -> Rect<AzFloat>;
+pub trait ToAzureStyle {
+ type Target;
+ fn to_azure_style(self) -> Self::Target;
}
-impl ToAzFloat for Rect<f64> {
- fn to_azfloat(&self) -> Rect<AzFloat> {
+impl ToAzureStyle for Rect<f64> {
+ type Target = Rect<AzFloat>;
+
+ fn to_azure_style(self) -> Rect<AzFloat> {
Rect::new(Point2D::new(self.origin.x as AzFloat, self.origin.y as AzFloat),
Size2D::new(self.size.width as AzFloat, self.size.height as AzFloat))
}
}
+
+
+impl ToAzureStyle for LineCapStyle {
+ type Target = CapStyle;
+
+ fn to_azure_style(self) -> CapStyle {
+ match self {
+ LineCapStyle::Butt => CapStyle::Butt,
+ LineCapStyle::Round => CapStyle::Round,
+ LineCapStyle::Square => CapStyle::Square,
+ }
+ }
+}
+
+impl ToAzureStyle for LineJoinStyle {
+ type Target = JoinStyle;
+
+ fn to_azure_style(self) -> JoinStyle {
+ match self {
+ LineJoinStyle::Round => JoinStyle::Round,
+ LineJoinStyle::Bevel => JoinStyle::Bevel,
+ LineJoinStyle::Miter => JoinStyle::Miter,
+ }
+ }
+}
+
+impl ToAzureStyle for CompositionStyle {
+ type Target = CompositionOp;
+
+ fn to_azure_style(self) -> CompositionOp {
+ match self {
+ CompositionStyle::SrcIn => CompositionOp::In,
+ CompositionStyle::SrcOut => CompositionOp::Out,
+ CompositionStyle::SrcOver => CompositionOp::Over,
+ CompositionStyle::SrcAtop => CompositionOp::Atop,
+ CompositionStyle::DestIn => CompositionOp::DestIn,
+ CompositionStyle::DestOut => CompositionOp::DestOut,
+ CompositionStyle::DestOver => CompositionOp::DestOver,
+ CompositionStyle::DestAtop => CompositionOp::DestAtop,
+ CompositionStyle::Copy => CompositionOp::Source,
+ CompositionStyle::Lighter => CompositionOp::Add,
+ CompositionStyle::Xor => CompositionOp::Xor,
+ }
+ }
+}
+
+impl ToAzureStyle for BlendingStyle {
+ type Target = CompositionOp;
+
+ fn to_azure_style(self) -> CompositionOp {
+ match self {
+ BlendingStyle::Multiply => CompositionOp::Multiply,
+ BlendingStyle::Screen => CompositionOp::Screen,
+ BlendingStyle::Overlay => CompositionOp::Overlay,
+ BlendingStyle::Darken => CompositionOp::Darken,
+ BlendingStyle::Lighten => CompositionOp::Lighten,
+ BlendingStyle::ColorDodge => CompositionOp::ColorDodge,
+ BlendingStyle::ColorBurn => CompositionOp::ColorBurn,
+ BlendingStyle::HardLight => CompositionOp::HardLight,
+ BlendingStyle::SoftLight => CompositionOp::SoftLight,
+ BlendingStyle::Difference => CompositionOp::Difference,
+ BlendingStyle::Exclusion => CompositionOp::Exclusion,
+ BlendingStyle::Hue => CompositionOp::Hue,
+ BlendingStyle::Saturation => CompositionOp::Saturation,
+ BlendingStyle::Color => CompositionOp::Color,
+ BlendingStyle::Luminosity => CompositionOp::Luminosity,
+ }
+ }
+}
+
+impl ToAzureStyle for CompositionOrBlending {
+ type Target = CompositionOp;
+
+ fn to_azure_style(self) -> CompositionOp {
+ match self {
+ CompositionOrBlending::Composition(op) => op.to_azure_style(),
+ CompositionOrBlending::Blending(op) => op.to_azure_style(),
+ }
+ }
+}
+
+pub trait ToAzurePattern {
+ fn to_azure_pattern(&self, drawtarget: &DrawTarget) -> Option<Pattern>;
+}
+
+impl ToAzurePattern for FillOrStrokeStyle {
+ fn to_azure_pattern(&self, drawtarget: &DrawTarget) -> Option<Pattern> {
+ match *self {
+ FillOrStrokeStyle::Color(ref color) => {
+ Some(Pattern::Color(ColorPattern::new(color.to_azure_style())))
+ },
+ FillOrStrokeStyle::LinearGradient(ref linear_gradient_style) => {
+ let gradient_stops: Vec<GradientStop> = linear_gradient_style.stops.iter().map(|s| {
+ GradientStop {
+ offset: s.offset as AzFloat,
+ color: s.color.to_azure_style()
+ }
+ }).collect();
+
+ Some(Pattern::LinearGradient(LinearGradientPattern::new(
+ &Point2D::new(linear_gradient_style.x0 as AzFloat, linear_gradient_style.y0 as AzFloat),
+ &Point2D::new(linear_gradient_style.x1 as AzFloat, linear_gradient_style.y1 as AzFloat),
+ drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp),
+ &Matrix2D::identity())))
+ },
+ FillOrStrokeStyle::RadialGradient(ref radial_gradient_style) => {
+ let gradient_stops: Vec<GradientStop> = radial_gradient_style.stops.iter().map(|s| {
+ GradientStop {
+ offset: s.offset as AzFloat,
+ color: s.color.to_azure_style()
+ }
+ }).collect();
+
+ Some(Pattern::RadialGradient(RadialGradientPattern::new(
+ &Point2D::new(radial_gradient_style.x0 as AzFloat, radial_gradient_style.y0 as AzFloat),
+ &Point2D::new(radial_gradient_style.x1 as AzFloat, radial_gradient_style.y1 as AzFloat),
+ radial_gradient_style.r0 as AzFloat, radial_gradient_style.r1 as AzFloat,
+ drawtarget.create_gradient_stops(&gradient_stops, ExtendMode::Clamp),
+ &Matrix2D::identity())))
+ },
+ FillOrStrokeStyle::Surface(ref surface_style) => {
+ drawtarget.create_source_surface_from_data(&surface_style.surface_data,
+ surface_style.surface_size,
+ surface_style.surface_size.width * 4,
+ SurfaceFormat::B8G8R8A8)
+ .map(|source_surface| {
+ Pattern::Surface(SurfacePattern::new(
+ source_surface.azure_source_surface,
+ surface_style.repeat_x,
+ surface_style.repeat_y,
+ &Matrix2D::identity()))
+ })
+ }
+ }
+ }
+}
+
+impl ToAzureStyle for RGBA {
+ type Target = Color;
+
+ fn to_azure_style(self) -> Color {
+ Color::rgba(self.red as AzFloat,
+ self.green as AzFloat,
+ self.blue as AzFloat,
+ self.alpha as AzFloat)
+ }
+}
diff --git a/components/canvas/lib.rs b/components/canvas/lib.rs
index 752207aa127..10470167372 100644
--- a/components/canvas/lib.rs
+++ b/components/canvas/lib.rs
@@ -10,6 +10,7 @@
extern crate azure;
extern crate canvas_traits;
extern crate core;
+extern crate cssparser;
extern crate euclid;
extern crate gleam;
extern crate ipc_channel;
@@ -17,7 +18,7 @@ extern crate ipc_channel;
extern crate log;
extern crate num_traits;
extern crate offscreen_gl_context;
-extern crate util;
+extern crate servo_config;
extern crate webrender_traits;
pub mod canvas_paint_thread;
diff --git a/components/canvas/webgl_paint_thread.rs b/components/canvas/webgl_paint_thread.rs
index 8a080aa639a..7de4fd67979 100644
--- a/components/canvas/webgl_paint_thread.rs
+++ b/components/canvas/webgl_paint_thread.rs
@@ -9,10 +9,10 @@ use gleam::gl;
use ipc_channel::ipc::{self, IpcSender};
use offscreen_gl_context::{ColorAttachmentType, GLContext, GLLimits};
use offscreen_gl_context::{GLContextAttributes, NativeGLContext, OSMesaContext};
+use servo_config::opts;
use std::borrow::ToOwned;
use std::sync::mpsc::channel;
-use util::opts;
-use util::thread::spawn_named;
+use std::thread;
use webrender_traits;
enum GLContextWrapper {
@@ -116,7 +116,8 @@ impl WebGLPaintThread {
webrender_api_sender: webrender_traits::RenderApiSender)
-> Result<(WebGLPaintThread, GLLimits), String> {
let wr_api = webrender_api_sender.create_api();
- match wr_api.request_webgl_context(&size, attrs) {
+ let device_size = webrender_traits::DeviceIntSize::from_untyped(&size);
+ match wr_api.request_webgl_context(&device_size, attrs) {
Ok((id, limits)) => {
let painter = WebGLPaintThread {
data: WebGLPaintTaskData::WebRender(wr_api, id),
@@ -151,7 +152,7 @@ impl WebGLPaintThread {
-> Result<(IpcSender<CanvasMsg>, GLLimits), String> {
let (sender, receiver) = ipc::channel::<CanvasMsg>().unwrap();
let (result_chan, result_port) = channel();
- spawn_named("WebGLThread".to_owned(), move || {
+ thread::Builder::new().name("WebGLThread".to_owned()).spawn(move || {
let mut painter = match WebGLPaintThread::new(size, attrs, webrender_api_sender) {
Ok((thread, limits)) => {
result_chan.send(Ok(limits)).unwrap();
@@ -191,7 +192,7 @@ impl WebGLPaintThread {
CanvasMsg::Canvas2d(_) => panic!("Wrong message sent to WebGLThread"),
}
}
- });
+ }).expect("Thread spawning failed");
result_port.recv().unwrap().map(|limits| (sender, limits))
}
@@ -252,7 +253,8 @@ impl WebGLPaintThread {
}
}
WebGLPaintTaskData::WebRender(ref api, id) => {
- api.resize_webgl_context(id, &size);
+ let device_size = webrender_traits::DeviceIntSize::from_untyped(&size);
+ api.resize_webgl_context(id, &device_size);
}
}