mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-15 22:28:10 +08:00
Convert groups to their legacy list form
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use core_types::bounds::{BoundingBox, RenderBoundingBox};
|
||||
use core_types::graphene_hash::CacheHash;
|
||||
use core_types::list::{ATTR_FILL, ATTR_STROKE, ItemAttributeValues, List};
|
||||
use core_types::list::{ATTR_FILL, ATTR_STROKE, AttributeValueDyn, Item, ItemAttributeValues, List};
|
||||
use core_types::ops::{FromAnchorPosition, ListConvert};
|
||||
use core_types::render_complexity::RenderComplexity;
|
||||
use core_types::uuid::NodeId;
|
||||
@@ -671,6 +671,83 @@ fn group_bounding_box(group: &core_types::record::Group, transform: DAffine2, in
|
||||
}
|
||||
}
|
||||
|
||||
/// One typed run as a legacy list, elements cloned and every attribute
|
||||
/// copied through its erased read.
|
||||
fn run_to_legacy_list<T: Clone + Send + Sync + 'static>(item: &core_types::record::GroupItem) -> Option<List<T>> {
|
||||
let lanes = item.typed_lanes::<T>()?;
|
||||
let mut list = List::new();
|
||||
for lane in 0..lanes.len() {
|
||||
list.push(Item::new_from_element(lanes.element_ref(lane).clone()));
|
||||
}
|
||||
for field in &item.layout().fields {
|
||||
for lane in 0..lanes.len() {
|
||||
// SAFETY: the offset comes from the item's own layout.
|
||||
let value = unsafe { (field.read_erased)(item.lanes().get(lane).rec().ptr().add(field.offset)) };
|
||||
list.set_attribute_value_dyn(field.name, lane, AttributeValueDyn(value));
|
||||
}
|
||||
}
|
||||
Some(list)
|
||||
}
|
||||
|
||||
/// The graphic with every `Group` converted to its legacy list form.
|
||||
pub fn map_groups_to_legacy(graphic: &Graphic) -> Graphic {
|
||||
match graphic {
|
||||
Graphic::Group(group) => Graphic::Graphic(group_to_legacy_list(group)),
|
||||
Graphic::Graphic(children) => {
|
||||
let mut children = children.clone();
|
||||
for child in children.iter_element_values_mut() {
|
||||
*child = map_groups_to_legacy(child);
|
||||
}
|
||||
Graphic::Graphic(children)
|
||||
}
|
||||
other => other.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// The group as a legacy `List<Graphic>`: a `Graphic` run becomes the items,
|
||||
/// another typed run becomes one item holding its typed list, and stack
|
||||
/// segments become one item each with the segment's row attributes.
|
||||
pub fn group_to_legacy_list(group: &core_types::record::Group) -> List<Graphic> {
|
||||
match &group.content {
|
||||
core_types::record::GroupContent::Run(item) => {
|
||||
if let Some(mut list) = run_to_legacy_list::<Graphic>(item) {
|
||||
for element in list.iter_element_values_mut() {
|
||||
*element = map_groups_to_legacy(element);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
let element = None
|
||||
.or_else(|| run_to_legacy_list::<Vector>(item).map(Graphic::Vector))
|
||||
.or_else(|| run_to_legacy_list::<Raster<CPU>>(item).map(Graphic::RasterCPU))
|
||||
.or_else(|| run_to_legacy_list::<Raster<GPU>>(item).map(Graphic::RasterGPU))
|
||||
.or_else(|| run_to_legacy_list::<Color>(item).map(Graphic::Color))
|
||||
.or_else(|| run_to_legacy_list::<GradientStops>(item).map(Graphic::Gradient))
|
||||
.or_else(|| run_to_legacy_list::<String>(item).map(Graphic::Text));
|
||||
match element {
|
||||
Some(element) => List::new_from_element(element),
|
||||
None => List::new(),
|
||||
}
|
||||
}
|
||||
core_types::record::GroupContent::Stack(children) => {
|
||||
let mut list = List::new();
|
||||
for child in children {
|
||||
list.push(Item::new_from_element(Graphic::Graphic(group_to_legacy_list(child))));
|
||||
let index = list.len() - 1;
|
||||
if let Some(row) = &child.row {
|
||||
if !row.is_empty() {
|
||||
for field in &row.layout().fields {
|
||||
// SAFETY: the offset comes from the row's own layout.
|
||||
let value = unsafe { (field.read_erased)(row.lanes().get(0).rec().ptr().add(field.offset)) };
|
||||
list.set_attribute_value_dyn(field.name, index, AttributeValueDyn(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
list
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn group_render_complexity(group: &core_types::record::Group) -> usize {
|
||||
fn typed_run<T: 'static + RenderComplexity>(item: &core_types::record::GroupItem) -> Option<usize> {
|
||||
let lanes = item.typed_lanes::<T>()?;
|
||||
|
||||
Reference in New Issue
Block a user