mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-09 04:22:20 +00:00
Let only a same-style complete program keep the bundled Thai face out
A complete program of the source's family in another style, such as one its descriptor marks bold, stopped the bundled Regular Thai outlines from completing a Regular subset, and the text was then drawn in that bold program. Count only a program in the source's style, as the subset completion itself does.
This commit is contained in:
1 parent
e8322a8fc2
commit
5f265960ad
2 files changed
+41
-3
No files matched your search
@@ -12692,6 +12692,38 @@ fn a_bold_thai_subset_is_not_completed_with_the_regular_bundled_face() {
|
||||
assert_eq!(pdfcraft_cos::write_full(&doc, &Default::default()).unwrap(), before, "a refused edit changes nothing");
|
||||
}
|
||||
|
||||
/// A complete program of the family in another style (bold, by its descriptor) can't complete a
|
||||
/// Regular subset, so it doesn't keep the bundled Regular outlines from doing so: the text is not
|
||||
/// drawn in the bold program instead.
|
||||
#[test]
|
||||
fn a_complete_program_in_another_style_does_not_keep_the_bundled_thai_face_out() {
|
||||
if pdfcraft_fonts::document_thai_font().is_none() {
|
||||
eprintln!(
|
||||
"skipping a_complete_program_in_another_style_does_not_keep_the_bundled_thai_face_out: built without craft-fonts (set CRAFT_FONTS_DIR to run it)"
|
||||
);
|
||||
return;
|
||||
}
|
||||
let mut doc = text_page("BT /F1 16 Tf 50 700 Td (A) Tj ET");
|
||||
let cmap =
|
||||
doc.add(Object::Stream(Stream::flate(Dict::new(), b"1 begincodespacerange <00> <FF> endcodespacerange 1 beginbfchar <41> <0E19> endbfchar")));
|
||||
doc.update_dict(pdfcraft_cos::ObjRef::new(5, 0), |f| {
|
||||
f.set(b"BaseFont".to_vec(), Object::name("ABCDEF+NotoSansThai"));
|
||||
f.set(b"ToUnicode".to_vec(), Object::Ref(cmap));
|
||||
})
|
||||
.unwrap();
|
||||
let complete = with_legacy_thai_cmap(include_bytes!("../../../assets/fonts/Inter-Regular.ttf").to_vec());
|
||||
let mut bold = legacy_thai_font(&mut doc, "NotoSansThai", &complete, LEGACY_THAI_UNICODE);
|
||||
let Some(Object::Array(mut descendants)) = bold.get(b"DescendantFonts").cloned() else { panic!("fixture") };
|
||||
let Some(Object::Dict(descendant)) = descendants.first_mut() else { panic!("fixture") };
|
||||
let Some(Object::Dict(mut descriptor)) = descendant.get(b"FontDescriptor").cloned() else { panic!("fixture") };
|
||||
descriptor.set(b"FontWeight".to_vec(), Object::Int(700));
|
||||
descendant.set(b"FontDescriptor".to_vec(), Object::Dict(descriptor));
|
||||
bold.set(b"DescendantFonts".to_vec(), Object::Array(descendants));
|
||||
doc.set(pdfcraft_cos::ObjRef::new(6, 0), Object::Dict(bold));
|
||||
let edited = text::rewrite_block(&mut doc, 0, 0, Some("ผู้ใช้"), &text::BlockStyle::default()).expect("completed with the bundled face");
|
||||
assert_eq!(edited.substituted.as_deref(), pdfcraft_fonts::document_thai_font().map(|f| f.family));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn grouped_source_text_preparation_edits_original_operators_without_changing_shared_forms() {
|
||||
let mut doc = page_with_forms("q 1 0 0 1 12 20 cm /Body Do Q", &[("Body".into(), "BT /F1 14 Tf 40 500 Td (Original body) Tj ET".into())]);
|
||||
|
||||
@@ -1051,8 +1051,11 @@ fn matching_thai_outline(doc: &Document, fonts: &Dict, source: &TextLine, span:
|
||||
// The bundled face is Regular and upright. A source its descriptor or name marks bold or
|
||||
// italic keeps that style, so completing it with these outlines would be a silent change:
|
||||
// it needs an explicit choice instead. (Variable-font instances often keep the family name.)
|
||||
let style = fonts.get(source.font.as_bytes()).and_then(|f| doc.dict(f)).map(|f| FontStyle::of(doc, &f, &Metrics::from_dict(doc, &f)));
|
||||
if style.map_or(source.bold || source.italic, |s| s.bold || s.italic) {
|
||||
let style = fonts
|
||||
.get(source.font.as_bytes())
|
||||
.and_then(|f| doc.dict(f))
|
||||
.map_or(FontStyle { bold: source.bold, italic: source.italic }, |f| FontStyle::of(doc, &f, &Metrics::from_dict(doc, &f)));
|
||||
if style.bold || style.italic {
|
||||
return false;
|
||||
}
|
||||
if !span.chars().any(|c| matches!(u32::from(c), 0x0e00..=0x0e7f))
|
||||
@@ -1063,9 +1066,12 @@ fn matching_thai_outline(doc: &Document, fonts: &Dict, source: &TextLine, span:
|
||||
}
|
||||
// A registered complete matching program also completes the source subset.
|
||||
// Do not replace it with bundled outlines merely because the original resource is a subset.
|
||||
// Only one in the source's style does (`program_candidates`), so only that one counts here.
|
||||
let family = pdfcraft_fonts::embedding::face_key(&source.base_font);
|
||||
!fonts.iter().filter_map(|(_, font)| doc.dict(font)).any(|font| {
|
||||
pdfcraft_fonts::embedding::face_key(&Metrics::from_dict(doc, &font).base_font) == family
|
||||
let metrics = Metrics::from_dict(doc, &font);
|
||||
pdfcraft_fonts::embedding::face_key(&metrics.base_font) == family
|
||||
&& FontStyle::of(doc, &font, &metrics) == style
|
||||
&& pdfcraft_fonts::pdf::embedded_sfnt(doc, &font).is_some_and(|bytes| {
|
||||
pdfcraft_fonts::embedding::validate(&bytes).is_ok()
|
||||
&& pdfcraft_fonts::source_shaping::has_thai_layout(&bytes)
|
||||
|
||||
Reference in new issue
Block a user