gpui: Add PathBuilder
based on lyon to build Path
(#22808)
Release Notes: - N/A --- Continue https://github.com/zed-industries/zed/pull/20499 We to draw more complex Path. Before this change, we only have `line_to`, but it is not enough. Add a new `PathBuilder` to use [lyon](https://github.com/nical/lyon) to build more complex path. And then with PR #22812 to enable anti-aliasing, all thing will be perfect. ## Show case ```bash cargo run -p gpui --example painting ``` Before: <img width="1136" alt="image" src="https://github.com/user-attachments/assets/0c15833a-ec95-404c-a469-24cf172cfd86" /> After: <img width="1136" alt="image" src="https://github.com/user-attachments/assets/42cfa35e-7e8f-4ef3-bb2d-b98defc62ad6" />
This commit is contained in:
parent
706f7be5e7
commit
31fa414422
8 changed files with 449 additions and 79 deletions
|
@ -7837,8 +7837,8 @@ impl HighlightedRange {
|
|||
};
|
||||
|
||||
let top_curve_width = curve_width(first_line.start_x, first_line.end_x);
|
||||
let mut path = gpui::Path::new(first_top_right - top_curve_width);
|
||||
path.curve_to(first_top_right + curve_height, first_top_right);
|
||||
let mut builder = gpui::PathBuilder::fill();
|
||||
builder.curve_to(first_top_right + curve_height, first_top_right);
|
||||
|
||||
let mut iter = lines.iter().enumerate().peekable();
|
||||
while let Some((ix, line)) = iter.next() {
|
||||
|
@ -7849,42 +7849,42 @@ impl HighlightedRange {
|
|||
|
||||
match next_top_right.x.partial_cmp(&bottom_right.x).unwrap() {
|
||||
Ordering::Equal => {
|
||||
path.line_to(bottom_right);
|
||||
builder.line_to(bottom_right);
|
||||
}
|
||||
Ordering::Less => {
|
||||
let curve_width = curve_width(next_top_right.x, bottom_right.x);
|
||||
path.line_to(bottom_right - curve_height);
|
||||
builder.line_to(bottom_right - curve_height);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(bottom_right - curve_width, bottom_right);
|
||||
builder.curve_to(bottom_right - curve_width, bottom_right);
|
||||
}
|
||||
path.line_to(next_top_right + curve_width);
|
||||
builder.line_to(next_top_right + curve_width);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(next_top_right + curve_height, next_top_right);
|
||||
builder.curve_to(next_top_right + curve_height, next_top_right);
|
||||
}
|
||||
}
|
||||
Ordering::Greater => {
|
||||
let curve_width = curve_width(bottom_right.x, next_top_right.x);
|
||||
path.line_to(bottom_right - curve_height);
|
||||
builder.line_to(bottom_right - curve_height);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(bottom_right + curve_width, bottom_right);
|
||||
builder.curve_to(bottom_right + curve_width, bottom_right);
|
||||
}
|
||||
path.line_to(next_top_right - curve_width);
|
||||
builder.line_to(next_top_right - curve_width);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(next_top_right + curve_height, next_top_right);
|
||||
builder.curve_to(next_top_right + curve_height, next_top_right);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let curve_width = curve_width(line.start_x, line.end_x);
|
||||
path.line_to(bottom_right - curve_height);
|
||||
builder.line_to(bottom_right - curve_height);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(bottom_right - curve_width, bottom_right);
|
||||
builder.curve_to(bottom_right - curve_width, bottom_right);
|
||||
}
|
||||
|
||||
let bottom_left = point(line.start_x, bottom_right.y);
|
||||
path.line_to(bottom_left + curve_width);
|
||||
builder.line_to(bottom_left + curve_width);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(bottom_left - curve_height, bottom_left);
|
||||
builder.curve_to(bottom_left - curve_height, bottom_left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7892,24 +7892,26 @@ impl HighlightedRange {
|
|||
if first_line.start_x > last_line.start_x {
|
||||
let curve_width = curve_width(last_line.start_x, first_line.start_x);
|
||||
let second_top_left = point(last_line.start_x, start_y + self.line_height);
|
||||
path.line_to(second_top_left + curve_height);
|
||||
builder.line_to(second_top_left + curve_height);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(second_top_left + curve_width, second_top_left);
|
||||
builder.curve_to(second_top_left + curve_width, second_top_left);
|
||||
}
|
||||
let first_bottom_left = point(first_line.start_x, second_top_left.y);
|
||||
path.line_to(first_bottom_left - curve_width);
|
||||
builder.line_to(first_bottom_left - curve_width);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(first_bottom_left - curve_height, first_bottom_left);
|
||||
builder.curve_to(first_bottom_left - curve_height, first_bottom_left);
|
||||
}
|
||||
}
|
||||
|
||||
path.line_to(first_top_left + curve_height);
|
||||
builder.line_to(first_top_left + curve_height);
|
||||
if self.corner_radius > Pixels::ZERO {
|
||||
path.curve_to(first_top_left + top_curve_width, first_top_left);
|
||||
builder.curve_to(first_top_left + top_curve_width, first_top_left);
|
||||
}
|
||||
path.line_to(first_top_right - top_curve_width);
|
||||
builder.line_to(first_top_right - top_curve_width);
|
||||
|
||||
window.paint_path(path, self.color);
|
||||
if let Ok(path) = builder.build() {
|
||||
window.paint_path(path, self.color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue