mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Rename gradient type to gradient form (#4405)
* Rename gradient type to gradient form * Update the demo art for the gradient form rename * Say form not type in the Gradient Form node's doc comment
This commit is contained in:
committed by
Dennis Kobert
parent
d5e31c23bb
commit
b9a8065eb8
@@ -1164,7 +1164,7 @@ impl<T: CacheHash> CacheHash for List<T> {
|
||||
self.element.cache_hash(state);
|
||||
|
||||
// Hash every attribute attribute (key + values) rather than just the well-known ones, so changes to user-defined keys
|
||||
// (e.g., gradient_type, gradient_spread) invalidate downstream graph caches as expected
|
||||
// (e.g., gradient_form, gradient_spread) invalidate downstream graph caches as expected
|
||||
for (key, attribute) in &self.attributes.attributes {
|
||||
std::hash::Hash::hash(key.as_str(), state);
|
||||
attribute.cache_hash_dyn(state);
|
||||
|
||||
@@ -32,7 +32,7 @@ pub mod migrations {
|
||||
pub struct LegacyGradient {
|
||||
#[serde(deserialize_with = "crate::migrations::migrate_to_gradient_ramp")]
|
||||
pub stops: GradientRamp,
|
||||
pub gradient_type: vector::style::GradientType,
|
||||
pub gradient_type: vector::style::GradientForm,
|
||||
pub start: DVec2,
|
||||
pub end: DVec2,
|
||||
#[serde(default)]
|
||||
@@ -54,7 +54,7 @@ pub mod migrations {
|
||||
|
||||
// The legacy radial drew as a circle in the layer's own space; bake the adjustment that, composed with the
|
||||
// endpoint frame, makes the new pipeline reproduce that circle through the (possibly non-uniform) layer transform.
|
||||
let radial_invertible = self.gradient_type == vector::style::GradientType::Radial
|
||||
let radial_invertible = self.gradient_type == vector::style::GradientForm::Radial
|
||||
&& layer_transform.is_finite()
|
||||
&& layer_transform.matrix2.determinant().recip().is_finite()
|
||||
&& direction.length_squared() > 1e-20;
|
||||
|
||||
@@ -7,8 +7,8 @@ use core_types::list::List;
|
||||
use core_types::uuid::generate_uuid;
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphic_types::Graphic;
|
||||
use graphic_types::vector_types::gradient::GradientType;
|
||||
use graphic_types::vector_types::markers::{GradientSpread as GradientSpreadAttr, GradientType as GradientTypeAttr};
|
||||
use graphic_types::vector_types::gradient::GradientForm;
|
||||
use graphic_types::vector_types::markers::{GradientForm as GradientFormAttr, GradientSpread as GradientSpreadAttr};
|
||||
use graphic_types::vector_types::vector::style::{PaintOrder, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
|
||||
use std::fmt::Write;
|
||||
use vector_types::Gradient;
|
||||
@@ -108,7 +108,7 @@ pub fn render_gradient_paint<S: core_types::lane::LaneSource<Element = Gradient>
|
||||
|
||||
{
|
||||
let Some(stops) = source.element(0) else { return 0 };
|
||||
let gradient_type: GradientType = source.attr::<GradientTypeAttr>(0);
|
||||
let gradient_form: GradientForm = source.attr::<GradientFormAttr>(0);
|
||||
let local_gradient_transform: DAffine2 = source.attr::<Transform>(0);
|
||||
let gradient_spread: GradientSpread = source.attr::<GradientSpreadAttr>(0);
|
||||
|
||||
@@ -141,7 +141,7 @@ pub fn render_gradient_paint<S: core_types::lane::LaneSource<Element = Gradient>
|
||||
|
||||
let document_transform = item_transform * local_gradient_transform;
|
||||
|
||||
let placement = gradient_placement(document_transform, gradient_type);
|
||||
let placement = gradient_placement(document_transform, gradient_form);
|
||||
let gradient_transform = format_transform_matrix(element_transform_inverse * placement);
|
||||
let gradient_transform = if gradient_transform.is_empty() {
|
||||
String::new()
|
||||
@@ -157,15 +157,15 @@ pub fn render_gradient_paint<S: core_types::lane::LaneSource<Element = Gradient>
|
||||
|
||||
let gradient_id = generate_uuid();
|
||||
|
||||
match gradient_type {
|
||||
GradientType::Linear => {
|
||||
match gradient_form {
|
||||
GradientForm::Linear => {
|
||||
let _ = write!(
|
||||
svg_defs,
|
||||
r#"<linearGradient id="{}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{gradient_spread}{gradient_transform}>{}</linearGradient>"#,
|
||||
gradient_id, stop
|
||||
);
|
||||
}
|
||||
GradientType::Radial => {
|
||||
GradientForm::Radial => {
|
||||
let _ = write!(
|
||||
svg_defs,
|
||||
r#"<radialGradient id="{}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{gradient_spread}{gradient_transform}>{}</radialGradient>"#,
|
||||
|
||||
@@ -26,8 +26,8 @@ use graphene_resource::Resource;
|
||||
use graphic_types::graphic::{PaintColumns, PaintOverlay, PaintReach, has_paint, is_paint_present, paint_graphics, set_paint_attribute, vector_can_reduce_to_clip_path};
|
||||
use graphic_types::markers::{EditorMergedLayers, Fill, Stroke};
|
||||
use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster, Texture};
|
||||
use graphic_types::vector_types::gradient::{Gradient, GradientType};
|
||||
use graphic_types::vector_types::markers::{GradientSpread as GradientSpreadAttr, GradientType as GradientTypeAttr};
|
||||
use graphic_types::vector_types::gradient::{Gradient, GradientForm};
|
||||
use graphic_types::vector_types::markers::{GradientForm as GradientFormAttr, GradientSpread as GradientSpreadAttr};
|
||||
use graphic_types::vector_types::subpath::Subpath;
|
||||
use graphic_types::vector_types::vector::click_target::{ClickTarget, FreePoint};
|
||||
use graphic_types::vector_types::vector::style::{PaintOrder, RenderMode, StrokeAlign, StrokeCap, StrokeJoin};
|
||||
@@ -385,10 +385,10 @@ pub(crate) fn transform_is_invertible(transform: DAffine2) -> bool {
|
||||
/// non-uniform transform makes an ellipse), while linear is reduced to the equivalent non-sheared gradient line (the
|
||||
/// axis projected onto the band normal) so the iso-color bands keep following a sheared transform, which Vello can
|
||||
/// represent since it stores only two endpoints.
|
||||
pub(crate) fn gradient_placement(transform: DAffine2, gradient_type: GradientType) -> DAffine2 {
|
||||
match gradient_type {
|
||||
GradientType::Radial => transform,
|
||||
GradientType::Linear => {
|
||||
pub(crate) fn gradient_placement(transform: DAffine2, gradient_form: GradientForm) -> DAffine2 {
|
||||
match gradient_form {
|
||||
GradientForm::Radial => transform,
|
||||
GradientForm::Linear => {
|
||||
let axis = transform.matrix2.x_axis;
|
||||
let band_normal = transform.matrix2.y_axis.perp();
|
||||
let line = if band_normal.length_squared() > 0. { axis.project_onto(band_normal) } else { axis };
|
||||
@@ -428,23 +428,23 @@ fn peniko_color_stops(gradient: &Gradient) -> peniko::ColorStops {
|
||||
fn create_peniko_gradient_brush<S: LaneSource<Element = Gradient>>(gradient_list: &S, multiplied_transform: &DAffine2) -> Option<(peniko::Brush, DAffine2)> {
|
||||
let stops = gradient_list.element(0)?;
|
||||
|
||||
let gradient_type: GradientType = gradient_list.attr::<GradientTypeAttr>(0);
|
||||
let gradient_form: GradientForm = gradient_list.attr::<GradientFormAttr>(0);
|
||||
let gradient_transform: DAffine2 = gradient_list.attr::<Transform>(0);
|
||||
let gradient_spread: GradientSpread = gradient_list.attr::<GradientSpreadAttr>(0);
|
||||
|
||||
let peniko_stops = peniko_color_stops(stops);
|
||||
|
||||
// The unit gradient is placed by the desheared frame so a non-uniform transform produces the intended ellipse
|
||||
let (start, end, gradient_to_device) = (DVec2::ZERO, DVec2::X, gradient_placement(multiplied_transform * gradient_transform, gradient_type));
|
||||
let (start, end, gradient_to_device) = (DVec2::ZERO, DVec2::X, gradient_placement(multiplied_transform * gradient_transform, gradient_form));
|
||||
|
||||
let brush = peniko::Brush::Gradient(peniko::Gradient {
|
||||
kind: match gradient_type {
|
||||
GradientType::Linear => peniko::LinearGradientPosition {
|
||||
kind: match gradient_form {
|
||||
GradientForm::Linear => peniko::LinearGradientPosition {
|
||||
start: to_point(start),
|
||||
end: to_point(end),
|
||||
}
|
||||
.into(),
|
||||
GradientType::Radial => peniko::RadialGradientPosition {
|
||||
GradientForm::Radial => peniko::RadialGradientPosition {
|
||||
start_center: to_point(start),
|
||||
start_radius: 0.,
|
||||
end_center: to_point(start),
|
||||
@@ -2328,7 +2328,7 @@ fn render_gradient_svg<S: LaneSource<Element = Gradient>>(source: &S, render: &m
|
||||
let opacity_attr: f64 = source.attr::<Opacity>(index);
|
||||
let opacity_fill_attr: f64 = source.attr::<OpacityFill>(index);
|
||||
let gradient_spread: GradientSpread = source.attr::<GradientSpreadAttr>(index);
|
||||
let gradient_type: GradientType = source.attr::<GradientTypeAttr>(index);
|
||||
let gradient_form: GradientForm = source.attr::<GradientFormAttr>(index);
|
||||
let tag = if thumbnail_rect.is_some() { "rect" } else { "polyline" };
|
||||
render.leaf_tag(tag, |attributes| {
|
||||
if let Some((min, size)) = thumbnail_rect {
|
||||
@@ -2373,14 +2373,14 @@ fn render_gradient_svg<S: LaneSource<Element = Gradient>>(source: &S, render: &m
|
||||
};
|
||||
|
||||
// The unit gradient line is the +X unit vector in local space, before the item's transform is applied
|
||||
match gradient_type {
|
||||
GradientType::Linear => {
|
||||
match gradient_form {
|
||||
GradientForm::Linear => {
|
||||
let _ = write!(
|
||||
&mut attributes.0.svg_defs,
|
||||
r#"<linearGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="1" y2="0"{spread_method_attribute}{gradient_transform_attribute}>{stop_string}</linearGradient>"#
|
||||
);
|
||||
}
|
||||
GradientType::Radial => {
|
||||
GradientForm::Radial => {
|
||||
let _ = write!(
|
||||
&mut attributes.0.svg_defs,
|
||||
r#"<radialGradient id="{gradient_id}" gradientUnits="userSpaceOnUse" cx="0" cy="0" r="1"{spread_method_attribute}{gradient_transform_attribute}>{stop_string}</radialGradient>"#
|
||||
@@ -2412,7 +2412,7 @@ fn render_gradient_vello<S: LaneSource<Element = Gradient>>(source: &S, scene: &
|
||||
for index in 0..source.lane_count() {
|
||||
let Some(gradient) = source.element(index) else { continue };
|
||||
let gradient_spread: GradientSpread = source.attr::<GradientSpreadAttr>(index);
|
||||
let gradient_type: GradientType = source.attr::<GradientTypeAttr>(index);
|
||||
let gradient_form: GradientForm = source.attr::<GradientFormAttr>(index);
|
||||
let transform: DAffine2 = source.attr::<Transform>(index);
|
||||
let blend_mode_attr: BlendMode = source.attr::<BlendModeAttr>(index);
|
||||
let opacity_attr: f64 = source.attr::<Opacity>(index);
|
||||
@@ -2432,13 +2432,13 @@ fn render_gradient_vello<S: LaneSource<Element = Gradient>>(source: &S, scene: &
|
||||
|
||||
// The unit gradient line is the +X unit vector in local space, before the item's transform is applied.
|
||||
// For radial, the unit-radius circle at the origin scales out to the line's length once the brush transform applies.
|
||||
let kind = match gradient_type {
|
||||
GradientType::Linear => peniko::LinearGradientPosition {
|
||||
let kind = match gradient_form {
|
||||
GradientForm::Linear => peniko::LinearGradientPosition {
|
||||
start: to_point(DVec2::ZERO),
|
||||
end: to_point(DVec2::X),
|
||||
}
|
||||
.into(),
|
||||
GradientType::Radial => peniko::RadialGradientPosition {
|
||||
GradientForm::Radial => peniko::RadialGradientPosition {
|
||||
start_center: to_point(DVec2::ZERO),
|
||||
start_radius: 0.,
|
||||
end_center: to_point(DVec2::ZERO),
|
||||
@@ -2454,7 +2454,7 @@ fn render_gradient_vello<S: LaneSource<Element = Gradient>>(source: &S, scene: &
|
||||
interpolation_alpha_space: peniko::InterpolationAlphaSpace::Premultiplied,
|
||||
..Default::default()
|
||||
});
|
||||
let brush_transform = kurbo::Affine::new(gradient_placement(gradient_transform, gradient_type).to_cols_array());
|
||||
let brush_transform = kurbo::Affine::new(gradient_placement(gradient_transform, gradient_form).to_cols_array());
|
||||
let rect = kurbo::Rect::from_origin_size(kurbo::Point::ZERO, kurbo::Size::new(1., 1.));
|
||||
|
||||
let mut layer = false;
|
||||
|
||||
@@ -10,7 +10,7 @@ use glam::{DAffine2, DVec2};
|
||||
#[derive(Default, PartialEq, Eq, Clone, Copy, Debug, Hash, graphene_hash::CacheHash, DynAny, node_macro::ChoiceType)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
#[widget(Radio)]
|
||||
pub enum GradientType {
|
||||
pub enum GradientForm {
|
||||
#[default]
|
||||
Linear,
|
||||
Radial,
|
||||
|
||||
@@ -9,8 +9,8 @@ pub mod vector;
|
||||
|
||||
// Re-export commonly used types at the crate root
|
||||
pub use core_types as gcore;
|
||||
pub use gradient::{Gradient, GradientRamp, GradientSpread, GradientStop, GradientType};
|
||||
pub use markers::{ATTR_EDITOR_CLICK_TARGET, ATTR_GRADIENT_SPREAD, ATTR_GRADIENT_TYPE};
|
||||
pub use gradient::{Gradient, GradientForm, GradientRamp, GradientSpread, GradientStop};
|
||||
pub use markers::{ATTR_EDITOR_CLICK_TARGET, ATTR_GRADIENT_FORM, ATTR_GRADIENT_SPREAD};
|
||||
pub use math::{QuadExt, RectExt};
|
||||
pub use subpath::Subpath;
|
||||
pub use vector::Vector;
|
||||
|
||||
@@ -7,7 +7,7 @@ core_types::attribute! {
|
||||
/// Gradient's spread behavior past its endpoints (`Pad`, `Reflect`, or `Repeat`).
|
||||
pub GradientSpread("gradient_spread"): crate::gradient::GradientSpread;
|
||||
/// Gradient's shape (`Linear` or `Radial`).
|
||||
pub GradientType("gradient_type"): crate::gradient::GradientType;
|
||||
pub GradientForm("gradient_form"): crate::gradient::GradientForm;
|
||||
/// Optional `Vector` that overrides the item's own geometry for click-target generation.
|
||||
/// Used by the 'Text' node for per-glyph bounding-box rectangles so glyphs are selectable
|
||||
/// by clicking anywhere within their bounds, not just the filled letterform. An absent
|
||||
@@ -19,11 +19,11 @@ core_types::attribute! {
|
||||
// named write or read reaches this crate's enums like any other plain value.
|
||||
core_types::named_value! {
|
||||
for crate::gradient::GradientSpread;
|
||||
for crate::gradient::GradientType;
|
||||
for crate::gradient::GradientForm;
|
||||
}
|
||||
|
||||
pub const ATTR_GRADIENT_SPREAD: &str = GradientSpread::NAME;
|
||||
pub const ATTR_GRADIENT_TYPE: &str = GradientType::NAME;
|
||||
pub const ATTR_GRADIENT_FORM: &str = GradientForm::NAME;
|
||||
pub const ATTR_EDITOR_CLICK_TARGET: &str = EditorClickTarget::NAME;
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -34,7 +34,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn the_census_carries_this_crates_names() {
|
||||
assert_eq!(info("gradient_type").unwrap().value_type, TypeId::of::<crate::gradient::GradientType>());
|
||||
assert_eq!(info("gradient_form").unwrap().value_type, TypeId::of::<crate::gradient::GradientForm>());
|
||||
assert_eq!(info("gradient_spread").unwrap().value_type, TypeId::of::<crate::gradient::GradientSpread>());
|
||||
assert_eq!(info("editor:click_target").unwrap().value_type, TypeId::of::<Option<&'static crate::Vector>>());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user