@@ -54,7 +54,13 @@ impl PathBuilder {
self.current = point;
}
- pub fn build(self, color: ColorU) -> Path {
+ pub fn build(mut self, color: ColorU, clip_bounds: Option<RectF>) -> Path {
+ if let Some(clip_bounds) = clip_bounds {
+ self.bounds = self
+ .bounds
+ .intersection(clip_bounds)
+ .unwrap_or(RectF::default());
+ }
Path {
bounds: self.bounds,
color,
@@ -181,6 +181,8 @@ impl Renderer {
vertices.push(shaders::GPUIPathVertex {
xy_position: (atlas_origin + xy_position).to_float2(),
st_position: vertex.st_position.to_float2(),
+ clip_rect_origin: atlas_origin.to_float2(),
+ clip_rect_size: size.to_float2(),
});
}
}
@@ -218,21 +218,33 @@ fragment float4 sprite_fragment(
return color;
}
+struct PathAtlasVertexOutput {
+ float4 position [[position]];
+ float2 st_position;
+ float clip_rect_distance [[clip_distance]] [4];
+};
+
struct PathAtlasFragmentInput {
float4 position [[position]];
float2 st_position;
};
-vertex PathAtlasFragmentInput path_atlas_vertex(
+vertex PathAtlasVertexOutput path_atlas_vertex(
uint vertex_id [[vertex_id]],
constant GPUIPathVertex *vertices [[buffer(GPUIPathAtlasVertexInputIndexVertices)]],
constant float2 *atlas_size [[buffer(GPUIPathAtlasVertexInputIndexAtlasSize)]]
) {
GPUIPathVertex v = vertices[vertex_id];
float4 device_position = to_device_position(v.xy_position, *atlas_size);
- return PathAtlasFragmentInput {
+ return PathAtlasVertexOutput {
device_position,
v.st_position,
+ {
+ v.xy_position.x - v.clip_rect_origin.x,
+ v.clip_rect_origin.x + v.clip_rect_size.x - v.xy_position.x,
+ v.xy_position.y - v.clip_rect_origin.y,
+ v.clip_rect_origin.y + v.clip_rect_size.y - v.xy_position.y
+ }
};
}
@@ -156,7 +156,9 @@ impl Layer {
}
fn push_path(&mut self, path: Path) {
- self.paths.push(path);
+ if !path.bounds.is_empty() {
+ self.paths.push(path);
+ }
}
pub fn paths(&self) -> &[Path] {
@@ -259,7 +259,7 @@ impl BufferElement {
.collect(),
};
- selection.paint(ctx.scene);
+ selection.paint(bounds, ctx.scene);
}
if view.cursors_visible() {
@@ -586,16 +586,21 @@ struct SelectionLine {
}
impl Selection {
- fn paint(&self, scene: &mut Scene) {
+ fn paint(&self, bounds: RectF, scene: &mut Scene) {
if self.lines.len() >= 2 && self.lines[0].start_x > self.lines[1].end_x {
- self.paint_lines(self.start_y, &self.lines[0..1], scene);
- self.paint_lines(self.start_y + self.line_height, &self.lines[1..], scene);
+ self.paint_lines(self.start_y, &self.lines[0..1], bounds, scene);
+ self.paint_lines(
+ self.start_y + self.line_height,
+ &self.lines[1..],
+ bounds,
+ scene,
+ );
} else {
- self.paint_lines(self.start_y, &self.lines, scene);
+ self.paint_lines(self.start_y, &self.lines, bounds, scene);
}
}
- fn paint_lines(&self, start_y: f32, lines: &[SelectionLine], scene: &mut Scene) {
+ fn paint_lines(&self, start_y: f32, lines: &[SelectionLine], bounds: RectF, scene: &mut Scene) {
if lines.is_empty() {
return;
}
@@ -675,7 +680,7 @@ impl Selection {
path.curve_to(first_top_left + top_curve_width, first_top_left);
path.line_to(first_top_right - top_curve_width);
- scene.push_path(path.build(ColorF::new(0.639, 0.839, 1.0, 1.0).to_u8()));
+ scene.push_path(path.build(ColorF::new(0.639, 0.839, 1.0, 1.0).to_u8(), Some(bounds)));
}
}