Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,14 @@ private void drawTextWithDP(int x, int y, String text, FontTriplet triplet,
double yd = (yo - yoLast) / 1000f;
tu.writeTd(xd, yd);
tu.writeTj(mp, tf.isMultiByte(), true);
xc += xa + pa[2];
// Each glyph is placed by its own Td, so the Tc character spacing set above never
// reaches the next glyph as it does inside the TJ array of drawTextWithDX. The
// letter spacing is added to the advance here, for every glyph including spaces and
// the last one, which is what Tc does on the other path and what the layout's word
// space adjustment assumes (TextLayoutManager.addMappingAreas). Without it a
// letter-spaced word in a font that positions (GPOS kerning) was painted at its
// bare advances while its area kept the letter spaces.
xc += xa + pa[2] + letterSpacing;
yc += ya + pa[3];
xoLast = xo;
yoLast = yo;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,36 @@ public void testDrawDpTextWithMultiByteFont() throws IFException {
+ "<0001> Tj\n", output.toString());
}

/**
* The position-adjustment path places every glyph with its own Td, so the Tc it sets has no
* effect on the next glyph's position; the letter spacing has to go into the advance, as it
* does through Tc on the TJ path. Two zero-width glyphs, a kern of -100 and a letter spacing
* of 500: the second glyph sits at 400, not at -100.
*/
@Test
public void testDrawDpTextKeepsLetterSpacing() throws IFException {
StringBuilder output = new StringBuilder();
PDFDocumentHandler pdfDocumentHandler = makePDFDocumentHandler(output);
MultiByteFont font = new MultiByteFont(null, null);
font.setWidthArray(new int[10]);
font.setCMap(new CMapSegment[]{new CMapSegment(128169, 128169, 1)});
FontInfo fi = new FontInfo();
fi.addFontProperties("f1", new FontTriplet("a", "normal", 400));
fi.addMetrics("f1", font);
pdfDocumentHandler.setFontInfo(fi);
MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null);
pdfPainter.setFont("a", "normal", 400, null, 12, null);
int[][] dp = new int[][] {{0, 0, -100, 0}, {0, 0, 0, 0}};
pdfPainter.drawText(0, 0, 500, 0, dp, "Hi");
assertEquals("BT\n"
+ "1 0 0 -1 0 0 Tm /f1 0.012 Tf\n"
+ "0 0 Td\n"
+ "<0000> Tj\n"
+ "0.4 0 Td\n"
+ "<0000> Tj\n", output.toString());
verify(pdfContentGenerator).updateCharacterSpacing(0.5f);
}

private PDFDocumentHandler makePDFDocumentHandler(final StringBuilder sb) throws IFException {
FopFactory fopFactory = FopFactory.newInstance(new File(".").toURI());
foUserAgent = fopFactory.newFOUserAgent();
Expand Down