Skip to content

Commit 4e9077b

Browse files
authored
Merge pull request #225 from martin-kolarik/fix-of-duplicate-remapping
Fix of duplicate remapping for codepoints, cleanup, many temporary allocations removed
2 parents 53e1f02 + bd3b60c commit 4e9077b

File tree

4 files changed

+104
-145
lines changed

4 files changed

+104
-145
lines changed

src/font.rs

Lines changed: 27 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,8 @@ impl ParsedFont {
614614
map.insert(sp, ' ');
615615
}
616616

617+
map.insert(0, '\0');
618+
617619
map
618620
}
619621

@@ -651,7 +653,7 @@ impl ParsedFont {
651653
}
652654

653655
/// Generates a new font file from the used glyph IDs
654-
pub fn subset(&self, glyph_ids: &[(u16, char)]) -> Result<SubsetFont, String> {
656+
pub fn subset(&self, glyph_ids: &BTreeMap<u16, char>) -> Result<SubsetFont, String> {
655657
let glyph_mapping = glyph_ids
656658
.iter()
657659
.enumerate()
@@ -669,11 +671,9 @@ impl ParsedFont {
669671
.map_err(|e| e.to_string())?;
670672

671673
// https://docs.rs/allsorts/latest/allsorts/subset/fn.subset.html
672-
// Glyph id 0, corresponding to the .notdef glyph must always be present.
673-
let mut ids = vec![0];
674-
for glyph_id in glyph_ids {
675-
ids.push(glyph_id.0);
676-
}
674+
// Glyph id 0, corresponding to the .notdef glyph is always present,
675+
// because it is returned from get_used_glyphs_ids.
676+
let ids: Vec<_> = glyph_ids.keys().copied().collect();
677677

678678
let font = allsorts_subset_browser::subset::subset(&provider, &ids, &SubsetProfile::Web)
679679
.map_err(|e| e.to_string())?;
@@ -685,41 +685,30 @@ impl ParsedFont {
685685
}
686686

687687
/// Replace this function in the ParsedFont implementation
688-
pub(crate) fn generate_cid_to_unicode_map(
688+
pub(crate) fn generate_cmap_string(
689689
&self,
690690
font_id: &FontId,
691-
glyph_ids: &BTreeMap<u16, char>,
691+
gid_to_cid_map: &[(u16, u16)],
692692
) -> String {
693693
// Convert the glyph_ids map to a ToUnicodeCMap structure
694-
let mut mappings: BTreeMap<u32, Vec<u32>> = BTreeMap::new();
695-
for (&glyph_id, &unicode) in glyph_ids {
696-
mappings.insert(glyph_id as u32, vec![unicode as u32]);
697-
}
694+
let mappings = gid_to_cid_map
695+
.iter()
696+
.map(|&(gid, cp)| (gid as u32, vec![cp as u32]))
697+
.collect();
698698

699699
// Create the CMap and generate its string representation
700700
let cmap = ToUnicodeCMap { mappings };
701701
cmap.to_cmap_string(&font_id.0)
702702
}
703703

704-
pub(crate) fn generate_cid_to_gid(
705-
&self,
706-
glyph_ids: &BTreeMap<u16, char>,
707-
) -> BTreeMap<u16, u16> {
708-
let mut mappings: BTreeMap<u16, u16> = BTreeMap::new();
709-
710-
for (&glyph_id, _) in glyph_ids {
711-
let cid = self.index_to_cid(glyph_id + 1).unwrap();
712-
713-
mappings.insert(glyph_id, cid);
714-
}
715-
716-
mappings
704+
pub(crate) fn generate_gid_to_cid_map(&self, glyph_ids: &[u16]) -> Vec<(u16, u16)> {
705+
glyph_ids
706+
.iter()
707+
.filter_map(|gid| self.index_to_cid(*gid).map(|cid| (*gid, cid)))
708+
.collect()
717709
}
718710

719-
pub(crate) fn get_normalized_widths_ttf(
720-
&self,
721-
glyph_ids: &BTreeMap<u16, char>,
722-
) -> Vec<lopdf::Object> {
711+
pub(crate) fn get_normalized_widths_ttf(&self, glyph_ids: &[u16]) -> Vec<lopdf::Object> {
723712
let mut widths_list = Vec::new();
724713
let mut current_low_gid = 0;
725714
let mut current_high_gid = 0;
@@ -728,16 +717,16 @@ impl ParsedFont {
728717
// scale the font width so that it sort-of fits into an 1000 unit square
729718
let percentage_font_scaling = 1000.0 / (self.font_metrics.units_per_em as f32);
730719

731-
for gid in glyph_ids.keys() {
732-
let width = match self.get_glyph_width_internal(*gid) {
720+
for &gid in glyph_ids {
721+
let width = match self.get_glyph_width_internal(gid) {
733722
Some(s) => s,
734723
None => match self.get_space_width() {
735724
Some(w) => w,
736725
None => 0,
737726
},
738727
};
739728

740-
if *gid == current_high_gid {
729+
if gid == current_high_gid {
741730
// subsequent GID
742731
current_width_vec.push(Integer((width as f32 * percentage_font_scaling) as i64));
743732
current_high_gid += 1;
@@ -747,7 +736,7 @@ impl ParsedFont {
747736
widths_list.push(Array(std::mem::take(&mut current_width_vec)));
748737

749738
current_width_vec.push(Integer((width as f32 * percentage_font_scaling) as i64));
750-
current_low_gid = *gid;
739+
current_low_gid = gid;
751740
current_high_gid = gid + 1;
752741
}
753742
}
@@ -757,32 +746,19 @@ impl ParsedFont {
757746
widths_list.push(Array(std::mem::take(&mut current_width_vec)));
758747

759748
widths_list
760-
/*
761-
let mut cmap = glyph_ids.iter()
762-
.filter_map(|(glyph_id, c)| {
763-
let (glyph_width, glyph_height) = self.get_glyph_size(*glyph_id)?;
764-
let k = *glyph_id as u32;
765-
let v = (*c as u32, glyph_width.abs() as u32, glyph_height.abs() as u32);
766-
Some((k, v))
767-
}).collect::<BTreeMap<_, _>>();
768-
769-
cmap.insert(0, (0, 1000, 1000));
770-
771-
widths.push((*glyph_id, width));
772-
*/
773749
}
774750

775751
pub(crate) fn get_normalized_widths_cff(
776752
&self,
777-
cid_to_gid: &BTreeMap<u16, u16>,
753+
gid_to_cid_map: &[(u16, u16)],
778754
) -> Vec<lopdf::Object> {
779755
let mut widths_list = Vec::new();
780756

781757
// scale the font width so that it sort-of fits into an 1000 unit square
782758
let percentage_font_scaling = 1000.0 / (self.font_metrics.units_per_em as f32);
783759

784-
for (gid, cid) in cid_to_gid {
785-
let width = match self.get_glyph_width_internal(*gid + 1) {
760+
for &(gid, cid) in gid_to_cid_map {
761+
let width = match self.get_glyph_width_internal(gid) {
786762
Some(s) => s,
787763
None => match self.get_space_width() {
788764
Some(w) => w,
@@ -792,8 +768,8 @@ impl ParsedFont {
792768

793769
let width = (width as f32 * percentage_font_scaling) as i64;
794770

795-
widths_list.push(Integer(*cid as i64));
796-
widths_list.push(Integer(*cid as i64));
771+
widths_list.push(Integer(cid as i64));
772+
widths_list.push(Integer(cid as i64));
797773
widths_list.push(Integer(width));
798774
}
799775

src/render.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,7 @@ fn render_to_svg_internal(
526526
for (font_id, font) in fonts.iter() {
527527
svg.push_str(&format!(
528528
r#"@font-face {{ font-family: "{}"; src: url("data:font/otf;charset=utf-8;base64,{}"); }}"#,
529-
font_id.0, base64::prelude::BASE64_STANDARD.encode(&font.subset_font.bytes),
529+
font_id.0, base64::prelude::BASE64_STANDARD.encode(&font.subset.bytes),
530530
));
531531
}
532532
svg.push_str("</style>\n");

0 commit comments

Comments
 (0)