use ifc_lite_core::EntityDecoder;
use rustc_hash::FxHashMap;
use crate::prepass::{collect_geometry_style_info, extract_style_info_from_styled_item, Span};
use crate::style::GeometryStyleInfo;
pub type StyleSeeds = (FxHashMap<u32, [f32; 4]>, FxHashMap<u32, GeometryStyleInfo>);
pub fn resolve_styled_items_into(
styled_items: &[Span],
decoder: &mut EntityDecoder,
defer_attached_styles: bool,
orphan_styled_items: &mut FxHashMap<u32, [f32; 4]>,
geometry_style_index: &mut FxHashMap<u32, GeometryStyleInfo>,
deferred_attached_styled_spans: &mut Vec<(usize, usize)>,
) {
for &(id, start, end) in styled_items {
let Ok(styled_item) = decoder.decode_at_with_id(id, start, end) else {
if defer_attached_styles {
deferred_attached_styled_spans.push((start, end));
}
continue;
};
if styled_item.get_ref(0).is_none() {
if let Some(info) = extract_style_info_from_styled_item(&styled_item, decoder) {
orphan_styled_items.insert(id, info.color);
}
} else if defer_attached_styles {
deferred_attached_styled_spans.push((start, end));
} else {
collect_geometry_style_info(geometry_style_index, &styled_item, decoder);
}
}
}
pub fn flat_styles_rgba8_from_geometry_columns(
geom_ids: &[u32],
geom_colors: &[f32],
resolved: &crate::prepass::ResolvedPrepass,
decoder: &mut EntityDecoder,
) -> (Vec<u32>, Vec<u8>) {
debug_assert!(resolved.geometry_style_index.is_empty());
let mut overlay: FxHashMap<u32, [f32; 4]> = FxHashMap::default();
for (&geometry_id, &color) in &resolved.indexed_colour_index {
overlay.entry(geometry_id).or_insert(color);
}
let material_styles = crate::style::build_material_style_index(
&resolved.material_def_reprs,
&resolved.orphan_styled_items,
decoder,
);
for (&mat_id, &color) in crate::style::flatten_material_color_index(&material_styles).iter() {
overlay.entry(mat_id).or_insert(color);
}
for (&element_id, colors) in &resolved.element_material_colors {
if let Some(&color) = colors.first() {
overlay.entry(element_id).or_insert(color);
}
}
let mut geom_order: Vec<u32> = (0..geom_ids.len() as u32).collect();
geom_order.sort_unstable_by_key(|&i| geom_ids[i as usize]);
let mut overlay_sorted: Vec<(u32, [f32; 4])> = overlay.into_iter().collect();
overlay_sorted.sort_unstable_by_key(|&(id, _)| id);
let mut ids: Vec<u32> = Vec::with_capacity(geom_ids.len() + overlay_sorted.len());
let mut rgba: Vec<u8> = Vec::with_capacity((geom_ids.len() + overlay_sorted.len()) * 4);
let push = |id: u32, color: [f32; 4], ids: &mut Vec<u32>, rgba: &mut Vec<u8>| {
ids.push(id);
rgba.extend_from_slice(&crate::style::Rgba::from_array(color).to_rgba8());
};
let mut oi = 0;
for &gi in &geom_order {
let id = geom_ids[gi as usize];
while oi < overlay_sorted.len() && overlay_sorted[oi].0 < id {
let (oid, oc) = overlay_sorted[oi];
push(oid, oc, &mut ids, &mut rgba);
oi += 1;
}
if oi < overlay_sorted.len() && overlay_sorted[oi].0 == id {
oi += 1; }
let c = gi as usize * 4;
push(
id,
[geom_colors[c], geom_colors[c + 1], geom_colors[c + 2], geom_colors[c + 3]],
&mut ids,
&mut rgba,
);
}
while oi < overlay_sorted.len() {
let (oid, oc) = overlay_sorted[oi];
push(oid, oc, &mut ids, &mut rgba);
oi += 1;
}
(ids, rgba)
}