Grouped Thai text writes its Type 3 fonts through shaped_text

The grouped-text writer that landed in #6627 called Add text's old type3_shaped,
which this branch moved into pdfcraft_fonts::shaped_text. shaped_text now offers
add_type3_font, so both share one writer.
This commit is contained in:
bflatastic committed 2026-11-09 01:05:47 +07:00
1 parent 8dace9ec00
commit a04e20dbb6
2 files changed
+23 -7

No files matched your search

+12 -7
View File
@@ -253,9 +253,9 @@ pub(crate) fn thai_glyph_resources(
if shaped.glyphs.len() > 65_534 {
return Err(EditError::Invalid("shaped row exceeds its geometry budget".into()));
}
let mut outlines = HashMap::new();
let mut outlines = std::collections::HashMap::new();
let mut clusters = Vec::new();
let mut index = HashMap::new();
let mut index = std::collections::HashMap::new();
let mut indices = Vec::new();
for glyph in &shaped.glyphs {
let id = glyph.id.to_u32();
@@ -266,7 +266,12 @@ pub(crate) fn thai_glyph_resources(
let at = *index.entry((id, glyph.text.as_str())).or_insert_with(|| {
let at = clusters.len();
let width = outlines.get(&key).map_or(0.0, |g| g.width);
clusters.push(ShapedCluster { script: ShapedScript::Thai, glyphs: vec![(id, [0.0, 0.0])], advance: width, text: glyph.text.clone() });
clusters.push(pdfcraft_fonts::ShapedCluster {
script: ShapedScript::Thai,
glyphs: vec![(id, [0.0, 0.0])],
advance: width,
text: glyph.text.clone(),
});
at
});
indices.push(at);
@@ -274,9 +279,9 @@ pub(crate) fn thai_glyph_resources(
// Validate all outlines before adding resources. Type 3 character codes are single bytes;
// shard long rows and return the appropriate resource/code for every positioned glyph.
let mut names = Vec::new();
for chunk in clusters.chunks(GLYPHS_PER_FONT) {
for chunk in clusters.chunks(shaped_text::GLYPHS_PER_FONT) {
let refs: Vec<_> = chunk.iter().collect();
let font = type3_shaped(doc, &refs, &outlines);
let font = shaped_text::add_type3_font(doc, &refs, &outlines);
doc.update_dict(font, |f| f.set(b"Name".to_vec(), Object::name("PCThai")))?;
let mut name = format!("PCThai{}", font.num);
while fonts.contains(name.as_bytes()) {
@@ -288,8 +293,8 @@ pub(crate) fn thai_glyph_resources(
indices
.into_iter()
.map(|at| {
let name = names.get(at / GLYPHS_PER_FONT).ok_or_else(|| EditError::Invalid("Thai font resource is missing".into()))?;
let code = u8::try_from(at % GLYPHS_PER_FONT + 1).map_err(|_| EditError::Invalid("Thai glyph limit".into()))?;
let name = names.get(at / shaped_text::GLYPHS_PER_FONT).ok_or_else(|| EditError::Invalid("Thai font resource is missing".into()))?;
let code = u8::try_from(at % shaped_text::GLYPHS_PER_FONT + 1).map_err(|_| EditError::Invalid("Thai glyph limit".into()))?;
Ok((name.clone(), vec![code]))
})
.collect()
+11
View File
@@ -292,6 +292,17 @@ pub fn thai_refusal(text: &str) -> Option<String> {
text.split(['\n', '\r']).filter(|l| l.chars().any(is_thai)).find_map(|l| thai_pieces(l).err().map(|e| thai_message(e, l)))
}
/// [`type3_font`] written into `doc`, with its glyphs, descriptor and ToUnicode as objects of their
/// own: for content that draws `clusters` (at most [`GLYPHS_PER_FONT`]) as codes 1… directly.
pub fn add_type3_font(
doc: &mut Document,
clusters: &[&ShapedCluster],
outlines: &HashMap<(ShapedScript, u32), GlyphOutline>,
) -> pdfcraft_cos::ObjRef {
let font = type3_font(clusters, outlines, &mut |o| Object::Ref(doc.add(o)));
doc.add(Object::Dict(font))
}
/// A Type 3 font with `clusters` as codes 1…, each drawn from its script face's glyph `outlines`.
fn type3_font(clusters: &[&ShapedCluster], outlines: &HashMap<(ShapedScript, u32), GlyphOutline>, store: &mut dyn FnMut(Object) -> Object) -> Dict {
let mut charprocs = Dict::new();