Auto merge of #5635 - mmatyas:canvas_linecapjoin, r=jdm

This patch adds support for setting the line cap and join. However, it seems there's a problem on the azure-side, as the line cap setting doesn't work. Changing either the default values or using the new function has no effect. Line join works fine though.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/5635)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2015-04-14 12:57:48 -05:00
commit fe81ce942a
18 changed files with 109 additions and 67 deletions

View file

@ -39,6 +39,8 @@ pub enum CanvasMsg {
SetFillStyle(FillOrStrokeStyle),
SetStrokeStyle(FillOrStrokeStyle),
SetLineWidth(f32),
SetLineCap(LineCapStyle),
SetLineJoin(LineJoinStyle),
SetMiterLimit(f32),
SetTransform(Matrix2D<f32>),
SetGlobalAlpha(f32),
@ -246,6 +248,8 @@ impl<'a> CanvasPaintTask<'a> {
CanvasMsg::SetFillStyle(style) => painter.set_fill_style(style),
CanvasMsg::SetStrokeStyle(style) => painter.set_stroke_style(style),
CanvasMsg::SetLineWidth(width) => painter.set_line_width(width),
CanvasMsg::SetLineCap(cap) => painter.set_line_cap(cap),
CanvasMsg::SetLineJoin(join) => painter.set_line_join(join),
CanvasMsg::SetMiterLimit(limit) => painter.set_miter_limit(limit),
CanvasMsg::SetTransform(ref matrix) => painter.set_transform(matrix),
CanvasMsg::SetGlobalAlpha(alpha) => painter.set_global_alpha(alpha),
@ -427,6 +431,14 @@ impl<'a> CanvasPaintTask<'a> {
self.stroke_opts.line_width = width;
}
fn set_line_cap(&mut self, cap: LineCapStyle) {
self.stroke_opts.line_cap = cap.to_azure_style();
}
fn set_line_join(&mut self, join: LineJoinStyle) {
self.stroke_opts.line_join = join.to_azure_style();
}
fn set_miter_limit(&mut self, limit: f32) {
self.stroke_opts.miter_limit = limit;
}
@ -626,6 +638,58 @@ impl FillOrStrokeStyle {
}
}
#[derive(Copy, Clone, PartialEq)]
pub enum LineCapStyle {
Butt = 0,
Round = 1,
Square = 2,
}
impl LineCapStyle {
fn to_azure_style(&self) -> CapStyle {
match *self {
LineCapStyle::Butt => CapStyle::Butt,
LineCapStyle::Round => CapStyle::Round,
LineCapStyle::Square => CapStyle::Square,
}
}
pub fn from_str(string: &str) -> Option<LineCapStyle> {
match string {
"butt" => Some(LineCapStyle::Butt),
"round" => Some(LineCapStyle::Round),
"square" => Some(LineCapStyle::Square),
_ => None
}
}
}
#[derive(Copy, Clone, PartialEq)]
pub enum LineJoinStyle {
Round = 0,
Bevel = 1,
Miter = 2,
}
impl LineJoinStyle {
fn to_azure_style(&self) -> JoinStyle {
match *self {
LineJoinStyle::Round => JoinStyle::Round,
LineJoinStyle::Bevel => JoinStyle::Bevel,
LineJoinStyle::Miter => JoinStyle::Miter,
}
}
pub fn from_str(string: &str) -> Option<LineJoinStyle> {
match string {
"round" => Some(LineJoinStyle::Round),
"bevel" => Some(LineJoinStyle::Bevel),
"miter" => Some(LineJoinStyle::Miter),
_ => None
}
}
}
/// Used by drawImage to get rid of the extra pixels of the image data that
/// won't be copied to the canvas
/// image_data: Color pixel data of the image

View file

@ -35,6 +35,7 @@ use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler};
use script_task::ScriptChan;
use canvas::canvas_paint_task::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle};
use canvas::canvas_paint_task::{LineCapStyle, LineJoinStyle};
use cssparser::RGBA;
use encoding::types::EncodingRef;
use geom::matrix2d::Matrix2D;
@ -259,6 +260,7 @@ no_jsmanaged_fields!(RGBA);
no_jsmanaged_fields!(Matrix2D<T>);
no_jsmanaged_fields!(StorageType);
no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle);
no_jsmanaged_fields!(LineCapStyle, LineJoinStyle);
impl JSTraceable for Box<ScriptChan+Send> {
#[inline]

View file

@ -29,6 +29,7 @@ use geom::size::Size2D;
use canvas::canvas_paint_task::{CanvasMsg, CanvasPaintTask, FillOrStrokeStyle};
use canvas::canvas_paint_task::{LinearGradientStyle, RadialGradientStyle};
use canvas::canvas_paint_task::{LineCapStyle, LineJoinStyle};
use net_traits::image::base::Image;
use net_traits::image_cache_task::{ImageResponseMsg, Msg};
@ -40,6 +41,7 @@ use std::num::{Float, ToPrimitive};
use std::sync::{Arc};
use std::sync::mpsc::{channel, Sender};
use util::str::DOMString;
use url::Url;
use util::vec::byte_swap;
@ -53,6 +55,8 @@ pub struct CanvasRenderingContext2D {
image_smoothing_enabled: Cell<bool>,
stroke_color: Cell<RGBA>,
line_width: Cell<f64>,
line_cap: Cell<LineCapStyle>,
line_join: Cell<LineJoinStyle>,
miter_limit: Cell<f64>,
fill_color: Cell<RGBA>,
transform: Cell<Matrix2D<f32>>,
@ -76,6 +80,8 @@ impl CanvasRenderingContext2D {
image_smoothing_enabled: Cell::new(true),
stroke_color: Cell::new(black),
line_width: Cell::new(1.0),
line_cap: Cell::new(LineCapStyle::Butt),
line_join: Cell::new(LineJoinStyle::Miter),
miter_limit: Cell::new(10.0),
fill_color: Cell::new(black),
transform: Cell::new(Matrix2D::identity()),
@ -819,6 +825,36 @@ impl<'a> CanvasRenderingContext2DMethods for JSRef<'a, CanvasRenderingContext2D>
self.renderer.send(CanvasMsg::SetLineWidth(width as f32)).unwrap()
}
fn LineCap(self) -> DOMString {
match self.line_cap.get() {
LineCapStyle::Butt => "butt".to_owned(),
LineCapStyle::Round => "round".to_owned(),
LineCapStyle::Square => "square".to_owned(),
}
}
fn SetLineCap(self, cap_str: DOMString) {
if let Some(cap) = LineCapStyle::from_str(&cap_str) {
self.line_cap.set(cap);
self.renderer.send(CanvasMsg::SetLineCap(cap)).unwrap()
}
}
fn LineJoin(self) -> DOMString {
match self.line_join.get() {
LineJoinStyle::Round => "round".to_owned(),
LineJoinStyle::Bevel => "bevel".to_owned(),
LineJoinStyle::Miter => "miter".to_owned(),
}
}
fn SetLineJoin(self, join_str: DOMString) {
if let Some(join) = LineJoinStyle::from_str(&join_str) {
self.line_join.set(join);
self.renderer.send(CanvasMsg::SetLineJoin(join)).unwrap()
}
}
fn MiterLimit(self) -> f64 {
self.miter_limit.get()
}

View file

@ -134,8 +134,8 @@ interface CanvasRenderingContext2D {
interface CanvasDrawingStyles {
// line caps/joins
attribute unrestricted double lineWidth; // (default 1)
//attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
//attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
attribute unrestricted double miterLimit; // (default 10)
// dashed lines

View file

@ -35,7 +35,7 @@ source = "git+https://github.com/tomaka/android-rs-glue#5a68056599fb498b0cf3715f
[[package]]
name = "azure"
version = "0.1.0"
source = "git+https://github.com/servo/rust-azure#c71473d94ae24fb195987660698207d5088a4042"
source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",

3
ports/cef/Cargo.lock generated
View file

@ -37,7 +37,7 @@ source = "git+https://github.com/tomaka/android-rs-glue#5a68056599fb498b0cf3715f
[[package]]
name = "azure"
version = "0.1.0"
source = "git+https://github.com/servo/rust-azure#c71473d94ae24fb195987660698207d5088a4042"
source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
@ -176,6 +176,7 @@ version = "0.0.1"
dependencies = [
"msg 0.0.1",
"rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
]

3
ports/gonk/Cargo.lock generated
View file

@ -26,7 +26,7 @@ dependencies = [
[[package]]
name = "azure"
version = "0.1.0"
source = "git+https://github.com/servo/rust-azure#c71473d94ae24fb195987660698207d5088a4042"
source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
dependencies = [
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
@ -156,6 +156,7 @@ version = "0.0.1"
dependencies = [
"msg 0.0.1",
"rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.19 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"util 0.0.1",
]

View file

@ -1,5 +0,0 @@
[2d.line.cap.closed.html]
type: testharness
[Line caps are not drawn at the corners of an unclosed rectangle]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.cap.invalid.html]
type: testharness
[Setting lineCap to invalid values is ignored]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.cap.open.html]
type: testharness
[Line caps are drawn at the corners of an unclosed rectangle]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.cap.round.html]
type: testharness
[lineCap \'round\' is rendered correctly]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.cap.square.html]
type: testharness
[lineCap \'square\' is rendered correctly]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.defaults.html]
type: testharness
[Canvas test: 2d.line.defaults]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.join.bevel.html]
type: testharness
[lineJoin \'bevel\' is rendered correctly]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.join.invalid.html]
type: testharness
[Setting lineJoin to invalid values is ignored]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.join.parallel.html]
type: testharness
[Line joins are drawn at 180-degree joins]
expected: FAIL

View file

@ -1,5 +0,0 @@
[2d.line.join.round.html]
type: testharness
[lineJoin \'round\' is rendered correctly]
expected: FAIL

View file

@ -6993,12 +6993,6 @@
[CanvasRenderingContext2D interface: operation putImageData(ImageData,double,double)]
expected: FAIL
[CanvasRenderingContext2D interface: attribute lineCap]
expected: FAIL
[CanvasRenderingContext2D interface: attribute lineJoin]
expected: FAIL
[CanvasRenderingContext2D interface: operation setLineDash([object Object\])]
expected: FAIL
@ -7200,12 +7194,6 @@
[CanvasRenderingContext2D interface: calling removeHitRegion(DOMString) on document.createElement("canvas").getContext("2d") with too few arguments must throw TypeError]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "lineCap" with the proper type (60)]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "lineJoin" with the proper type (61)]
expected: FAIL
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "setLineDash" with the proper type (63)]
expected: FAIL