mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-21 22:08:12 +08:00
Collect a group element as its typed lowering
This commit is contained in:
@@ -701,8 +701,9 @@ fn element_can_reduce_to_clip_path<'a>(element: &'a Graphic, reach: PaintReach<'
|
|||||||
fn collect_element_metadata<'a>(element: &'a Graphic, reach: PaintReach<'a>, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
fn collect_element_metadata<'a>(element: &'a Graphic, reach: PaintReach<'a>, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
||||||
if let Some(element_id) = element_id {
|
if let Some(element_id) = element_id {
|
||||||
match element {
|
match element {
|
||||||
Graphic::Group(_) => {
|
Graphic::Group(group) => {
|
||||||
metadata.upstream_footprints.insert(element_id, footprint);
|
metadata.upstream_footprints.insert(element_id, footprint);
|
||||||
|
collect_group_row_metadata(group, metadata, element_id);
|
||||||
}
|
}
|
||||||
Graphic::Graphic(_) => {
|
Graphic::Graphic(_) => {
|
||||||
metadata.upstream_footprints.insert(element_id, footprint);
|
metadata.upstream_footprints.insert(element_id, footprint);
|
||||||
@@ -775,6 +776,35 @@ fn collect_element_metadata<'a>(element: &'a Graphic, reach: PaintReach<'a>, met
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The id-level metadata the legacy lowering exposed for a group element: a
|
||||||
|
/// bare typed run serves its lane-0 transform (and source id for vectors) as
|
||||||
|
/// the layer's local transform, matching the typed list the conversion made.
|
||||||
|
fn collect_group_row_metadata(group: &Group, metadata: &mut RenderMetadata, element_id: NodeId) {
|
||||||
|
fn lane_zero_transform<T: 'static>(item: &core_types::record::GroupItem) -> Option<DAffine2> {
|
||||||
|
RunView::<T>::new(item).map(|run| run.attr::<Transform>(0))
|
||||||
|
}
|
||||||
|
|
||||||
|
let GroupContent::Run(item) = &group.content else { return };
|
||||||
|
if group.row.is_some() || item.is_empty() || item.typed_lanes::<Graphic>().is_some() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if let Some(run) = RunView::<Vector>::new(item) {
|
||||||
|
let layer_path: &[NodeId] = run.attr::<EditorLayerPath>(0);
|
||||||
|
metadata.first_element_source_id.insert(element_id, layer_path.last().copied());
|
||||||
|
metadata.local_transforms.insert(element_id, run.attr::<Transform>(0));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let transform = None
|
||||||
|
.or_else(|| lane_zero_transform::<Raster<CPU>>(item))
|
||||||
|
.or_else(|| lane_zero_transform::<Raster<GPU>>(item))
|
||||||
|
.or_else(|| lane_zero_transform::<Color>(item))
|
||||||
|
.or_else(|| lane_zero_transform::<GradientStops>(item))
|
||||||
|
.or_else(|| lane_zero_transform::<String>(item));
|
||||||
|
if let Some(transform) = transform {
|
||||||
|
metadata.local_transforms.insert(element_id, transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn add_element_upstream_click_targets<'a>(element: &'a Graphic, reach: PaintReach<'a>, click_targets: &mut Vec<ClickTarget>) {
|
fn add_element_upstream_click_targets<'a>(element: &'a Graphic, reach: PaintReach<'a>, click_targets: &mut Vec<ClickTarget>) {
|
||||||
match element {
|
match element {
|
||||||
Graphic::Graphic(list) => add_graphic_upstream_click_targets_with(list, reach.nested(), click_targets),
|
Graphic::Graphic(list) => add_graphic_upstream_click_targets_with(list, reach.nested(), click_targets),
|
||||||
@@ -853,29 +883,10 @@ fn render_group_vello<'a>(group: &'a Group, reach: PaintReach<'a>, scene: &mut S
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reproduces the legacy wrapper's metadata effects for a typed run: the
|
/// Collects a group as its legacy lowering did: a typed run behaves as the
|
||||||
/// lanes collect with their own recovered ids, and the caller's element id
|
/// typed variant the conversion produced, so a caller's element id passes
|
||||||
/// aggregates the run's upstream click targets and outlines.
|
/// through to the typed body unchanged.
|
||||||
fn collect_group_metadata<'a>(group: &'a Group, reach: PaintReach<'a>, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
fn collect_group_metadata<'a>(group: &'a Group, reach: PaintReach<'a>, metadata: &mut RenderMetadata, footprint: Footprint, element_id: Option<NodeId>) {
|
||||||
fn typed_run<S: LaneSource>(
|
|
||||||
source: &S,
|
|
||||||
metadata: &mut RenderMetadata,
|
|
||||||
footprint: Footprint,
|
|
||||||
element_id: Option<NodeId>,
|
|
||||||
collect: impl Fn(&S, &mut RenderMetadata, Footprint, Option<NodeId>),
|
|
||||||
click: impl Fn(&S, &mut Vec<ClickTarget>),
|
|
||||||
outline: impl Fn(&S, &mut Vec<ClickTarget>),
|
|
||||||
) {
|
|
||||||
collect(source, metadata, footprint, None);
|
|
||||||
let Some(element_id) = element_id else { return };
|
|
||||||
let mut click_targets = Vec::new();
|
|
||||||
click(source, &mut click_targets);
|
|
||||||
metadata.click_targets.insert(element_id, click_targets.into_iter().map(Into::into).collect());
|
|
||||||
let mut outlines = Vec::new();
|
|
||||||
outline(source, &mut outlines);
|
|
||||||
metadata.outlines.insert(element_id, outlines.into_iter().map(Into::into).collect());
|
|
||||||
}
|
|
||||||
|
|
||||||
let GroupContent::Run(item) = &group.content else {
|
let GroupContent::Run(item) = &group.content else {
|
||||||
return group_to_legacy_list(group).collect_metadata(metadata, footprint, element_id);
|
return group_to_legacy_list(group).collect_metadata(metadata, footprint, element_id);
|
||||||
};
|
};
|
||||||
@@ -883,31 +894,16 @@ fn collect_group_metadata<'a>(group: &'a Group, reach: PaintReach<'a>, metadata:
|
|||||||
collect_graphic_metadata_with(&run, reach.into_group_graphics(), metadata, footprint, element_id)
|
collect_graphic_metadata_with(&run, reach.into_group_graphics(), metadata, footprint, element_id)
|
||||||
} else if let Some(run) = RunView::<Vector>::new(item) {
|
} else if let Some(run) = RunView::<Vector>::new(item) {
|
||||||
match reach.applies() {
|
match reach.applies() {
|
||||||
true => typed_run(
|
true => collect_vector_metadata(&PaintOverlay::new(&run, reach.paint), metadata, footprint, element_id),
|
||||||
&PaintOverlay::new(&run, reach.paint),
|
false => collect_vector_metadata(&run, metadata, footprint, element_id),
|
||||||
metadata,
|
|
||||||
footprint,
|
|
||||||
element_id,
|
|
||||||
collect_vector_metadata,
|
|
||||||
add_vector_upstream_click_targets,
|
|
||||||
add_vector_upstream_outline_targets,
|
|
||||||
),
|
|
||||||
false => typed_run(&run, metadata, footprint, element_id, collect_vector_metadata, add_vector_upstream_click_targets, add_vector_upstream_outline_targets),
|
|
||||||
}
|
}
|
||||||
} else if let Some(run) = RunView::<Raster<CPU>>::new(item) {
|
} else if let Some(run) = RunView::<Raster<CPU>>::new(item) {
|
||||||
typed_run(&run, metadata, footprint, element_id, collect_raster_metadata, |_, out| add_raster_upstream_click_targets(out), |_, out| {
|
collect_raster_metadata(&run, metadata, footprint, element_id)
|
||||||
add_raster_upstream_click_targets(out)
|
|
||||||
})
|
|
||||||
} else if let Some(run) = RunView::<Raster<GPU>>::new(item) {
|
} else if let Some(run) = RunView::<Raster<GPU>>::new(item) {
|
||||||
typed_run(&run, metadata, footprint, element_id, collect_raster_metadata, |_, out| add_raster_upstream_click_targets(out), |_, out| {
|
collect_raster_metadata(&run, metadata, footprint, element_id)
|
||||||
add_raster_upstream_click_targets(out)
|
} else if item.typed_lanes::<Color>().is_some() || item.typed_lanes::<GradientStops>().is_some() {
|
||||||
})
|
|
||||||
} else if let Some(run) = RunView::<Color>::new(item) {
|
|
||||||
typed_run(&run, metadata, footprint, element_id, |_, _, _, _| (), |_, _| (), |_, _| ())
|
|
||||||
} else if let Some(run) = RunView::<GradientStops>::new(item) {
|
|
||||||
typed_run(&run, metadata, footprint, element_id, |_, _, _, _| (), |_, _| (), |_, _| ())
|
|
||||||
} else if let Some(run) = RunView::<String>::new(item) {
|
} else if let Some(run) = RunView::<String>::new(item) {
|
||||||
typed_run(&run, metadata, footprint, element_id, collect_text_metadata, add_text_upstream_click_targets, add_text_upstream_click_targets)
|
collect_text_metadata(&run, metadata, footprint, element_id)
|
||||||
} else {
|
} else {
|
||||||
group_to_legacy_list(group).collect_metadata(metadata, footprint, element_id)
|
group_to_legacy_list(group).collect_metadata(metadata, footprint, element_id)
|
||||||
}
|
}
|
||||||
@@ -3105,7 +3101,7 @@ mod group_walk_tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_group_collects_the_wrapper_metadata() {
|
fn a_group_collects_like_its_legacy_lowering() {
|
||||||
let paint = color_paint();
|
let paint = color_paint();
|
||||||
let vectors = [unit_square_at(DVec2::ZERO)];
|
let vectors = [unit_square_at(DVec2::ZERO)];
|
||||||
let layout = Layout::default().with_writes(0, element_write_hashed::<Vector>(), &[FieldWrite::of::<Fill>(0)]);
|
let layout = Layout::default().with_writes(0, element_write_hashed::<Vector>(), &[FieldWrite::of::<Fill>(0)]);
|
||||||
@@ -3122,15 +3118,15 @@ mod group_walk_tests {
|
|||||||
Graphic::Group(group.clone()).collect_metadata(&mut native, footprint, Some(caller));
|
Graphic::Group(group.clone()).collect_metadata(&mut native, footprint, Some(caller));
|
||||||
|
|
||||||
let mut legacy = RenderMetadata::default();
|
let mut legacy = RenderMetadata::default();
|
||||||
legacy.upstream_footprints.insert(caller, footprint);
|
group_to_legacy_graphic(&group).collect_metadata(&mut legacy, footprint, Some(caller));
|
||||||
graphic_types::graphic::group_to_legacy_list(&group).collect_metadata(&mut legacy, footprint, Some(caller));
|
|
||||||
|
|
||||||
assert!(native.click_targets.get(&caller).is_some_and(|targets| !targets.is_empty()));
|
assert!(native.click_targets.get(&caller).is_some_and(|targets| !targets.is_empty()));
|
||||||
|
assert!(native.local_transforms.contains_key(&caller));
|
||||||
assert_eq!(native, legacy);
|
assert_eq!(native, legacy);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn a_group_serves_the_wrapper_click_targets() {
|
fn a_group_serves_its_legacy_lowerings_click_targets() {
|
||||||
let paint = color_paint();
|
let paint = color_paint();
|
||||||
let vectors = [unit_square_at(DVec2::ZERO), unit_square_at(DVec2::new(2., 2.))];
|
let vectors = [unit_square_at(DVec2::ZERO), unit_square_at(DVec2::new(2., 2.))];
|
||||||
let layout = Layout::default().with_writes(0, element_write_hashed::<Vector>(), &[FieldWrite::of::<Fill>(0)]);
|
let layout = Layout::default().with_writes(0, element_write_hashed::<Vector>(), &[FieldWrite::of::<Fill>(0)]);
|
||||||
|
|||||||
Reference in New Issue
Block a user