mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Insert default glyph when subsetting ⚙
This commit is contained in:
parent
0b2ae78534
commit
a522a15a66
@ -187,7 +187,7 @@ impl Default for Style {
|
||||
|
||||
// Default font family, font size and line spacing.
|
||||
font_families: vec![SansSerif, Serif, Monospace],
|
||||
font_size: 12.0,
|
||||
font_size: 11.0,
|
||||
line_spacing: 1.25,
|
||||
}
|
||||
}
|
||||
|
@ -164,35 +164,33 @@ impl<'d, W: Write> PdfEngine<'d, W> {
|
||||
let mut id = self.offsets.fonts.0;
|
||||
|
||||
for font in &self.fonts {
|
||||
let base_font = format!("ABCDEF+{}", font.name);
|
||||
|
||||
// Write the base font object referencing the CID font.
|
||||
self.writer.write_obj(id,
|
||||
Type0Font::new(
|
||||
font.name.clone(),
|
||||
base_font.clone(),
|
||||
CMapEncoding::Predefined("Identity-H".to_owned()),
|
||||
id + 1
|
||||
).to_unicode(id + 2)
|
||||
).to_unicode(id + 3)
|
||||
)?;
|
||||
|
||||
let system_info = CIDSystemInfo::new("(Adobe)", "(Identity)", 0);
|
||||
let system_info = CIDSystemInfo::new("Adobe", "Identity", 0);
|
||||
|
||||
// Write the CID font referencing the font descriptor.
|
||||
self.writer.write_obj(id + 1,
|
||||
CIDFont::new(
|
||||
CIDFontType::Type2,
|
||||
font.name.clone(),
|
||||
base_font.clone(),
|
||||
system_info.clone(),
|
||||
id + 3,
|
||||
id + 2,
|
||||
).widths(vec![WidthRecord::start(0, font.widths.clone())])
|
||||
)?;
|
||||
|
||||
// The CMap, which maps glyphs to unicode codepoints.
|
||||
let mapping = font.font.mapping.iter().map(|(&c, &cid)| (cid, c));
|
||||
self.writer.write_obj(id + 2, &CMap::new("Custom", system_info, mapping))?;
|
||||
|
||||
// Write the font descriptor (contains the global information about the font).
|
||||
self.writer.write_obj(id + 3,
|
||||
self.writer.write_obj(id + 2,
|
||||
FontDescriptor::new(
|
||||
font.name.clone(),
|
||||
base_font,
|
||||
font.flags,
|
||||
font.italic_angle,
|
||||
)
|
||||
@ -204,6 +202,10 @@ impl<'d, W: Write> PdfEngine<'d, W> {
|
||||
.font_file_3(id + 4)
|
||||
)?;
|
||||
|
||||
// The CMap, which maps glyphs to unicode codepoints.
|
||||
let mapping = font.font.mapping.iter().map(|(&c, &cid)| (cid, c));
|
||||
self.writer.write_obj(id + 3, &CMap::new("Custom", system_info, mapping))?;
|
||||
|
||||
// Finally write the subsetted font program.
|
||||
self.writer.write_obj(id + 4, &FontStream::new(
|
||||
&font.program,
|
||||
@ -249,7 +251,7 @@ impl PdfFont {
|
||||
let subsetted = font.subsetted(
|
||||
chars.iter().cloned(),
|
||||
&["head", "hhea", "maxp", "hmtx", "loca", "glyf"][..],
|
||||
&["cvt ", "prep", "fpgm"][..],
|
||||
&["cvt ", "prep", "fpgm", /* "OS/2", "cmap", "name", "post" */][..],
|
||||
)?;
|
||||
|
||||
// Specify flags for the font
|
||||
|
22
src/font.rs
22
src/font.rs
@ -141,7 +141,7 @@ impl Font {
|
||||
cmap: None,
|
||||
hmtx: None,
|
||||
loca: None,
|
||||
glyphs: Vec::with_capacity(chars.len()),
|
||||
glyphs: Vec::with_capacity(1 + chars.len()),
|
||||
chars,
|
||||
records: vec![],
|
||||
body: vec![],
|
||||
@ -445,12 +445,15 @@ impl<'d> Subsetter<'d> {
|
||||
|
||||
self.write_header()?;
|
||||
|
||||
// Build the new widths.
|
||||
let widths = self.glyphs.iter()
|
||||
.map(|&glyph| self.font.widths.get(glyph as usize).map(|&w| w)
|
||||
.take_invalid("missing glyph metrics"))
|
||||
.collect::<FontResult<Vec<_>>>()?;
|
||||
.map(|&glyph| {
|
||||
self.font.widths.get(glyph as usize).map(|&w| w)
|
||||
.take_invalid("missing glyph metrics")
|
||||
}).collect::<FontResult<Vec<_>>>()?;
|
||||
|
||||
let mapping = self.chars.into_iter().enumerate().map(|(i, c)| (c, i as u16))
|
||||
// We add one to the index here because we added the default glyph to the front.
|
||||
let mapping = self.chars.into_iter().enumerate().map(|(i, c)| (c, 1 + i as u16))
|
||||
.collect::<HashMap<char, u16>>();
|
||||
|
||||
Ok(Font {
|
||||
@ -467,12 +470,12 @@ impl<'d> Subsetter<'d> {
|
||||
self.read_cmap()?;
|
||||
let cmap = self.cmap.as_ref().unwrap();
|
||||
|
||||
// The default glyph should be always present.
|
||||
self.glyphs.push(self.font.default_glyph);
|
||||
for &c in &self.chars {
|
||||
self.glyphs.push(cmap.get(c).ok_or_else(|| FontError::MissingCharacter(c))?)
|
||||
}
|
||||
|
||||
self.glyphs.push(self.font.default_glyph);
|
||||
|
||||
// Composite glyphs may need additional glyphs we have not yet in our list.
|
||||
// So now we have a look at the glyf table to check that and add glyphs
|
||||
// we need additionally.
|
||||
@ -678,7 +681,10 @@ impl<'d> Subsetter<'d> {
|
||||
while i + 1 < len && this.chars[i+1] as u32 == this.chars[i] as u32 + 1 {
|
||||
i += 1;
|
||||
}
|
||||
groups.push((this.chars[start], this.chars[i], start));
|
||||
|
||||
// Add one to the start because we inserted the default glyph in front.
|
||||
let glyph = 1 + start;
|
||||
groups.push((this.chars[start], this.chars[i], glyph));
|
||||
i += 1;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user