mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
canvas: Respect FillRule (#38294)
We just need to pass user provided FillRule via IPC to canvas paint thread, then pass it all down to backend, which will handle it. Testing: Added WPT tests. --------- Signed-off-by: sagudev <16504129+sagudev@users.noreply.github.com>
This commit is contained in:
parent
4188852963
commit
bc71fb8c0d
22 changed files with 693 additions and 32 deletions
|
@ -3,7 +3,7 @@
|
||||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
use canvas_traits::canvas::{
|
use canvas_traits::canvas::{
|
||||||
CompositionOptions, FillOrStrokeStyle, LineOptions, Path, ShadowOptions,
|
CompositionOptions, FillOrStrokeStyle, FillRule, LineOptions, Path, ShadowOptions,
|
||||||
};
|
};
|
||||||
use compositing_traits::SerializableImageData;
|
use compositing_traits::SerializableImageData;
|
||||||
use euclid::default::{Point2D, Rect, Size2D, Transform2D};
|
use euclid::default::{Point2D, Rect, Size2D, Transform2D};
|
||||||
|
@ -47,6 +47,7 @@ pub(crate) trait GenericDrawTarget {
|
||||||
fn fill(
|
fn fill(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
|
fill_rule: FillRule,
|
||||||
style: FillOrStrokeStyle,
|
style: FillOrStrokeStyle,
|
||||||
composition_options: CompositionOptions,
|
composition_options: CompositionOptions,
|
||||||
transform: Transform2D<f32>,
|
transform: Transform2D<f32>,
|
||||||
|
@ -68,7 +69,7 @@ pub(crate) trait GenericDrawTarget {
|
||||||
);
|
);
|
||||||
fn get_size(&self) -> Size2D<i32>;
|
fn get_size(&self) -> Size2D<i32>;
|
||||||
fn pop_clip(&mut self);
|
fn pop_clip(&mut self);
|
||||||
fn push_clip(&mut self, path: &Path, transform: Transform2D<f32>);
|
fn push_clip(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f32>);
|
||||||
fn push_clip_rect(&mut self, rect: &Rect<i32>);
|
fn push_clip_rect(&mut self, rect: &Rect<i32>);
|
||||||
fn stroke(
|
fn stroke(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
|
@ -567,6 +567,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
||||||
pub(crate) fn fill_path(
|
pub(crate) fn fill_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
|
fill_rule: FillRule,
|
||||||
style: FillOrStrokeStyle,
|
style: FillOrStrokeStyle,
|
||||||
_shadow_options: ShadowOptions,
|
_shadow_options: ShadowOptions,
|
||||||
composition_options: CompositionOptions,
|
composition_options: CompositionOptions,
|
||||||
|
@ -584,7 +585,7 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
||||||
|self_, style| {
|
|self_, style| {
|
||||||
self_
|
self_
|
||||||
.drawtarget
|
.drawtarget
|
||||||
.fill(path, style, composition_options, transform)
|
.fill(path, fill_rule, style, composition_options, transform)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -615,8 +616,13 @@ impl<DrawTarget: GenericDrawTarget> CanvasData<DrawTarget> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn clip_path(&mut self, path: &Path, transform: Transform2D<f32>) {
|
pub(crate) fn clip_path(
|
||||||
self.drawtarget.push_clip(path, transform);
|
&mut self,
|
||||||
|
path: &Path,
|
||||||
|
fill_rule: FillRule,
|
||||||
|
transform: Transform2D<f32>,
|
||||||
|
) {
|
||||||
|
self.drawtarget.push_clip(path, fill_rule, transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://html.spec.whatwg.org/multipage/#reset-the-rendering-context-to-its-default-state>
|
/// <https://html.spec.whatwg.org/multipage/#reset-the-rendering-context-to-its-default-state>
|
||||||
|
|
|
@ -173,9 +173,17 @@ impl CanvasPaintThread {
|
||||||
Canvas2dMsg::ClearRect(ref rect, transform) => {
|
Canvas2dMsg::ClearRect(ref rect, transform) => {
|
||||||
self.canvas(canvas_id).clear_rect(rect, transform)
|
self.canvas(canvas_id).clear_rect(rect, transform)
|
||||||
},
|
},
|
||||||
Canvas2dMsg::FillPath(style, path, shadow_options, composition_options, transform) => {
|
Canvas2dMsg::FillPath(
|
||||||
|
style,
|
||||||
|
path,
|
||||||
|
fill_rule,
|
||||||
|
shadow_options,
|
||||||
|
composition_options,
|
||||||
|
transform,
|
||||||
|
) => {
|
||||||
self.canvas(canvas_id).fill_path(
|
self.canvas(canvas_id).fill_path(
|
||||||
&path,
|
&path,
|
||||||
|
fill_rule,
|
||||||
style,
|
style,
|
||||||
shadow_options,
|
shadow_options,
|
||||||
composition_options,
|
composition_options,
|
||||||
|
@ -199,8 +207,9 @@ impl CanvasPaintThread {
|
||||||
transform,
|
transform,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
Canvas2dMsg::ClipPath(path, transform) => {
|
Canvas2dMsg::ClipPath(path, fill_rule, transform) => {
|
||||||
self.canvas(canvas_id).clip_path(&path, transform);
|
self.canvas(canvas_id)
|
||||||
|
.clip_path(&path, fill_rule, transform);
|
||||||
},
|
},
|
||||||
Canvas2dMsg::DrawImage(
|
Canvas2dMsg::DrawImage(
|
||||||
snapshot,
|
snapshot,
|
||||||
|
@ -412,19 +421,30 @@ impl Canvas {
|
||||||
fn fill_path(
|
fn fill_path(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
|
fill_rule: FillRule,
|
||||||
style: FillOrStrokeStyle,
|
style: FillOrStrokeStyle,
|
||||||
shadow_options: ShadowOptions,
|
shadow_options: ShadowOptions,
|
||||||
composition_options: CompositionOptions,
|
composition_options: CompositionOptions,
|
||||||
transform: Transform2D<f32>,
|
transform: Transform2D<f32>,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
Canvas::Raqote(canvas_data) => {
|
Canvas::Raqote(canvas_data) => canvas_data.fill_path(
|
||||||
canvas_data.fill_path(path, style, shadow_options, composition_options, transform)
|
path,
|
||||||
},
|
fill_rule,
|
||||||
|
style,
|
||||||
|
shadow_options,
|
||||||
|
composition_options,
|
||||||
|
transform,
|
||||||
|
),
|
||||||
#[cfg(feature = "vello")]
|
#[cfg(feature = "vello")]
|
||||||
Canvas::Vello(canvas_data) => {
|
Canvas::Vello(canvas_data) => canvas_data.fill_path(
|
||||||
canvas_data.fill_path(path, style, shadow_options, composition_options, transform)
|
path,
|
||||||
},
|
fill_rule,
|
||||||
|
style,
|
||||||
|
shadow_options,
|
||||||
|
composition_options,
|
||||||
|
transform,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,11 +535,11 @@ impl Canvas {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clip_path(&mut self, path: &Path, transform: Transform2D<f32>) {
|
fn clip_path(&mut self, path: &Path, fill_rule: FillRule, transform: Transform2D<f32>) {
|
||||||
match self {
|
match self {
|
||||||
Canvas::Raqote(canvas_data) => canvas_data.clip_path(path, transform),
|
Canvas::Raqote(canvas_data) => canvas_data.clip_path(path, fill_rule, transform),
|
||||||
#[cfg(feature = "vello")]
|
#[cfg(feature = "vello")]
|
||||||
Canvas::Vello(canvas_data) => canvas_data.clip_path(path, transform),
|
Canvas::Vello(canvas_data) => canvas_data.clip_path(path, fill_rule, transform),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -207,3 +207,12 @@ impl Convert<peniko::ImageQuality> for Filter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Convert<peniko::Fill> for FillRule {
|
||||||
|
fn convert(self) -> peniko::Fill {
|
||||||
|
match self {
|
||||||
|
FillRule::Nonzero => peniko::Fill::NonZero,
|
||||||
|
FillRule::Evenodd => peniko::Fill::EvenOdd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -277,6 +277,7 @@ impl GenericDrawTarget for raqote::DrawTarget {
|
||||||
fn fill(
|
fn fill(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &canvas_traits::canvas::Path,
|
path: &canvas_traits::canvas::Path,
|
||||||
|
fill_rule: FillRule,
|
||||||
style: FillOrStrokeStyle,
|
style: FillOrStrokeStyle,
|
||||||
composition_options: CompositionOptions,
|
composition_options: CompositionOptions,
|
||||||
transform: Transform2D<f32>,
|
transform: Transform2D<f32>,
|
||||||
|
@ -284,7 +285,11 @@ impl GenericDrawTarget for raqote::DrawTarget {
|
||||||
self.set_transform(&transform);
|
self.set_transform(&transform);
|
||||||
let draw_options = draw_options(composition_options);
|
let draw_options = draw_options(composition_options);
|
||||||
let pattern = style.to_raqote_pattern();
|
let pattern = style.to_raqote_pattern();
|
||||||
let path = to_path(path);
|
let mut path = to_path(path);
|
||||||
|
path.winding = match fill_rule {
|
||||||
|
FillRule::Nonzero => raqote::Winding::NonZero,
|
||||||
|
FillRule::Evenodd => raqote::Winding::EvenOdd,
|
||||||
|
};
|
||||||
fill_draw_target(self, draw_options, &source(&pattern), path);
|
fill_draw_target(self, draw_options, &source(&pattern), path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,7 +373,14 @@ impl GenericDrawTarget for raqote::DrawTarget {
|
||||||
rect.size.height,
|
rect.size.height,
|
||||||
);
|
);
|
||||||
|
|
||||||
<Self as GenericDrawTarget>::fill(self, &pb, style, composition_options, transform);
|
<Self as GenericDrawTarget>::fill(
|
||||||
|
self,
|
||||||
|
&pb,
|
||||||
|
FillRule::Nonzero,
|
||||||
|
style,
|
||||||
|
composition_options,
|
||||||
|
transform,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
fn get_size(&self) -> Size2D<i32> {
|
fn get_size(&self) -> Size2D<i32> {
|
||||||
Size2D::new(self.width(), self.height())
|
Size2D::new(self.width(), self.height())
|
||||||
|
@ -376,9 +388,19 @@ impl GenericDrawTarget for raqote::DrawTarget {
|
||||||
fn pop_clip(&mut self) {
|
fn pop_clip(&mut self) {
|
||||||
self.pop_clip();
|
self.pop_clip();
|
||||||
}
|
}
|
||||||
fn push_clip(&mut self, path: &canvas_traits::canvas::Path, transform: Transform2D<f32>) {
|
fn push_clip(
|
||||||
|
&mut self,
|
||||||
|
path: &canvas_traits::canvas::Path,
|
||||||
|
fill_rule: FillRule,
|
||||||
|
transform: Transform2D<f32>,
|
||||||
|
) {
|
||||||
self.set_transform(&transform);
|
self.set_transform(&transform);
|
||||||
self.push_clip(&to_path(path));
|
let mut path = to_path(path);
|
||||||
|
path.winding = match fill_rule {
|
||||||
|
FillRule::Nonzero => raqote::Winding::NonZero,
|
||||||
|
FillRule::Evenodd => raqote::Winding::EvenOdd,
|
||||||
|
};
|
||||||
|
self.push_clip(&path);
|
||||||
}
|
}
|
||||||
fn push_clip_rect(&mut self, rect: &Rect<i32>) {
|
fn push_clip_rect(&mut self, rect: &Rect<i32>) {
|
||||||
self.push_clip_rect(rect.to_box2d());
|
self.push_clip_rect(rect.to_box2d());
|
||||||
|
|
|
@ -17,7 +17,7 @@ use std::num::NonZeroUsize;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
|
||||||
use canvas_traits::canvas::{
|
use canvas_traits::canvas::{
|
||||||
CompositionOptions, FillOrStrokeStyle, LineOptions, Path, ShadowOptions,
|
CompositionOptions, FillOrStrokeStyle, FillRule, LineOptions, Path, ShadowOptions,
|
||||||
};
|
};
|
||||||
use compositing_traits::SerializableImageData;
|
use compositing_traits::SerializableImageData;
|
||||||
use euclid::default::{Point2D, Rect, Size2D, Transform2D};
|
use euclid::default::{Point2D, Rect, Size2D, Transform2D};
|
||||||
|
@ -311,13 +311,14 @@ impl GenericDrawTarget for VelloDrawTarget {
|
||||||
fn fill(
|
fn fill(
|
||||||
&mut self,
|
&mut self,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
|
fill_rule: FillRule,
|
||||||
style: FillOrStrokeStyle,
|
style: FillOrStrokeStyle,
|
||||||
composition_options: CompositionOptions,
|
composition_options: CompositionOptions,
|
||||||
transform: Transform2D<f32>,
|
transform: Transform2D<f32>,
|
||||||
) {
|
) {
|
||||||
self.with_draw_options(&composition_options, |self_| {
|
self.with_draw_options(&composition_options, |self_| {
|
||||||
self_.scene.fill(
|
self_.scene.fill(
|
||||||
peniko::Fill::NonZero,
|
fill_rule.convert(),
|
||||||
transform.cast().into(),
|
transform.cast().into(),
|
||||||
&style
|
&style
|
||||||
.convert()
|
.convert()
|
||||||
|
@ -418,7 +419,7 @@ impl GenericDrawTarget for VelloDrawTarget {
|
||||||
self.scene.pop_layer();
|
self.scene.pop_layer();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn push_clip(&mut self, path: &Path, transform: Transform2D<f32>) {
|
fn push_clip(&mut self, path: &Path, _fill_rule: FillRule, transform: Transform2D<f32>) {
|
||||||
self.scene
|
self.scene
|
||||||
.push_layer(peniko::Mix::Clip, 1.0, transform.cast().into(), &path.0);
|
.push_layer(peniko::Mix::Clip, 1.0, transform.cast().into(), &path.0);
|
||||||
}
|
}
|
||||||
|
@ -432,7 +433,7 @@ impl GenericDrawTarget for VelloDrawTarget {
|
||||||
rect.size.width,
|
rect.size.width,
|
||||||
rect.size.height,
|
rect.size.height,
|
||||||
);
|
);
|
||||||
self.push_clip(&path, Transform2D::identity());
|
self.push_clip(&path, FillRule::Nonzero, Transform2D::identity());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn stroke(
|
fn stroke(
|
||||||
|
|
|
@ -38,6 +38,7 @@ use url::Url;
|
||||||
use webrender_api::ImageKey;
|
use webrender_api::ImageKey;
|
||||||
|
|
||||||
use crate::canvas_context::{CanvasContext, OffscreenRenderingContext, RenderingContext};
|
use crate::canvas_context::{CanvasContext, OffscreenRenderingContext, RenderingContext};
|
||||||
|
use crate::conversions::Convert;
|
||||||
use crate::dom::bindings::cell::DomRefCell;
|
use crate::dom::bindings::cell::DomRefCell;
|
||||||
use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{
|
use crate::dom::bindings::codegen::Bindings::CanvasRenderingContext2DBinding::{
|
||||||
CanvasDirection, CanvasFillRule, CanvasImageSource, CanvasLineCap, CanvasLineJoin,
|
CanvasDirection, CanvasFillRule, CanvasImageSource, CanvasLineCap, CanvasLineJoin,
|
||||||
|
@ -1927,12 +1928,12 @@ impl CanvasState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fill
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-fill
|
||||||
pub(crate) fn fill_(&self, path: Path, _fill_rule: CanvasFillRule) {
|
pub(crate) fn fill_(&self, path: Path, fill_rule: CanvasFillRule) {
|
||||||
// TODO: Process fill rule
|
|
||||||
let style = self.state.borrow().fill_style.to_fill_or_stroke_style();
|
let style = self.state.borrow().fill_style.to_fill_or_stroke_style();
|
||||||
self.send_canvas_2d_msg(Canvas2dMsg::FillPath(
|
self.send_canvas_2d_msg(Canvas2dMsg::FillPath(
|
||||||
style,
|
style,
|
||||||
path,
|
path,
|
||||||
|
fill_rule.convert(),
|
||||||
self.state.borrow().shadow_options(),
|
self.state.borrow().shadow_options(),
|
||||||
self.state.borrow().composition_options(),
|
self.state.borrow().composition_options(),
|
||||||
self.state.borrow().transform,
|
self.state.borrow().transform,
|
||||||
|
@ -1964,9 +1965,12 @@ impl CanvasState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clip
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-clip
|
||||||
pub(crate) fn clip_(&self, path: Path, _fill_rule: CanvasFillRule) {
|
pub(crate) fn clip_(&self, path: Path, fill_rule: CanvasFillRule) {
|
||||||
// TODO: Process fill rule
|
self.send_canvas_2d_msg(Canvas2dMsg::ClipPath(
|
||||||
self.send_canvas_2d_msg(Canvas2dMsg::ClipPath(path, self.state.borrow().transform));
|
path,
|
||||||
|
fill_rule.convert(),
|
||||||
|
self.state.borrow().transform,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/#dom-context-2d-ispointinpath
|
// https://html.spec.whatwg.org/multipage/#dom-context-2d-ispointinpath
|
||||||
|
@ -2332,3 +2336,12 @@ fn adjust_canvas_size(size: Size2D<u64>) -> Size2D<u64> {
|
||||||
Size2D::zero()
|
Size2D::zero()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Convert<FillRule> for CanvasFillRule {
|
||||||
|
fn convert(self) -> FillRule {
|
||||||
|
match self {
|
||||||
|
CanvasFillRule::Nonzero => FillRule::Nonzero,
|
||||||
|
CanvasFillRule::Evenodd => FillRule::Evenodd,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -482,11 +482,12 @@ pub enum Canvas2dMsg {
|
||||||
Transform2D<f32>,
|
Transform2D<f32>,
|
||||||
),
|
),
|
||||||
ClearRect(Rect<f32>, Transform2D<f32>),
|
ClearRect(Rect<f32>, Transform2D<f32>),
|
||||||
ClipPath(Path, Transform2D<f32>),
|
ClipPath(Path, FillRule, Transform2D<f32>),
|
||||||
PopClip,
|
PopClip,
|
||||||
FillPath(
|
FillPath(
|
||||||
FillOrStrokeStyle,
|
FillOrStrokeStyle,
|
||||||
Path,
|
Path,
|
||||||
|
FillRule,
|
||||||
ShadowOptions,
|
ShadowOptions,
|
||||||
CompositionOptions,
|
CompositionOptions,
|
||||||
Transform2D<f32>,
|
Transform2D<f32>,
|
||||||
|
|
86
tests/wpt/meta/MANIFEST.json
vendored
86
tests/wpt/meta/MANIFEST.json
vendored
|
@ -479233,7 +479233,7 @@
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
"path-objects.yaml": [
|
"path-objects.yaml": [
|
||||||
"cf218829598c1ee4275ceefd025974590fbe1cd8",
|
"ccb3d79b93a44d36fec6abebc9a95621c2913b6c",
|
||||||
[]
|
[]
|
||||||
],
|
],
|
||||||
"pixel-manipulation.yaml": [
|
"pixel-manipulation.yaml": [
|
||||||
|
@ -706232,6 +706232,20 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"2d.path.clip.winding.evenodd.1.html": [
|
||||||
|
"a1922011e4ac937605a42e0b14a0de63b05ded73",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.clip.winding.evenodd.2.html": [
|
||||||
|
"e5aeba44b008e76000af1db74a756becf27ecadc",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"2d.path.closePath.empty.html": [
|
"2d.path.closePath.empty.html": [
|
||||||
"837f5a76dc9701748f4d485c102cc93f6d410ce9",
|
"837f5a76dc9701748f4d485c102cc93f6d410ce9",
|
||||||
[
|
[
|
||||||
|
@ -706295,6 +706309,20 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"2d.path.fill.winding.evenodd.1.html": [
|
||||||
|
"d030b93239c310a76a1423fe13c1adcf9fe399ce",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.fill.winding.evenodd.2.html": [
|
||||||
|
"4553f29d1e4b245fe231eeeb75973b5eba69c15d",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"2d.path.fill.winding.subtract.1.html": [
|
"2d.path.fill.winding.subtract.1.html": [
|
||||||
"fa1232e8d0ff59c5d283dc01641b1075372f0a77",
|
"fa1232e8d0ff59c5d283dc01641b1075372f0a77",
|
||||||
[
|
[
|
||||||
|
@ -717826,6 +717854,34 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"2d.path.clip.winding.evenodd.1.html": [
|
||||||
|
"4cf680f62f2b6328d838929f64ebe50729b5b270",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.clip.winding.evenodd.1.worker.js": [
|
||||||
|
"da772ea73d00beb9ae3332e4bf9d19fda68fdd70",
|
||||||
|
[
|
||||||
|
"html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.1.worker.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.clip.winding.evenodd.2.html": [
|
||||||
|
"6d47707e5ec00a8a9302c3a2caea1e9e8f25350b",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.clip.winding.evenodd.2.worker.js": [
|
||||||
|
"23f626e7d7293c7559baa66793264685876e7c0d",
|
||||||
|
[
|
||||||
|
"html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.2.worker.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"2d.path.closePath.empty.html": [
|
"2d.path.closePath.empty.html": [
|
||||||
"a14a036b253d90462d5f4d1881a0d947b869c5dd",
|
"a14a036b253d90462d5f4d1881a0d947b869c5dd",
|
||||||
[
|
[
|
||||||
|
@ -717952,6 +718008,34 @@
|
||||||
{}
|
{}
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
|
"2d.path.fill.winding.evenodd.1.html": [
|
||||||
|
"fc839c9f58b19a4be7a0e43fe661799902ee257e",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.fill.winding.evenodd.1.worker.js": [
|
||||||
|
"64e1aa1099370dc955bf79e0f05642a53609b2c9",
|
||||||
|
[
|
||||||
|
"html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.1.worker.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.fill.winding.evenodd.2.html": [
|
||||||
|
"acb70538fd946bd7a6bbb561eae0e93724161b8b",
|
||||||
|
[
|
||||||
|
null,
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
|
"2d.path.fill.winding.evenodd.2.worker.js": [
|
||||||
|
"1a69f4639d0c8b9a67d3e6b16fd764ea7e5f6683",
|
||||||
|
[
|
||||||
|
"html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.2.worker.html",
|
||||||
|
{}
|
||||||
|
]
|
||||||
|
],
|
||||||
"2d.path.fill.winding.subtract.1.html": [
|
"2d.path.fill.winding.subtract.1.html": [
|
||||||
"814f3c3a9e76b711e1fc2f3dac373afc0ab07f0a",
|
"814f3c3a9e76b711e1fc2f3dac373afc0ab07f0a",
|
||||||
[
|
[
|
||||||
|
|
38
tests/wpt/tests/html/canvas/element/path-objects/2d.path.clip.winding.evenodd.1.html
vendored
Normal file
38
tests/wpt/tests/html/canvas/element/path-objects/2d.path.clip.winding.evenodd.1.html
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Canvas test: 2d.path.clip.winding.evenodd.1</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
|
||||||
|
<body class="show_output">
|
||||||
|
|
||||||
|
<h1>2d.path.clip.winding.evenodd.1</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in clip</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="output">Actual output:</p>
|
||||||
|
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
|
||||||
|
<ul id="d"></ul>
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in clip");
|
||||||
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip("evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
39
tests/wpt/tests/html/canvas/element/path-objects/2d.path.clip.winding.evenodd.2.html
vendored
Normal file
39
tests/wpt/tests/html/canvas/element/path-objects/2d.path.clip.winding.evenodd.2.html
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Canvas test: 2d.path.clip.winding.evenodd.2</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
|
||||||
|
<body class="show_output">
|
||||||
|
|
||||||
|
<h1>2d.path.clip.winding.evenodd.2</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in clip</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="output">Actual output:</p>
|
||||||
|
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
|
||||||
|
<ul id="d"></ul>
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in clip");
|
||||||
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip(path, "evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
37
tests/wpt/tests/html/canvas/element/path-objects/2d.path.fill.winding.evenodd.1.html
vendored
Normal file
37
tests/wpt/tests/html/canvas/element/path-objects/2d.path.fill.winding.evenodd.1.html
vendored
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Canvas test: 2d.path.fill.winding.evenodd.1</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
|
||||||
|
<body class="show_output">
|
||||||
|
|
||||||
|
<h1>2d.path.fill.winding.evenodd.1</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in fill</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="output">Actual output:</p>
|
||||||
|
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
|
||||||
|
<ul id="d"></ul>
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in fill");
|
||||||
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill("evenodd");
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
38
tests/wpt/tests/html/canvas/element/path-objects/2d.path.fill.winding.evenodd.2.html
vendored
Normal file
38
tests/wpt/tests/html/canvas/element/path-objects/2d.path.fill.winding.evenodd.2.html
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Canvas test: 2d.path.fill.winding.evenodd.2</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
<link rel="stylesheet" href="/html/canvas/resources/canvas-tests.css">
|
||||||
|
<body class="show_output">
|
||||||
|
|
||||||
|
<h1>2d.path.fill.winding.evenodd.2</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in fill</p>
|
||||||
|
|
||||||
|
|
||||||
|
<p class="output">Actual output:</p>
|
||||||
|
<canvas id="c" class="output" width="100" height="50"><p class="fallback">FAIL (fallback content)</p></canvas>
|
||||||
|
|
||||||
|
<ul id="d"></ul>
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in fill");
|
||||||
|
_addTest(function(canvas, ctx) {
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill(path, "evenodd");
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
39
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.1.html
vendored
Normal file
39
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.1.html
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>OffscreenCanvas test: 2d.path.clip.winding.evenodd.1</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
|
||||||
|
<h1>2d.path.clip.winding.evenodd.1</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in clip</p>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in clip");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip("evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
33
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.1.worker.js
vendored
Normal file
33
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.1.worker.js
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
|
||||||
|
// OffscreenCanvas test in a worker:2d.path.clip.winding.evenodd.1
|
||||||
|
// Description:evenodd winding number rule works in clip
|
||||||
|
// Note:
|
||||||
|
|
||||||
|
importScripts("/resources/testharness.js");
|
||||||
|
importScripts("/html/canvas/resources/canvas-tests.js");
|
||||||
|
|
||||||
|
var t = async_test("evenodd winding number rule works in clip");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip("evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
done();
|
40
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.2.html
vendored
Normal file
40
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.2.html
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>OffscreenCanvas test: 2d.path.clip.winding.evenodd.2</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
|
||||||
|
<h1>2d.path.clip.winding.evenodd.2</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in clip</p>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in clip");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip(path, "evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
34
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.2.worker.js
vendored
Normal file
34
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.clip.winding.evenodd.2.worker.js
vendored
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
|
||||||
|
// OffscreenCanvas test in a worker:2d.path.clip.winding.evenodd.2
|
||||||
|
// Description:evenodd winding number rule works in clip
|
||||||
|
// Note:
|
||||||
|
|
||||||
|
importScripts("/resources/testharness.js");
|
||||||
|
importScripts("/html/canvas/resources/canvas-tests.js");
|
||||||
|
|
||||||
|
var t = async_test("evenodd winding number rule works in clip");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip(path, "evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
done();
|
38
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.1.html
vendored
Normal file
38
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.1.html
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>OffscreenCanvas test: 2d.path.fill.winding.evenodd.1</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
|
||||||
|
<h1>2d.path.fill.winding.evenodd.1</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in fill</p>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in fill");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill("evenodd");
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
32
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.1.worker.js
vendored
Normal file
32
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.1.worker.js
vendored
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
|
||||||
|
// OffscreenCanvas test in a worker:2d.path.fill.winding.evenodd.1
|
||||||
|
// Description:evenodd winding number rule works in fill
|
||||||
|
// Note:
|
||||||
|
|
||||||
|
importScripts("/resources/testharness.js");
|
||||||
|
importScripts("/html/canvas/resources/canvas-tests.js");
|
||||||
|
|
||||||
|
var t = async_test("evenodd winding number rule works in fill");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill("evenodd");
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
done();
|
39
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.2.html
vendored
Normal file
39
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.2.html
vendored
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py. -->
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>OffscreenCanvas test: 2d.path.fill.winding.evenodd.2</title>
|
||||||
|
<script src="/resources/testharness.js"></script>
|
||||||
|
<script src="/resources/testharnessreport.js"></script>
|
||||||
|
<script src="/html/canvas/resources/canvas-tests.js"></script>
|
||||||
|
|
||||||
|
<h1>2d.path.fill.winding.evenodd.2</h1>
|
||||||
|
<p class="desc">evenodd winding number rule works in fill</p>
|
||||||
|
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var t = async_test("evenodd winding number rule works in fill");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill(path, "evenodd");
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
33
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.2.worker.js
vendored
Normal file
33
tests/wpt/tests/html/canvas/offscreen/path-objects/2d.path.fill.winding.evenodd.2.worker.js
vendored
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
// DO NOT EDIT! This test has been generated by /html/canvas/tools/gentest.py.
|
||||||
|
// OffscreenCanvas test in a worker:2d.path.fill.winding.evenodd.2
|
||||||
|
// Description:evenodd winding number rule works in fill
|
||||||
|
// Note:
|
||||||
|
|
||||||
|
importScripts("/resources/testharness.js");
|
||||||
|
importScripts("/html/canvas/resources/canvas-tests.js");
|
||||||
|
|
||||||
|
var t = async_test("evenodd winding number rule works in fill");
|
||||||
|
var t_pass = t.done.bind(t);
|
||||||
|
var t_fail = t.step_func(function(reason) {
|
||||||
|
throw reason;
|
||||||
|
});
|
||||||
|
t.step(function() {
|
||||||
|
|
||||||
|
var canvas = new OffscreenCanvas(100, 50);
|
||||||
|
var ctx = canvas.getContext('2d');
|
||||||
|
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill(path, "evenodd");
|
||||||
|
|
||||||
|
_assertPixel(canvas, 50,25, 0,255,0,255);
|
||||||
|
t.done();
|
||||||
|
});
|
||||||
|
done();
|
|
@ -2479,6 +2479,37 @@
|
||||||
cr.rectangle(0, 0, 100, 50)
|
cr.rectangle(0, 0, 100, 50)
|
||||||
cr.fill()
|
cr.fill()
|
||||||
|
|
||||||
|
- name: 2d.path.fill.winding.evenodd.1
|
||||||
|
desc: evenodd winding number rule works in fill
|
||||||
|
code: |
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill("evenodd");
|
||||||
|
|
||||||
|
@assert pixel 50,25 == 0,255,0,255;
|
||||||
|
|
||||||
|
- name: 2d.path.fill.winding.evenodd.2
|
||||||
|
desc: evenodd winding number rule works in fill
|
||||||
|
code: |
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.fill(path, "evenodd");
|
||||||
|
|
||||||
|
@assert pixel 50,25 == 0,255,0,255;
|
||||||
|
|
||||||
- name: 2d.path.fill.winding.add
|
- name: 2d.path.fill.winding.add
|
||||||
code: |
|
code: |
|
||||||
ctx.fillStyle = '#f00';
|
ctx.fillStyle = '#f00';
|
||||||
|
@ -3046,6 +3077,39 @@
|
||||||
@assert pixel 50,25 == 0,255,0,255;
|
@assert pixel 50,25 == 0,255,0,255;
|
||||||
expected: green
|
expected: green
|
||||||
|
|
||||||
|
- name: 2d.path.clip.winding.evenodd.1
|
||||||
|
desc: evenodd winding number rule works in clip
|
||||||
|
code: |
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
ctx.rect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip("evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
@assert pixel 50,25 == 0,255,0,255;
|
||||||
|
|
||||||
|
- name: 2d.path.clip.winding.evenodd.2
|
||||||
|
desc: evenodd winding number rule works in clip
|
||||||
|
code: |
|
||||||
|
ctx.fillStyle = '#0f0';
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
let path = new Path2D();
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.rect(0, 0, 100, 50);
|
||||||
|
path.closePath();
|
||||||
|
|
||||||
|
ctx.fillStyle = "#f00";
|
||||||
|
ctx.clip(path, "evenodd");
|
||||||
|
ctx.fillRect(0, 0, 100, 50);
|
||||||
|
|
||||||
|
@assert pixel 50,25 == 0,255,0,255;
|
||||||
|
|
||||||
- name: 2d.path.clip.winding.1
|
- name: 2d.path.clip.winding.1
|
||||||
code: |
|
code: |
|
||||||
ctx.fillStyle = '#0f0';
|
ctx.fillStyle = '#0f0';
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue