1pub mod cff2;
7pub mod charstring;
8#[cfg(feature = "outline")]
9pub mod outline;
10mod subset;
11
12use std::convert::{TryFrom, TryInto};
13use std::io::Write;
14use std::iter;
15use std::marker::PhantomData;
16
17use byteorder::{BigEndian, ByteOrder};
18use itertools::Itertools;
19use lazy_static::lazy_static;
20use num_traits as num;
21use tinyvec::{array_vec, tiny_vec, TinyVec};
22
23use crate::binary::read::{
24 CheckIndex, ReadArray, ReadArrayCow, ReadBinary, ReadBinaryDep, ReadCtxt, ReadFrom, ReadScope,
25 ReadUnchecked,
26};
27use crate::binary::write::{WriteBinary, WriteBinaryDep, WriteBuffer, WriteContext, WriteCounter};
28use crate::binary::{I16Be, I32Be, U16Be, U24Be, U32Be, U8};
29use crate::error::{ParseError, WriteError};
30use crate::tables::variable_fonts::{ItemVariationStore, OwnedTuple};
31use crate::variations::VariationError;
32use cff2::BlendOperand;
33use charstring::{ArgumentsStack, GlyphId, TryNumFrom};
34pub use subset::SubsetCFF;
35
36pub const MAX_OPERANDS: usize = 48;
40const END_OF_FLOAT_FLAG: u8 = 0xf;
41
42const OPERAND_ZERO: [Operand; 1] = [Operand::Integer(0)];
43const OFFSET_ZERO: [Operand; 1] = [Operand::Offset(0)];
44const DEFAULT_UNDERLINE_POSITION: [Operand; 1] = [Operand::Integer(-100)];
45const DEFAULT_UNDERLINE_THICKNESS: [Operand; 1] = [Operand::Integer(50)];
46const DEFAULT_CHARSTRING_TYPE: [Operand; 1] = [Operand::Integer(2)];
47lazy_static! {
48 static ref DEFAULT_FONT_MATRIX: [Operand; 6] = {
49 let real_0_001 = Operand::Real(Real(tiny_vec![0x0a, 0x00, 0x1f])); [
51 real_0_001.clone(),
52 Operand::Integer(0),
53 Operand::Integer(0),
54 real_0_001,
55 Operand::Integer(0),
56 Operand::Integer(0),
57 ]
58 };
59}
60const DEFAULT_BBOX: [Operand; 4] = [
61 Operand::Integer(0),
62 Operand::Integer(0),
63 Operand::Integer(0),
64 Operand::Integer(0),
65];
66const DEFAULT_CID_COUNT: [Operand; 1] = [Operand::Integer(8720)];
67const DEFAULT_BLUE_SHIFT: [Operand; 1] = [Operand::Integer(7)];
68const DEFAULT_BLUE_FUZZ: [Operand; 1] = [Operand::Integer(1)];
69lazy_static! {
70 static ref DEFAULT_BLUE_SCALE: [Operand; 1] =
71 [Operand::Real(Real(tiny_vec![0x0a, 0x03, 0x96, 0x25, 0xff]))]; static ref DEFAULT_EXPANSION_FACTOR: [Operand; 1] =
73 [Operand::Real(Real(tiny_vec![0x0a, 0x06, 0xff]))]; }
75
76const ISO_ADOBE_LAST_SID: u16 = 228;
77const ADOBE: &[u8] = b"Adobe";
78const IDENTITY: &[u8] = b"Identity";
79
80#[derive(Clone)]
84pub struct CFF<'a> {
85 pub header: Header,
86 pub name_index: MaybeOwnedIndex<'a>,
87 pub string_index: MaybeOwnedIndex<'a>,
88 pub global_subr_index: MaybeOwnedIndex<'a>,
89 pub fonts: Vec<Font<'a>>,
90}
91
92#[derive(Clone, Debug, PartialEq)]
94pub struct Header {
95 pub major: u8,
96 pub minor: u8,
97 pub hdr_size: u8,
98 pub off_size: u8,
99}
100
101pub struct IndexU16;
103
104pub struct IndexU32;
106
107#[derive(Clone)]
109pub struct Index<'a> {
110 pub count: usize,
111 off_size: u8,
112 offset_array: &'a [u8],
113 data_array: &'a [u8],
114}
115
116#[derive(Clone)]
118pub struct Font<'a> {
119 pub top_dict: TopDict,
120 pub char_strings_index: MaybeOwnedIndex<'a>,
121 pub charset: Charset<'a>,
122 pub data: CFFVariant<'a>,
123}
124
125#[derive(Copy, Clone)]
127pub enum CFFFont<'a, 'data> {
128 CFF(&'a Font<'data>),
129 CFF2(&'a cff2::Font<'data>),
130}
131
132#[derive(Clone)]
134pub enum MaybeOwnedIndex<'a> {
135 Borrowed(Index<'a>),
136 Owned(owned::Index),
137}
138
139pub struct MaybeOwnedIndexIterator<'a> {
141 data: &'a MaybeOwnedIndex<'a>,
142 index: usize,
143}
144
145#[derive(Clone, Eq, PartialEq, Debug)]
147pub enum CFFError {
148 ParseError(ParseError),
149 InvalidOperator,
150 InvalidOperand,
152 UnsupportedOperator,
153 MissingEndChar,
154 DataAfterEndChar,
155 NestingLimitReached,
156 ArgumentsStackLimitReached,
157 InvalidArgumentsStackLength,
158 BboxOverflow,
159 MissingMoveTo,
160 DuplicateVsIndex,
161 InvalidSubroutineIndex,
162 InvalidFontIndex,
163 NoLocalSubroutines,
164 InvalidSeacCode,
165 VsIndexAfterBlend,
166 MissingVariationStore,
167}
168
169mod owned {
170 use super::{TryFrom, U16Be, U32Be, WriteBinary, WriteContext, WriteError, U8};
171
172 pub(super) struct IndexU16;
173 pub(super) struct IndexU32;
174
175 #[derive(Clone)]
176 pub struct Index {
177 pub(super) data: Vec<Vec<u8>>,
178 }
179
180 impl WriteBinary<&Index> for IndexU16 {
181 type Output = ();
182
183 fn write<C: WriteContext>(ctxt: &mut C, index: &Index) -> Result<(), WriteError> {
184 let count = u16::try_from(index.data.len())?;
185 U16Be::write(ctxt, count)?;
186 write_index_body(ctxt, index)
187 }
188 }
189
190 impl WriteBinary<&Index> for IndexU32 {
191 type Output = ();
192
193 fn write<C: WriteContext>(ctxt: &mut C, index: &Index) -> Result<(), WriteError> {
194 let count = u32::try_from(index.data.len())?;
195 U32Be::write(ctxt, count)?;
196 write_index_body(ctxt, index)
197 }
198 }
199
200 fn write_index_body<C: WriteContext>(ctxt: &mut C, index: &Index) -> Result<(), WriteError> {
201 if index.data.is_empty() {
202 return Ok(());
203 }
204
205 let mut offset = 1; let mut offsets = Vec::with_capacity(index.data.len() + 1);
207 for data in &index.data {
208 offsets.push(offset);
209 offset += data.len();
210 }
211 offsets.push(offset);
212 let (off_size, offset_array) = super::serialise_offset_array(offsets)?;
213 U8::write(ctxt, off_size)?;
214 ctxt.write_bytes(&offset_array)?;
215 for data in &index.data {
216 ctxt.write_bytes(data)?;
217 }
218
219 Ok(())
220 }
221
222 impl Index {
223 pub(super) fn read_object(&self, index: usize) -> Option<&[u8]> {
224 self.data.get(index).map(|data| data.as_slice())
225 }
226 }
227}
228
229#[derive(Clone)]
230pub enum CFFVariant<'a> {
231 CID(CIDData<'a>),
232 Type1(Type1Data<'a>),
233}
234
235#[derive(Clone)]
236pub struct CIDData<'a> {
237 pub font_dict_index: MaybeOwnedIndex<'a>,
238 pub private_dicts: Vec<PrivateDict>,
239 pub local_subr_indices: Vec<Option<MaybeOwnedIndex<'a>>>,
241 pub fd_select: FDSelect<'a>,
242}
243
244pub struct CIDDataOffsets {
245 pub font_dict_index: usize,
246 pub fd_select: usize,
247}
248
249#[derive(Clone)]
250pub struct Type1Data<'a> {
251 pub encoding: Encoding<'a>,
252 pub private_dict: PrivateDict,
253 pub local_subr_index: Option<MaybeOwnedIndex<'a>>,
254}
255
256pub struct Type1DataOffsets {
257 pub custom_encoding: Option<usize>,
258 pub private_dict: usize,
259 pub private_dict_len: usize,
260}
261
262#[derive(Clone)]
265pub enum Encoding<'a> {
266 Standard,
267 Expert,
268 Custom(CustomEncoding<'a>),
269}
270
271#[derive(Clone)]
272pub enum Charset<'a> {
273 ISOAdobe,
274 Expert,
275 ExpertSubset,
276 Custom(CustomCharset<'a>),
277}
278
279#[derive(Clone)]
280pub enum CustomEncoding<'a> {
281 Format0 {
282 codes: ReadArray<'a, U8>,
283 },
284 Format1 {
285 ranges: ReadArray<'a, Range<u8, u8>>,
286 },
287}
288
289type SID = u16;
291
292#[derive(Clone)]
293pub enum CustomCharset<'a> {
294 Format0 {
295 glyphs: ReadArrayCow<'a, U16Be>,
296 },
297 Format1 {
298 ranges: ReadArrayCow<'a, Range<SID, u8>>,
299 },
300 Format2 {
301 ranges: ReadArrayCow<'a, Range<SID, u16>>,
302 },
303}
304
305#[derive(Copy, Clone, Debug, PartialEq)]
307pub struct Range<F, N> {
308 pub first: F,
309 pub n_left: N,
310}
311
312#[derive(Debug, PartialEq, Clone)]
314pub struct Dict<T>
315where
316 T: DictDefault,
317{
318 dict: Vec<(Operator, Vec<Operand>)>,
319 default: PhantomData<T>,
320}
321
322pub trait DictDefault {
324 fn default(op: Operator) -> Option<&'static [Operand]>;
326}
327
328#[derive(Debug, PartialEq, Clone)]
329pub struct TopDictDefault;
330
331#[derive(Debug, PartialEq, Clone)]
332pub struct FontDictDefault;
333
334#[derive(Debug, PartialEq, Clone)]
335pub struct PrivateDictDefault;
336
337pub type TopDict = Dict<TopDictDefault>;
338
339pub type FontDict = Dict<FontDictDefault>;
340
341pub type PrivateDict = Dict<PrivateDictDefault>;
342
343#[derive(Debug, PartialEq, Clone)]
347pub struct DictDelta {
348 dict: Vec<(Operator, TinyVec<[Operand; 1]>)>,
350}
351
352#[derive(Clone, Debug)]
354pub enum FDSelect<'a> {
355 Format0 {
356 glyph_font_dict_indices: ReadArrayCow<'a, U8>,
357 },
358 Format3 {
360 ranges: ReadArrayCow<'a, Range<u16, u8>>,
361 sentinel: u16,
362 },
363 }
365
366#[derive(Debug, PartialEq)]
368enum Op {
369 Operator(Operator),
370 Operand(Operand),
371}
372
373#[derive(Debug, PartialEq, Clone)]
375pub enum Operand {
376 Integer(i32),
377 Offset(i32),
378 Real(Real),
379}
380
381#[derive(Debug, PartialEq, Clone)]
396pub struct Real(TinyVec<[u8; 7]>);
397
398#[repr(u16)]
399#[derive(Debug, PartialEq, Copy, Clone)]
400pub enum Operator {
401 Version = 0,
402 Notice = 1,
403 FullName = 2,
404 FamilyName = 3,
405 Weight = 4,
406 FontBBox = 5,
407 BlueValues = 6,
408 OtherBlues = 7,
409 FamilyBlues = 8,
410 FamilyOtherBlues = 9,
411 StdHW = 10,
412 StdVW = 11,
413 UniqueID = 13,
414 XUID = 14,
415 Charset = 15,
416 Encoding = 16,
417 CharStrings = 17,
418 Private = 18,
419 Subrs = 19,
420 DefaultWidthX = 20,
421 NominalWidthX = 21,
422 VSIndex = 22,
424 Blend = 23,
425 VStore = 24,
426
427 Copyright = op2(0),
428 IsFixedPitch = op2(1),
429 ItalicAngle = op2(2),
430 UnderlinePosition = op2(3),
431 UnderlineThickness = op2(4),
432 PaintType = op2(5),
433 CharstringType = op2(6),
434 FontMatrix = op2(7),
435 StrokeWidth = op2(8),
436 BlueScale = op2(9),
437 BlueShift = op2(10),
438 BlueFuzz = op2(11),
439 StemSnapH = op2(12),
440 StemSnapV = op2(13),
441 ForceBold = op2(14),
442 LanguageGroup = op2(17),
443 ExpansionFactor = op2(18),
444 InitialRandomSeed = op2(19),
445 SyntheticBase = op2(20),
446 PostScript = op2(21),
447 BaseFontName = op2(22),
448 BaseFontBlend = op2(23),
449 ROS = op2(30),
450 CIDFontVersion = op2(31),
451 CIDFontRevision = op2(32),
452 CIDFontType = op2(33),
453 CIDCount = op2(34),
454 UIDBase = op2(35),
455 FDArray = op2(36),
456 FDSelect = op2(37),
457 FontName = op2(38),
458}
459
460const fn op2(value: u8) -> u16 {
461 (12 << 8) | (value as u16)
462}
463
464impl<'b> ReadBinary for CFF<'b> {
465 type HostType<'a> = CFF<'a>;
466
467 fn read<'a>(ctxt: &mut ReadCtxt<'a>) -> Result<Self::HostType<'a>, ParseError> {
468 let scope = ctxt.scope();
471
472 let header = ctxt.read::<Header>()?;
473 let name_index = ctxt.read::<IndexU16>()?;
474 let top_dict_index = ctxt.read::<IndexU16>()?;
475 let string_index = ctxt.read::<IndexU16>()?;
476 let global_subr_index = ctxt.read::<IndexU16>().map(MaybeOwnedIndex::Borrowed)?;
477
478 let mut fonts = Vec::with_capacity(name_index.count);
479 for font_index in 0..name_index.count {
480 let top_dict = top_dict_index.read::<TopDict>(font_index, MAX_OPERANDS)?;
481
482 let offset = top_dict
484 .get_i32(Operator::CharStrings)
485 .unwrap_or(Err(ParseError::MissingValue))?;
486 let char_strings_index = scope.offset(usize::try_from(offset)?).read::<IndexU16>()?;
487
488 let data = match top_dict.first_operator() {
492 Some(Operator::ROS) => {
493 let cid_data = read_cid_data(&scope, &top_dict, char_strings_index.count)?;
494 CFFVariant::CID(cid_data)
495 }
496 Some(Operator::SyntheticBase) => {
497 return Err(ParseError::NotImplemented);
498 }
499 Some(_) => {
500 let (private_dict, private_dict_offset) =
501 top_dict.read_private_dict::<PrivateDict>(&scope, MAX_OPERANDS)?;
502 let local_subr_index = read_local_subr_index::<_, IndexU16>(
503 &scope,
504 &private_dict,
505 private_dict_offset,
506 )?
507 .map(MaybeOwnedIndex::Borrowed);
508 let encoding = read_encoding(&scope, &top_dict)?;
509
510 CFFVariant::Type1(Type1Data {
511 encoding,
512 private_dict,
513 local_subr_index,
514 })
515 }
516 None => return Err(ParseError::MissingValue),
517 };
518
519 let charset = read_charset(&scope, &top_dict, char_strings_index.count)?;
520
521 fonts.push(Font {
522 top_dict,
523 char_strings_index: MaybeOwnedIndex::Borrowed(char_strings_index),
524 charset,
525 data,
526 });
527 }
528
529 Ok(CFF {
530 header,
531 name_index: MaybeOwnedIndex::Borrowed(name_index),
532 string_index: MaybeOwnedIndex::Borrowed(string_index),
533 global_subr_index,
534 fonts,
535 })
536 }
537}
538
539impl<'a> WriteBinary<&Self> for CFF<'a> {
540 type Output = ();
541
542 fn write<C: WriteContext>(ctxt: &mut C, cff: &CFF<'a>) -> Result<(), WriteError> {
543 Header::write(ctxt, &cff.header)?;
544 MaybeOwnedIndex::write16(ctxt, &cff.name_index)?;
545 let top_dicts = cff.fonts.iter().map(|font| &font.top_dict).collect_vec();
546 let top_dict_index_length =
547 Index::calculate_size::<TopDict, _>(top_dicts.as_slice(), DictDelta::new())?;
548 let top_dict_index_placeholder = ctxt.reserve::<IndexU16, _>(top_dict_index_length)?;
549 MaybeOwnedIndex::write16(ctxt, &cff.string_index)?;
550 MaybeOwnedIndex::write16(ctxt, &cff.global_subr_index)?;
551
552 let mut top_dict_deltas = vec![DictDelta::new(); cff.fonts.len()];
554 for (font, top_dict_delta) in cff.fonts.iter().zip(top_dict_deltas.iter_mut()) {
555 top_dict_delta.push_offset(Operator::CharStrings, i32::try_from(ctxt.bytes_written())?);
556 MaybeOwnedIndex::write16(ctxt, &font.char_strings_index)?;
557
558 match &font.charset {
559 Charset::ISOAdobe => top_dict_delta.push_offset(Operator::Charset, 0),
560 Charset::Expert => top_dict_delta.push_offset(Operator::Charset, 1),
561 Charset::ExpertSubset => top_dict_delta.push_offset(Operator::Charset, 2),
562 Charset::Custom(custom) => {
563 top_dict_delta
564 .push_offset(Operator::Charset, i32::try_from(ctxt.bytes_written())?);
565 CustomCharset::write(ctxt, custom)?;
566 }
567 }
568 write_cff_variant(ctxt, &font.data, top_dict_delta)?;
569 }
570
571 let mut top_dict_data = WriteBuffer::new();
573 let mut offsets = Vec::with_capacity(cff.fonts.len());
574 for (font, top_dict_delta) in cff.fonts.iter().zip(top_dict_deltas.into_iter()) {
575 offsets.push(top_dict_data.bytes_written() + 1); TopDict::write_dep(&mut top_dict_data, &font.top_dict, top_dict_delta)?;
577 }
578 offsets.push(top_dict_data.bytes_written() + 1); let (off_size, offset_array) = serialise_offset_array(offsets)?;
580
581 let top_dict_index = Index {
583 count: cff.fonts.len(),
584 off_size,
585 offset_array: &offset_array,
586 data_array: top_dict_data.bytes(),
587 };
588 ctxt.write_placeholder(top_dict_index_placeholder, &top_dict_index)?;
589
590 Ok(())
591 }
592}
593
594impl<'a> CFF<'a> {
595 pub fn read_string(&self, sid: SID) -> Result<&str, ParseError> {
597 read_string_index_string(&self.string_index, sid)
598 }
599}
600
601fn read_string_index_string<'idx>(
603 string_index: &'idx MaybeOwnedIndex<'_>,
604 sid: SID,
605) -> Result<&'idx str, ParseError> {
606 let sid = usize::from(sid);
607 if let Some(string) = STANDARD_STRINGS.get(sid) {
612 Ok(string)
613 } else {
614 let bytes = string_index
615 .read_object(sid - STANDARD_STRINGS.len())
616 .ok_or(ParseError::BadIndex)?;
617
618 std::str::from_utf8(bytes).map_err(|_utf8_err| ParseError::BadValue)
619 }
620}
621
622impl ReadBinary for Header {
623 type HostType<'b> = Self;
624
625 fn read(ctxt: &mut ReadCtxt<'_>) -> Result<Self, ParseError> {
626 let major = ctxt.read_u8()?;
635 ctxt.check(major == 1)?;
636 let minor = ctxt.read_u8()?;
637 let hdr_size = ctxt.read_u8()?;
638 let off_size = ctxt.read_u8()?;
639
640 if hdr_size < 4 {
641 return Err(ParseError::BadValue);
642 }
643
644 if off_size < 1 || off_size > 4 {
645 return Err(ParseError::BadValue);
646 }
647
648 let _unknown = ctxt.read_slice((hdr_size - 4) as usize)?;
649
650 Ok(Header {
651 major,
652 minor,
653 hdr_size,
654 off_size,
655 })
656 }
657}
658
659impl WriteBinary<&Self> for Header {
660 type Output = ();
661
662 fn write<C: WriteContext>(ctxt: &mut C, header: &Header) -> Result<(), WriteError> {
663 U8::write(ctxt, header.major)?;
664 U8::write(ctxt, header.minor)?;
665 U8::write(ctxt, 4)?; U8::write(ctxt, header.off_size)?;
669
670 Ok(())
671 }
672}
673
674impl<'b> ReadBinary for IndexU16 {
675 type HostType<'a> = Index<'a>;
676
677 fn read<'a>(ctxt: &mut ReadCtxt<'a>) -> Result<Self::HostType<'a>, ParseError> {
678 let count = usize::from(ctxt.read_u16be()?);
679 read_index(ctxt, count)
680 }
681}
682
683fn read_index<'a>(ctxt: &mut ReadCtxt<'a>, count: usize) -> Result<Index<'a>, ParseError> {
684 if count > 0 {
685 let off_size = ctxt.read_u8()?;
686 if off_size < 1 || off_size > 4 {
687 return Err(ParseError::BadValue);
688 }
689
690 let offset_array_size = (count + 1) * usize::from(off_size);
691 let offset_array = ctxt.read_slice(offset_array_size)?;
692
693 let last_offset_index = lookup_offset_index(off_size, offset_array, count);
694 if last_offset_index < 1 {
695 return Err(ParseError::BadValue);
696 }
697
698 let data_array_size = last_offset_index - 1;
699 let data_array = ctxt.read_slice(data_array_size)?;
700
701 Ok(Index {
702 count,
703 off_size,
704 offset_array,
705 data_array,
706 })
707 } else {
708 Ok(Index {
710 count,
711 off_size: 1,
712 offset_array: &[],
713 data_array: &[],
714 })
715 }
716}
717
718impl<'a> WriteBinary<&Index<'a>> for IndexU16 {
719 type Output = ();
720
721 fn write<C: WriteContext>(ctxt: &mut C, index: &Index<'a>) -> Result<(), WriteError> {
722 U16Be::write(ctxt, u16::try_from(index.count)?)?;
723 write_index_body(ctxt, index)
724 }
725}
726
727fn write_index_body<C: WriteContext>(ctxt: &mut C, index: &Index<'_>) -> Result<(), WriteError> {
728 if index.count == 0 {
729 return Ok(());
730 }
731
732 U8::write(ctxt, index.off_size)?;
733 ctxt.write_bytes(index.offset_array)?;
734 ctxt.write_bytes(index.data_array)?;
735
736 Ok(())
737}
738
739impl<T> ReadBinaryDep for Dict<T>
740where
741 T: DictDefault,
742{
743 type Args<'a> = usize;
744 type HostType<'b> = Self;
745
746 fn read_dep<'a>(
747 ctxt: &mut ReadCtxt<'a>,
748 max_operands: usize,
749 ) -> Result<Self::HostType<'a>, ParseError> {
750 let mut dict = Vec::new();
751 let mut operands = Vec::new();
752
753 while ctxt.bytes_available() {
754 match Op::read(ctxt)? {
755 Op::Operator(operator) => {
756 integer_to_offset(operator, &mut operands);
757 dict.push((operator, operands.clone()));
758 operands.clear();
759 }
760 Op::Operand(operand) => {
761 operands.push(operand);
762 if operands.len() > max_operands {
763 return Err(ParseError::LimitExceeded);
764 }
765 }
766 }
767 }
768
769 Ok(Dict {
770 dict,
771 default: PhantomData,
772 })
773 }
774}
775
776fn offset_size(value: usize) -> Option<u8> {
777 match value {
778 0..=0xFF => Some(1),
779 0x100..=0xFFFF => Some(2),
780 0x1_0000..=0xFF_FFFF => Some(3),
781 0x100_0000..=0xFFFF_FFFF => Some(4),
782 _ => None,
783 }
784}
785
786fn integer_to_offset(operator: Operator, operands: &mut [Operand]) {
789 match (operator, &operands) {
790 (Operator::Encoding, [Operand::Integer(offset)]) if *offset > 1 => {
792 operands[0] = Operand::Offset(*offset);
793 }
794 (Operator::Charset, [Operand::Integer(offset)])
795 | (Operator::CharStrings, [Operand::Integer(offset)])
796 | (Operator::Subrs, [Operand::Integer(offset)])
797 | (Operator::FDArray, [Operand::Integer(offset)])
798 | (Operator::FDSelect, [Operand::Integer(offset)])
799 | (Operator::VStore, [Operand::Integer(offset)]) => {
800 operands[0] = Operand::Offset(*offset);
801 }
802 (Operator::Private, [Operand::Integer(length), Operand::Integer(offset)]) => {
803 let offset = *offset; operands[0] = Operand::Offset(*length);
805 operands[1] = Operand::Offset(offset);
806 }
807 _ => {}
808 }
809}
810
811impl<T> WriteBinaryDep<&Self> for Dict<T>
812where
813 T: DictDefault,
814{
815 type Args = DictDelta;
816 type Output = usize; fn write_dep<C: WriteContext>(
819 ctxt: &mut C,
820 dict: &Dict<T>,
821 delta: DictDelta,
822 ) -> Result<Self::Output, WriteError> {
823 let offset = ctxt.bytes_written();
824
825 for (operator, operands) in dict.iter() {
826 let mut operands = operands.as_slice();
827
828 if let Some(delta_operands) = delta.get(*operator) {
832 operands = delta_operands;
833 } else if T::default(*operator)
834 .map(|defaults| defaults == operands)
835 .unwrap_or(false)
836 {
837 continue;
838 }
839
840 for operand in operands {
841 Operand::write(ctxt, operand)?;
842 }
843 Operator::write(ctxt, *operator)?;
844 }
845
846 Ok(ctxt.bytes_written() - offset)
847 }
848}
849
850impl ReadBinary for Op {
851 type HostType<'b> = Self;
852
853 fn read<'a>(ctxt: &mut ReadCtxt<'a>) -> Result<Self, ParseError> {
854 let b0 = ctxt.read_u8()?;
855
856 match b0 {
857 0..=11 | 13..=21 => ok_operator(u16::from(b0).try_into().unwrap()), 22..=24 => ok_operator(u16::from(b0).try_into().unwrap()), 12 => ok_operator(op2(ctxt.read_u8()?).try_into()?),
861 28 => {
862 let num = ctxt.read_i16be()?;
863 Ok(Op::Operand(Operand::Integer(i32::from(num))))
864 }
865 29 => ok_int(ctxt.read_i32be()?),
866 30 => ok_real(ctxt.read_until_nibble(END_OF_FLOAT_FLAG)?),
867 32..=246 => ok_int(i32::from(b0) - 139),
868 247..=250 => {
869 let b1 = ctxt.read_u8()?;
870 ok_int((i32::from(b0) - 247) * 256 + i32::from(b1) + 108)
871 }
872 251..=254 => {
873 let b1 = ctxt.read_u8()?;
874 ok_int(-(i32::from(b0) - 251) * 256 - i32::from(b1) - 108)
875 }
876 25..=27 | 31 | 255 => Err(ParseError::BadValue),
878 }
879 }
880}
881
882impl WriteBinary<Self> for Operator {
883 type Output = ();
884
885 fn write<C: WriteContext>(ctxt: &mut C, op: Operator) -> Result<(), WriteError> {
886 let value = op as u16;
887 if value > 0xFF {
888 U16Be::write(ctxt, value)?;
889 } else {
890 U8::write(ctxt, value as u8)?;
891 }
892
893 Ok(())
894 }
895}
896
897impl WriteBinary<&Self> for Operand {
898 type Output = ();
899
900 fn write<C: WriteContext>(ctxt: &mut C, op: &Operand) -> Result<(), WriteError> {
903 match op {
904 Operand::Integer(val) => match *val {
905 -107..=107 => {
907 U8::write(ctxt, (val + 139) as u8)?;
908 }
909 108..=1131 => {
910 let val = *val - 108;
911 U8::write(ctxt, ((val >> 8) + 247) as u8)?;
912 U8::write(ctxt, val as u8)?;
913 }
914 -1131..=-108 => {
915 let val = -*val - 108;
916 U8::write(ctxt, ((val >> 8) + 251) as u8)?;
917 U8::write(ctxt, val as u8)?;
918 }
919 -32768..=32767 => {
920 U8::write(ctxt, 28)?;
921 I16Be::write(ctxt, *val as i16)?
922 }
923 _ => {
924 U8::write(ctxt, 29)?;
925 I32Be::write(ctxt, *val)?
926 }
927 },
928 Operand::Offset(val) => {
929 U8::write(ctxt, 29)?;
930 I32Be::write(ctxt, *val)?;
933 }
934 Operand::Real(Real(val)) => {
935 U8::write(ctxt, 30)?;
936 ctxt.write_bytes(val)?;
937 }
938 }
939
940 Ok(())
941 }
942}
943
944fn ok_operator(op: Operator) -> Result<Op, ParseError> {
945 Ok(Op::Operator(op))
946}
947
948fn ok_int(num: i32) -> Result<Op, ParseError> {
949 Ok(Op::Operand(Operand::Integer(num)))
950}
951
952fn ok_real(slice: &[u8]) -> Result<Op, ParseError> {
953 Ok(Op::Operand(Operand::Real(Real(TinyVec::from(slice)))))
954}
955
956const FLOAT_BUF_LEN: usize = 64;
957
958impl TryFrom<&Real> for f64 {
961 type Error = ParseError;
962
963 fn try_from(real: &Real) -> Result<Self, Self::Error> {
965 let mut buf = [0u8; FLOAT_BUF_LEN];
966 let mut used = 0;
967
968 for byte in real.0.iter().copied() {
969 let nibble1 = byte >> 4;
970 let nibble2 = byte & 0xF;
971
972 if nibble1 == END_OF_FLOAT_FLAG {
973 break;
974 }
975 parse_float_nibble(nibble1, &mut used, &mut buf)?;
976 if nibble2 == END_OF_FLOAT_FLAG {
977 break;
978 }
979 parse_float_nibble(nibble2, &mut used, &mut buf)?;
980 }
981
982 let s = core::str::from_utf8(&buf[..used]).unwrap();
985 s.parse().map_err(|_| ParseError::BadValue)
986 }
987}
988
989fn parse_float_nibble(nibble: u8, idx: &mut usize, data: &mut [u8]) -> Result<(), ParseError> {
991 if *idx == FLOAT_BUF_LEN {
992 return Err(ParseError::LimitExceeded);
993 }
994
995 match nibble {
996 0..=9 => {
997 data[*idx] = b'0' + nibble;
998 }
999 10 => {
1000 data[*idx] = b'.';
1001 }
1002 11 => {
1003 data[*idx] = b'E';
1004 }
1005 12 => {
1006 if *idx + 1 == FLOAT_BUF_LEN {
1007 return Err(ParseError::LimitExceeded);
1008 }
1009
1010 data[*idx] = b'E';
1011 *idx += 1;
1012 data[*idx] = b'-';
1013 }
1014 13 => return Err(ParseError::BadValue),
1015 14 => {
1016 data[*idx] = b'-';
1017 }
1018 _ => return Err(ParseError::BadValue),
1019 }
1020
1021 *idx += 1;
1022 Ok(())
1023}
1024
1025impl ReadFrom for Range<u8, u8> {
1026 type ReadType = (U8, U8);
1027 fn read_from((first, n_left): (u8, u8)) -> Self {
1028 Range { first, n_left }
1029 }
1030}
1031
1032impl WriteBinary for Range<u8, u8> {
1033 type Output = ();
1034
1035 fn write<C: WriteContext>(ctxt: &mut C, range: Self) -> Result<(), WriteError> {
1036 U8::write(ctxt, range.first)?;
1037 U8::write(ctxt, range.n_left)?;
1038
1039 Ok(())
1040 }
1041}
1042
1043impl ReadFrom for Range<SID, u8> {
1044 type ReadType = (U16Be, U8);
1045 fn read_from((first, n_left): (SID, u8)) -> Self {
1046 Range { first, n_left }
1047 }
1048}
1049
1050impl WriteBinary for Range<SID, u8> {
1051 type Output = ();
1052
1053 fn write<C: WriteContext>(ctxt: &mut C, range: Self) -> Result<(), WriteError> {
1054 U16Be::write(ctxt, range.first)?;
1055 U8::write(ctxt, range.n_left)?;
1056
1057 Ok(())
1058 }
1059}
1060
1061impl ReadFrom for Range<SID, u16> {
1062 type ReadType = (U16Be, U16Be);
1063 fn read_from((first, n_left): (SID, u16)) -> Self {
1064 Range { first, n_left }
1065 }
1066}
1067
1068impl WriteBinary for Range<SID, u16> {
1069 type Output = ();
1070
1071 fn write<C: WriteContext>(ctxt: &mut C, range: Self) -> Result<(), WriteError> {
1072 U16Be::write(ctxt, range.first)?;
1073 U16Be::write(ctxt, range.n_left)?;
1074
1075 Ok(())
1076 }
1077}
1078
1079impl<F, N> Range<F, N>
1080where
1081 N: num::Unsigned + Copy,
1082 usize: From<N>,
1083{
1084 pub fn len(&self) -> usize {
1085 usize::from(self.n_left) + 1
1086 }
1087}
1088
1089impl Range<SID, u8> {
1092 pub fn iter(&self) -> impl Iterator<Item = SID> {
1093 let last = self.first + SID::from(self.n_left);
1094 self.first..=last
1095 }
1096}
1097
1098impl Range<SID, u16> {
1099 pub fn iter(&self) -> impl Iterator<Item = SID> {
1100 let last = self.first + self.n_left;
1101 self.first..=last
1102 }
1103}
1104
1105impl<'b> ReadBinary for CustomEncoding<'b> {
1106 type HostType<'a> = CustomEncoding<'a>;
1107
1108 fn read<'a>(ctxt: &mut ReadCtxt<'a>) -> Result<Self::HostType<'a>, ParseError> {
1109 match ctxt.read::<U8>()? {
1111 0 => {
1112 let ncodes = ctxt.read::<U8>()?;
1113 let codes = ctxt.read_array::<U8>(usize::from(ncodes))?;
1114 Ok(CustomEncoding::Format0 { codes })
1115 }
1116 1 => {
1117 let nranges = ctxt.read::<U8>()?;
1118 let ranges = ctxt.read_array::<Range<u8, u8>>(usize::from(nranges))?;
1119 Ok(CustomEncoding::Format1 { ranges })
1120 }
1121 format if format & 0x80 == 0x80 => Err(ParseError::NotImplemented),
1129 _ => Err(ParseError::BadValue),
1130 }
1131 }
1132}
1133
1134impl<'a> WriteBinary<&Self> for CustomEncoding<'a> {
1135 type Output = ();
1136
1137 fn write<C: WriteContext>(ctxt: &mut C, encoding: &Self) -> Result<(), WriteError> {
1138 match encoding {
1139 CustomEncoding::Format0 { codes } => {
1140 U8::write(ctxt, 0)?; U8::write(ctxt, u8::try_from(codes.len())?)?;
1142 <&ReadArray<'_, _>>::write(ctxt, codes)?;
1143 }
1144 CustomEncoding::Format1 { ranges } => {
1145 U8::write(ctxt, 1)?; U8::write(ctxt, u8::try_from(ranges.len())?)?;
1147 <&ReadArray<'_, _>>::write(ctxt, ranges)?;
1148 }
1149 }
1150
1151 Ok(())
1152 }
1153}
1154
1155impl<'a> Charset<'a> {
1156 pub fn id_for_glyph(&self, glyph_id: u16) -> Option<u16> {
1158 match self {
1159 Charset::ISOAdobe => {
1161 if glyph_id <= ISO_ADOBE_LAST_SID {
1162 Some(glyph_id)
1163 } else {
1164 None
1165 }
1166 }
1167 Charset::Expert => EXPERT_CHARSET.get(usize::from(glyph_id)).copied(),
1168 Charset::ExpertSubset => EXPERT_SUBSET_CHARSET.get(usize::from(glyph_id)).copied(),
1169 Charset::Custom(custom) => custom.id_for_glyph(glyph_id),
1170 }
1171 }
1172
1173 pub fn sid_to_gid(&self, sid: SID) -> Option<u16> {
1175 if sid == 0 {
1176 return Some(0);
1177 }
1178
1179 match self {
1180 Charset::ISOAdobe | Charset::Expert | Charset::ExpertSubset => None,
1181 Charset::Custom(custom) => custom.sid_to_gid(sid),
1182 }
1183 }
1184}
1185
1186impl<'b> ReadBinaryDep for CustomCharset<'b> {
1187 type Args<'a> = usize;
1188 type HostType<'a> = CustomCharset<'a>;
1189
1190 fn read_dep<'a>(
1191 ctxt: &mut ReadCtxt<'a>,
1192 n_glyphs: usize,
1193 ) -> Result<Self::HostType<'a>, ParseError> {
1194 let n_glyphs = n_glyphs.checked_sub(1).ok_or(ParseError::BadValue)?;
1196 match ctxt.read::<U8>()? {
1197 0 => {
1198 let glyphs = ctxt.read_array::<U16Be>(n_glyphs)?;
1201 Ok(CustomCharset::Format0 {
1202 glyphs: ReadArrayCow::Borrowed(glyphs),
1203 })
1204 }
1205 1 => {
1206 let ranges = read_range_array(ctxt, n_glyphs)?;
1207 Ok(CustomCharset::Format1 {
1208 ranges: ReadArrayCow::Borrowed(ranges),
1209 })
1210 }
1211 2 => {
1212 let ranges = read_range_array(ctxt, n_glyphs)?;
1213 Ok(CustomCharset::Format2 {
1214 ranges: ReadArrayCow::Borrowed(ranges),
1215 })
1216 }
1217 _ => Err(ParseError::BadValue),
1218 }
1219 }
1220}
1221
1222impl<'a> WriteBinary<&Self> for CustomCharset<'a> {
1223 type Output = ();
1224
1225 fn write<C: WriteContext>(ctxt: &mut C, charset: &Self) -> Result<(), WriteError> {
1226 match charset {
1227 CustomCharset::Format0 { glyphs } => {
1228 U8::write(ctxt, 0)?; ReadArrayCow::write(ctxt, glyphs)?;
1230 }
1231 CustomCharset::Format1 { ranges } => {
1232 U8::write(ctxt, 1)?; ReadArrayCow::write(ctxt, ranges)?;
1234 }
1235 CustomCharset::Format2 { ranges } => {
1236 U8::write(ctxt, 2)?; ReadArrayCow::write(ctxt, ranges)?;
1238 }
1239 }
1240
1241 Ok(())
1242 }
1243}
1244
1245impl<'a> CustomCharset<'a> {
1246 pub fn iter(&'a self) -> Box<dyn Iterator<Item = u16> + 'a> {
1247 let notdef = iter::once(0);
1248 match &self {
1249 CustomCharset::Format0 { glyphs } => Box::new(notdef.chain(glyphs.iter())),
1250 CustomCharset::Format1 { ranges } => {
1251 Box::new(notdef.chain(ranges.iter().flat_map(|range| range.iter())))
1252 }
1253 CustomCharset::Format2 { ranges } => {
1254 Box::new(notdef.chain(ranges.iter().flat_map(|range| range.iter())))
1255 }
1256 }
1257 }
1258
1259 pub fn id_for_glyph(&self, glyph_id: u16) -> Option<u16> {
1261 if glyph_id == 0 {
1267 return Some(0);
1268 }
1269
1270 match self {
1271 CustomCharset::Format0 { glyphs } => {
1272 let index = usize::from(glyph_id - 1);
1273 glyphs
1274 .check_index(index)
1275 .map(|_| glyphs.get_item(index))
1276 .ok()
1277 }
1278 CustomCharset::Format1 { ranges } => Self::id_for_glyph_in_ranges(ranges, glyph_id),
1279 CustomCharset::Format2 { ranges } => Self::id_for_glyph_in_ranges(ranges, glyph_id),
1280 }
1281 }
1282
1283 pub fn sid_to_gid(&self, sid: SID) -> Option<u16> {
1284 match self {
1285 CustomCharset::Format0 { glyphs: array } => {
1286 array
1288 .into_iter()
1289 .position(|n| n == sid)
1290 .and_then(|n| u16::try_from(n + 1).ok())
1291 }
1292 CustomCharset::Format1 { ranges } => Self::glyph_id_for_sid_in_ranges(ranges, sid),
1293 CustomCharset::Format2 { ranges } => Self::glyph_id_for_sid_in_ranges(ranges, sid),
1294 }
1295 }
1296
1297 fn glyph_id_for_sid_in_ranges<F, N>(
1298 ranges: &ReadArrayCow<'a, Range<F, N>>,
1299 sid: SID,
1300 ) -> Option<u16>
1301 where
1302 F: num::Unsigned + Copy,
1303 N: num::Unsigned + Copy,
1304 u32: From<N> + From<F>,
1305 u16: From<N> + From<F>,
1306 Range<F, N>: ReadFrom,
1307 {
1308 let mut glyph_id = 1;
1309 for range in ranges.iter() {
1310 let last = u32::from(range.first) + u32::from(range.n_left);
1311 if u16::from(range.first) <= sid && u32::from(sid) <= last {
1312 glyph_id += sid - u16::from(range.first);
1313 return Some(glyph_id);
1314 }
1315
1316 glyph_id += u16::from(range.n_left) + 1;
1317 }
1318
1319 None
1320 }
1321
1322 fn id_for_glyph_in_ranges<F, N>(
1323 ranges: &ReadArrayCow<'a, Range<F, N>>,
1324 glyph_id: u16,
1325 ) -> Option<u16>
1326 where
1327 F: num::Unsigned + Copy,
1328 N: num::Unsigned + Copy,
1329 usize: From<N> + From<F>,
1330 Range<F, N>: ReadFrom,
1331 <Range<F, N> as ReadUnchecked>::HostType: Copy,
1332 {
1333 let glyph_id = usize::from(glyph_id);
1334
1335 ranges
1336 .iter()
1337 .scan(0usize, |glyphs_covered, range| {
1338 *glyphs_covered += range.len();
1339 Some((*glyphs_covered, range))
1340 })
1341 .find(|(glyphs_covered, _range)| glyph_id <= *glyphs_covered)
1342 .and_then(|(glyphs_covered, range)| {
1343 (usize::from(range.first) + (glyph_id - (glyphs_covered - range.len()) - 1))
1344 .try_into()
1345 .ok()
1346 })
1347 }
1348}
1349
1350impl<'b> ReadBinaryDep for FDSelect<'b> {
1351 type Args<'a> = usize;
1352 type HostType<'a> = FDSelect<'a>;
1353
1354 fn read_dep<'a>(
1355 ctxt: &mut ReadCtxt<'a>,
1356 n_glyphs: usize,
1357 ) -> Result<Self::HostType<'a>, ParseError> {
1358 match ctxt.read::<U8>()? {
1359 0 => {
1360 let glyph_font_dict_indices = ctxt.read_array::<U8>(n_glyphs)?;
1361 Ok(FDSelect::Format0 {
1362 glyph_font_dict_indices: ReadArrayCow::Borrowed(glyph_font_dict_indices),
1363 })
1364 }
1365 3 => {
1366 let nranges = usize::from(ctxt.read::<U16Be>()?);
1367 let ranges = ctxt.read_array(nranges)?;
1368 let sentinel = ctxt.read::<U16Be>()?;
1369 Ok(FDSelect::Format3 {
1370 ranges: ReadArrayCow::Borrowed(ranges),
1371 sentinel,
1372 })
1373 }
1374 4 => Err(ParseError::NotImplemented),
1378 _ => Err(ParseError::BadValue),
1379 }
1380 }
1381}
1382
1383impl<'a> WriteBinary<&Self> for FDSelect<'a> {
1384 type Output = ();
1385
1386 fn write<C: WriteContext>(ctxt: &mut C, fd_select: &Self) -> Result<(), WriteError> {
1387 match fd_select {
1388 FDSelect::Format0 {
1389 glyph_font_dict_indices,
1390 } => {
1391 U8::write(ctxt, 0)?; ReadArrayCow::write(ctxt, glyph_font_dict_indices)?;
1393 }
1394 FDSelect::Format3 { ranges, sentinel } => {
1395 U8::write(ctxt, 3)?; U16Be::write(ctxt, u16::try_from(ranges.len())?)?;
1397 ReadArrayCow::write(ctxt, ranges)?;
1398 U16Be::write(ctxt, *sentinel)?;
1399 }
1400 }
1401
1402 Ok(())
1403 }
1404}
1405
1406impl<'a> PartialEq for FDSelect<'a> {
1407 fn eq(&self, other: &Self) -> bool {
1408 match (self, other) {
1409 (
1410 FDSelect::Format0 {
1411 glyph_font_dict_indices: self_glyph_font_dict_indices,
1412 },
1413 FDSelect::Format0 {
1414 glyph_font_dict_indices: other_glyph_font_dict_indices,
1415 },
1416 ) => {
1417 self_glyph_font_dict_indices.len() == other_glyph_font_dict_indices.len()
1418 && self_glyph_font_dict_indices
1419 .iter()
1420 .zip(other_glyph_font_dict_indices.iter())
1421 .all(|(left, right)| left == right)
1422 }
1423 (
1424 FDSelect::Format3 {
1425 ranges: self_ranges,
1426 sentinel: self_sentinel,
1427 },
1428 FDSelect::Format3 {
1429 ranges: other_ranges,
1430 sentinel: other_sentinel,
1431 },
1432 ) => {
1433 self_ranges.len() == other_ranges.len()
1434 && self_sentinel == other_sentinel
1435 && self_ranges
1436 .iter()
1437 .zip(other_ranges.iter())
1438 .all(|(left, right)| left == right)
1439 }
1440 _ => false,
1441 }
1442 }
1443}
1444
1445impl<'a> FDSelect<'a> {
1446 pub fn font_dict_index(&self, glyph_id: u16) -> Option<u8> {
1448 let index = usize::from(glyph_id);
1449 match self {
1450 FDSelect::Format0 {
1451 glyph_font_dict_indices,
1452 } => glyph_font_dict_indices
1453 .check_index(index)
1454 .ok()
1455 .map(|_| glyph_font_dict_indices.get_item(index)),
1456 FDSelect::Format3 { ranges, sentinel } => {
1457 #[rustfmt::skip]
1458 let range_windows = ranges
1459 .iter()
1460 .map(|Range { first, n_left }| (first, Some(n_left)))
1461 .chain(iter::once((*sentinel, None)))
1462 .tuple_windows();
1463
1464 for ((first, fd_index), (last, _)) in range_windows {
1465 if glyph_id >= first && glyph_id < last {
1466 return fd_index;
1467 }
1468 }
1469
1470 None
1471 }
1472 }
1473 }
1474}
1475
1476impl<'a> Index<'a> {
1477 fn read_object(&self, index: usize) -> Option<&[u8]> {
1478 if index < self.count {
1479 let start_index = lookup_offset_index(self.off_size, self.offset_array, index) - 1;
1480 let end_index = lookup_offset_index(self.off_size, self.offset_array, index + 1) - 1;
1481 Some(&self.data_array[start_index..end_index])
1482 } else {
1483 None
1484 }
1485 }
1486
1487 pub fn read<T: ReadBinaryDep>(
1488 &'a self,
1489 index: usize,
1490 args: T::Args<'a>,
1491 ) -> Result<T::HostType<'a>, ParseError> {
1492 let data = self.read_object(index).ok_or(ParseError::BadIndex)?;
1493 ReadScope::new(data).read_dep::<T>(args)
1494 }
1495
1496 pub fn iter(&self) -> impl Iterator<Item = &[u8]> {
1497 (0..self.count).map(move |i| self.read_object(i).unwrap())
1499 }
1500
1501 pub fn calculate_size<'b, T, HostType>(
1503 objects: &'b [&HostType],
1504 args: T::Args,
1505 ) -> Result<usize, WriteError>
1506 where
1507 T: WriteBinaryDep<&'b HostType>,
1508 T::Args: Clone,
1509 {
1510 let mut counter = WriteCounter::new();
1511
1512 U16Be::write(&mut counter, u16::try_from(objects.len())?)?;
1513 let off_size = if !objects.is_empty() {
1514 let start = counter.bytes_written();
1515 for obj in objects {
1516 T::write_dep(&mut counter, obj, args.clone())?;
1517 }
1518 let last_offset = counter.bytes_written() - start + 1; let off_size = offset_size(last_offset).ok_or(WriteError::BadValue)?;
1520 U8::write(&mut counter, off_size)?;
1521 off_size
1522 } else {
1523 0
1524 };
1525
1526 let offset_array_size = usize::from(off_size) * (objects.len() + 1);
1527 Ok(counter.bytes_written() + offset_array_size)
1528 }
1529
1530 pub fn data_len(&self) -> usize {
1532 self.data_array.len()
1533 }
1534}
1535
1536impl<'a> MaybeOwnedIndex<'a> {
1537 pub fn iter(&'a self) -> MaybeOwnedIndexIterator<'a> {
1538 MaybeOwnedIndexIterator {
1539 data: self,
1540 index: 0,
1541 }
1542 }
1543
1544 pub fn read_object(&self, index: usize) -> Option<&[u8]> {
1545 match self {
1546 MaybeOwnedIndex::Borrowed(idx) => idx.read_object(index),
1547 MaybeOwnedIndex::Owned(idx) => idx.read_object(index),
1548 }
1549 }
1550
1551 pub fn len(&self) -> usize {
1553 match self {
1554 MaybeOwnedIndex::Borrowed(index) => index.count,
1555 MaybeOwnedIndex::Owned(index) => index.data.len(),
1556 }
1557 }
1558
1559 fn index(&self, object: &[u8]) -> Option<usize> {
1561 self.iter().position(|obj| obj == object)
1562 }
1563
1564 fn push(&mut self, object: Vec<u8>) -> usize {
1568 match self {
1569 MaybeOwnedIndex::Borrowed(_) => {
1570 self.to_owned();
1571 self.push(object);
1572 }
1573 MaybeOwnedIndex::Owned(index) => {
1574 index.data.push(object);
1575 }
1576 }
1577
1578 self.len() - 1
1579 }
1580
1581 pub fn replace(&mut self, idx: usize, object: Vec<u8>) {
1589 match self {
1590 MaybeOwnedIndex::Borrowed(_) => {
1591 self.to_owned();
1592 self.replace(idx, object);
1593 }
1594 MaybeOwnedIndex::Owned(index) => index.data[idx] = object,
1595 }
1596 }
1597
1598 fn to_owned(&mut self) {
1600 match self {
1601 MaybeOwnedIndex::Borrowed(data) => {
1602 let data = data.iter().map(|obj| obj.to_owned()).collect();
1603 *self = MaybeOwnedIndex::Owned(owned::Index { data })
1604 }
1605 MaybeOwnedIndex::Owned(_) => {}
1606 }
1607 }
1608
1609 pub fn data_len(&self) -> usize {
1610 match self {
1611 MaybeOwnedIndex::Borrowed(index) => index.data_len(),
1612 MaybeOwnedIndex::Owned(index) => index.data.iter().map(|data| data.len()).sum(),
1613 }
1614 }
1615
1616 pub(crate) fn write32<C: WriteContext>(
1617 ctxt: &mut C,
1618 index: &MaybeOwnedIndex<'_>,
1619 ) -> Result<(), WriteError> {
1620 match index {
1621 MaybeOwnedIndex::Borrowed(index) => IndexU32::write(ctxt, index),
1622 MaybeOwnedIndex::Owned(index) => owned::IndexU32::write(ctxt, index),
1623 }
1624 }
1625
1626 pub(crate) fn write16<C: WriteContext>(
1627 ctxt: &mut C,
1628 index: &MaybeOwnedIndex<'_>,
1629 ) -> Result<(), WriteError> {
1630 match index {
1631 MaybeOwnedIndex::Borrowed(index) => IndexU16::write(ctxt, index),
1632 MaybeOwnedIndex::Owned(index) => owned::IndexU16::write(ctxt, index),
1633 }
1634 }
1635}
1636
1637impl<'a> Iterator for MaybeOwnedIndexIterator<'a> {
1638 type Item = &'a [u8];
1639
1640 fn next(&mut self) -> Option<Self::Item> {
1641 if self.index < self.data.len() {
1642 let index = self.index;
1643 self.index += 1;
1644 self.data.read_object(index)
1645 } else {
1646 None
1647 }
1648 }
1649
1650 fn size_hint(&self) -> (usize, Option<usize>) {
1651 let len = self.data.len();
1652 (len, Some(len))
1653 }
1654}
1655
1656impl DictDefault for TopDictDefault {
1657 fn default(op: Operator) -> Option<&'static [Operand]> {
1658 match op {
1659 Operator::IsFixedPitch => Some(&OPERAND_ZERO),
1660 Operator::ItalicAngle => Some(&OPERAND_ZERO),
1661 Operator::UnderlinePosition => Some(&DEFAULT_UNDERLINE_POSITION),
1662 Operator::UnderlineThickness => Some(&DEFAULT_UNDERLINE_THICKNESS),
1663 Operator::PaintType => Some(&OPERAND_ZERO),
1664 Operator::CharstringType => Some(&DEFAULT_CHARSTRING_TYPE),
1665 Operator::FontMatrix => Some(DEFAULT_FONT_MATRIX.as_ref()),
1666 Operator::FontBBox => Some(&DEFAULT_BBOX),
1667 Operator::StrokeWidth => Some(&OPERAND_ZERO),
1668 Operator::Charset => Some(&OFFSET_ZERO),
1669 Operator::Encoding => Some(&OFFSET_ZERO),
1670 Operator::CIDFontVersion => Some(&OPERAND_ZERO),
1671 Operator::CIDFontRevision => Some(&OPERAND_ZERO),
1672 Operator::CIDFontType => Some(&OPERAND_ZERO),
1673 Operator::CIDCount => Some(&DEFAULT_CID_COUNT),
1674 _ => None,
1675 }
1676 }
1677}
1678
1679impl DictDefault for FontDictDefault {
1680 fn default(_op: Operator) -> Option<&'static [Operand]> {
1681 None
1682 }
1683}
1684
1685impl DictDefault for PrivateDictDefault {
1686 fn default(op: Operator) -> Option<&'static [Operand]> {
1687 match op {
1688 Operator::BlueScale => Some(DEFAULT_BLUE_SCALE.as_ref()),
1689 Operator::BlueShift => Some(&DEFAULT_BLUE_SHIFT),
1690 Operator::BlueFuzz => Some(&DEFAULT_BLUE_FUZZ),
1691 Operator::ForceBold => Some(&OPERAND_ZERO),
1692 Operator::LanguageGroup => Some(&OPERAND_ZERO),
1693 Operator::ExpansionFactor => Some(DEFAULT_EXPANSION_FACTOR.as_ref()),
1694 Operator::InitialRandomSeed => Some(&OPERAND_ZERO),
1695 Operator::StrokeWidth => Some(&OPERAND_ZERO),
1696 Operator::DefaultWidthX => Some(&OPERAND_ZERO),
1697 Operator::NominalWidthX => Some(&OPERAND_ZERO),
1698 _ => None,
1699 }
1700 }
1701}
1702
1703impl<'a, T> Dict<T>
1704where
1705 T: DictDefault,
1706{
1707 pub fn new() -> Self {
1708 Dict {
1709 dict: Vec::new(),
1710 default: PhantomData,
1711 }
1712 }
1713
1714 pub fn get_with_default(&self, key: Operator) -> Option<&[Operand]> {
1715 self.get(key).or_else(|| T::default(key))
1716 }
1717
1718 pub fn get(&self, key: Operator) -> Option<&[Operand]> {
1719 self.dict.iter().find_map(|(op, args)| {
1720 if *op == key {
1721 Some(args.as_slice())
1722 } else {
1723 None
1724 }
1725 })
1726 }
1727
1728 pub fn get_i32(&self, key: Operator) -> Option<Result<i32, ParseError>> {
1730 self.get_with_default(key).map(|operands| match operands {
1731 [Operand::Integer(number)] => Ok(*number),
1732 [Operand::Offset(number)] => Ok(*number),
1733 _ => Err(ParseError::BadValue),
1734 })
1735 }
1736
1737 pub fn iter(&self) -> impl Iterator<Item = &(Operator, Vec<Operand>)> {
1738 self.dict.iter()
1739 }
1740
1741 pub fn first_operator(&self) -> Option<Operator> {
1743 self.iter().next().map(|(operator, _)| *operator)
1744 }
1745
1746 pub fn read_private_dict<D: ReadBinaryDep<Args<'a> = usize>>(
1751 &self,
1752 scope: &ReadScope<'a>,
1753 max_operands: usize,
1754 ) -> Result<(D::HostType<'a>, usize), ParseError> {
1755 let (private_dict_offset, private_dict_length) =
1756 match self.get_with_default(Operator::Private) {
1757 Some([Operand::Offset(length), Operand::Offset(offset)]) => {
1758 Ok((usize::try_from(*offset)?, usize::try_from(*length)?))
1759 }
1760 Some(_) => Err(ParseError::BadValue),
1761 None => Err(ParseError::MissingValue),
1762 }?;
1763 scope
1764 .offset_length(private_dict_offset, private_dict_length)?
1765 .read_dep::<D>(max_operands)
1766 .map(|dict| (dict, private_dict_offset))
1767 }
1768
1769 pub fn len(&self) -> usize {
1770 self.dict.len()
1771 }
1772
1773 fn inner_mut(&mut self) -> &mut Vec<(Operator, Vec<Operand>)> {
1774 &mut self.dict
1775 }
1776
1777 fn remove(&mut self, operator: Operator) {
1778 if let Some(index) = self.dict.iter().position(|(op, _)| *op == operator) {
1779 self.dict.remove(index);
1780 }
1781 }
1782
1783 fn replace(&mut self, operator: Operator, operands: Vec<Operand>) {
1787 match self.dict.iter().position(|(op, _)| *op == operator) {
1788 Some(index) => self.dict[index] = (operator, operands),
1789 None => self.dict.push((operator, operands)),
1790 }
1791 }
1792
1793 fn instance(
1797 &self,
1798 instance: &OwnedTuple,
1799 vstore: &ItemVariationStore<'_>,
1800 ) -> Result<Self, VariationError> {
1801 let mut dict = Vec::new();
1802 let mut vsindex = 0;
1803 let mut stack = ArgumentsStack {
1804 data: &mut [0.0; cff2::MAX_OPERANDS],
1805 len: 0,
1806 max_len: cff2::MAX_OPERANDS,
1807 };
1808
1809 for (op, operands) in self.iter() {
1810 match op {
1811 Operator::VSIndex => match operands.as_slice() {
1812 [Operand::Integer(variation_index)] => vsindex = *variation_index,
1813 _ => return Err(ParseError::BadValue.into()),
1814 },
1815 Operator::Blend => {
1816 operands
1818 .iter()
1819 .try_for_each(|operand| stack.push(f32::try_from(operand)?))?;
1820
1821 let scalars = cff2::scalars(
1822 u16::try_from(vsindex).map_err(ParseError::from)?,
1823 vstore,
1824 instance,
1825 )?;
1826
1827 cff2::blend(&scalars, &mut stack)?;
1828 }
1829 _ if !stack.is_empty() => {
1830 let mut new_operands = stack
1840 .pop_all()
1841 .iter()
1842 .copied()
1843 .map(Operand::from)
1844 .collect::<Vec<_>>();
1845 new_operands.extend(operands.iter().cloned());
1846 dict.push((*op, new_operands));
1847 }
1848 _ => dict.push((*op, operands.clone())),
1849 }
1850 }
1851
1852 Ok(Dict {
1853 dict,
1854 default: PhantomData,
1855 })
1856 }
1857}
1858
1859impl BlendOperand for f32 {
1860 fn try_as_i32(self) -> Option<i32> {
1861 i32::try_num_from(self)
1862 }
1863
1864 fn try_as_u16(self) -> Option<u16> {
1865 if self.fract() == 0.0 {
1866 u16::try_from(self as i32).ok()
1867 } else {
1868 None
1869 }
1870 }
1871
1872 fn try_as_u8(self) -> Option<u8> {
1873 u8::try_num_from(self)
1874 }
1875}
1876
1877impl DictDelta {
1878 pub fn new() -> Self {
1879 DictDelta { dict: Vec::new() }
1880 }
1881
1882 pub fn get(&self, key: Operator) -> Option<&[Operand]> {
1883 self.dict
1884 .iter()
1885 .filter_map(|(op, args)| {
1886 if *op == key {
1887 Some(args.as_slice())
1888 } else {
1889 None
1890 }
1891 })
1892 .next()
1893 }
1894
1895 pub fn push_offset(&mut self, operator: Operator, offset: i32) {
1897 self.dict
1898 .push((operator, tiny_vec!([Operand; 1] => Operand::Offset(offset))))
1899 }
1900
1901 pub fn push(&mut self, operator: Operator, operands: TinyVec<[Operand; 1]>) {
1905 assert!(operands.iter().all(Operand::is_offset));
1906 self.dict.push((operator, operands))
1907 }
1908}
1909
1910impl<'a> CIDData<'a> {
1911 pub fn font_dict(&self, index: usize) -> Result<FontDict, ParseError> {
1912 let data = self
1913 .font_dict_index
1914 .read_object(index)
1915 .ok_or(ParseError::BadIndex)?;
1916 ReadScope::new(data).read_dep::<FontDict>(MAX_OPERANDS)
1917 }
1918}
1919
1920impl TryFrom<u16> for Operator {
1921 type Error = ParseError;
1922
1923 fn try_from(value: u16) -> Result<Self, Self::Error> {
1924 if (value & 0xFF00) == (12 << 8) {
1925 match value as u8 {
1926 0 => Ok(Operator::Copyright),
1927 1 => Ok(Operator::IsFixedPitch),
1928 2 => Ok(Operator::ItalicAngle),
1929 3 => Ok(Operator::UnderlinePosition),
1930 4 => Ok(Operator::UnderlineThickness),
1931 5 => Ok(Operator::PaintType),
1932 6 => Ok(Operator::CharstringType),
1933 7 => Ok(Operator::FontMatrix),
1934 8 => Ok(Operator::StrokeWidth),
1935 9 => Ok(Operator::BlueScale),
1936 10 => Ok(Operator::BlueShift),
1937 11 => Ok(Operator::BlueFuzz),
1938 12 => Ok(Operator::StemSnapH),
1939 13 => Ok(Operator::StemSnapV),
1940 14 => Ok(Operator::ForceBold),
1941 17 => Ok(Operator::LanguageGroup),
1942 18 => Ok(Operator::ExpansionFactor),
1943 19 => Ok(Operator::InitialRandomSeed),
1944 20 => Ok(Operator::SyntheticBase),
1945 21 => Ok(Operator::PostScript),
1946 22 => Ok(Operator::BaseFontName),
1947 23 => Ok(Operator::BaseFontBlend),
1948 30 => Ok(Operator::ROS),
1949 31 => Ok(Operator::CIDFontVersion),
1950 32 => Ok(Operator::CIDFontRevision),
1951 33 => Ok(Operator::CIDFontType),
1952 34 => Ok(Operator::CIDCount),
1953 35 => Ok(Operator::UIDBase),
1954 36 => Ok(Operator::FDArray),
1955 37 => Ok(Operator::FDSelect),
1956 38 => Ok(Operator::FontName),
1957 _ => Err(ParseError::BadValue),
1958 }
1959 } else {
1960 match value {
1961 0 => Ok(Operator::Version),
1962 1 => Ok(Operator::Notice),
1963 2 => Ok(Operator::FullName),
1964 3 => Ok(Operator::FamilyName),
1965 4 => Ok(Operator::Weight),
1966 5 => Ok(Operator::FontBBox),
1967 6 => Ok(Operator::BlueValues),
1968 7 => Ok(Operator::OtherBlues),
1969 8 => Ok(Operator::FamilyBlues),
1970 9 => Ok(Operator::FamilyOtherBlues),
1971 10 => Ok(Operator::StdHW),
1972 11 => Ok(Operator::StdVW),
1973 13 => Ok(Operator::UniqueID),
1974 14 => Ok(Operator::XUID),
1975 15 => Ok(Operator::Charset),
1976 16 => Ok(Operator::Encoding),
1977 17 => Ok(Operator::CharStrings),
1978 18 => Ok(Operator::Private),
1979 19 => Ok(Operator::Subrs),
1980 20 => Ok(Operator::DefaultWidthX),
1981 21 => Ok(Operator::NominalWidthX),
1982 22 => Ok(Operator::VSIndex),
1984 23 => Ok(Operator::Blend),
1985 24 => Ok(Operator::VStore),
1986 _ => Err(ParseError::BadValue),
1987 }
1988 }
1989 }
1990}
1991
1992impl Operand {
1993 pub fn is_offset(&self) -> bool {
1994 matches!(self, Operand::Offset(_))
1995 }
1996
1997 fn bcd_encode(buf: &mut TinyVec<[u8; 32]>, val: f32) -> Operand {
1998 if val == 0.0 {
1999 Operand::Integer(0)
2000 } else if val.fract() == 0.0 {
2001 Operand::Integer(val as i32)
2002 } else {
2003 buf.clear();
2006 write!(buf, "{:E}", val).unwrap();
2008 if buf.ends_with(b"E0") {
2010 buf.truncate(buf.len() - 2);
2011 }
2012
2013 let mut chars = buf.iter().peekable();
2014 let mut bcd = tiny_vec!([u8; 7]);
2015 let mut pair = array_vec!([u8; 2]);
2016
2017 while let Some(c) = chars.next() {
2018 let nibble = match c {
2019 b'0'..=b'9' => c - b'0',
2020 b'.' => 0xA,
2021 b'E' if chars.peek() == Some(&&b'-') => {
2022 let _ = chars.next(); 0xC
2024 }
2025 b'E' => 0xB,
2026 b'-' => 0xE,
2027 _ => unreachable!(),
2028 };
2029 pair.push(nibble);
2030 if let [high, low] = pair.as_slice() {
2031 bcd.push((high << 4) | low);
2032 pair.clear();
2033 }
2034 }
2035
2036 match pair.as_slice() {
2038 [] => bcd.push(0xFF),
2042 [high] => bcd.push((high << 4) | 0xF),
2043 _ => unreachable!(),
2044 }
2045 Operand::Real(Real(bcd))
2046 }
2047 }
2048}
2049
2050impl TryFrom<&Operand> for f32 {
2051 type Error = ParseError;
2052
2053 fn try_from(operand: &Operand) -> Result<f32, Self::Error> {
2054 const MAX: i32 = 1 << f32::MANTISSA_DIGITS;
2055 const MIN: i32 = -MAX;
2056
2057 match operand {
2058 Operand::Integer(int) | Operand::Offset(int) => (MIN..=MAX)
2059 .contains(int)
2060 .then_some(*int as f32)
2061 .ok_or(ParseError::LimitExceeded),
2062 Operand::Real(r) => f64::try_from(r).map_err(ParseError::from).and_then(|val| {
2063 (f32::MIN as f64..=f32::MAX as f64)
2064 .contains(&val)
2065 .then_some(val as f32)
2066 .ok_or(ParseError::LimitExceeded)
2067 }),
2068 }
2069 }
2070}
2071
2072impl From<f32> for Operand {
2073 fn from(val: f32) -> Self {
2074 let mut buf = tiny_vec!([u8; 32]);
2075 Operand::bcd_encode(&mut buf, val)
2076 }
2077}
2078
2079impl Default for Operand {
2081 fn default() -> Self {
2082 Operand::Offset(0)
2083 }
2084}
2085
2086impl<'a> Font<'a> {
2087 pub fn is_cid_keyed(&self) -> bool {
2088 match self.data {
2089 CFFVariant::CID(_) => true,
2090 CFFVariant::Type1(_) => false,
2091 }
2092 }
2093
2094 pub(crate) fn seac_code_to_glyph_id(&self, code: u8) -> Option<GlyphId> {
2097 let sid = STANDARD_ENCODING[usize::from(code)];
2098
2099 match self.charset {
2100 Charset::ISOAdobe => {
2101 if code <= 228 {
2103 Some(u16::from(sid))
2104 } else {
2105 None
2106 }
2107 }
2108 Charset::Expert | Charset::ExpertSubset => None,
2109 Charset::Custom(_) => self.charset.sid_to_gid(u16::from(sid)),
2110 }
2111 }
2112}
2113
2114fn lookup_offset_index(off_size: u8, offset_array: &[u8], index: usize) -> usize {
2115 let buf = &offset_array[index * usize::from(off_size)..];
2116 match off_size {
2117 1 => buf[0] as usize,
2118 2 => BigEndian::read_u16(buf) as usize,
2119 3 => BigEndian::read_u24(buf) as usize,
2120 4 => BigEndian::read_u32(buf) as usize,
2121 _ => panic!("unexpected off_size"),
2122 }
2123}
2124
2125fn read_range_array<'a, F, N>(
2126 ctxt: &mut ReadCtxt<'a>,
2127 n_glyphs: usize,
2128) -> Result<ReadArray<'a, Range<F, N>>, ParseError>
2129where
2130 Range<F, N>: ReadFrom,
2131 usize: From<N>,
2132 N: num::Unsigned + Copy,
2133{
2134 let mut peek = ctxt.scope().ctxt();
2135 let mut range_count = 0;
2136 let mut glyphs_covered = 0;
2137 while glyphs_covered < n_glyphs {
2138 let range = peek.read::<Range<F, N>>()?;
2139 range_count += 1;
2140 glyphs_covered += range.len();
2141 }
2142
2143 ctxt.read_array::<Range<F, N>>(range_count)
2144}
2145
2146fn write_cff_variant<C: WriteContext>(
2147 ctxt: &mut C,
2148 variant: &CFFVariant<'_>,
2149 top_dict_delta: &mut DictDelta,
2150) -> Result<(), WriteError> {
2151 match variant {
2152 CFFVariant::CID(cid_data) => {
2153 let offsets = CIDData::write(ctxt, cid_data)?;
2154 top_dict_delta.push_offset(Operator::FDArray, i32::try_from(offsets.font_dict_index)?);
2155 top_dict_delta.push_offset(Operator::FDSelect, i32::try_from(offsets.fd_select)?);
2156 }
2157 CFFVariant::Type1(type1_data) => {
2158 let offsets = Type1Data::write(ctxt, type1_data)?;
2159 if let Some(custom_encoding_offset) = offsets.custom_encoding {
2160 top_dict_delta
2161 .push_offset(Operator::Encoding, i32::try_from(custom_encoding_offset)?);
2162 }
2163 top_dict_delta.push(
2164 Operator::Private,
2165 tiny_vec!([Operand; 1] =>
2166 Operand::Offset(i32::try_from(offsets.private_dict_len)?),
2167 Operand::Offset(i32::try_from(offsets.private_dict)?)),
2168 );
2169 }
2170 }
2171
2172 Ok(())
2173}
2174
2175fn read_cid_data<'a>(
2183 scope: &ReadScope<'a>,
2184 top_dict: &TopDict,
2185 n_glyphs: usize,
2186) -> Result<CIDData<'a>, ParseError> {
2187 let offset = top_dict
2197 .get_i32(Operator::FDArray)
2198 .ok_or(ParseError::MissingValue)??;
2199 let font_dict_index = scope.offset(usize::try_from(offset)?).read::<IndexU16>()?;
2200
2201 let offset = top_dict
2202 .get_i32(Operator::FDSelect)
2203 .ok_or(ParseError::MissingValue)??;
2204 let fd_select = scope
2205 .offset(usize::try_from(offset)?)
2206 .read_dep::<FDSelect<'a>>(n_glyphs)?;
2207
2208 let mut private_dicts = Vec::with_capacity(font_dict_index.count);
2209 let mut local_subr_indices = Vec::with_capacity(font_dict_index.count);
2210 for object in font_dict_index.iter() {
2211 let font_dict = ReadScope::new(object).read_dep::<FontDict>(MAX_OPERANDS)?;
2212 let (private_dict, private_dict_offset) =
2213 font_dict.read_private_dict::<PrivateDict>(scope, MAX_OPERANDS)?;
2214 let local_subr_index =
2215 read_local_subr_index::<_, IndexU16>(scope, &private_dict, private_dict_offset)?
2216 .map(MaybeOwnedIndex::Borrowed);
2217
2218 private_dicts.push(private_dict);
2219 local_subr_indices.push(local_subr_index);
2220 }
2221
2222 Ok(CIDData {
2223 font_dict_index: MaybeOwnedIndex::Borrowed(font_dict_index),
2224 private_dicts,
2225 local_subr_indices,
2226 fd_select,
2227 })
2228}
2229
2230impl<'a> WriteBinary<&Self> for CIDData<'a> {
2231 type Output = CIDDataOffsets;
2232
2233 fn write<C: WriteContext>(ctxt: &mut C, data: &Self) -> Result<Self::Output, WriteError> {
2234 let mut private_dict_offset_lengths = Vec::with_capacity(data.private_dicts.len());
2236 for (private_dict, local_subr_index) in data
2237 .private_dicts
2238 .iter()
2239 .zip(data.local_subr_indices.iter())
2240 {
2241 let offset = ctxt.bytes_written();
2242 let written_length =
2243 write_private_dict_and_local_subr_index(ctxt, private_dict, local_subr_index)?;
2244 private_dict_offset_lengths.push((offset, written_length));
2245 }
2246
2247 let mut font_dict_data = WriteBuffer::new();
2249 let mut font_dict_offsets = Vec::with_capacity(data.font_dict_index.len());
2250 for (object, (offset, length)) in data
2251 .font_dict_index
2252 .iter()
2253 .zip(private_dict_offset_lengths.into_iter())
2254 {
2255 let font_dict = ReadScope::new(object)
2256 .read_dep::<FontDict>(MAX_OPERANDS)
2257 .map_err(|_err| WriteError::BadValue)?;
2258 let mut font_dict_delta = DictDelta::new();
2259 font_dict_delta.push(
2260 Operator::Private,
2261 tiny_vec!([Operand; 1] =>
2262 Operand::Offset(i32::try_from(length)?),
2263 Operand::Offset(i32::try_from(offset)?)),
2264 );
2265
2266 font_dict_offsets.push(font_dict_data.bytes_written() + 1); FontDict::write_dep(&mut font_dict_data, &font_dict, font_dict_delta)?;
2268 }
2269 let last_font_dict_offset = font_dict_data.bytes_written() + 1;
2270 font_dict_offsets.push(last_font_dict_offset);
2271
2272 let (off_size, offset_array) = serialise_offset_array(font_dict_offsets)?;
2273 let font_dict_index = Index {
2274 count: data.font_dict_index.len(),
2275 off_size,
2276 offset_array: &offset_array,
2277 data_array: font_dict_data.bytes(),
2278 };
2279 let font_dict_index_offset = ctxt.bytes_written();
2280 IndexU16::write(ctxt, &font_dict_index)?;
2281
2282 let fd_select_offset = ctxt.bytes_written();
2283 FDSelect::write(ctxt, &data.fd_select)?;
2284
2285 Ok(CIDDataOffsets {
2286 font_dict_index: font_dict_index_offset,
2287 fd_select: fd_select_offset,
2288 })
2289 }
2290}
2291
2292impl<'a> WriteBinary<&Self> for Type1Data<'a> {
2293 type Output = Type1DataOffsets;
2294
2295 fn write<C: WriteContext>(ctxt: &mut C, data: &Self) -> Result<Self::Output, WriteError> {
2296 let mut offsets = Type1DataOffsets {
2297 custom_encoding: None,
2298 private_dict: ctxt.bytes_written(),
2299 private_dict_len: 0,
2300 };
2301
2302 offsets.private_dict_len = write_private_dict_and_local_subr_index(
2303 ctxt,
2304 &data.private_dict,
2305 &data.local_subr_index,
2306 )?;
2307
2308 if let Type1Data {
2309 encoding: Encoding::Custom(ref custom_encoding),
2310 ..
2311 } = data
2312 {
2313 offsets.custom_encoding = Some(ctxt.bytes_written());
2314 CustomEncoding::write(ctxt, custom_encoding)?;
2315 }
2316
2317 Ok(offsets)
2318 }
2319}
2320
2321fn write_private_dict_and_local_subr_index<C: WriteContext>(
2323 ctxt: &mut C,
2324 private_dict: &PrivateDict,
2325 local_subr_index: &Option<MaybeOwnedIndex<'_>>,
2326) -> Result<usize, WriteError> {
2327 let private_dict_length =
2329 PrivateDict::write_dep(&mut WriteCounter::new(), private_dict, DictDelta::new())?;
2330
2331 let mut private_dict_delta = DictDelta::new();
2333 if local_subr_index.is_some() {
2334 private_dict_delta.push_offset(Operator::Subrs, i32::try_from(private_dict_length)?);
2336 }
2337 let written_length = PrivateDict::write_dep(ctxt, private_dict, private_dict_delta)?;
2338 assert_eq!(written_length, private_dict_length);
2339
2340 if let Some(local_subr_index) = local_subr_index {
2341 MaybeOwnedIndex::write16(ctxt, local_subr_index)?;
2342 }
2343
2344 Ok(written_length)
2345}
2346
2347fn read_encoding<'a>(
2348 scope: &ReadScope<'a>,
2349 top_dict: &TopDict,
2350) -> Result<Encoding<'a>, ParseError> {
2351 let offset = top_dict
2352 .get_i32(Operator::Encoding)
2353 .ok_or(ParseError::MissingValue)??;
2354 let encoding = match offset {
2355 0 => Encoding::Standard,
2356 1 => Encoding::Expert,
2357 _ => Encoding::Custom(
2358 scope
2359 .offset(usize::try_from(offset)?)
2360 .read::<CustomEncoding<'_>>()?,
2361 ),
2362 };
2363
2364 Ok(encoding)
2365}
2366
2367fn read_charset<'a>(
2368 scope: &ReadScope<'a>,
2369 top_dict: &TopDict,
2370 char_strings_count: usize,
2371) -> Result<Charset<'a>, ParseError> {
2372 let offset = top_dict
2373 .get_i32(Operator::Charset)
2374 .ok_or(ParseError::MissingValue)??;
2375 let charset = match offset {
2376 0 => Charset::ISOAdobe,
2377 1 => Charset::Expert,
2378 2 => Charset::ExpertSubset,
2379 _ => Charset::Custom(
2380 scope
2381 .offset(usize::try_from(offset)?)
2382 .read_dep::<CustomCharset<'_>>(char_strings_count)?,
2383 ),
2384 };
2385
2386 Ok(charset)
2387}
2388
2389fn read_local_subr_index<'a, T, Idx>(
2390 scope: &ReadScope<'a>,
2391 private_dict: &Dict<T>,
2392 private_dict_offset: usize,
2393) -> Result<Option<Index<'a>>, ParseError>
2394where
2395 T: DictDefault,
2396 Idx: ReadBinary<HostType<'a> = Index<'a>>,
2397{
2398 private_dict
2403 .get_i32(Operator::Subrs)
2404 .transpose()?
2405 .map(|offset| {
2406 let offset = usize::try_from(offset)?;
2407 scope.offset(private_dict_offset + offset).read::<Idx>()
2408 })
2409 .transpose()
2410}
2411
2412fn serialise_offset_array(offsets: Vec<usize>) -> Result<(u8, Vec<u8>), WriteError> {
2414 if offsets.is_empty() {
2415 return Ok((1, Vec::new()));
2416 }
2417
2418 let off_size = offset_size(*offsets.last().unwrap()).ok_or(WriteError::BadValue)?;
2420 let mut offset_array = WriteBuffer::new();
2421 match off_size {
2422 1 => offset_array.write_iter::<U8, _>(offsets.into_iter().map(|offset| offset as u8))?,
2423
2424 2 => {
2425 offset_array.write_iter::<U16Be, _>(offsets.into_iter().map(|offset| offset as u16))?
2426 }
2427
2428 3 => {
2429 offset_array.write_iter::<U24Be, _>(offsets.into_iter().map(|offset| offset as u32))?
2430 }
2431
2432 4 => {
2433 offset_array.write_iter::<U32Be, _>(offsets.into_iter().map(|offset| offset as u32))?
2434 }
2435
2436 _ => unreachable!(), }
2438
2439 Ok((off_size, offset_array.into_inner()))
2440}
2441
2442impl<'a, 'data> CFFFont<'a, 'data> {
2443 pub fn is_cff(&self) -> bool {
2444 matches!(self, CFFFont::CFF(_))
2445 }
2446
2447 pub fn is_cff2(&self) -> bool {
2448 matches!(self, CFFFont::CFF2(_))
2449 }
2450}
2451
2452const STANDARD_STRINGS: [&str; 391] = [
2453 ".notdef",
2454 "space",
2455 "exclam",
2456 "quotedbl",
2457 "numbersign",
2458 "dollar",
2459 "percent",
2460 "ampersand",
2461 "quoteright",
2462 "parenleft",
2463 "parenright",
2464 "asterisk",
2465 "plus",
2466 "comma",
2467 "hyphen",
2468 "period",
2469 "slash",
2470 "zero",
2471 "one",
2472 "two",
2473 "three",
2474 "four",
2475 "five",
2476 "six",
2477 "seven",
2478 "eight",
2479 "nine",
2480 "colon",
2481 "semicolon",
2482 "less",
2483 "equal",
2484 "greater",
2485 "question",
2486 "at",
2487 "A",
2488 "B",
2489 "C",
2490 "D",
2491 "E",
2492 "F",
2493 "G",
2494 "H",
2495 "I",
2496 "J",
2497 "K",
2498 "L",
2499 "M",
2500 "N",
2501 "O",
2502 "P",
2503 "Q",
2504 "R",
2505 "S",
2506 "T",
2507 "U",
2508 "V",
2509 "W",
2510 "X",
2511 "Y",
2512 "Z",
2513 "bracketleft",
2514 "backslash",
2515 "bracketright",
2516 "asciicircum",
2517 "underscore",
2518 "quoteleft",
2519 "a",
2520 "b",
2521 "c",
2522 "d",
2523 "e",
2524 "f",
2525 "g",
2526 "h",
2527 "i",
2528 "j",
2529 "k",
2530 "l",
2531 "m",
2532 "n",
2533 "o",
2534 "p",
2535 "q",
2536 "r",
2537 "s",
2538 "t",
2539 "u",
2540 "v",
2541 "w",
2542 "x",
2543 "y",
2544 "z",
2545 "braceleft",
2546 "bar",
2547 "braceright",
2548 "asciitilde",
2549 "exclamdown",
2550 "cent",
2551 "sterling",
2552 "fraction",
2553 "yen",
2554 "florin",
2555 "section",
2556 "currency",
2557 "quotesingle",
2558 "quotedblleft",
2559 "guillemotleft",
2560 "guilsinglleft",
2561 "guilsinglright",
2562 "fi",
2563 "fl",
2564 "endash",
2565 "dagger",
2566 "daggerdbl",
2567 "periodcentered",
2568 "paragraph",
2569 "bullet",
2570 "quotesinglbase",
2571 "quotedblbase",
2572 "quotedblright",
2573 "guillemotright",
2574 "ellipsis",
2575 "perthousand",
2576 "questiondown",
2577 "grave",
2578 "acute",
2579 "circumflex",
2580 "tilde",
2581 "macron",
2582 "breve",
2583 "dotaccent",
2584 "dieresis",
2585 "ring",
2586 "cedilla",
2587 "hungarumlaut",
2588 "ogonek",
2589 "caron",
2590 "emdash",
2591 "AE",
2592 "ordfeminine",
2593 "Lslash",
2594 "Oslash",
2595 "OE",
2596 "ordmasculine",
2597 "ae",
2598 "dotlessi",
2599 "lslash",
2600 "oslash",
2601 "oe",
2602 "germandbls",
2603 "onesuperior",
2604 "logicalnot",
2605 "mu",
2606 "trademark",
2607 "Eth",
2608 "onehalf",
2609 "plusminus",
2610 "Thorn",
2611 "onequarter",
2612 "divide",
2613 "brokenbar",
2614 "degree",
2615 "thorn",
2616 "threequarters",
2617 "twosuperior",
2618 "registered",
2619 "minus",
2620 "eth",
2621 "multiply",
2622 "threesuperior",
2623 "copyright",
2624 "Aacute",
2625 "Acircumflex",
2626 "Adieresis",
2627 "Agrave",
2628 "Aring",
2629 "Atilde",
2630 "Ccedilla",
2631 "Eacute",
2632 "Ecircumflex",
2633 "Edieresis",
2634 "Egrave",
2635 "Iacute",
2636 "Icircumflex",
2637 "Idieresis",
2638 "Igrave",
2639 "Ntilde",
2640 "Oacute",
2641 "Ocircumflex",
2642 "Odieresis",
2643 "Ograve",
2644 "Otilde",
2645 "Scaron",
2646 "Uacute",
2647 "Ucircumflex",
2648 "Udieresis",
2649 "Ugrave",
2650 "Yacute",
2651 "Ydieresis",
2652 "Zcaron",
2653 "aacute",
2654 "acircumflex",
2655 "adieresis",
2656 "agrave",
2657 "aring",
2658 "atilde",
2659 "ccedilla",
2660 "eacute",
2661 "ecircumflex",
2662 "edieresis",
2663 "egrave",
2664 "iacute",
2665 "icircumflex",
2666 "idieresis",
2667 "igrave",
2668 "ntilde",
2669 "oacute",
2670 "ocircumflex",
2671 "odieresis",
2672 "ograve",
2673 "otilde",
2674 "scaron",
2675 "uacute",
2676 "ucircumflex",
2677 "udieresis",
2678 "ugrave",
2679 "yacute",
2680 "ydieresis",
2681 "zcaron",
2682 "exclamsmall",
2683 "Hungarumlautsmall",
2684 "dollaroldstyle",
2685 "dollarsuperior",
2686 "ampersandsmall",
2687 "Acutesmall",
2688 "parenleftsuperior",
2689 "parenrightsuperior",
2690 "twodotenleader",
2691 "onedotenleader",
2692 "zerooldstyle",
2693 "oneoldstyle",
2694 "twooldstyle",
2695 "threeoldstyle",
2696 "fouroldstyle",
2697 "fiveoldstyle",
2698 "sixoldstyle",
2699 "sevenoldstyle",
2700 "eightoldstyle",
2701 "nineoldstyle",
2702 "commasuperior",
2703 "threequartersemdash",
2704 "periodsuperior",
2705 "questionsmall",
2706 "asuperior",
2707 "bsuperior",
2708 "centsuperior",
2709 "dsuperior",
2710 "esuperior",
2711 "isuperior",
2712 "lsuperior",
2713 "msuperior",
2714 "nsuperior",
2715 "osuperior",
2716 "rsuperior",
2717 "ssuperior",
2718 "tsuperior",
2719 "ff",
2720 "ffi",
2721 "ffl",
2722 "parenleftinferior",
2723 "parenrightinferior",
2724 "Circumflexsmall",
2725 "hyphensuperior",
2726 "Gravesmall",
2727 "Asmall",
2728 "Bsmall",
2729 "Csmall",
2730 "Dsmall",
2731 "Esmall",
2732 "Fsmall",
2733 "Gsmall",
2734 "Hsmall",
2735 "Ismall",
2736 "Jsmall",
2737 "Ksmall",
2738 "Lsmall",
2739 "Msmall",
2740 "Nsmall",
2741 "Osmall",
2742 "Psmall",
2743 "Qsmall",
2744 "Rsmall",
2745 "Ssmall",
2746 "Tsmall",
2747 "Usmall",
2748 "Vsmall",
2749 "Wsmall",
2750 "Xsmall",
2751 "Ysmall",
2752 "Zsmall",
2753 "colonmonetary",
2754 "onefitted",
2755 "rupiah",
2756 "Tildesmall",
2757 "exclamdownsmall",
2758 "centoldstyle",
2759 "Lslashsmall",
2760 "Scaronsmall",
2761 "Zcaronsmall",
2762 "Dieresissmall",
2763 "Brevesmall",
2764 "Caronsmall",
2765 "Dotaccentsmall",
2766 "Macronsmall",
2767 "figuredash",
2768 "hypheninferior",
2769 "Ogoneksmall",
2770 "Ringsmall",
2771 "Cedillasmall",
2772 "questiondownsmall",
2773 "oneeighth",
2774 "threeeighths",
2775 "fiveeighths",
2776 "seveneighths",
2777 "onethird",
2778 "twothirds",
2779 "zerosuperior",
2780 "foursuperior",
2781 "fivesuperior",
2782 "sixsuperior",
2783 "sevensuperior",
2784 "eightsuperior",
2785 "ninesuperior",
2786 "zeroinferior",
2787 "oneinferior",
2788 "twoinferior",
2789 "threeinferior",
2790 "fourinferior",
2791 "fiveinferior",
2792 "sixinferior",
2793 "seveninferior",
2794 "eightinferior",
2795 "nineinferior",
2796 "centinferior",
2797 "dollarinferior",
2798 "periodinferior",
2799 "commainferior",
2800 "Agravesmall",
2801 "Aacutesmall",
2802 "Acircumflexsmall",
2803 "Atildesmall",
2804 "Adieresissmall",
2805 "Aringsmall",
2806 "AEsmall",
2807 "Ccedillasmall",
2808 "Egravesmall",
2809 "Eacutesmall",
2810 "Ecircumflexsmall",
2811 "Edieresissmall",
2812 "Igravesmall",
2813 "Iacutesmall",
2814 "Icircumflexsmall",
2815 "Idieresissmall",
2816 "Ethsmall",
2817 "Ntildesmall",
2818 "Ogravesmall",
2819 "Oacutesmall",
2820 "Ocircumflexsmall",
2821 "Otildesmall",
2822 "Odieresissmall",
2823 "OEsmall",
2824 "Oslashsmall",
2825 "Ugravesmall",
2826 "Uacutesmall",
2827 "Ucircumflexsmall",
2828 "Udieresissmall",
2829 "Yacutesmall",
2830 "Thornsmall",
2831 "Ydieresissmall",
2832 "001.000",
2833 "001.001",
2834 "001.002",
2835 "001.003",
2836 "Black",
2837 "Bold",
2838 "Book",
2839 "Light",
2840 "Medium",
2841 "Regular",
2842 "Roman",
2843 "Semibold",
2844];
2845
2846#[allow(dead_code)]
2847const STANDARD_ENCODING: [u8; 256] = [
2848 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 0, 111, 112, 113, 114, 0, 115, 116, 117, 118, 119, 120, 121, 122, 0, 123, 0, 124, 125, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 134, 135, 136, 137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 0, 139, 0, 0, 0, 0, 140, 141, 142, 143, 0, 0, 0, 0, 0, 144, 0, 0, 0, 145, 0, 0, 146, 147, 148, 149, 0, 0, 0, 0, ];
3105
3106const EXPERT_CHARSET: [u16; 166] = [
3107 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, ];
3274
3275const EXPERT_SUBSET_CHARSET: [u16; 87] = [
3276 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, ];
3364
3365#[cfg(test)]
3366mod tests {
3367 use super::*;
3368 use crate::binary::read::ReadScope;
3369
3370 fn assert_close(actual: f64, expected: f64) {
3371 assert!(
3372 (actual - expected).abs() < f64::EPSILON,
3373 "{:?} != {:?} ± {}",
3374 actual,
3375 expected,
3376 f64::EPSILON
3377 );
3378 }
3379
3380 #[test]
3381 fn test_iter_index() {
3382 let offset_array = [1, 2, 3];
3383 let data_array = [4, 5];
3384 let index = Index {
3385 count: 2,
3386 off_size: 1,
3387 offset_array: &offset_array,
3388 data_array: &data_array,
3389 };
3390
3391 assert_eq!(index.iter().collect::<Vec<_>>(), vec![[4], [5]]);
3392 }
3393
3394 #[test]
3395 fn test_read_op1() {
3396 let mut ctxt = ReadScope::new(&[0, 0]).ctxt();
3397 assert_eq!(
3398 Op::read(&mut ctxt).unwrap(),
3399 Op::Operator(Operator::Version)
3400 );
3401 }
3402
3403 #[test]
3404 fn test_fail_op1() {
3405 let mut ctxt = ReadScope::new(&[]).ctxt();
3406 assert!(Op::read(&mut ctxt).is_err());
3407 }
3408
3409 #[test]
3410 fn test_read_op2() {
3411 let mut ctxt = ReadScope::new(&[12, 1]).ctxt();
3412 assert_eq!(
3413 Op::read(&mut ctxt).unwrap(),
3414 Op::Operator(Operator::IsFixedPitch)
3415 );
3416 }
3417
3418 #[test]
3419 fn test_fail_op2() {
3420 let mut ctxt = ReadScope::new(&[12]).ctxt();
3421 assert!(Op::read(&mut ctxt).is_err());
3422 }
3423
3424 #[test]
3425 fn test_read_i8() {
3426 let mut ctxt = ReadScope::new(&[0x8b]).ctxt();
3427 assert_eq!(
3428 Op::read(&mut ctxt).unwrap(),
3429 Op::Operand(Operand::Integer(0))
3430 );
3431 }
3432
3433 #[test]
3434 fn test_read_i16() {
3435 let mut ctxt = ReadScope::new(&[0x1c, 0xd8, 0xf0, 0x1c, 0x27, 0x10, 0xef, 0x27]).ctxt();
3437 assert_eq!(
3438 Op::read(&mut ctxt).unwrap(),
3439 Op::Operand(Operand::Integer(-10000))
3440 );
3441 assert_eq!(
3442 Op::read(&mut ctxt).unwrap(),
3443 Op::Operand(Operand::Integer(10000))
3444 );
3445 assert_eq!(
3446 Op::read(&mut ctxt).unwrap(),
3447 Op::Operand(Operand::Integer(100))
3448 );
3449 assert_eq!(
3450 Op::read(&mut ctxt).unwrap(),
3451 Op::Operand(Operand::Integer(-100))
3452 );
3453 }
3454
3455 #[test]
3456 fn test_read_i32() {
3457 let mut ctxt =
3459 ReadScope::new(&[0x1d, 0xff, 0xfe, 0x79, 0x60, 0x1d, 0x00, 0x01, 0x86, 0xa0]).ctxt();
3460 assert_eq!(
3461 Op::read(&mut ctxt).unwrap(),
3462 Op::Operand(Operand::Integer(-100000))
3463 );
3464 assert_eq!(
3465 Op::read(&mut ctxt).unwrap(),
3466 Op::Operand(Operand::Integer(100000))
3467 );
3468 }
3469
3470 #[test]
3471 fn test_read_real() {
3472 let mut ctxt = ReadScope::new(&[
3476 0x1e, 0xe2, 0xa2, 0x5f, 0x1e, 0x0a, 0x14, 0x05, 0x41, 0xc3, 0xff,
3478 ])
3479 .ctxt();
3480 let op = Op::read(&mut ctxt).unwrap();
3481 assert_eq!(
3482 op,
3483 Op::Operand(Operand::Real(Real(tiny_vec![0xe2, 0xa2, 0x5f])))
3484 );
3485 let Op::Operand(Operand::Real(real)) = op else {
3486 panic!("op didn't match Real")
3487 };
3488 assert_close(f64::try_from(&real).unwrap(), -2.25);
3489 let op = Op::read(&mut ctxt).unwrap();
3490 assert_eq!(
3491 op,
3492 Op::Operand(Operand::Real(Real(tiny_vec![
3493 0x0a, 0x14, 0x05, 0x41, 0xc3, 0xff
3494 ])))
3495 );
3496 let Op::Operand(Operand::Real(real)) = op else {
3497 panic!("op didn't match Real")
3498 };
3499 assert_close(f64::try_from(&real).unwrap(), 0.000140541);
3500 }
3501
3502 #[test]
3503 fn test_read_top_dict() {
3504 let expected = TopDict {
3505 dict: vec![
3506 (Operator::IsFixedPitch, vec![Operand::Integer(1)]),
3507 (Operator::Notice, vec![Operand::Integer(123)]),
3508 ],
3509 default: PhantomData,
3510 };
3511 let mut ctxt = ReadScope::new(&[0x8c, 12, 1, 247, 15, 1]).ctxt();
3515 assert_eq!(
3516 TopDict::read_dep(&mut ctxt, MAX_OPERANDS).unwrap(),
3517 expected
3518 );
3519 }
3520
3521 #[test]
3522 fn test_write_top_dict() {
3523 let dict = TopDict {
3524 dict: vec![
3525 (Operator::IsFixedPitch, vec![Operand::Integer(1)]),
3526 (Operator::Notice, vec![Operand::Integer(123)]),
3527 (Operator::PaintType, vec![Operand::Integer(0)]),
3529 ],
3530 default: PhantomData,
3531 };
3532 let expected = [0x8c, 12, 1, 247, 15, 1];
3536 let mut ctxt = WriteBuffer::new();
3537 TopDict::write_dep(&mut ctxt, &dict, DictDelta::new()).unwrap();
3538
3539 assert_eq!(ctxt.bytes(), &expected);
3540 }
3541
3542 #[test]
3543 fn test_write_top_dict_delta() {
3544 let dict = TopDict {
3545 dict: vec![(Operator::CharStrings, vec![Operand::Offset(123)])],
3546 default: PhantomData,
3547 };
3548 let mut delta = DictDelta::new();
3549 delta.push(
3550 Operator::CharStrings,
3551 tiny_vec!([Operand; 1] => Operand::Offset(1000)),
3552 );
3553
3554 let expected = [29, 0, 0, 0x03, 0xE8, 17];
3558 let mut ctxt = WriteBuffer::new();
3559 TopDict::write_dep(&mut ctxt, &dict, delta).unwrap();
3560
3561 assert_eq!(ctxt.bytes(), &expected);
3563 }
3564
3565 #[test]
3566 fn test_write_top_dict_size() {
3567 let dict = TopDict {
3568 dict: vec![
3569 (Operator::IsFixedPitch, vec![Operand::Integer(1)]),
3570 (Operator::Notice, vec![Operand::Integer(123)]),
3571 (Operator::PaintType, vec![Operand::Integer(0)]),
3573 ],
3574 default: PhantomData,
3575 };
3576 let mut counter = WriteCounter::new();
3577 TopDict::write_dep(&mut counter, &dict, DictDelta::new()).unwrap();
3578
3579 assert_eq!(counter.bytes_written(), 6);
3580 }
3581
3582 #[test]
3583 fn test_read_top_dict_operand_limit() {
3584 let mut ctxt = ReadScope::new(&[0x8c; 2]).ctxt();
3585 match TopDict::read_dep(&mut ctxt, 1) {
3586 Err(ParseError::LimitExceeded) => {}
3587 _ => panic!("expected Err(ParseError::LimitExceeded) got something else"),
3588 }
3589 }
3590
3591 #[test]
3592 fn test_read_empty_private_dict() {
3593 let dict = ReadScope::new(&[]).read_dep::<PrivateDict>(MAX_OPERANDS);
3596 assert!(dict.is_ok());
3597 }
3598
3599 #[test]
3600 fn test_read_custom_encoding_format0() {
3601 let data_format0 = [0, 3, 4, 5, 6];
3602 let mut ctxt = ReadScope::new(&data_format0).ctxt();
3603 let format0_encoding = ctxt.read::<CustomEncoding<'_>>().unwrap();
3604 match format0_encoding {
3605 CustomEncoding::Format0 { codes } => {
3606 assert_eq!(codes.iter().collect_vec(), vec![4, 5, 6])
3607 }
3608 _ => panic!("expected CustomEncoding::Format0 got something else"),
3609 }
3610 }
3611
3612 #[test]
3613 fn test_read_custom_encoding_format1() {
3614 let data_format1 = [1, 2, 4, 5, 6, 7];
3615 let mut ctxt = ReadScope::new(&data_format1).ctxt();
3616 let format1_encoding = ctxt.read::<CustomEncoding<'_>>().unwrap();
3617 match format1_encoding {
3618 CustomEncoding::Format1 { ranges } => assert_eq!(
3619 ranges.iter().collect_vec(),
3620 vec![
3621 Range {
3622 first: 4,
3623 n_left: 5
3624 },
3625 Range {
3626 first: 6,
3627 n_left: 7
3628 }
3629 ]
3630 ),
3631 _ => panic!("expected CustomEncoding::Format1 got something else"),
3632 }
3633 }
3634
3635 #[test]
3636 fn test_read_custom_charset_format0() {
3637 let n_glyphs = 2;
3638 let data_format0 = [0, 0xAA, 0xBB];
3639 let mut ctxt = ReadScope::new(&data_format0).ctxt();
3640 let format0_charset = ctxt.read_dep::<CustomCharset<'_>>(n_glyphs).unwrap();
3641 match format0_charset {
3642 CustomCharset::Format0 { glyphs } => {
3643 assert_eq!(glyphs.iter().collect_vec(), vec![0xAABB])
3644 }
3645 _ => panic!("expected CustomCharset::Format0 got something else"),
3646 }
3647 }
3648
3649 #[test]
3650 fn test_read_custom_charset_format1() {
3651 let n_glyphs = 5;
3652 let data_format1 = [1, 0, 1, 3];
3653 let mut ctxt = ReadScope::new(&data_format1).ctxt();
3654 let format1_charset = ctxt.read_dep::<CustomCharset<'_>>(n_glyphs).unwrap();
3655 match format1_charset {
3656 CustomCharset::Format1 { ranges } => assert_eq!(
3657 ranges.iter().collect_vec(),
3658 vec![Range {
3659 first: 1,
3660 n_left: 3
3661 },]
3662 ),
3663 _ => panic!("expected CustomCharset::Format1 got something else"),
3664 }
3665 }
3666
3667 #[test]
3668 fn test_read_custom_charset_format2() {
3669 let n_glyphs = 5;
3670 let data_format2 = [2, 0, 1, 0, 3];
3671 let mut ctxt = ReadScope::new(&data_format2).ctxt();
3672 let format2_charset = ctxt.read_dep::<CustomCharset<'_>>(n_glyphs).unwrap();
3673 match format2_charset {
3674 CustomCharset::Format2 { ranges } => assert_eq!(
3675 ranges.iter().collect_vec(),
3676 vec![Range {
3677 first: 1,
3678 n_left: 3
3679 },]
3680 ),
3681 _ => panic!("expected CustomCharset::Format2 got something else"),
3682 }
3683 }
3684
3685 #[test]
3686 fn test_read_write_index() {
3687 let mut count = vec![0, 1];
3688 let off_size = 3;
3689 let mut offset0 = vec![0, 0, 1];
3690 let mut offset1 = vec![0, 0, 2];
3691 let object = 5;
3692
3693 let mut data = Vec::new();
3695 data.append(&mut count);
3696 data.push(off_size);
3697 data.append(&mut offset0);
3698 data.append(&mut offset1);
3699 data.push(object);
3700
3701 let mut ctxt = ReadScope::new(&data).ctxt();
3703 let index = ctxt.read::<IndexU16>().unwrap();
3704
3705 let actual: Vec<_> = index.iter().collect();
3706 assert_eq!(actual, &[&[5]]);
3707
3708 let mut ctxt = WriteBuffer::new();
3710 IndexU16::write(&mut ctxt, &index).unwrap();
3711
3712 assert_eq!(ctxt.bytes(), &[0, 1, 3, 0, 0, 1, 0, 0, 2, 5]);
3713 }
3714
3715 #[test]
3716 fn test_write_int_operand() {
3717 assert_eq!(write_int_operand(0), &[0x8b]);
3718 assert_eq!(write_int_operand(100), &[0xef]);
3719 assert_eq!(write_int_operand(-100), &[0x27]);
3720 assert_eq!(write_int_operand(1000), &[0xfa, 0x7c]);
3721 assert_eq!(write_int_operand(-1000), &[0xfe, 0x7c]);
3722 assert_eq!(write_int_operand(10000), &[0x1c, 0x27, 0x10]);
3723 assert_eq!(write_int_operand(-10000), &[0x1c, 0xd8, 0xf0]);
3724 assert_eq!(write_int_operand(100000), &[0x1d, 0x00, 0x01, 0x86, 0xa0]);
3725 assert_eq!(write_int_operand(-100000), &[0x1d, 0xff, 0xfe, 0x79, 0x60]);
3726 }
3727
3728 #[test]
3729 fn test_write_int_operand_round_trip() {
3730 int_operand_round_trip(0);
3731 int_operand_round_trip(100);
3732 int_operand_round_trip(540);
3733 int_operand_round_trip(-100);
3734 int_operand_round_trip(-267);
3735 int_operand_round_trip(1000);
3736 int_operand_round_trip(-1000);
3737 int_operand_round_trip(10000);
3738 int_operand_round_trip(-10000);
3739 int_operand_round_trip(100000);
3740 int_operand_round_trip(-100000);
3741 }
3742
3743 fn int_operand_round_trip(val: i32) {
3744 let int = write_int_operand(val);
3745 match ReadScope::new(&int).read::<Op>().unwrap() {
3746 Op::Operand(Operand::Integer(actual)) => assert_eq!(actual, val),
3747 _ => unreachable!(),
3748 }
3749 }
3750
3751 fn write_int_operand(val: i32) -> Vec<u8> {
3752 let mut ctxt = WriteBuffer::new();
3753 Operand::write(&mut ctxt, &Operand::Integer(val)).unwrap();
3754 ctxt.into_inner()
3755 }
3756
3757 #[test]
3758 fn test_fd_select_font_dict_index_format0() {
3759 let glyph_font_dict_indices = ReadArrayCow::Owned(vec![1, 2, 3]);
3760 let fd_select = FDSelect::Format0 {
3761 glyph_font_dict_indices,
3762 };
3763
3764 assert_eq!(fd_select.font_dict_index(2), Some(3));
3765 assert_eq!(fd_select.font_dict_index(3), None);
3766 }
3767
3768 #[test]
3769 fn test_fd_select_font_dict_index_format3() {
3770 let ranges: Vec<Range<u16, u8>> = vec![
3775 Range {
3776 first: 0,
3777 n_left: 2,
3778 },
3779 Range {
3780 first: 10,
3781 n_left: 1,
3782 },
3783 Range {
3784 first: 17,
3785 n_left: 0,
3786 },
3787 ];
3788 let fd_select = FDSelect::Format3 {
3789 ranges: ReadArrayCow::Owned(ranges),
3790 sentinel: 33,
3791 };
3792
3793 assert_eq!(fd_select.font_dict_index(2), Some(2));
3794 assert_eq!(fd_select.font_dict_index(10), Some(1));
3795 assert_eq!(fd_select.font_dict_index(32), Some(0));
3796 assert_eq!(fd_select.font_dict_index(33), None);
3797 }
3798
3799 #[test]
3800 fn test_charset_id_for_glyph_pre_defined_charsets() {
3801 assert_eq!(Charset::ISOAdobe.id_for_glyph(2), Some(2));
3802 assert_eq!(Charset::ISOAdobe.id_for_glyph(300), None);
3803 assert_eq!(Charset::Expert.id_for_glyph(2), Some(229));
3804 assert_eq!(Charset::Expert.id_for_glyph(300), None);
3805 assert_eq!(Charset::ExpertSubset.id_for_glyph(2), Some(231));
3806 assert_eq!(Charset::ExpertSubset.id_for_glyph(300), None);
3807 }
3808
3809 #[test]
3810 fn test_custom_charset_id_for_glyph_format0() {
3811 let glyph_sids = ReadArrayCow::Owned(vec![1, 2, 3]);
3812 let charset = CustomCharset::Format0 { glyphs: glyph_sids };
3813
3814 assert_eq!(charset.id_for_glyph(0), Some(0));
3816 assert_eq!(charset.id_for_glyph(1), Some(1));
3817 assert_eq!(charset.id_for_glyph(4), None);
3818 }
3819
3820 #[test]
3821 fn test_custom_charset_id_for_glyph_format1() {
3822 let ranges = ReadArrayCow::Owned(vec![Range {
3823 first: 34,
3824 n_left: 5,
3825 }]);
3826 let charset = CustomCharset::Format1 { ranges };
3827
3828 assert_eq!(charset.id_for_glyph(0), Some(0));
3830 assert_eq!(charset.id_for_glyph(1), Some(34));
3831 assert_eq!(charset.id_for_glyph(6), Some(39));
3832 assert_eq!(charset.id_for_glyph(7), None);
3833 }
3834
3835 #[test]
3836 fn test_custom_charset_id_for_glyph_format2() {
3837 let ranges = ReadArrayCow::Owned(vec![Range {
3838 first: 34,
3839 n_left: 5,
3840 }]);
3841 let charset = CustomCharset::Format2 { ranges };
3842
3843 assert_eq!(charset.id_for_glyph(0), Some(0));
3845 assert_eq!(charset.id_for_glyph(1), Some(34));
3846 assert_eq!(charset.id_for_glyph(6), Some(39));
3847 assert_eq!(charset.id_for_glyph(7), None);
3848 }
3849
3850 #[test]
3851 fn test_arno_custom_charset_ranges() {
3852 #[rustfmt::skip]
3855 let ranges = ReadArrayCow::Owned(vec![
3856 Range { first: 1, n_left: 107, },
3857 Range { first: 111, n_left: 38, },
3858 Range { first: 151, n_left: 12, },
3859 Range { first: 165, n_left: 3, },
3860 Range { first: 170, n_left: 58, },
3861 Range { first: 237, n_left: 1, },
3862 Range { first: 391, n_left: 0, },
3863 Range { first: 393, n_left: 0, },
3864 Range { first: 300, n_left: 0, },
3865 Range { first: 392, n_left: 0, },
3866 Range { first: 314, n_left: 0, },
3867 Range { first: 324, n_left: 1, },
3868 Range { first: 320, n_left: 3, },
3869 Range { first: 394, n_left: 2577, },
3870 Range { first: 109, n_left: 1, },
3871 Range { first: 2972, n_left: 28, },
3872 Range { first: 2846, n_left: 768, },
3873 ]);
3874 let charset = CustomCharset::Format2 { ranges };
3875
3876 assert_eq!(charset.id_for_glyph(134), Some(136));
3878 assert_eq!(charset.id_for_glyph(265), Some(422));
3879 assert_eq!(charset.id_for_glyph(279), Some(436));
3880 }
3881
3882 #[test]
3883 fn test_custom_charset_iter() {
3884 #[rustfmt::skip]
3887 let ranges = ReadArrayCow::Owned(vec![
3888 Range { first: 111, n_left: 4, },
3889 Range { first: 1, n_left: 3, },
3890 Range { first: 2972, n_left: 2, },
3891 ]);
3892 let charset = CustomCharset::Format2 { ranges };
3893 let actual = charset.iter().collect_vec();
3894 let expected = vec![0, 111, 112, 113, 114, 115, 1, 2, 3, 4, 2972, 2973, 2974];
3895
3896 assert_eq!(actual, expected);
3897 }
3898
3899 #[test]
3900 fn test_read_standard_string() {
3901 let data = b"Ferris";
3902 let offsets = [1, (data.len() + 1) as u8];
3903 let string_index = MaybeOwnedIndex::Borrowed(Index {
3904 count: 1,
3905 off_size: 1,
3906 offset_array: &offsets,
3907 data_array: data,
3908 });
3909
3910 assert_eq!(
3911 read_string_index_string(&string_index, 7).unwrap(),
3912 "ampersand"
3913 );
3914 assert_eq!(
3915 read_string_index_string(&string_index, 390).unwrap(),
3916 "Semibold"
3917 );
3918 }
3919
3920 #[test]
3921 fn test_read_custom_string() {
3922 let data = b"Ferris";
3923 let offsets = [1, (data.len() + 1) as u8];
3924 let string_index = MaybeOwnedIndex::Borrowed(Index {
3925 count: 1,
3926 off_size: 1,
3927 offset_array: &offsets,
3928 data_array: data,
3929 });
3930
3931 assert_eq!(
3932 read_string_index_string(&string_index, 391).unwrap(),
3933 "Ferris"
3934 );
3935 assert!(read_string_index_string(&string_index, 392).is_err());
3936 }
3937
3938 #[test]
3939 fn bcd_encode() {
3940 let mut buf = tiny_vec!([u8; 32]);
3941 assert_eq!(Operand::bcd_encode(&mut buf, 0.0), Operand::Integer(0));
3942 assert_eq!(Operand::bcd_encode(&mut buf, 1.0), Operand::Integer(1));
3943 assert_eq!(Operand::bcd_encode(&mut buf, -1.0), Operand::Integer(-1));
3944 assert_eq!(
3945 Operand::bcd_encode(&mut buf, -2.25),
3946 Operand::Real(Real(tiny_vec![0xe2, 0xa2, 0x5f]))
3947 );
3948 assert_eq!(
3949 Operand::bcd_encode(&mut buf, 1.140541E-3),
3950 Operand::Real(Real(tiny_vec![0x1a, 0x14, 0x05, 0x41, 0xc3, 0xff]))
3951 );
3952 }
3953}