#[cfg(feature = "std")]
mod closure;
use super::variations::{DeltaSetIndexMap, ItemVariationStore};
include!("../../generated/generated_colr.rs");
pub type PaintId = usize;
impl<'a> Colr<'a> {
pub fn v0_base_glyph(&self, glyph_id: GlyphId) -> Result<Option<Range<usize>>, ReadError> {
let records = self.base_glyph_records().ok_or(ReadError::NullOffset)??;
let Ok(glyph_id) = glyph_id.try_into() else {
return Ok(None);
};
let record = match records.binary_search_by(|rec| rec.glyph_id().cmp(&glyph_id)) {
Ok(ix) => &records[ix],
_ => return Ok(None),
};
let start = record.first_layer_index() as usize;
let end = start + record.num_layers() as usize;
Ok(Some(start..end))
}
pub fn v0_layer(&self, index: usize) -> Result<(GlyphId16, u16), ReadError> {
let layers = self.layer_records().ok_or(ReadError::NullOffset)??;
let layer = layers.get(index).ok_or(ReadError::OutOfBounds)?;
Ok((layer.glyph_id(), layer.palette_index()))
}
pub fn v1_base_glyph(
&self,
glyph_id: GlyphId,
) -> Result<Option<(Paint<'a>, PaintId)>, ReadError> {
let Ok(glyph_id) = glyph_id.try_into() else {
return Ok(None);
};
let list = self.base_glyph_list().ok_or(ReadError::NullOffset)??;
let records = list.base_glyph_paint_records();
let record = match records.binary_search_by(|rec| rec.glyph_id().cmp(&glyph_id)) {
Ok(ix) => &records[ix],
_ => return Ok(None),
};
let offset_data = list.offset_data();
let id = record.paint_offset().to_u32() as usize + offset_data.as_ref().as_ptr() as usize;
Ok(Some((record.paint(offset_data)?, id)))
}
pub fn v1_layer(&self, index: usize) -> Result<(Paint<'a>, PaintId), ReadError> {
let list = self.layer_list().ok_or(ReadError::NullOffset)??;
let offset = list
.paint_offsets()
.get(index)
.ok_or(ReadError::OutOfBounds)?
.get();
let offset_data = list.offset_data();
let id = offset.to_u32() as usize + offset_data.as_ref().as_ptr() as usize;
Ok((offset.resolve(offset_data)?, id))
}
pub fn v1_clip_box(&self, glyph_id: GlyphId) -> Result<Option<ClipBox<'a>>, ReadError> {
use core::cmp::Ordering;
let Ok(glyph_id): Result<GlyphId16, _> = glyph_id.try_into() else {
return Ok(None);
};
let list = self.clip_list().ok_or(ReadError::NullOffset)??;
let clips = list.clips();
let clip = match clips.binary_search_by(|clip| {
if glyph_id < clip.start_glyph_id() {
Ordering::Greater
} else if glyph_id > clip.end_glyph_id() {
Ordering::Less
} else {
Ordering::Equal
}
}) {
Ok(ix) => &clips[ix],
_ => return Ok(None),
};
Ok(Some(clip.clip_box(list.offset_data())?))
}
}