mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
canvas: Implement line dash setters and getters (#36257)
Implement `setLineDash`, `getLineDash`, and `lineDashOffset` from `CanvasPathDrawingStyles` mixin, according to the spec https://html.spec.whatwg.org/multipage/canvas.html#canvaspathdrawingstyles. Testing: Existing WPT. --------- Signed-off-by: stevennovaryo <steven.novaryo@gmail.com>
This commit is contained in:
parent
bc6926d1fe
commit
a77592e281
21 changed files with 144 additions and 92 deletions
|
@ -1366,6 +1366,14 @@ impl<'a> CanvasData<'a> {
|
|||
self.state.stroke_opts.set_miter_limit(limit);
|
||||
}
|
||||
|
||||
pub fn set_line_dash(&mut self, items: Vec<f32>) {
|
||||
self.state.stroke_opts.set_line_dash(items);
|
||||
}
|
||||
|
||||
pub fn set_line_dash_offset(&mut self, offset: f32) {
|
||||
self.state.stroke_opts.set_line_dash_offset(offset);
|
||||
}
|
||||
|
||||
pub fn get_transform(&self) -> Transform2D<f32> {
|
||||
self.drawtarget.get_transform()
|
||||
}
|
||||
|
|
|
@ -230,6 +230,10 @@ impl<'a> CanvasPaintThread<'a> {
|
|||
Canvas2dMsg::SetLineCap(cap) => self.canvas(canvas_id).set_line_cap(cap),
|
||||
Canvas2dMsg::SetLineJoin(join) => self.canvas(canvas_id).set_line_join(join),
|
||||
Canvas2dMsg::SetMiterLimit(limit) => self.canvas(canvas_id).set_miter_limit(limit),
|
||||
Canvas2dMsg::SetLineDash(items) => self.canvas(canvas_id).set_line_dash(items),
|
||||
Canvas2dMsg::SetLineDashOffset(offset) => {
|
||||
self.canvas(canvas_id).set_line_dash_offset(offset)
|
||||
},
|
||||
Canvas2dMsg::GetTransform(sender) => {
|
||||
let transform = self.canvas(canvas_id).get_transform();
|
||||
sender.send(transform).unwrap();
|
||||
|
|
|
@ -298,6 +298,16 @@ impl StrokeOptions {
|
|||
StrokeOptions::Raqote(options) => options.cap = val.to_raqote_style(),
|
||||
}
|
||||
}
|
||||
pub fn set_line_dash(&mut self, items: Vec<f32>) {
|
||||
match self {
|
||||
StrokeOptions::Raqote(options) => options.dash_array = items,
|
||||
}
|
||||
}
|
||||
pub fn set_line_dash_offset(&mut self, offset: f32) {
|
||||
match self {
|
||||
StrokeOptions::Raqote(options) => options.dash_offset = offset,
|
||||
}
|
||||
}
|
||||
pub fn as_raqote(&self) -> &raqote::StrokeStyle {
|
||||
match self {
|
||||
StrokeOptions::Raqote(options) => options,
|
||||
|
|
|
@ -94,6 +94,8 @@ pub(crate) struct CanvasContextState {
|
|||
#[no_trace]
|
||||
line_join: LineJoinStyle,
|
||||
miter_limit: f64,
|
||||
line_dash: Vec<f64>,
|
||||
line_dash_offset: f64,
|
||||
#[no_trace]
|
||||
transform: Transform2D<f32>,
|
||||
shadow_offset_x: f64,
|
||||
|
@ -134,6 +136,8 @@ impl CanvasContextState {
|
|||
text_align: Default::default(),
|
||||
text_baseline: Default::default(),
|
||||
direction: Default::default(),
|
||||
line_dash: Vec::new(),
|
||||
line_dash_offset: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1286,6 +1290,59 @@ impl CanvasState {
|
|||
self.send_canvas_2d_msg(Canvas2dMsg::SetMiterLimit(limit as f32))
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-getlinedash>
|
||||
pub(crate) fn line_dash(&self) -> Vec<f64> {
|
||||
// > return a sequence whose values are the values of
|
||||
// > the object's dash list, in the same order.
|
||||
self.state.borrow().line_dash.clone()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-setlinedash>
|
||||
pub(crate) fn set_line_dash(&self, segments: Vec<f64>) {
|
||||
// > If any value in segments is not finite (e.g. an Infinity or a NaN value),
|
||||
// > or if any value is negative (less than zero), then return (without throwing
|
||||
// > an exception; user agents could show a message on a developer console,
|
||||
// > though, as that would be helpful for debugging).
|
||||
if segments
|
||||
.iter()
|
||||
.any(|segment| !segment.is_finite() || *segment < 0.0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// > If the number of elements in segments is odd, then let segments
|
||||
// > be the concatenation of two copies of segments.
|
||||
let mut line_dash: Vec<_> = segments.clone();
|
||||
if segments.len() & 1 == 1 {
|
||||
line_dash.extend(line_dash.clone());
|
||||
}
|
||||
|
||||
// > Let the object's dash list be segments.
|
||||
self.state.borrow_mut().line_dash = line_dash.clone();
|
||||
self.send_canvas_2d_msg(Canvas2dMsg::SetLineDash(
|
||||
line_dash.into_iter().map(|dash| dash as f32).collect(),
|
||||
))
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
|
||||
pub(crate) fn line_dash_offset(&self) -> f64 {
|
||||
// > On getting, it must return the current value.
|
||||
self.state.borrow().line_dash_offset
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset?
|
||||
pub(crate) fn set_line_dash_offset(&self, offset: f64) {
|
||||
// > On setting, infinite and NaN values must be ignored,
|
||||
// > leaving the value unchanged;
|
||||
if !offset.is_finite() {
|
||||
return;
|
||||
}
|
||||
|
||||
// > other values must change the current value to the new value.
|
||||
self.state.borrow_mut().line_dash_offset = offset;
|
||||
self.send_canvas_2d_msg(Canvas2dMsg::SetLineDashOffset(offset as f32));
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
||||
pub(crate) fn create_image_data(
|
||||
&self,
|
||||
|
|
|
@ -642,6 +642,26 @@ impl CanvasRenderingContext2DMethods<crate::DomTypeHolder> for CanvasRenderingCo
|
|||
self.canvas_state.set_miter_limit(limit)
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-setlinedash>
|
||||
fn SetLineDash(&self, segments: Vec<f64>) {
|
||||
self.canvas_state.set_line_dash(segments);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-getlinedash>
|
||||
fn GetLineDash(&self) -> Vec<f64> {
|
||||
self.canvas_state.line_dash()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
|
||||
fn LineDashOffset(&self) -> f64 {
|
||||
self.canvas_state.line_dash_offset()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
|
||||
fn SetLineDashOffset(&self, offset: f64) {
|
||||
self.canvas_state.set_line_dash_offset(offset);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
|
||||
fn ShadowOffsetX(&self) -> f64 {
|
||||
self.canvas_state.shadow_offset_x()
|
||||
|
|
|
@ -340,6 +340,26 @@ impl OffscreenCanvasRenderingContext2DMethods<crate::DomTypeHolder>
|
|||
self.context.SetMiterLimit(limit)
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-setlinedash>
|
||||
fn SetLineDash(&self, segments: Vec<f64>) {
|
||||
self.context.SetLineDash(segments)
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-getlinedash>
|
||||
fn GetLineDash(&self) -> Vec<f64> {
|
||||
self.context.GetLineDash()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
|
||||
fn LineDashOffset(&self) -> f64 {
|
||||
self.context.LineDashOffset()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
|
||||
fn SetLineDashOffset(&self, offset: f64) {
|
||||
self.context.SetLineDashOffset(offset)
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-createimagedata
|
||||
fn CreateImageData(&self, sw: i32, sh: i32, can_gc: CanGc) -> Fallible<DomRoot<ImageData>> {
|
||||
self.context.CreateImageData(sw, sh, can_gc)
|
||||
|
|
|
@ -430,6 +430,26 @@ impl PaintRenderingContext2DMethods<crate::DomTypeHolder> for PaintRenderingCont
|
|||
self.canvas_state.set_miter_limit(limit)
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-setlinedash>
|
||||
fn SetLineDash(&self, segments: Vec<f64>) {
|
||||
self.canvas_state.set_line_dash(segments);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-getlinedash>
|
||||
fn GetLineDash(&self) -> Vec<f64> {
|
||||
self.canvas_state.line_dash()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
|
||||
fn LineDashOffset(&self) -> f64 {
|
||||
self.canvas_state.line_dash_offset()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-context-2d-linedashoffset>
|
||||
fn SetLineDashOffset(&self, offset: f64) {
|
||||
self.canvas_state.set_line_dash_offset(offset);
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-shadowoffsetx
|
||||
fn ShadowOffsetX(&self) -> f64 {
|
||||
self.canvas_state.shadow_offset_x()
|
||||
|
|
|
@ -191,9 +191,9 @@ interface mixin CanvasPathDrawingStyles {
|
|||
attribute unrestricted double miterLimit; // (default 10)
|
||||
|
||||
// dashed lines
|
||||
//void setLineDash(sequence<unrestricted double> segments); // default empty
|
||||
//sequence<unrestricted double> getLineDash();
|
||||
//attribute unrestricted double lineDashOffset;
|
||||
undefined setLineDash(sequence<unrestricted double> segments); // default empty
|
||||
sequence<unrestricted double> getLineDash();
|
||||
attribute unrestricted double lineDashOffset;
|
||||
};
|
||||
|
||||
interface mixin CanvasTextDrawingStyles {
|
||||
|
|
|
@ -120,6 +120,8 @@ pub enum Canvas2dMsg {
|
|||
SetLineCap(LineCapStyle),
|
||||
SetLineJoin(LineJoinStyle),
|
||||
SetMiterLimit(f32),
|
||||
SetLineDash(Vec<f32>),
|
||||
SetLineDashOffset(f32),
|
||||
SetGlobalAlpha(f32),
|
||||
SetGlobalComposition(CompositionOrBlending),
|
||||
SetTransform(Transform2D<f32>),
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
[setLineDash.html]
|
||||
[Invalid arguments to setLineDash()]
|
||||
expected: FAIL
|
||||
|
||||
[setLineDash]
|
||||
expected: FAIL
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
[2d.reset.render.line.html]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[2d.reset.state.line_dash.html]
|
||||
[check that the line dash is reset]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[2d.reset.state.line_dash_offset.html]
|
||||
[check that the state is reset]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[2d.reset.render.line.html]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[2d.reset.state.line_dash.html]
|
||||
[check that the line dash is reset]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[2d.reset.state.line_dash.worker.html]
|
||||
[check that the line dash is reset]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[2d.reset.state.line_dash_offset.html]
|
||||
[check that the state is reset]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[2d.reset.state.line_dash_offset.worker.html]
|
||||
[check that the state is reset]
|
||||
expected: FAIL
|
|
@ -71,15 +71,6 @@
|
|||
[OffscreenCanvasRenderingContext2D interface: operation strokeText(DOMString, unrestricted double, unrestricted double, optional unrestricted double)]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: operation setLineDash(sequence<unrestricted double>)]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: operation getLineDash()]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: attribute lineDashOffset]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: attribute letterSpacing]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -146,9 +146,6 @@
|
|||
[OffscreenCanvasRenderingContext2D interface: operation commit()]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: operation setLineDash(sequence<unrestricted double>)]
|
||||
expected: FAIL
|
||||
|
||||
[DataTransferItemList interface object name]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4613,15 +4610,6 @@
|
|||
[CanvasRenderingContext2D interface: operation strokeText(DOMString, unrestricted double, unrestricted double, optional unrestricted double)]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: operation setLineDash(sequence<unrestricted double>)]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: operation getLineDash()]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: attribute lineDashOffset]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: attribute letterSpacing]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4691,18 +4679,6 @@
|
|||
[CanvasRenderingContext2D interface: calling strokeText(DOMString, unrestricted double, unrestricted double, optional unrestricted double) 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 "setLineDash(sequence<unrestricted double>)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: calling setLineDash(sequence<unrestricted double>) 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 "getLineDash()" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "lineDashOffset" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[CanvasRenderingContext2D interface: document.createElement("canvas").getContext("2d") must inherit property "letterSpacing" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -4802,15 +4778,6 @@
|
|||
[OffscreenCanvasRenderingContext2D interface: operation strokeText(DOMString, unrestricted double, unrestricted double, optional unrestricted double)]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: operation setLineDash(sequence<unrestricted double>)]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: operation getLineDash()]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: attribute lineDashOffset]
|
||||
expected: FAIL
|
||||
|
||||
[OffscreenCanvasRenderingContext2D interface: attribute letterSpacing]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
[sequence-conversion.html]
|
||||
[An array]
|
||||
expected: FAIL
|
||||
|
||||
[A generator]
|
||||
expected: FAIL
|
||||
|
||||
[An array with an overridden Symbol.iterator]
|
||||
expected: FAIL
|
||||
|
||||
[An array with an overridden Symbol.iterator on the prototype]
|
||||
expected: FAIL
|
||||
|
||||
[An array with an overridden %ArrayIterator%.prototype.next]
|
||||
expected: FAIL
|
||||
|
||||
[A holey array with fallback to an accessor on the prototype]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue