mirror of
https://github.com/italicsjenga/vello.git
synced 2025-01-08 20:01:30 +11:00
Merge pull request #335 from armansito/fix-clip-bug
Correctly handle disjoint bounding-box intersections in binning
This commit is contained in:
commit
443539891c
|
@ -51,6 +51,7 @@ pub fn test_scenes() -> SceneSet {
|
||||||
scene!(conflation_artifacts),
|
scene!(conflation_artifacts),
|
||||||
scene!(labyrinth),
|
scene!(labyrinth),
|
||||||
scene!(base_color_test: animated),
|
scene!(base_color_test: animated),
|
||||||
|
scene!(clip_test: animated),
|
||||||
];
|
];
|
||||||
|
|
||||||
SceneSet { scenes }
|
SceneSet { scenes }
|
||||||
|
@ -824,6 +825,96 @@ fn base_color_test(sb: &mut SceneBuilder, params: &mut SceneParams) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn clip_test(sb: &mut SceneBuilder, params: &mut SceneParams) {
|
||||||
|
let clip = {
|
||||||
|
const X0: f64 = 50.0;
|
||||||
|
const Y0: f64 = 0.0;
|
||||||
|
const X1: f64 = 200.0;
|
||||||
|
const Y1: f64 = 500.0;
|
||||||
|
[
|
||||||
|
PathEl::MoveTo((X0, Y0).into()),
|
||||||
|
PathEl::LineTo((X1, Y0).into()),
|
||||||
|
PathEl::LineTo((X1, Y0 + (Y1 - Y0)).into()),
|
||||||
|
PathEl::LineTo((X1 + (X0 - X1), Y1).into()),
|
||||||
|
PathEl::LineTo((X0, Y1).into()),
|
||||||
|
PathEl::ClosePath,
|
||||||
|
]
|
||||||
|
};
|
||||||
|
sb.push_layer(Mix::Clip, 1.0, Affine::IDENTITY, &clip);
|
||||||
|
{
|
||||||
|
let text_size = 60.0 + 40.0 * (params.time as f32).sin();
|
||||||
|
let s = "Some clipped text!";
|
||||||
|
params.text.add(
|
||||||
|
sb,
|
||||||
|
None,
|
||||||
|
text_size,
|
||||||
|
None,
|
||||||
|
Affine::translate((110.0, 100.0)),
|
||||||
|
s,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
sb.pop_layer();
|
||||||
|
|
||||||
|
let large_background_rect = kurbo::Rect::new(-1000.0, -1000.0, 2000.0, 2000.0);
|
||||||
|
let inside_clip_rect = kurbo::Rect::new(11.0, 13.399999999999999, 59.0, 56.6);
|
||||||
|
let outside_clip_rect = kurbo::Rect::new(
|
||||||
|
12.599999999999998,
|
||||||
|
12.599999999999998,
|
||||||
|
57.400000000000006,
|
||||||
|
57.400000000000006,
|
||||||
|
);
|
||||||
|
let clip_rect = kurbo::Rect::new(0.0, 0.0, 74.4, 339.20000000000005);
|
||||||
|
let scale = 2.0;
|
||||||
|
|
||||||
|
sb.push_layer(
|
||||||
|
BlendMode {
|
||||||
|
mix: peniko::Mix::Normal,
|
||||||
|
compose: peniko::Compose::SrcOver,
|
||||||
|
},
|
||||||
|
1.0,
|
||||||
|
Affine::new([scale, 0.0, 0.0, scale, 27.07470703125, 176.40660533027858]),
|
||||||
|
&clip_rect,
|
||||||
|
);
|
||||||
|
|
||||||
|
sb.fill(
|
||||||
|
peniko::Fill::NonZero,
|
||||||
|
kurbo::Affine::new([scale, 0.0, 0.0, scale, 27.07470703125, 176.40660533027858]),
|
||||||
|
peniko::Color::rgb8(0, 0, 255),
|
||||||
|
None,
|
||||||
|
&large_background_rect,
|
||||||
|
);
|
||||||
|
sb.fill(
|
||||||
|
peniko::Fill::NonZero,
|
||||||
|
kurbo::Affine::new([
|
||||||
|
scale,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
scale,
|
||||||
|
29.027636718750003,
|
||||||
|
182.9755506427786,
|
||||||
|
]),
|
||||||
|
peniko::Color::rgb8(0, 255, 0),
|
||||||
|
None,
|
||||||
|
&inside_clip_rect,
|
||||||
|
);
|
||||||
|
sb.fill(
|
||||||
|
peniko::Fill::NonZero,
|
||||||
|
kurbo::Affine::new([
|
||||||
|
scale,
|
||||||
|
0.0,
|
||||||
|
0.0,
|
||||||
|
scale,
|
||||||
|
29.027636718750003,
|
||||||
|
scale * 559.3583631427786,
|
||||||
|
]),
|
||||||
|
peniko::Color::rgb8(255, 0, 0),
|
||||||
|
None,
|
||||||
|
&outside_clip_rect,
|
||||||
|
);
|
||||||
|
|
||||||
|
sb.pop_layer();
|
||||||
|
}
|
||||||
|
|
||||||
fn around_center(xform: Affine, center: Point) -> Affine {
|
fn around_center(xform: Affine, center: Point) -> Affine {
|
||||||
Affine::translate(center.to_vec2()) * xform * Affine::translate(-center.to_vec2())
|
Affine::translate(center.to_vec2()) * xform * Affine::translate(-center.to_vec2())
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,15 +86,20 @@ fn main(
|
||||||
|
|
||||||
let path_bbox = path_bbox_buf[draw_monoid.path_ix];
|
let path_bbox = path_bbox_buf[draw_monoid.path_ix];
|
||||||
let pb = vec4<f32>(vec4(path_bbox.x0, path_bbox.y0, path_bbox.x1, path_bbox.y1));
|
let pb = vec4<f32>(vec4(path_bbox.x0, path_bbox.y0, path_bbox.x1, path_bbox.y1));
|
||||||
let bbox_raw = bbox_intersect(clip_bbox, pb);
|
let bbox = bbox_intersect(clip_bbox, pb);
|
||||||
// TODO(naga): clunky expression a workaround for broken lhs swizzle
|
|
||||||
let bbox = vec4(bbox_raw.xy, max(bbox_raw.xy, bbox_raw.zw));
|
|
||||||
|
|
||||||
intersected_bbox[element_ix] = bbox;
|
intersected_bbox[element_ix] = bbox;
|
||||||
x0 = i32(floor(bbox.x * SX));
|
|
||||||
y0 = i32(floor(bbox.y * SY));
|
// `bbox_intersect` can result in a zero or negative area intersection if the path bbox lies
|
||||||
x1 = i32(ceil(bbox.z * SX));
|
// outside the clip bbox. If that is the case, Don't round up the bottom-right corner of the
|
||||||
y1 = i32(ceil(bbox.w * SY));
|
// and leave the coordinates at 0. This way the path will get clipped out and won't get
|
||||||
|
// assigned to a bin.
|
||||||
|
if bbox.x < bbox.z && bbox.y < bbox.w {
|
||||||
|
x0 = i32(floor(bbox.x * SX));
|
||||||
|
y0 = i32(floor(bbox.y * SY));
|
||||||
|
x1 = i32(ceil(bbox.z * SX));
|
||||||
|
y1 = i32(ceil(bbox.w * SY));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let width_in_bins = i32((config.width_in_tiles + N_TILE_X - 1u) / N_TILE_X);
|
let width_in_bins = i32((config.width_in_tiles + N_TILE_X - 1u) / N_TILE_X);
|
||||||
let height_in_bins = i32((config.height_in_tiles + N_TILE_Y - 1u) / N_TILE_Y);
|
let height_in_bins = i32((config.height_in_tiles + N_TILE_Y - 1u) / N_TILE_Y);
|
||||||
|
|
|
@ -68,10 +68,15 @@ fn main(
|
||||||
var y1 = 0;
|
var y1 = 0;
|
||||||
if drawtag != DRAWTAG_NOP && drawtag != DRAWTAG_END_CLIP {
|
if drawtag != DRAWTAG_NOP && drawtag != DRAWTAG_END_CLIP {
|
||||||
let bbox = draw_bboxes[drawobj_ix];
|
let bbox = draw_bboxes[drawobj_ix];
|
||||||
x0 = i32(floor(bbox.x * SX));
|
|
||||||
y0 = i32(floor(bbox.y * SY));
|
// Don't round up the bottom-right corner of the bbox if the area is zero and leave the
|
||||||
x1 = i32(ceil(bbox.z * SX));
|
// coordinates at 0. This will make `tile_count` zero as the shape is clipped out.
|
||||||
y1 = i32(ceil(bbox.w * SY));
|
if bbox.x < bbox.z && bbox.y < bbox.w {
|
||||||
|
x0 = i32(floor(bbox.x * SX));
|
||||||
|
y0 = i32(floor(bbox.y * SY));
|
||||||
|
x1 = i32(ceil(bbox.z * SX));
|
||||||
|
y1 = i32(ceil(bbox.w * SY));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let ux0 = u32(clamp(x0, 0, i32(config.width_in_tiles)));
|
let ux0 = u32(clamp(x0, 0, i32(config.width_in_tiles)));
|
||||||
let uy0 = u32(clamp(y0, 0, i32(config.height_in_tiles)));
|
let uy0 = u32(clamp(y0, 0, i32(config.height_in_tiles)));
|
||||||
|
|
Loading…
Reference in a new issue