mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 23:08:05 +08:00
Rename the Graphic enum wrapper variants with a "List" suffix (#4434)
Only the list-holding variant takes the suffix here: the record model already carries the rank-0 leaves upstream adds in #4437. Co-authored-by: Dennis Kobert <dennis@kobert.dev>
This commit is contained in:
committed by
Dennis Kobert
parent
a41b362fe2
commit
f09eb73c08
@@ -12,7 +12,7 @@ use glam::DAffine2;
|
||||
/// enclosing `List<Artboard>`, not as fields here. This keeps `Artboard` a pure type-system boundary
|
||||
/// that prevents arbitrary `List<List<...<Graphic>>>` nesting.
|
||||
#[derive(Clone, Debug, Default, CacheHash, PartialEq, DynAny)]
|
||||
pub struct Artboard<'e>(List<Graphic<'e>>);
|
||||
pub struct Artboard<'e>(pub List<Graphic<'e>>);
|
||||
|
||||
impl<'e> Artboard<'e> {
|
||||
pub fn new(content: List<Graphic<'e>>) -> Self {
|
||||
|
||||
@@ -14,14 +14,14 @@ pub fn map_groups_to_owned<'out>(graphic: &Graphic<'_>) -> Graphic<'out> {
|
||||
match graphic {
|
||||
Graphic::None => Graphic::None,
|
||||
Graphic::Group(group) => Graphic::Group(group.copy_out()),
|
||||
Graphic::Graphic(children) => {
|
||||
Graphic::GraphicList(children) => {
|
||||
let mut out = List::new();
|
||||
for item in children.clone().into_iter() {
|
||||
let (element, attributes) = item.into_parts();
|
||||
out.push(Item::from_parts(map_groups_to_owned(&element), attributes));
|
||||
}
|
||||
map_attribute_groups_to_owned(&mut out);
|
||||
Graphic::Graphic(out)
|
||||
Graphic::GraphicList(out)
|
||||
}
|
||||
Graphic::Vector(vector) => Graphic::Vector(vector.clone()),
|
||||
Graphic::RasterCPU(raster) => Graphic::RasterCPU(raster.clone()),
|
||||
@@ -37,13 +37,13 @@ pub fn map_groups_to_owned<'out>(graphic: &Graphic<'_>) -> Graphic<'out> {
|
||||
pub fn map_groups_to_resident<'a>(graphic: &Graphic<'a>, arena: &'a core_types::arena::Arena) -> Option<Graphic<'a>> {
|
||||
match graphic {
|
||||
Graphic::Group(group) => group.replay(arena).map(Graphic::Group),
|
||||
Graphic::Graphic(children) => {
|
||||
Graphic::GraphicList(children) => {
|
||||
let mut children = children.clone();
|
||||
for child in children.iter_element_values_mut() {
|
||||
*child = map_groups_to_resident(child, arena)?;
|
||||
}
|
||||
map_attribute_groups_to_resident(&mut children, arena)?;
|
||||
Some(Graphic::Graphic(children))
|
||||
Some(Graphic::GraphicList(children))
|
||||
}
|
||||
other => Some(other.clone()),
|
||||
}
|
||||
@@ -82,14 +82,14 @@ pub fn map_groups_to_persistent<'p>(graphic: &Graphic<'_>, promotion: &core_type
|
||||
match graphic {
|
||||
Graphic::None => Some(Graphic::None),
|
||||
Graphic::Group(group) => group.to_persistent(promotion).map(Graphic::Group),
|
||||
Graphic::Graphic(children) => {
|
||||
Graphic::GraphicList(children) => {
|
||||
let mut out = List::new();
|
||||
for item in children.clone().into_iter() {
|
||||
let (element, attributes) = item.into_parts();
|
||||
out.push(Item::from_parts(map_groups_to_persistent(&element, promotion)?, attributes));
|
||||
}
|
||||
map_attribute_groups_to_persistent(&mut out, promotion)?;
|
||||
Some(Graphic::Graphic(out))
|
||||
Some(Graphic::GraphicList(out))
|
||||
}
|
||||
Graphic::Vector(vector) => Some(Graphic::Vector(vector.clone())),
|
||||
Graphic::RasterCPU(raster) => Some(Graphic::RasterCPU(raster.clone())),
|
||||
@@ -216,7 +216,7 @@ fn graphic_retained_heap(graphic: &Graphic<'_>) -> usize {
|
||||
Graphic::RasterCPU(raster) => raster.data.len() * size_of::<Color>(),
|
||||
Graphic::Text(text) => text.len(),
|
||||
Graphic::Gradient(gradient) => gradient.len() * size_of::<(f64, Color)>(),
|
||||
Graphic::Graphic(children) => (0..children.len()).filter_map(|index| children.element(index)).map(graphic_retained_heap).sum(),
|
||||
Graphic::GraphicList(children) => (0..children.len()).filter_map(|index| children.element(index)).map(graphic_retained_heap).sum(),
|
||||
Graphic::None | Graphic::Group(_) | Graphic::RasterGPU(_) | Graphic::Color(_) => 0,
|
||||
}
|
||||
}
|
||||
@@ -236,7 +236,7 @@ fn vector_retained_heap(vector: &Vector) -> usize {
|
||||
fn graphic_contains_groups(graphic: &Graphic) -> bool {
|
||||
match graphic {
|
||||
Graphic::Group(_) => true,
|
||||
Graphic::Graphic(children) => list_contains_groups(children),
|
||||
Graphic::GraphicList(children) => list_contains_groups(children),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,14 +49,14 @@ pub fn map_groups_to_legacy<'out>(graphic: &Graphic<'_>) -> Graphic<'out> {
|
||||
match graphic {
|
||||
Graphic::None => Graphic::None,
|
||||
Graphic::Group(group) => group_to_legacy_graphic(group),
|
||||
Graphic::Graphic(children) => {
|
||||
Graphic::GraphicList(children) => {
|
||||
let mut out = List::new();
|
||||
for item in children.clone().into_iter() {
|
||||
let (element, attributes) = item.into_parts();
|
||||
out.push(Item::from_parts(map_groups_to_legacy(&element), attributes));
|
||||
}
|
||||
map_paint_attrs_to_legacy(&mut out);
|
||||
Graphic::Graphic(out)
|
||||
Graphic::GraphicList(out)
|
||||
}
|
||||
Graphic::Vector(vector) => Graphic::Vector(vector.clone()),
|
||||
Graphic::RasterCPU(raster) => Graphic::RasterCPU(raster.clone()),
|
||||
@@ -81,10 +81,10 @@ pub fn group_to_legacy_graphic(group: &core_types::record::Group) -> Graphic<'st
|
||||
.or_else(|| run_to_legacy_list::<Gradient>(item).map(|list| detable_items(list, Graphic::Gradient)))
|
||||
.or_else(|| run_to_legacy_list::<String>(item).map(|list| detable_items(list, Graphic::Text)));
|
||||
if let Some(typed) = typed {
|
||||
return Graphic::Graphic(typed);
|
||||
return Graphic::GraphicList(typed);
|
||||
}
|
||||
}
|
||||
Graphic::Graphic(group_to_legacy_list(group))
|
||||
Graphic::GraphicList(group_to_legacy_list(group))
|
||||
}
|
||||
|
||||
/// The group as a legacy `List<Graphic>`: a `Graphic` run becomes the items,
|
||||
@@ -122,7 +122,7 @@ mod run_tests {
|
||||
// SAFETY: the erased native list serves only while `source` is live; the
|
||||
// deep glue under test replaces its borrows at the copy-out seam.
|
||||
let paint = unsafe { core_types::record::erase_static(native_group_paint(&inner_vector, &source)) };
|
||||
let appearance = Appearance::new_single(Coverage::new_fill(), Graphic::Graphic(paint.clone()));
|
||||
let appearance = Appearance::new_single(Coverage::new_fill(), Graphic::GraphicList(paint.clone()));
|
||||
|
||||
let vector = unit_square_at(DVec2::new(4., 4.));
|
||||
let mut builder = RunBuilder::new(&source, element_write_hashed::<Vector>(), &[FieldWrite::of::<AppearanceMarker>(0)], 1).unwrap();
|
||||
@@ -137,7 +137,7 @@ mod run_tests {
|
||||
|
||||
let served = legacy.attribute::<Appearance>(ATTR_APPEARANCE, 0).expect("the appearance rides the list");
|
||||
let cell = served.paint_at(0).expect("the fill coverage keeps its paint");
|
||||
let Graphic::Graphic(cell_rows) = cell else { panic!("the paint cell keeps the list form") };
|
||||
let Graphic::GraphicList(cell_rows) = cell else { panic!("the paint cell keeps the list form") };
|
||||
assert_eq!(cell_rows.element(0).unwrap(), &expected);
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ impl<'e> Graphic<'e> {
|
||||
|
||||
match self {
|
||||
// The legacy interior is owned outright, so its lanes map in place.
|
||||
Graphic::Graphic(children) => {
|
||||
Graphic::GraphicList(children) => {
|
||||
for row in 0..children.len() {
|
||||
let lane_transform: DAffine2 = children.attribute_cloned_or_default(ATTR_TRANSFORM, row);
|
||||
let Some(child) = children.element_mut(row) else { continue };
|
||||
@@ -217,7 +217,7 @@ mod tests {
|
||||
let mut children = List::new();
|
||||
children.push(Item::new_from_element(Graphic::Color(core_types::Color::WHITE)));
|
||||
children.push(Item::new_from_element(Graphic::Vector(unit_square_at(DVec2::ZERO))));
|
||||
let mut graphic = Graphic::Graphic(children);
|
||||
let mut graphic = Graphic::GraphicList(children);
|
||||
|
||||
let mut mapped = 0;
|
||||
graphic
|
||||
@@ -228,7 +228,7 @@ mod tests {
|
||||
.expect("no rebuild is needed");
|
||||
|
||||
assert_eq!(mapped, 1, "only the vector leaf is mapped");
|
||||
let Graphic::Graphic(children) = &graphic else { panic!("the list form survives") };
|
||||
let Graphic::GraphicList(children) = &graphic else { panic!("the list form survives") };
|
||||
assert!(matches!(children.element(0), Some(Graphic::Color(_))), "the color leaf passes through untouched");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ pub enum Graphic<'e> {
|
||||
/// The absence of graphical content, like CSS's `none` keyword: painting it produces nothing.
|
||||
#[default]
|
||||
None,
|
||||
Graphic(List<Graphic<'e>>),
|
||||
GraphicList(List<Graphic<'e>>),
|
||||
Vector(Vector),
|
||||
RasterCPU(Raster<CPU>),
|
||||
RasterGPU(Raster<GPU>),
|
||||
@@ -164,7 +164,7 @@ impl From<String> for Graphic<'_> {
|
||||
/// Both group forms are excluded: a lone native `Group` still has interior structure to flatten.
|
||||
pub fn is_lone_anonymous_leaf(content: &List<Graphic>) -> bool {
|
||||
content.len() == 1
|
||||
&& !matches!(content.element(0), Some(Graphic::Graphic(_)) | Some(Graphic::Group(_)))
|
||||
&& !matches!(content.element(0), Some(Graphic::GraphicList(_)) | Some(Graphic::Group(_)))
|
||||
&& content.attribute::<DAffine2>(ATTR_TRANSFORM, 0).is_none()
|
||||
&& content.attribute::<f64>(ATTR_OPACITY, 0).is_none()
|
||||
&& content.attribute::<f64>(ATTR_OPACITY_FILL, 0).is_none()
|
||||
@@ -172,7 +172,7 @@ pub fn is_lone_anonymous_leaf(content: &List<Graphic>) -> bool {
|
||||
}
|
||||
|
||||
/// Deeply flattens a `List<Graphic>`, collecting only elements matching a specific variant (extracted by `extract_variant`)
|
||||
/// and discarding all other non-matching content. Recursion through `Graphic::Graphic` sub-`List`s composes transforms and opacity.
|
||||
/// and discarding all other non-matching content. Recursion through `Graphic::GraphicList` sub-`List`s composes transforms and opacity.
|
||||
fn flatten_graphic_list<T>(content: List<Graphic>, extract_variant: fn(Graphic) -> Option<List<T>>) -> List<T> {
|
||||
// Its list is already the flat answer, so hand it back rather than rebuilding it item by item
|
||||
if is_lone_anonymous_leaf(&content) {
|
||||
@@ -200,7 +200,7 @@ fn flatten_graphic_list<T>(content: List<Graphic>, extract_variant: fn(Graphic)
|
||||
match element {
|
||||
// Compose the parent's transform/opacity/fill onto each child, but only for attributes the parent carries.
|
||||
// A child lacking one is padded with the composition identity (`1.` for opacity/fill, identity for transform), so composing through it is a no-op.
|
||||
Graphic::Graphic(mut sub_list) => {
|
||||
Graphic::GraphicList(mut sub_list) => {
|
||||
// A group's first child has no preceding sibling, so its clipping flag is inert until splicing
|
||||
// hands it the group's own predecessor. Clear it (keeping the column) to stay clip-neutral.
|
||||
if sub_list.attribute::<bool>(ATTR_CLIPPING_MASK, 0).is_some() {
|
||||
@@ -379,14 +379,14 @@ impl From<DVec2> for Graphic<'_> {
|
||||
impl<'e> Graphic<'e> {
|
||||
pub fn as_graphic(&self) -> Option<&List<Graphic<'_>>> {
|
||||
match self {
|
||||
Graphic::Graphic(graphic) => Some(graphic),
|
||||
Graphic::GraphicList(graphic) => Some(graphic),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn as_graphic_mut(&mut self) -> Option<&mut List<Graphic<'e>>> {
|
||||
match self {
|
||||
Graphic::Graphic(graphic) => Some(graphic),
|
||||
Graphic::GraphicList(graphic) => Some(graphic),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -420,7 +420,7 @@ impl<'e> Graphic<'e> {
|
||||
|
||||
match self {
|
||||
Graphic::None => true,
|
||||
Graphic::Graphic(list) => all_clipped(list),
|
||||
Graphic::GraphicList(list) => all_clipped(list),
|
||||
Graphic::Group(group) => group_all_clipped(group),
|
||||
_ => false,
|
||||
}
|
||||
@@ -436,7 +436,7 @@ impl<'e> Graphic<'e> {
|
||||
pub fn is_opaque(&self) -> bool {
|
||||
match self {
|
||||
Graphic::None => false,
|
||||
Graphic::Graphic(list) => !list.is_empty() && list.iter_element_values().all(Graphic::is_opaque),
|
||||
Graphic::GraphicList(list) => !list.is_empty() && list.iter_element_values().all(Graphic::is_opaque),
|
||||
// A bare leaf carries no paint attribute, which rides its lane, so
|
||||
// nothing here claims opacity.
|
||||
Graphic::Vector(_) => false,
|
||||
@@ -450,7 +450,7 @@ impl<'e> Graphic<'e> {
|
||||
pub fn is_fully_transparent(&self) -> bool {
|
||||
match self {
|
||||
Graphic::None => true,
|
||||
Graphic::Graphic(list) => list.iter_element_values().all(Graphic::is_fully_transparent),
|
||||
Graphic::GraphicList(list) => list.iter_element_values().all(Graphic::is_fully_transparent),
|
||||
// A bare vector leaf carries no paint or stroke of its own, so it is invisible on its own
|
||||
Graphic::Vector(_) => true,
|
||||
Graphic::Color(color) => color.a() == 0.,
|
||||
@@ -470,7 +470,7 @@ impl<'e> Graphic<'e> {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
Graphic::None => true,
|
||||
Graphic::Graphic(list) => list.is_empty(),
|
||||
Graphic::GraphicList(list) => list.is_empty(),
|
||||
Graphic::Group(group) => group_is_empty(group),
|
||||
_ => false,
|
||||
}
|
||||
@@ -484,7 +484,7 @@ impl BoundingBox for Graphic<'_> {
|
||||
Graphic::Vector(vector) => BoundingBox::bounding_box(vector, transform, include_stroke),
|
||||
Graphic::RasterCPU(raster) => raster.bounding_box(transform, include_stroke),
|
||||
Graphic::RasterGPU(raster) => raster.bounding_box(transform, include_stroke),
|
||||
Graphic::Graphic(list) => list.bounding_box(transform, include_stroke),
|
||||
Graphic::GraphicList(list) => list.bounding_box(transform, include_stroke),
|
||||
Graphic::Color(color) => color.bounding_box(transform, include_stroke),
|
||||
Graphic::Gradient(gradient) => gradient.bounding_box(transform, include_stroke),
|
||||
Graphic::Text(text) => text.bounding_box(transform, include_stroke),
|
||||
@@ -498,7 +498,7 @@ impl BoundingBox for Graphic<'_> {
|
||||
Graphic::Vector(vector) => vector.thumbnail_bounding_box(transform, include_stroke),
|
||||
Graphic::RasterCPU(raster) => raster.thumbnail_bounding_box(transform, include_stroke),
|
||||
Graphic::RasterGPU(raster) => raster.thumbnail_bounding_box(transform, include_stroke),
|
||||
Graphic::Graphic(graphic) => graphic.thumbnail_bounding_box(transform, include_stroke),
|
||||
Graphic::GraphicList(graphic) => graphic.thumbnail_bounding_box(transform, include_stroke),
|
||||
Graphic::Color(color) => color.thumbnail_bounding_box(transform, include_stroke),
|
||||
Graphic::Gradient(gradient) => gradient.thumbnail_bounding_box(transform, include_stroke),
|
||||
Graphic::Text(list) => list.thumbnail_bounding_box(transform, include_stroke),
|
||||
@@ -527,7 +527,7 @@ impl RenderComplexity for Graphic<'_> {
|
||||
fn render_complexity(&self) -> usize {
|
||||
match self {
|
||||
Self::None => 0,
|
||||
Self::Graphic(list) => list.render_complexity(),
|
||||
Self::GraphicList(list) => list.render_complexity(),
|
||||
Self::Vector(list) => list.render_complexity(),
|
||||
Self::RasterCPU(list) => list.render_complexity(),
|
||||
Self::RasterGPU(list) => list.render_complexity(),
|
||||
@@ -676,7 +676,7 @@ mod tests {
|
||||
let flattened: List<Vector> = graphics.into_flattened_list();
|
||||
assert_eq!(flattened.attribute_cloned_or_default::<f64>(ATTR_OPACITY, 0), 0.5);
|
||||
|
||||
let mut group = List::new_from_element(Graphic::Graphic(List::new_from_element(vector_graphic())));
|
||||
let mut group = List::new_from_element(Graphic::GraphicList(List::new_from_element(vector_graphic())));
|
||||
group.set_attribute(ATTR_OPACITY, 0, 0.5_f64);
|
||||
let flattened: List<Vector> = group.into_flattened_list();
|
||||
assert_eq!(flattened.attribute_cloned_or_default::<f64>(ATTR_OPACITY, 0), 0.5);
|
||||
@@ -695,7 +695,7 @@ mod tests {
|
||||
inner.push(Item::new_from_element(vector_graphic()));
|
||||
inner.set_attribute(ATTR_APPEARANCE, 0, single(Color::BLACK));
|
||||
|
||||
let mut outer = List::new_from_element(Graphic::Graphic(inner));
|
||||
let mut outer = List::new_from_element(Graphic::GraphicList(inner));
|
||||
outer.set_attribute(ATTR_APPEARANCE, 0, single(Color::WHITE));
|
||||
|
||||
let flattened: List<Vector> = outer.into_flattened_list();
|
||||
|
||||
@@ -90,7 +90,7 @@ impl<'a> PaintReach<'a> {
|
||||
/// cell of any other form is treated as paint that draws nothing.
|
||||
pub fn paint_cell_rows<'a>(cell: &'a Graphic<'static>) -> Option<&'a List<Graphic<'static>>> {
|
||||
match cell {
|
||||
Graphic::Graphic(list) => Some(list).filter(|list| is_paint_present(list)),
|
||||
Graphic::GraphicList(list) => Some(list).filter(|list| is_paint_present(list)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
@@ -103,7 +103,7 @@ pub fn bake_paint_transforms(attributes: &mut ItemAttributeValues, transform: DA
|
||||
*item_transform = transform * *item_transform;
|
||||
}
|
||||
for graphic in graphics.iter_element_values_mut() {
|
||||
if let Graphic::Graphic(list) = graphic {
|
||||
if let Graphic::GraphicList(list) = graphic {
|
||||
bake_graphic_paint_transform(list, transform);
|
||||
}
|
||||
}
|
||||
@@ -113,7 +113,7 @@ pub fn bake_paint_transforms(attributes: &mut ItemAttributeValues, transform: DA
|
||||
&& let Some(cells) = appearance.0.iter_attribute_values_mut::<Graphic>(crate::markers::ATTR_PAINT)
|
||||
{
|
||||
for cell in cells {
|
||||
if let Graphic::Graphic(list) = cell {
|
||||
if let Graphic::GraphicList(list) = cell {
|
||||
bake_graphic_paint_transform(list, transform);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -399,7 +399,7 @@ fn walk_vector_rows_impl<'a>(
|
||||
appearance: reach.appearance,
|
||||
top_lane: row_top,
|
||||
}),
|
||||
Graphic::Graphic(children) => walk_vector_rows_impl(
|
||||
Graphic::GraphicList(children) => walk_vector_rows_impl(
|
||||
GraphicLevel::Legacy(children),
|
||||
scale.composed(&level, index),
|
||||
level.try_attr::<EditorLayerPath>(index),
|
||||
@@ -496,11 +496,11 @@ mod run_tests {
|
||||
let deep = List::new_from_element(Graphic::Vector(unit_square_at(DVec2::new(3., 3.))));
|
||||
let mut mixed = List::new();
|
||||
mixed.push(Item::new_from_element(Graphic::Vector(unit_square_at(DVec2::ZERO))));
|
||||
mixed.push(Item::new_from_element(Graphic::Graphic(deep)));
|
||||
mixed.push(Item::new_from_element(Graphic::GraphicList(deep)));
|
||||
|
||||
let mut top = List::new();
|
||||
top.push(Item::new_from_element(Graphic::Vector(unit_square_at(DVec2::new(9., 9.)))));
|
||||
top.push(Item::new_from_element(Graphic::Graphic(mixed)));
|
||||
top.push(Item::new_from_element(Graphic::GraphicList(mixed)));
|
||||
|
||||
let mut reported = Vec::new();
|
||||
walk_vector_rows(GraphicLevel::Legacy(&top), &mut |row| {
|
||||
@@ -537,8 +537,8 @@ mod run_tests {
|
||||
nested.set_attribute(core_types::ATTR_TRANSFORM, 0, DAffine2::from_scale(DVec2::splat(2.)));
|
||||
|
||||
let mut top = List::new();
|
||||
top.push(Item::new_from_element(Graphic::Graphic(painted)));
|
||||
top.push(Item::new_from_element(Graphic::Graphic(nested)));
|
||||
top.push(Item::new_from_element(Graphic::GraphicList(painted)));
|
||||
top.push(Item::new_from_element(Graphic::GraphicList(nested)));
|
||||
top.push(Item::new_from_element(Graphic::Group(core_types::record::Group { row: None, content: inner_item })));
|
||||
top.push(Item::new_from_element(Graphic::Color(Color::BLACK)));
|
||||
top.push(Item::new_from_element(Graphic::Vector(unit_square_at(DVec2::new(6., 0.)))));
|
||||
@@ -621,7 +621,7 @@ mod run_tests {
|
||||
inner.push(Item::new_from_element(Graphic::Vector(unit_square_at(DVec2::ONE))));
|
||||
inner.set_attribute(ATTR_APPEARANCE, 0, single(Color::BLACK));
|
||||
|
||||
let mut top = List::new_from_element(Graphic::Graphic(inner));
|
||||
let mut top = List::new_from_element(Graphic::GraphicList(inner));
|
||||
top.set_attribute(ATTR_APPEARANCE, 0, single(Color::WHITE));
|
||||
|
||||
let walked = flatten_vector_rows(GraphicLevel::Legacy(&top));
|
||||
|
||||
@@ -271,7 +271,7 @@ impl RenderExt for List<Graphic<'_>> {
|
||||
format!(r##" {paint_attr}="url(#{gradient_id})""##)
|
||||
}
|
||||
Some(Graphic::None) => format!(r#" {paint_attr}="none""#),
|
||||
Some(Graphic::Vector(_)) | Some(Graphic::RasterCPU(_)) | Some(Graphic::RasterGPU(_)) | Some(Graphic::Graphic(_)) | Some(Graphic::Text(_)) | Some(Graphic::Group(_)) => {
|
||||
Some(Graphic::Vector(_)) | Some(Graphic::RasterCPU(_)) | Some(Graphic::RasterGPU(_)) | Some(Graphic::GraphicList(_)) | Some(Graphic::Text(_)) | Some(Graphic::Group(_)) => {
|
||||
let bounds = if target == PaintTarget::Stroke {
|
||||
// To prevent a wraparound artefact occurring when the tile boundary and the stroke region are perfectly aligned, the local coordinate is expanded slightly.
|
||||
let inverse = |len: f64| if len > 0. { 1. / len } else { 0. };
|
||||
|
||||
@@ -210,7 +210,7 @@ pub struct RenderContext {
|
||||
|
||||
/// The single black-fill appearance a mask clone paints with, at full alpha so the mask fully covers the interior.
|
||||
fn black_fill_appearance() -> Appearance {
|
||||
Appearance::new_single(Coverage::new_fill(), Graphic::Graphic(List::new_from_element(Graphic::Color(Color::BLACK))))
|
||||
Appearance::new_single(Coverage::new_fill(), Graphic::GraphicList(List::new_from_element(Graphic::Color(Color::BLACK))))
|
||||
}
|
||||
|
||||
/// The alpha multiplier a paint row's opacity attributes apply when it serves as a paint.
|
||||
@@ -737,7 +737,7 @@ impl Render for Graphic<'_> {
|
||||
fn render_svg(&self, render: &mut SvgRender, render_params: &RenderParams) {
|
||||
match self {
|
||||
Graphic::None => (),
|
||||
Graphic::Graphic(list) => list.render_svg(render, render_params),
|
||||
Graphic::GraphicList(list) => list.render_svg(render, render_params),
|
||||
Graphic::Vector(vector) => render_vector_svg(&Single(vector), None, render, render_params),
|
||||
Graphic::RasterCPU(raster) => render_raster_cpu_svg(&Single(raster), render, render_params),
|
||||
Graphic::RasterGPU(_) => (),
|
||||
@@ -751,7 +751,7 @@ impl Render for Graphic<'_> {
|
||||
fn render_to_vello(&self, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext, render_params: &RenderParams) {
|
||||
match self {
|
||||
Graphic::None => (),
|
||||
Graphic::Graphic(list) => list.render_to_vello(scene, transform, context, render_params),
|
||||
Graphic::GraphicList(list) => list.render_to_vello(scene, transform, context, render_params),
|
||||
Graphic::Vector(vector) => render_vector_vello(&Single(vector), None, scene, transform, context, render_params),
|
||||
Graphic::RasterCPU(raster) => render_raster_cpu_vello(&Single(raster), scene, transform, render_params),
|
||||
Graphic::RasterGPU(raster) => render_raster_gpu_vello(&Single(raster), scene, transform, context, render_params),
|
||||
@@ -777,7 +777,7 @@ impl Render for Graphic<'_> {
|
||||
fn contains_artboard(&self) -> bool {
|
||||
match self {
|
||||
Graphic::None => false,
|
||||
Graphic::Graphic(list) => list.contains_artboard(),
|
||||
Graphic::GraphicList(list) => list.contains_artboard(),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
@@ -785,7 +785,7 @@ impl Render for Graphic<'_> {
|
||||
fn new_ids_from_hash(&mut self, reference: Option<NodeId>) {
|
||||
match self {
|
||||
Graphic::None => (),
|
||||
Graphic::Graphic(list) => list.new_ids_from_hash(reference),
|
||||
Graphic::GraphicList(list) => list.new_ids_from_hash(reference),
|
||||
Graphic::Vector(vector) => vector.vector_new_ids_from_hash(reference.map(|id| id.0).unwrap_or_default()),
|
||||
_ => (),
|
||||
}
|
||||
@@ -795,7 +795,7 @@ impl Render for Graphic<'_> {
|
||||
fn render_element_svg<'a>(element: &'a Graphic, reach: PaintReach<'a>, render: &mut SvgRender, render_params: &RenderParams) {
|
||||
match element {
|
||||
Graphic::Vector(vector) => render_vector_svg(&Single(vector), reach.appearance, render, render_params),
|
||||
Graphic::Graphic(inner) => render_graphic_svg_with(inner, reach, render, render_params),
|
||||
Graphic::GraphicList(inner) => render_graphic_svg_with(inner, reach, render, render_params),
|
||||
Graphic::Group(group) => render_group_svg(group, reach, render, render_params),
|
||||
_ => element.render_svg(render, render_params),
|
||||
}
|
||||
@@ -804,7 +804,7 @@ fn render_element_svg<'a>(element: &'a Graphic, reach: PaintReach<'a>, render: &
|
||||
fn render_element_vello<'a>(element: &'a Graphic, reach: PaintReach<'a>, scene: &mut Scene, transform: DAffine2, context: &mut RenderContext, render_params: &RenderParams) {
|
||||
match element {
|
||||
Graphic::Vector(vector) => render_vector_vello(&Single(vector), reach.appearance, scene, transform, context, render_params),
|
||||
Graphic::Graphic(inner) => render_graphic_vello_with(inner, reach, scene, transform, context, render_params),
|
||||
Graphic::GraphicList(inner) => render_graphic_vello_with(inner, reach, scene, transform, context, render_params),
|
||||
Graphic::Group(group) => render_group_vello(group, reach, scene, transform, context, render_params),
|
||||
_ => element.render_to_vello(scene, transform, context, render_params),
|
||||
}
|
||||
@@ -834,7 +834,7 @@ fn collect_element_metadata<'a>(
|
||||
metadata.upstream_footprints.insert(element_id, footprint);
|
||||
match element {
|
||||
Graphic::Group(group) => collect_group_row_metadata(group, metadata, element_id),
|
||||
Graphic::Graphic(_) => {}
|
||||
Graphic::GraphicList(_) => {}
|
||||
// A leaf's layer identity and transform ride its containing lane.
|
||||
Graphic::Vector(_) => {
|
||||
metadata.first_element_source_id.insert(element_id, lane_source);
|
||||
@@ -848,7 +848,7 @@ fn collect_element_metadata<'a>(
|
||||
|
||||
match element {
|
||||
Graphic::None => {}
|
||||
Graphic::Graphic(list) => collect_graphic_metadata_with(list, reach, metadata, footprint, element_id),
|
||||
Graphic::GraphicList(list) => collect_graphic_metadata_with(list, reach, metadata, footprint, element_id),
|
||||
Graphic::Vector(vector) => collect_vector_metadata(&Single(vector), reach.appearance, metadata, footprint, element_id),
|
||||
Graphic::RasterCPU(raster) => collect_raster_metadata(&Single(raster), metadata, footprint, element_id),
|
||||
Graphic::RasterGPU(raster) => collect_raster_metadata(&Single(raster), metadata, footprint, element_id),
|
||||
@@ -891,7 +891,7 @@ fn collect_group_row_metadata(group: &Group, metadata: &mut RenderMetadata, elem
|
||||
fn add_element_upstream_click_targets<'a>(element: &'a Graphic, reach: PaintReach<'a>, click_targets: &mut Vec<ClickTarget>) {
|
||||
match element {
|
||||
Graphic::None => (),
|
||||
Graphic::Graphic(list) => add_graphic_upstream_click_targets_with(list, reach, click_targets),
|
||||
Graphic::GraphicList(list) => add_graphic_upstream_click_targets_with(list, reach, click_targets),
|
||||
Graphic::Vector(vector) => add_vector_upstream_click_targets(&Single(vector), reach.appearance, click_targets),
|
||||
Graphic::RasterCPU(_) | Graphic::RasterGPU(_) => add_raster_upstream_click_targets(click_targets),
|
||||
Graphic::Color(_) => {}
|
||||
@@ -904,7 +904,7 @@ fn add_element_upstream_click_targets<'a>(element: &'a Graphic, reach: PaintReac
|
||||
fn add_element_upstream_outline_targets<'a>(element: &'a Graphic, reach: PaintReach<'a>, outlines: &mut Vec<ClickTarget>) {
|
||||
match element {
|
||||
Graphic::None => (),
|
||||
Graphic::Graphic(list) => add_graphic_upstream_outline_targets_with(list, reach, outlines),
|
||||
Graphic::GraphicList(list) => add_graphic_upstream_outline_targets_with(list, reach, outlines),
|
||||
Graphic::Vector(vector) => add_vector_upstream_outline_targets(&Single(vector), reach.appearance, outlines),
|
||||
Graphic::RasterCPU(_) | Graphic::RasterGPU(_) => add_raster_upstream_click_targets(outlines),
|
||||
Graphic::Color(_) => {}
|
||||
@@ -1856,7 +1856,7 @@ fn render_vector_item_vello<S: LaneSource<Element = Vector>>(
|
||||
let brush_transform = kurbo::Affine::new((inverse_element_transform * gradient_to_device).to_cols_array());
|
||||
scene.fill(fill_rule, kurbo::Affine::new(element_transform.to_cols_array()), &brush, Some(brush_transform), path);
|
||||
}
|
||||
Graphic::Vector(_) | Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::Graphic(_) | Graphic::Text(_) | Graphic::Group(_) => {
|
||||
Graphic::Vector(_) | Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::GraphicList(_) | Graphic::Text(_) | Graphic::Group(_) => {
|
||||
scene.push_clip_layer(fill_rule, kurbo::Affine::new(element_transform.to_cols_array()), path);
|
||||
paint.render_to_vello(scene, multiplied_transform, context, render_params);
|
||||
scene.pop_layer();
|
||||
@@ -1941,7 +1941,7 @@ fn render_vector_item_vello<S: LaneSource<Element = Vector>>(
|
||||
|
||||
scene.stroke(&stroke, kurbo::Affine::new(element_transform.to_cols_array()), &brush, Some(brush_transform), &path);
|
||||
}
|
||||
Graphic::Vector(_) | Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::Graphic(_) | Graphic::Text(_) | Graphic::Group(_) => {
|
||||
Graphic::Vector(_) | Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::GraphicList(_) | Graphic::Text(_) | Graphic::Group(_) => {
|
||||
let stroked = peniko::kurbo::stroke(path.iter(), &stroke, &StrokeOpts::default(), 0.01);
|
||||
|
||||
scene.push_clip_layer(peniko::Fill::NonZero, kurbo::Affine::new(element_transform.to_cols_array()), &stroked);
|
||||
@@ -3015,7 +3015,7 @@ pub fn graphic_list_bounding_box<'e, S: LaneSource<Element = Graphic<'e>>>(sourc
|
||||
let Some(graphic) = source.element(index) else { continue };
|
||||
let bounds = match graphic {
|
||||
Graphic::Text(text) => text_list_bounding_box(&Single(text), item_transform),
|
||||
Graphic::Graphic(sub_list) => graphic_list_bounding_box(sub_list, item_transform),
|
||||
Graphic::GraphicList(sub_list) => graphic_list_bounding_box(sub_list, item_transform),
|
||||
other => other.thumbnail_bounding_box(item_transform, true),
|
||||
};
|
||||
match bounds {
|
||||
@@ -3462,7 +3462,7 @@ mod group_walk_tests {
|
||||
|
||||
/// The appearance the fill node stamps, so test content mirrors node output.
|
||||
fn fill_appearance(paint: &List<Graphic<'static>>) -> Appearance {
|
||||
Appearance::new_single(Coverage::new_fill(), Graphic::Graphic(paint.clone()))
|
||||
Appearance::new_single(Coverage::new_fill(), Graphic::GraphicList(paint.clone()))
|
||||
}
|
||||
|
||||
fn rendered_svg(render: impl FnOnce(&mut SvgRender)) -> (String, String) {
|
||||
@@ -3506,7 +3506,7 @@ mod group_walk_tests {
|
||||
|
||||
let params = RenderParams::default();
|
||||
let native = rendered_svg(|render| Graphic::Group(group.clone()).render_svg(render, ¶ms));
|
||||
let legacy = rendered_svg(|render| Graphic::Graphic(graphic_types::graphic::group_to_legacy_list(&group)).render_svg(render, ¶ms));
|
||||
let legacy = rendered_svg(|render| Graphic::GraphicList(graphic_types::graphic::group_to_legacy_list(&group)).render_svg(render, ¶ms));
|
||||
|
||||
assert!(native.0.contains(r##"fill="#"##), "the lane's fill paint must reach the vector interior: {}", native.0);
|
||||
assert_eq!(native, legacy);
|
||||
|
||||
@@ -26,7 +26,7 @@ pub enum GradientForm {
|
||||
/// attributes place each stop along the 0 to 1 range. Stops lacking the `position` attribute distribute evenly,
|
||||
/// and stops lacking the `midpoint` attribute interpolate linearly (`0.5`).
|
||||
#[derive(Default, Debug, Clone, PartialEq, graphene_hash::CacheHash, DynAny)]
|
||||
pub struct Gradient(List<Color>);
|
||||
pub struct Gradient(pub List<Color>);
|
||||
|
||||
/// A gradient's per-stop parallel arrays, generic over color format: `GradientStops<Color>` nests inside the
|
||||
/// [`GradientRamp`] exchange struct, while `GradientStops<SRGBA8>` is the JS-boundary shape used by the color picker UI.
|
||||
|
||||
Reference in New Issue
Block a user