pdfcraft/crates
krinry e33b66e9b5
Edit text: support per-font visual-order Indic text and nukta reordering (#1380)
* Edit text: support per-font visual-order Indic text and nukta reordering

- Detect legacy visual-order Indic fonts via Metrics.visual_order (fonts with
  Indic codepoints without OpenType GSUB tables, or legacy visual font names).
- Implement Indic visual-to-logical and logical-to-visual pre-base vowel
  reordering in crates/edit/src/indic.rs, with support for decomposed/precomposed
  nuktas and conjuncts.
- Apply reordering during extraction and source font reuse only when visual_order
  is set, leaving modern logical-order text untouched.
- Add unit tests for nuktas, conjuncts, and round-trips in crates/edit/src/indic.rs
  and font visual_order tests in crates/edit/src/tests.rs.

* Visual-order Indic: positive evidence only, ActualText kept logical, no font decoding

- A font is visual order only when it is a known legacy Indic family (subset tag
  allowed; aps-/dv- as prefixes) with an Indic Unicode mapping. A missing GSUB is
  no evidence (bare CFF and subset fonts drop it), so Metrics::from_dict no longer
  decodes every embedded font program on every call.
- Lines with /ActualText text are already logical: skip indic::to_logical, so
  "बढ़िया" no longer becomes "बढ़यिा".
- reading_lines no longer runs bidi recovery on every line (it changed RTL
  reading_blocks output for all documents); only the Indic recovery remains.
- indic.rs indexes through get().
- Tests use a ToUnicode fixture (not visual-order ActualText), cover an edit
  round-trip, logical ActualText in a legacy font, and a subset Noto font.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Brandon Thomas <echelon@gmail.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 08:18:37 -04:00
..
a11y Keep manual review visible in accessibility summaries (#1224) 2026-10-12 02:52:35 -04:00
annot M14: text the fonts can't draw is kept and reported, never written as ? silently (#1112) 2026-10-11 17:53:55 -04:00
audit fix(audit): an identity cm between re and fill no longer hides a cover (#1333) (#1410) 2026-10-12 07:54:52 -04:00
automation fix(automation): doc_save reports a required full rewrite as not incremental (#1329) (#1405) 2026-10-12 07:54:17 -04:00
compare Rename PrintCraft to PdfCraft (#174) 2026-10-07 16:03:57 -04:00
content fix(content): skip an inline image with an unreadable key to its EI (#1318) (#1404) 2026-10-12 07:53:44 -04:00
cos fix(preflight): find colour operators after any PDF whitespace (#1334) (#1373) 2026-10-12 06:25:42 -04:00
create M14: text the fonts can't draw is kept and reported, never written as ? silently (#1112) 2026-10-11 17:53:55 -04:00
crypt Issue #1185: Protect refuses passwords that encryption would make empty or equal (#1186) 2026-10-11 18:30:00 -04:00
edit Edit text: support per-font visual-order Indic text and nukta reordering (#1380) 2026-10-12 08:18:37 -04:00
engine M10: edit OCR text on scanned pages so the change shows (#1397) 2026-10-12 08:16:42 -04:00
export M10: Presentation (.pptx) export (#1137) (#1162) 2026-10-11 21:55:25 -04:00
filters Rename PrintCraft to PdfCraft (#174) 2026-10-07 16:03:57 -04:00
fonts Edit text: support per-font visual-order Indic text and nukta reordering (#1380) 2026-10-12 08:18:37 -04:00
forms fix(forms): keep a whitespace-only value in a text field without a format (#1323) (#1403) 2026-10-12 07:53:10 -04:00
geom M10: Enhance camera image finds the document's edges; rotate, crop or organize after Enhance page (part 3 of #1008) (#1027) 2026-10-11 12:31:23 -04:00
js XFA: one script thread per event, and the live form kept up to date in place (#1355) 2026-10-12 05:39:49 -04:00
measure Issue #432: global Units preference (mm, cm, in, pt), defaulting to the system region (#463) 2026-10-11 15:33:54 -04:00
model M2: pages with /UserUnit are shown at their size in points, as in Acrobat (#722) 2026-10-10 06:19:31 -04:00
ocr M10: edit OCR text on scanned pages so the change shows (#1397) 2026-10-12 08:16:42 -04:00
optimize M11: strip redundant ASCII stream wrappers during optimization (#989) 2026-10-11 13:21:20 -04:00
organize M4: rename colliding form field names when combining (organize.field-name-conflicts) (#1155) 2026-10-11 21:18:21 -04:00
platform fix(theme): complete Linux System appearance tracking (#1017) 2026-10-11 15:23:49 -04:00
preflight fix(preflight): find colour operators after any PDF whitespace (#1334) (#1373) 2026-10-12 06:25:42 -04:00
print fix(print): refuse huge posters at the sheet limit instead of overflowing (#1335) (#1376) 2026-10-12 06:27:50 -04:00
redact fix(redact): removing comments keeps non-comment annotations (#1325) (#1375) 2026-10-12 06:27:04 -04:00
render fix(render): draw Turkish Ğ İ Ş ğ ş in non-embedded fonts (vendored hayro-interpret patch 26) (#1409) 2026-10-12 07:57:03 -04:00
sign fix(sign): refuse to sign a field whose /V is not a signature (#1328) (#1402) 2026-10-12 07:52:34 -04:00
ui-egui M10: edit OCR text on scanned pages so the change shows (#1397) 2026-10-12 08:16:42 -04:00
xfa XFA: one script thread per event, and the live form kept up to date in place (#1355) 2026-10-12 05:39:49 -04:00
xfdf fix(xfdf): text data from a one-field form keeps its commas (#1321) (#1371) 2026-10-12 06:24:27 -04:00