mirror of
https://github.com/servo/servo.git
synced 2025-06-24 17:14:33 +01:00
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:
commit
fe81ce942a
18 changed files with 109 additions and 67 deletions
|
@ -39,6 +39,8 @@ pub enum CanvasMsg {
|
||||||
SetFillStyle(FillOrStrokeStyle),
|
SetFillStyle(FillOrStrokeStyle),
|
||||||
SetStrokeStyle(FillOrStrokeStyle),
|
SetStrokeStyle(FillOrStrokeStyle),
|
||||||
SetLineWidth(f32),
|
SetLineWidth(f32),
|
||||||
|
SetLineCap(LineCapStyle),
|
||||||
|
SetLineJoin(LineJoinStyle),
|
||||||
SetMiterLimit(f32),
|
SetMiterLimit(f32),
|
||||||
SetTransform(Matrix2D<f32>),
|
SetTransform(Matrix2D<f32>),
|
||||||
SetGlobalAlpha(f32),
|
SetGlobalAlpha(f32),
|
||||||
|
@ -246,6 +248,8 @@ impl<'a> CanvasPaintTask<'a> {
|
||||||
CanvasMsg::SetFillStyle(style) => painter.set_fill_style(style),
|
CanvasMsg::SetFillStyle(style) => painter.set_fill_style(style),
|
||||||
CanvasMsg::SetStrokeStyle(style) => painter.set_stroke_style(style),
|
CanvasMsg::SetStrokeStyle(style) => painter.set_stroke_style(style),
|
||||||
CanvasMsg::SetLineWidth(width) => painter.set_line_width(width),
|
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::SetMiterLimit(limit) => painter.set_miter_limit(limit),
|
||||||
CanvasMsg::SetTransform(ref matrix) => painter.set_transform(matrix),
|
CanvasMsg::SetTransform(ref matrix) => painter.set_transform(matrix),
|
||||||
CanvasMsg::SetGlobalAlpha(alpha) => painter.set_global_alpha(alpha),
|
CanvasMsg::SetGlobalAlpha(alpha) => painter.set_global_alpha(alpha),
|
||||||
|
@ -427,6 +431,14 @@ impl<'a> CanvasPaintTask<'a> {
|
||||||
self.stroke_opts.line_width = width;
|
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) {
|
fn set_miter_limit(&mut self, limit: f32) {
|
||||||
self.stroke_opts.miter_limit = limit;
|
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
|
/// Used by drawImage to get rid of the extra pixels of the image data that
|
||||||
/// won't be copied to the canvas
|
/// won't be copied to the canvas
|
||||||
/// image_data: Color pixel data of the image
|
/// image_data: Color pixel data of the image
|
||||||
|
|
|
@ -35,6 +35,7 @@ use dom::bindings::utils::{Reflectable, Reflector, WindowProxyHandler};
|
||||||
use script_task::ScriptChan;
|
use script_task::ScriptChan;
|
||||||
|
|
||||||
use canvas::canvas_paint_task::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle};
|
use canvas::canvas_paint_task::{CanvasGradientStop, LinearGradientStyle, RadialGradientStyle};
|
||||||
|
use canvas::canvas_paint_task::{LineCapStyle, LineJoinStyle};
|
||||||
use cssparser::RGBA;
|
use cssparser::RGBA;
|
||||||
use encoding::types::EncodingRef;
|
use encoding::types::EncodingRef;
|
||||||
use geom::matrix2d::Matrix2D;
|
use geom::matrix2d::Matrix2D;
|
||||||
|
@ -259,6 +260,7 @@ no_jsmanaged_fields!(RGBA);
|
||||||
no_jsmanaged_fields!(Matrix2D<T>);
|
no_jsmanaged_fields!(Matrix2D<T>);
|
||||||
no_jsmanaged_fields!(StorageType);
|
no_jsmanaged_fields!(StorageType);
|
||||||
no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle);
|
no_jsmanaged_fields!(CanvasGradientStop, LinearGradientStyle, RadialGradientStyle);
|
||||||
|
no_jsmanaged_fields!(LineCapStyle, LineJoinStyle);
|
||||||
|
|
||||||
impl JSTraceable for Box<ScriptChan+Send> {
|
impl JSTraceable for Box<ScriptChan+Send> {
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
|
@ -29,6 +29,7 @@ use geom::size::Size2D;
|
||||||
|
|
||||||
use canvas::canvas_paint_task::{CanvasMsg, CanvasPaintTask, FillOrStrokeStyle};
|
use canvas::canvas_paint_task::{CanvasMsg, CanvasPaintTask, FillOrStrokeStyle};
|
||||||
use canvas::canvas_paint_task::{LinearGradientStyle, RadialGradientStyle};
|
use canvas::canvas_paint_task::{LinearGradientStyle, RadialGradientStyle};
|
||||||
|
use canvas::canvas_paint_task::{LineCapStyle, LineJoinStyle};
|
||||||
|
|
||||||
use net_traits::image::base::Image;
|
use net_traits::image::base::Image;
|
||||||
use net_traits::image_cache_task::{ImageResponseMsg, Msg};
|
use net_traits::image_cache_task::{ImageResponseMsg, Msg};
|
||||||
|
@ -40,6 +41,7 @@ use std::num::{Float, ToPrimitive};
|
||||||
use std::sync::{Arc};
|
use std::sync::{Arc};
|
||||||
use std::sync::mpsc::{channel, Sender};
|
use std::sync::mpsc::{channel, Sender};
|
||||||
|
|
||||||
|
use util::str::DOMString;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use util::vec::byte_swap;
|
use util::vec::byte_swap;
|
||||||
|
|
||||||
|
@ -53,6 +55,8 @@ pub struct CanvasRenderingContext2D {
|
||||||
image_smoothing_enabled: Cell<bool>,
|
image_smoothing_enabled: Cell<bool>,
|
||||||
stroke_color: Cell<RGBA>,
|
stroke_color: Cell<RGBA>,
|
||||||
line_width: Cell<f64>,
|
line_width: Cell<f64>,
|
||||||
|
line_cap: Cell<LineCapStyle>,
|
||||||
|
line_join: Cell<LineJoinStyle>,
|
||||||
miter_limit: Cell<f64>,
|
miter_limit: Cell<f64>,
|
||||||
fill_color: Cell<RGBA>,
|
fill_color: Cell<RGBA>,
|
||||||
transform: Cell<Matrix2D<f32>>,
|
transform: Cell<Matrix2D<f32>>,
|
||||||
|
@ -76,6 +80,8 @@ impl CanvasRenderingContext2D {
|
||||||
image_smoothing_enabled: Cell::new(true),
|
image_smoothing_enabled: Cell::new(true),
|
||||||
stroke_color: Cell::new(black),
|
stroke_color: Cell::new(black),
|
||||||
line_width: Cell::new(1.0),
|
line_width: Cell::new(1.0),
|
||||||
|
line_cap: Cell::new(LineCapStyle::Butt),
|
||||||
|
line_join: Cell::new(LineJoinStyle::Miter),
|
||||||
miter_limit: Cell::new(10.0),
|
miter_limit: Cell::new(10.0),
|
||||||
fill_color: Cell::new(black),
|
fill_color: Cell::new(black),
|
||||||
transform: Cell::new(Matrix2D::identity()),
|
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()
|
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 {
|
fn MiterLimit(self) -> f64 {
|
||||||
self.miter_limit.get()
|
self.miter_limit.get()
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,8 +134,8 @@ interface CanvasRenderingContext2D {
|
||||||
interface CanvasDrawingStyles {
|
interface CanvasDrawingStyles {
|
||||||
// line caps/joins
|
// line caps/joins
|
||||||
attribute unrestricted double lineWidth; // (default 1)
|
attribute unrestricted double lineWidth; // (default 1)
|
||||||
//attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
|
attribute DOMString lineCap; // "butt", "round", "square" (default "butt")
|
||||||
//attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
|
attribute DOMString lineJoin; // "round", "bevel", "miter" (default "miter")
|
||||||
attribute unrestricted double miterLimit; // (default 10)
|
attribute unrestricted double miterLimit; // (default 10)
|
||||||
|
|
||||||
// dashed lines
|
// dashed lines
|
||||||
|
|
2
components/servo/Cargo.lock
generated
2
components/servo/Cargo.lock
generated
|
@ -35,7 +35,7 @@ source = "git+https://github.com/tomaka/android-rs-glue#5a68056599fb498b0cf3715f
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "azure"
|
name = "azure"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/rust-azure#c71473d94ae24fb195987660698207d5088a4042"
|
source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
|
"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)",
|
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
|
||||||
|
|
3
ports/cef/Cargo.lock
generated
3
ports/cef/Cargo.lock
generated
|
@ -37,7 +37,7 @@ source = "git+https://github.com/tomaka/android-rs-glue#5a68056599fb498b0cf3715f
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "azure"
|
name = "azure"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/rust-azure#c71473d94ae24fb195987660698207d5088a4042"
|
source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
|
"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)",
|
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
|
||||||
|
@ -176,6 +176,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
3
ports/gonk/Cargo.lock
generated
3
ports/gonk/Cargo.lock
generated
|
@ -26,7 +26,7 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "azure"
|
name = "azure"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/servo/rust-azure#c71473d94ae24fb195987660698207d5088a4042"
|
source = "git+https://github.com/servo/rust-azure#358fc5da081cf7d0618fae2d9d5582951beb791f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"core_foundation 0.1.0 (git+https://github.com/servo/rust-core-foundation)",
|
"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)",
|
"core_graphics 0.1.0 (git+https://github.com/servo/rust-core-graphics)",
|
||||||
|
@ -156,6 +156,7 @@ version = "0.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"rustc-serialize 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"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)",
|
"url 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"util 0.0.1",
|
"util 0.0.1",
|
||||||
]
|
]
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.cap.invalid.html]
|
|
||||||
type: testharness
|
|
||||||
[Setting lineCap to invalid values is ignored]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.cap.open.html]
|
|
||||||
type: testharness
|
|
||||||
[Line caps are drawn at the corners of an unclosed rectangle]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.cap.round.html]
|
|
||||||
type: testharness
|
|
||||||
[lineCap \'round\' is rendered correctly]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.cap.square.html]
|
|
||||||
type: testharness
|
|
||||||
[lineCap \'square\' is rendered correctly]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.defaults.html]
|
|
||||||
type: testharness
|
|
||||||
[Canvas test: 2d.line.defaults]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.join.bevel.html]
|
|
||||||
type: testharness
|
|
||||||
[lineJoin \'bevel\' is rendered correctly]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.join.invalid.html]
|
|
||||||
type: testharness
|
|
||||||
[Setting lineJoin to invalid values is ignored]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.join.parallel.html]
|
|
||||||
type: testharness
|
|
||||||
[Line joins are drawn at 180-degree joins]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
[2d.line.join.round.html]
|
|
||||||
type: testharness
|
|
||||||
[lineJoin \'round\' is rendered correctly]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
|
@ -6993,12 +6993,6 @@
|
||||||
[CanvasRenderingContext2D interface: operation putImageData(ImageData,double,double)]
|
[CanvasRenderingContext2D interface: operation putImageData(ImageData,double,double)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
[CanvasRenderingContext2D interface: attribute lineCap]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CanvasRenderingContext2D interface: attribute lineJoin]
|
|
||||||
expected: FAIL
|
|
||||||
|
|
||||||
[CanvasRenderingContext2D interface: operation setLineDash([object Object\])]
|
[CanvasRenderingContext2D interface: operation setLineDash([object Object\])]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
@ -7200,12 +7194,6 @@
|
||||||
[CanvasRenderingContext2D interface: calling removeHitRegion(DOMString) on document.createElement("canvas").getContext("2d") with too few arguments must throw TypeError]
|
[CanvasRenderingContext2D interface: calling removeHitRegion(DOMString) on document.createElement("canvas").getContext("2d") with too few arguments must throw TypeError]
|
||||||
expected: FAIL
|
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)]
|
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "setLineDash" with the proper type (63)]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue