mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-09 04:22:20 +00:00
Give an unencoded space in legacy Thai the source font's space fallback
A space that no subset of the face encodes was drawn as a quarter-em gap, narrower than the text-space fallback the source font uses elsewhere. Keep each subset's source space with it and use that for the gap.
This commit is contained in:
1 parent
fbc2dc77a7
commit
5f356ade12
2 files changed
+26
-7
No files matched your search
@@ -13112,6 +13112,25 @@ fn editing_legacy_thai_shapes_a_run_across_subsets_of_the_same_face() {
|
||||
assert_eq!(pdfcraft_cos::write_full(&doc, &Default::default()).unwrap(), before, "a refused edit changes nothing");
|
||||
}
|
||||
|
||||
/// A space no subset of the face encodes is the gap the source font's text-space fallback gives
|
||||
/// (`source_space`, a third of an em here), as wrapping measures it everywhere else.
|
||||
#[test]
|
||||
fn an_unencoded_space_in_legacy_thai_takes_the_source_space_fallback() {
|
||||
let mut doc = text_page("BT /F1 16 Tf 50 650 Td <00d6> Tj ET");
|
||||
let font = legacy_thai_font(&mut doc, "ABCDEF+THSarabunPSK", &legacy_thai_program(), LEGACY_THAI_UNICODE);
|
||||
doc.set(pdfcraft_cos::ObjRef::new(5, 0), Object::Dict(font));
|
||||
let style = BlockStyle { width: Some(400.0), ..Default::default() };
|
||||
text::rewrite_block(&mut doc, 0, 0, Some("ก ก"), &style).unwrap();
|
||||
// After the first ก (500 units), the second starts 330 units further: the gap.
|
||||
let gaps: Vec<f64> = pdfcraft_content::parse(&page_content_bytes(&doc, 0))
|
||||
.ops
|
||||
.iter()
|
||||
.filter(|op| op.is("TJ"))
|
||||
.flat_map(|op| op.operands.first().and_then(Object::as_array).into_iter().flatten().filter_map(Object::as_f64))
|
||||
.collect();
|
||||
assert!(gaps.iter().any(|g| (g + 330.0).abs() < 0.01), "{gaps:?}");
|
||||
}
|
||||
|
||||
/// Every resource name of one THSarabunPSK font object shares its program, decoded once. Distinct
|
||||
/// subsets of the face are read within one budget for the edit: past it the edit is refused with
|
||||
/// the reason, and the document is unchanged.
|
||||
|
||||
@@ -112,6 +112,8 @@ struct LegacyFace {
|
||||
style: FontStyle,
|
||||
/// The font object the resource names, when it is given by reference.
|
||||
object: Option<pdfcraft_cos::ObjRef>,
|
||||
/// Its text-space fallback ([`source_space`]), in ems.
|
||||
space: f64,
|
||||
}
|
||||
|
||||
/// What one edit may decode, and so keep, of the font programs of its THSarabunPSK subsets
|
||||
@@ -860,15 +862,13 @@ fn legacy_thai_font(
|
||||
let Some(font) = doc.dict(resource) else { continue };
|
||||
let object = resource.as_ref();
|
||||
let face = match object.and_then(|o| cache.values().find(|face| face.object == Some(o))) {
|
||||
Some(alias) => LegacyFace { glyphs: alias.glyphs.clone(), metrics: alias.metrics.clone(), style: alias.style, object },
|
||||
Some(alias) => LegacyFace { glyphs: alias.glyphs.clone(), metrics: alias.metrics.clone(), object, ..*alias },
|
||||
None => {
|
||||
let metrics = Metrics::from_dict(doc, &font);
|
||||
let glyphs = pdfcraft_fonts::pdf::LegacyThaiFont::from_pdf(doc, &font, source_space(doc, fonts, &metrics), budget)
|
||||
.ok()
|
||||
.flatten()
|
||||
.map(std::rc::Rc::new);
|
||||
let space = source_space(doc, fonts, &metrics);
|
||||
let glyphs = pdfcraft_fonts::pdf::LegacyThaiFont::from_pdf(doc, &font, space, budget).ok().flatten().map(std::rc::Rc::new);
|
||||
let style = FontStyle::of(doc, &font, &metrics);
|
||||
LegacyFace { glyphs, metrics, style, object }
|
||||
LegacyFace { glyphs, metrics, style, object, space }
|
||||
}
|
||||
};
|
||||
cache.insert(name, face);
|
||||
@@ -996,7 +996,7 @@ fn shape_existing_thai(cache: &HashMap<String, LegacyFace>, primary: &str, text:
|
||||
let code = f.metrics.encode(" ")?;
|
||||
Some(f.metrics.width(f.metrics.codes(&code).first()?.0))
|
||||
})
|
||||
.unwrap_or(0.25);
|
||||
.unwrap_or(first.space);
|
||||
(primary, Vec::new(), width)
|
||||
} else {
|
||||
return Err(EditError::Invalid(format!(
|
||||
|
||||
Reference in new issue
Block a user