Skip to content

DOCX: Hangul lines break at syllable boundaries, splitting words Word keeps whole #626

Description

@developer0hye

Summary

Hangul lines are broken at syllable boundaries. Word breaks at eojeol
(space-delimited word) boundaries on ordinary lines and only falls back to
character-level breaking to keep a justified line from going too loose. The
result is that a Korean word is split across two lines where Word moves the
whole word down.

Neither w:wordWrap nor w:kinsoku appears in the source, and settings.xml
carries only compatibilityMode=15, so Word's defaults are in force.

This is Word-specific behaviour, not a general CJK rule: PowerPoint itself
breaks Korean mid-word, and office2pdf's PPTX output matches PowerPoint's break
points exactly on the same corpus.

Measured

tests/golden_mocks/business/sources/docx/02_contract_ko.docx, page 1:

paragraph Word office2pdf
제1조 line 1 ends / line 2 begins …필요한 제반 사항을 / 정함을 목적으로 한다. …사항을 정 / 함을
제4조 line 1 ends / line 2 begins …VAT 별도)으로 / 하며, 을은… …으로 하 / 며, 을은…

One syllable (10.5pt) migrates in each case.

Word was not out of room. On 제1조 the trailing space of Word's line 1 ends at
507.99pt and "정" would end at 518.49pt, well inside the 524.47pt right margin —
Word had 6pt of space and still moved the whole word down. Line width: Word
493.80 vs office2pdf 508.11.

The trigger shows up in the same file's two justified paragraphs
(<w:jc w:val="both"/>): there Word does break mid-eojeol, and identically to
office2pdf (both split 보관|한다.). So character-level breaking is Word's
fallback for justified lines, not its default.

Corroborated across every wrapped body paragraph of an internal test document,
where office2pdf breaks 제공하는 → 제 / 공하는, 지원하는 → 지원하 / 는,
발화량 → 발 / 화량, 발생할 → 발생 / 할 and 103,125 / 원 while Word breaks at the
space each time. That is not a metrics difference: matched wrapped lines agree
to ≤0.1pt, both sides use a 70.8pt left margin and the same 453.6pt text width,
and the constant 3.7pt difference on paragraph-final lines is Word's trailing
space glyph.

Reproduction

cargo run --release -p office2pdf-cli -- \
    tests/golden_mocks/business/sources/docx/02_contract_ko.docx -o out.pdf

Compare the line endings of 제1조 and 제4조 against Word.

Expected

On a non-justified line, a Hangul eojeol is treated as an unbreakable unit: 제1조
line 1 ends at "…제반 사항을" and 정함을 begins line 2 whole.

Actual

Every syllable boundary is a break opportunity, so the last word of the line is
split and one syllable is left behind on the line above.

Found in the 2026-07-29 full-corpus visual audit at c1adfbd (native Office GT, 150 DPI, mutool-trace geometry).

Visual comparison

Compare
Compare

GT left, office2pdf right, 150 DPI, same page.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions