[ 
https://issues.apache.org/jira/browse/FOP-3344?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Jason Harrop updated FOP-3344:
------------------------------
    Attachment: FOP-3344-letter-spacing-dp.fo
                fop-test-fonts.xconf

> letter-spacing is not painted on text that carries glyph position adjustments 
> (GPOS kerning): the word is drawn at its bare advances inside an area that 
> keeps the letter spaces
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: FOP-3344
>                 URL: https://issues.apache.org/jira/browse/FOP-3344
>             Project: FOP
>          Issue Type: Bug
>          Components: renderer/pdf
>    Affects Versions: 2.11
>            Reporter: Jason Harrop
>            Priority: Minor
>         Attachments: FOP-3344-letter-spacing-dp.fo, fop-test-fonts.xconf
>
>
> PDFPainter.drawText takes one of two paths. With no position adjustments, or 
> adjustments that are DX-only, drawTextWithDX writes the word as one TJ array 
> and sets Tc to the letter spacing, which the PDF viewer adds after every 
> glyph. With general adjustments (a GPOS kern produces an x-advance 
> adjustment, so IFUtil.isDPOnlyDX is false), drawTextWithDP writes each glyph 
> with its own Td and Tj and advances by
> {noformat}
> xc += xa + pa[2];
> {noformat}
> that is, the glyph width plus the advance adjustment. It sets Tc too, but Tc 
> acts only between glyphs inside a TJ array; with one glyph per Tj and an 
> explicit Td before each, the letter spacing never reaches the next glyph.
> The layout side is consistent with the first path. TextLayoutManager puts the 
> letter spaces into the word's Knuth elements and the TextArea, and 
> addMappingAreas computes the word-space adjustment on the assumption that the 
> renderer "adds the character spacing even to the last character of a word and 
> to space characters" (its own comment). So a letter-spaced word in a font 
> that positions is measured with its letter spaces and painted without them, 
> and the gap to the next word absorbs the difference: negative letter spacing 
> opens the gap, positive closes it, to the point of overprinting.
> Reproducer: Arimo (or any font whose GPOS kern applies; Liberation, DejaVu 
> Serif, Noto), kerning="true", 11pt,
> {noformat}
> <fo:block font-family="Arimo">During <fo:inline
>     letter-spacing="-0.417pt">repair,</fo:inline> if however</fo:block>
> {noformat}
> Per-glyph steps read back with mutool draw -F stext, 2.11:
> {noformat}
> r>e 3.663  e>p 6.116  p>a 6.116  a>i 6.116  i>r 2.442  r>, 3.058   
> comma>space 3.047
> {noformat}
> Every step is the bare advance (r>, carries the kern), and the space after 
> the comma is 2.5 pt narrower than the same text without kerning, where the 
> steps are 3.246 5.699 5.699 5.699 2.025 3.246 and the gap 5.549. On the 
> docx4j corpus the collapsed gap made pdftotext read "repair, if" as 
> "repair,if"; with positive letter spacing the words overprint.
> h3. Fix
> PDFPainter.drawTextWithDP: add the letter spacing to the advance of every 
> glyph, spaces and the last glyph included, which is what Tc does on the other 
> path and what the layout's word-space adjustment assumes:
> {noformat}
> xc += xa + pa[2] + letterSpacing;
> {noformat}
> Java2DPainter and PCLPainter already add letterSpacing per glyph in their dp 
> loops; PSPainter applies it through ATJ; AFPPainter converts dp to dx. Only 
> the PDF painter was missing it.
> After the fix, same sample: 3.246 5.699 5.699 5.699 2.025 2.641, gap 5.549; 
> the last step is the advance less the letter spacing less the kern.
> Test: PDFPainterTestCase.testDrawDpTextKeepsLetterSpacing, two zero-width 
> glyphs with a kern of -100 and a letter spacing of 500; the second glyph's Td 
> must be 0.4, not -0.1.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to