|
| 1 | +use std::marker::PhantomData; |
| 2 | + |
1 | 3 | use super::*;
|
2 | 4 |
|
3 | 5 | /// Writer for a _Type-1 font dictionary_.
|
@@ -653,13 +655,17 @@ impl<'a> Cmap<'a> {
|
653 | 655 | deref!('a, Cmap<'a> => Stream<'a>, stream);
|
654 | 656 |
|
655 | 657 | /// A builder for a `/ToUnicode` character map stream.
|
656 |
| -pub struct UnicodeCmap { |
| 658 | +pub struct UnicodeCmap<G = u16> { |
657 | 659 | buf: Vec<u8>,
|
658 | 660 | mappings: Vec<u8>,
|
659 | 661 | count: i32,
|
| 662 | + glyph_id: PhantomData<G>, |
660 | 663 | }
|
661 | 664 |
|
662 |
| -impl UnicodeCmap { |
| 665 | +impl<G> UnicodeCmap<G> |
| 666 | +where |
| 667 | + G: GlyphId, |
| 668 | +{ |
663 | 669 | /// Create a new, empty unicode character map.
|
664 | 670 | pub fn new(name: Name, info: SystemInfo) -> Self {
|
665 | 671 | // https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5014.CIDFont_Spec.pdf
|
@@ -710,25 +716,34 @@ impl UnicodeCmap {
|
710 | 716 |
|
711 | 717 | // We just cover the whole unicode codespace.
|
712 | 718 | buf.extend(b"1 begincodespacerange\n");
|
713 |
| - buf.extend(b"<0000> <ffff>\n"); |
| 719 | + buf.push(b'<'); |
| 720 | + G::MIN.push(&mut buf); |
| 721 | + buf.extend(b"> <"); |
| 722 | + G::MAX.push(&mut buf); |
| 723 | + buf.extend(b">\n"); |
714 | 724 | buf.extend(b"endcodespacerange\n");
|
715 | 725 |
|
716 |
| - Self { buf, mappings: vec![], count: 0 } |
| 726 | + Self { |
| 727 | + buf, |
| 728 | + mappings: vec![], |
| 729 | + count: 0, |
| 730 | + glyph_id: PhantomData, |
| 731 | + } |
717 | 732 | }
|
718 | 733 |
|
719 | 734 | /// Add a mapping from a glyph ID to a codepoint.
|
720 |
| - pub fn pair(&mut self, glyph: u16, codepoint: char) { |
| 735 | + pub fn pair(&mut self, glyph: G, codepoint: char) { |
721 | 736 | self.pair_with_multiple(glyph, [codepoint]);
|
722 | 737 | }
|
723 | 738 |
|
724 | 739 | /// Add a mapping from a glyph ID to multiple codepoints.
|
725 | 740 | pub fn pair_with_multiple(
|
726 | 741 | &mut self,
|
727 |
| - glyph: u16, |
| 742 | + glyph: G, |
728 | 743 | codepoints: impl IntoIterator<Item = char>,
|
729 | 744 | ) {
|
730 | 745 | self.mappings.push(b'<');
|
731 |
| - self.mappings.push_hex_u16(glyph); |
| 746 | + glyph.push(&mut self.mappings); |
732 | 747 | self.mappings.extend(b"> <");
|
733 | 748 |
|
734 | 749 | for c in codepoints {
|
@@ -775,6 +790,45 @@ impl UnicodeCmap {
|
775 | 790 | }
|
776 | 791 | }
|
777 | 792 |
|
| 793 | +/// Type3 fonts require (in Acrobat at least) IDs in CMaps to be encoded with |
| 794 | +/// one byte only, whereas other font types use two bytes. |
| 795 | +/// |
| 796 | +/// This trait provides an abstraction to support both. |
| 797 | +pub trait GlyphId: private::Sealed {} |
| 798 | + |
| 799 | +impl GlyphId for u8 {} |
| 800 | + |
| 801 | +impl GlyphId for u16 {} |
| 802 | + |
| 803 | +/// Module to seal the `GlyphId` trait. |
| 804 | +mod private { |
| 805 | + use crate::buf::BufExt; |
| 806 | + |
| 807 | + pub trait Sealed { |
| 808 | + const MIN: Self; |
| 809 | + const MAX: Self; |
| 810 | + fn push(self, buf: &mut Vec<u8>); |
| 811 | + } |
| 812 | + |
| 813 | + impl Sealed for u8 { |
| 814 | + const MIN: Self = u8::MIN; |
| 815 | + const MAX: Self = u8::MAX; |
| 816 | + |
| 817 | + fn push(self, buf: &mut Vec<u8>) { |
| 818 | + buf.push_hex(self); |
| 819 | + } |
| 820 | + } |
| 821 | + |
| 822 | + impl Sealed for u16 { |
| 823 | + const MIN: Self = u16::MIN; |
| 824 | + const MAX: Self = u16::MAX; |
| 825 | + |
| 826 | + fn push(self, buf: &mut Vec<u8>) { |
| 827 | + buf.push_hex_u16(self); |
| 828 | + } |
| 829 | + } |
| 830 | +} |
| 831 | + |
778 | 832 | /// Specifics about a character collection.
|
779 | 833 | #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
|
780 | 834 | pub struct SystemInfo<'a> {
|
|
0 commit comments