mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Add support for gradients with midpoints and add draggable diamonds to the color picker dialog (#3813)
* Refactor GradientStops to use struct-of-arrays and include midpoint * Implement interaction and rendering * Make color picker saturation-value color picking snap to original position and show both axis lines Make color picker saturation-value color picking snap to original position and show both axis lines * Add graphite:midpoint attribute to SVG exports * Add graphite:midpoint parsing to SVG importer
This commit is contained in:
@@ -16,15 +16,18 @@ impl RenderExt for Gradient {
|
||||
/// Adds the gradient def through mutating the first argument, returning the gradient ID.
|
||||
fn render(&self, svg_defs: &mut String, element_transform: DAffine2, stroke_transform: DAffine2, bounds: DAffine2, transformed_bounds: DAffine2, _render_params: &RenderParams) -> Self::Output {
|
||||
let mut stop = String::new();
|
||||
for (position, color) in self.stops.0.iter() {
|
||||
for (position, color, original_midpoint) in self.stops.interpolated_samples() {
|
||||
stop.push_str("<stop");
|
||||
if *position != 0. {
|
||||
if position != 0. {
|
||||
let _ = write!(stop, r#" offset="{}""#, (position * 1_000_000.).round() / 1_000_000.);
|
||||
}
|
||||
let _ = write!(stop, r##" stop-color="#{}""##, color.to_rgb_hex_srgb_from_gamma());
|
||||
if color.a() < 1. {
|
||||
let _ = write!(stop, r#" stop-opacity="{}""#, (color.a() * 1000.).round() / 1000.);
|
||||
}
|
||||
if let Some(midpoint) = original_midpoint {
|
||||
let _ = write!(stop, r#" graphite:midpoint="{}""#, (midpoint * 1000.).round() / 1000.);
|
||||
}
|
||||
stop.push_str(" />")
|
||||
}
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ impl SvgRender {
|
||||
let (x, y) = bounds_min.into();
|
||||
let (size_x, size_y) = (bounds_max - bounds_min).into();
|
||||
let defs = &self.svg_defs;
|
||||
let svg_header = format!(r#"<svg xmlns="http://www.w3.org/2000/svg" viewBox="{x} {y} {size_x} {size_y}"><defs>{defs}</defs>"#,);
|
||||
let svg_header = format!(r#"<svg xmlns="http://www.w3.org/2000/svg" xmlns:graphite="https://graphite.art" viewBox="{x} {y} {size_x} {size_y}"><defs>{defs}</defs>"#,);
|
||||
self.svg.insert(0, svg_header.into());
|
||||
self.svg.push("</svg>".into());
|
||||
}
|
||||
@@ -99,7 +99,7 @@ impl SvgRender {
|
||||
let matrix = format_transform_matrix(transform);
|
||||
let transform = if matrix.is_empty() { String::new() } else { format!(r#" transform="{matrix}""#) };
|
||||
|
||||
let svg_header = format!(r#"<svg xmlns="http://www.w3.org/2000/svg" {view_box}><defs>{defs}</defs><g{transform}>"#);
|
||||
let svg_header = format!(r#"<svg xmlns="http://www.w3.org/2000/svg" xmlns:graphite="https://graphite.art" {view_box}><defs>{defs}</defs><g{transform}>"#);
|
||||
self.svg.insert(0, svg_header.into());
|
||||
self.svg.push("</g></svg>".into());
|
||||
}
|
||||
@@ -997,9 +997,9 @@ impl Render for Table<Vector> {
|
||||
}
|
||||
Fill::Gradient(gradient) => {
|
||||
let mut stops = peniko::ColorStops::new();
|
||||
for &(offset, color) in &gradient.stops {
|
||||
for (position, color, _) in gradient.stops.interpolated_samples() {
|
||||
stops.push(peniko::ColorStop {
|
||||
offset: offset as f32,
|
||||
offset: position as f32,
|
||||
color: peniko::color::DynamicColor::from_alpha_color(peniko::Color::new([color.r(), color.g(), color.b(), color.a()])),
|
||||
});
|
||||
}
|
||||
@@ -1557,11 +1557,14 @@ impl Render for Table<GradientStops> {
|
||||
attributes.push("points", format!("{max},{max} -{max},{max} -{max},-{max} {max},-{max}"));
|
||||
|
||||
let mut stop_string = String::new();
|
||||
for (position, color) in row.element.0.iter() {
|
||||
for (position, color, original_midpoint) in row.element.interpolated_samples() {
|
||||
let _ = write!(stop_string, r##"<stop offset="{}" stop-color="#{}""##, position, color.to_rgb_hex_srgb_from_gamma());
|
||||
if color.a() < 1. {
|
||||
let _ = write!(stop_string, r#" stop-opacity="{}""#, color.a());
|
||||
}
|
||||
if let Some(midpoint) = original_midpoint {
|
||||
let _ = write!(stop_string, r#" graphite:midpoint="{}""#, (midpoint * 1000.).round() / 1000.);
|
||||
}
|
||||
stop_string.push_str(" />");
|
||||
}
|
||||
|
||||
@@ -1619,7 +1622,7 @@ impl Render for Table<GradientStops> {
|
||||
let blend_mode = alpha_blending.blend_mode.to_peniko();
|
||||
let opacity = alpha_blending.opacity(render_params.for_mask);
|
||||
|
||||
let color = row.element.0.first().map(|stop| stop.1).unwrap_or(Color::MAGENTA);
|
||||
let color = row.element.color.first().copied().unwrap_or(Color::MAGENTA);
|
||||
let vello_color = peniko::Color::new([color.r(), color.g(), color.b(), color.a()]);
|
||||
|
||||
let rect = kurbo::Rect::from_origin_size(kurbo::Point::ZERO, kurbo::Size::new(1., 1.));
|
||||
|
||||
Reference in New Issue
Block a user