mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-16 06:38:03 +08:00
Count assign colors lanes without legacy conversion and cache the offsets
This commit is contained in:
@@ -770,6 +770,20 @@ const _: () = {
|
||||
};
|
||||
|
||||
/// The graphic with every `Group` converted to its legacy form.
|
||||
/// The count [`map_groups_to_legacy`] would expose through [`Graphic::as_vector`],
|
||||
/// read from the run's lanes instead of materializing the legacy list. Mirrors
|
||||
/// [`group_to_legacy_graphic`]'s typed-run path, where `Vector` is tried first.
|
||||
pub fn direct_vector_len(graphic: &Graphic) -> usize {
|
||||
match graphic {
|
||||
Graphic::Vector(list) => list.len(),
|
||||
Graphic::Group(group) => match (&group.row, &group.content) {
|
||||
(None, core_types::record::GroupContent::Run(item)) => item.typed_lanes::<Vector>().map_or(0, |lanes| lanes.len()),
|
||||
_ => 0,
|
||||
},
|
||||
_ => 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_groups_to_legacy(graphic: &Graphic) -> Graphic {
|
||||
match graphic {
|
||||
Graphic::Group(group) => group_to_legacy_graphic(group),
|
||||
|
||||
@@ -163,8 +163,9 @@ fn assign_colors_extent(
|
||||
/// under the assign colors identifier.
|
||||
#[node_macro::node(category(""), extent(assign_colors_graphic_extent))]
|
||||
fn assign_colors_graphic<'e>(
|
||||
ctx: impl Ctx + ExtractArena<'e> + ExtractIndex + InjectIndex + Copy,
|
||||
ctx: impl Ctx + CacheHash + ExtractArena<'e> + ExtractIndex + InjectIndex + Copy,
|
||||
content: IList<Graphic>,
|
||||
#[data] lane_offsets: std::sync::Arc<std::sync::Mutex<Option<LaneOffsets>>>,
|
||||
#[default(true)] fill: bool,
|
||||
stroke: bool,
|
||||
gradient: IList<GradientStops>,
|
||||
@@ -195,9 +196,27 @@ fn assign_colors_graphic<'e>(
|
||||
|
||||
// The interiors the pre-flip node reached: only a lane's DIRECT vector
|
||||
// list, so wrapped groups keep their own styling and consume no position.
|
||||
let count_lane = |row: usize| graphic_types::graphic::map_groups_to_legacy(content.element_ref(row)).as_vector().map_or(0, |list| list.len());
|
||||
let length: usize = (0..content.len()).map(count_lane).sum();
|
||||
let mut position: usize = (0..lane).map(count_lane).sum();
|
||||
let key = {
|
||||
let mut keyed = *ctx;
|
||||
core_types::context::InjectIndex::set_index(&mut keyed, 0);
|
||||
core_types::registry::cache_key(&keyed)
|
||||
};
|
||||
let generation = ctx.arena().generation();
|
||||
let (length, mut position) = {
|
||||
let mut cached = lane_offsets.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
|
||||
if !matches!(cached.as_ref(), Some(entry) if entry.key == key && entry.generation == generation) {
|
||||
let mut offsets = Vec::with_capacity(content.len() + 1);
|
||||
let mut running = 0;
|
||||
offsets.push(running);
|
||||
for row in 0..content.len() {
|
||||
running += graphic_types::graphic::direct_vector_len(content.element_ref(row));
|
||||
offsets.push(running);
|
||||
}
|
||||
*cached = Some(LaneOffsets { key, generation, offsets });
|
||||
}
|
||||
let entry = cached.as_ref().expect("populated above");
|
||||
(entry.offsets[content.len()], entry.offsets[lane])
|
||||
};
|
||||
|
||||
if let Some(vector_list) = element.as_vector_mut() {
|
||||
for index in 0..vector_list.len() {
|
||||
@@ -218,6 +237,16 @@ fn assign_colors_graphic<'e>(
|
||||
Ok((element, transform, layer_path))
|
||||
}
|
||||
|
||||
/// Where each lane's colors start in the level's flattened vector run, so the
|
||||
/// level is counted once per evaluation rather than once per lane. `offsets`
|
||||
/// holds one entry per lane plus the total.
|
||||
#[derive(Debug)]
|
||||
pub struct LaneOffsets {
|
||||
key: u64,
|
||||
generation: u64,
|
||||
offsets: Vec<usize>,
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn assign_colors_graphic_extent(
|
||||
content: ListIn<'_, Graphic>,
|
||||
|
||||
Reference in New Issue
Block a user