use crate::cff::cid_font::CIDMetadata;
use crate::cff::dict::operators::*;
use crate::cff::dict::DictionaryParser;
use crate::cff::number::Number;
use crate::cff::remapper::FontDictRemapper;
use crate::cff::Offsets;
use crate::write::Writer;
use crate::Error::{MalformedFont, SubsetError};
use crate::Result;
use std::array;
pub fn parse_subr_offset(data: &[u8]) -> Option<usize> {
let mut operands_buffer: [Number; 48] = array::from_fn(|_| Number::zero());
let mut dict_parser = DictionaryParser::new(data, &mut operands_buffer);
while let Some(operator) = dict_parser.parse_next() {
if operator == SUBRS {
return dict_parser.parse_offset();
}
}
None
}
pub fn rewrite_cid_private_dicts(
fd_remapper: &FontDictRemapper,
offsets: &mut Offsets,
metadata: &CIDMetadata,
w: &mut Writer,
) -> Result<()> {
for (new_df, old_df) in fd_remapper.sorted_iter().enumerate() {
let font_dict = metadata.font_dicts.get(old_df as usize).ok_or(SubsetError)?;
rewrite_private_dict(offsets, font_dict.private_dict, w, new_df)?;
}
Ok(())
}
pub(crate) fn rewrite_private_dict(
offsets: &mut Offsets,
private_dict_data: &[u8],
w: &mut Writer,
dict_index: usize,
) -> Result<()> {
let private_dict_offset = w.len();
let private_dict_data = {
let mut operands_buffer: [Number; 48] = array::from_fn(|_| Number::zero());
let mut dict_parser =
DictionaryParser::new(private_dict_data, &mut operands_buffer);
let mut sub_w = Writer::new();
while let Some(operator) = dict_parser.parse_next() {
match operator {
SUBRS => {
}
_ => {
dict_parser.parse_operands().ok_or(MalformedFont)?;
let operands = dict_parser.operands();
sub_w.write(operands);
sub_w.write(operator);
}
}
}
sub_w.finish()
};
let private_dict_len = private_dict_data.len();
offsets
.private_dicts_lens
.get_mut(dict_index)
.ok_or(SubsetError)?
.update_value(private_dict_len)?;
offsets
.private_dicts_offsets
.get_mut(dict_index)
.ok_or(SubsetError)?
.update_value(private_dict_offset)?;
w.extend(&private_dict_data);
Ok(())
}