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
20 changes: 16 additions & 4 deletions fop-core/src/main/java/org/apache/fop/render/pdf/PDFPainter.java
Original file line number Diff line number Diff line change
Expand Up @@ -607,15 +607,22 @@ private void drawTextWithDX(int x, int y, String text, FontTriplet triplet,
endSimulateStyle(tf, triplet);
}

/**
* Synthesises the style a triplet names from the face it is registered on, where the font entry asks for it
* (simulate-style), as Word synthesises a style a family lacks: a bold triplet is stroked at 1/35 em, and an
* italic one sheared by 0.3333, each only where the face is not bold, or not italic, already.
* @return the shear for the text matrix
*/
private double startSimulateStyle(Typeface tf, FontTriplet triplet) {
double shear = 0;
boolean simulateStyle = tf instanceof CustomFont && ((CustomFont) tf).getSimulateStyle();
if (simulateStyle) {
if (triplet.getWeight() == 700) {
CustomFont face = (CustomFont) tf;
if (simulatesBold(face, triplet)) {
generator.updateColor(state.getTextColor(), false, null);
generator.add("2 Tr 0.31543 w\n");
generator.add("2 Tr " + PDFNumber.doubleOut(state.getFontSize() / 1000.0 / 35, 5) + " w\n");
}
if (triplet.getStyle().equals("italic")) {
if (triplet.getStyle().equals("italic") && face.getItalicAngle() == 0) {
shear = 0.3333;
}
}
Expand All @@ -624,11 +631,16 @@ private double startSimulateStyle(Typeface tf, FontTriplet triplet) {

private void endSimulateStyle(Typeface tf, FontTriplet triplet) {
boolean simulateStyle = tf instanceof CustomFont && ((CustomFont) tf).getSimulateStyle();
if (simulateStyle && triplet.getWeight() == 700) {
if (simulateStyle && simulatesBold((CustomFont) tf, triplet)) {
generator.add("0 Tr\n");
}
}

/** A bold triplet on a face that is not bold already (its weight class below 700, or unknown). */
private static boolean simulatesBold(CustomFont face, FontTriplet triplet) {
return triplet.getWeight() == 700 && face.getWeight() < 700;
}

private static int[] paZero = new int[4];

private void drawTextWithDP(int x, int y, String text, FontTriplet triplet,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.contains;
import static org.mockito.ArgumentMatchers.endsWith;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.nullable;
Expand Down Expand Up @@ -290,14 +291,67 @@ public void testSimulateStyle() throws IFException {
fi.addMetrics("f1", font);
pdfDocumentHandler.setFontInfo(fi);
MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null);
pdfPainter.setFont("a", "italic", 700, null, 12, null);
pdfPainter.setFont("a", "italic", 700, null, 11040, null);
pdfPainter.drawText(0, 0, 0, 0, null, "test");

assertEquals(sb.toString(), "BT\n/f1 11.04 Tf\n1 0 0.3333 -1 0 0 Tm [<0000000000000000>] TJ\n");
verify(pdfContentGenerator).add("2 Tr 0.31543 w\n");
verify(pdfContentGenerator).add("0 Tr\n");
}

/** The output of a bold italic triplet on a face, at a size, for the simulated-style tests. */
private String simulateStyle(MultiByteFont font, int size) throws IFException {
final StringBuilder sb = new StringBuilder();
pdfDocumentHandler = makePDFDocumentHandler(sb);
FontInfo fi = new FontInfo();
fi.addFontProperties("f1", new FontTriplet("a", "italic", 700));
font.setSimulateStyle(true);
fi.addMetrics("f1", font);
pdfDocumentHandler.setFontInfo(fi);
MyPDFPainter pdfPainter = new MyPDFPainter(pdfDocumentHandler, null);
pdfPainter.setFont("a", "italic", 700, null, size, null);
pdfPainter.drawText(0, 0, 0, 0, null, "test");
return sb.toString();
}

assertEquals(sb.toString(), "BT\n/f1 0.012 Tf\n1 0 0.3333 -1 0 0 Tm [<0000000000000000>] TJ\n");
/**
* An italic face is not slanted again, but is stroked, as Word draws the italic face of a family that has no
* bold one.
* @throws IFException if the painting fails
*/
@Test
public void testSimulateStyleItalicFaceIsNotSheared() throws IFException {
MultiByteFont font = new MultiByteFont(null, null);
font.setItalicAngle(-11);
assertEquals("BT\n/f1 11.04 Tf\n1 0 0 -1 0 0 Tm [<0000000000000000>] TJ\n", simulateStyle(font, 11040));
verify(pdfContentGenerator).add("2 Tr 0.31543 w\n");
verify(pdfContentGenerator).add("0 Tr\n");
}

/**
* A bold face is not stroked again, but is sheared, as Word draws the bold face of a family that has no bold
* italic one.
* @throws IFException if the painting fails
*/
@Test
public void testSimulateStyleBoldFaceIsNotStroked() throws IFException {
MultiByteFont font = new MultiByteFont(null, null);
font.setWeight(700);
assertEquals("BT\n/f1 11.04 Tf\n1 0 0.3333 -1 0 0 Tm [<0000000000000000>] TJ\n", simulateStyle(font, 11040));
verify(pdfContentGenerator, never()).add(contains(" Tr "));
verify(pdfContentGenerator, never()).add("0 Tr\n");
}

/**
* The simulated bold's stroke is 1/35 em, Word's at every size: 0.63086 at 22.08pt.
* @throws IFException if the painting fails
*/
@Test
public void testSimulateStyleStrokeScalesWithSize() throws IFException {
simulateStyle(new MultiByteFont(null, null), 22080);
verify(pdfContentGenerator).add("2 Tr 0.63086 w\n");
}

@Test
public void testSoftHyphenNotReplaced() throws IFException {
pdfDocumentHandler = makePDFDocumentHandler(new StringBuilder());
Expand Down Expand Up @@ -376,7 +430,7 @@ public void testSimulateStyleColor() throws Exception {
fi.addMetrics("f1", font);
pdfDocumentHandler.setFontInfo(fi);
PDFPainter pdfPainter = new PDFPainter(pdfDocumentHandler, null);
pdfPainter.setFont("a", "italic", 700, null, 12, Color.red);
pdfPainter.setFont("a", "italic", 700, null, 11040, Color.red);
pdfPainter.drawText(0, 0, 0, 0, null, "test");

ByteArrayOutputStream bos = new ByteArrayOutputStream();
Expand All @@ -389,7 +443,7 @@ public void testSimulateStyleColor() throws Exception {
+ "1 0 0 -1 0 0 cm\n"
+ "1 0 0 rg\n"
+ "BT\n"
+ "/f1 0.012 Tf\n"
+ "/f1 11.04 Tf\n"
+ "1 0 0 RG\n"
+ "2 Tr 0.31543 w\n"
+ "1 0 0.3333 -1 0 0 Tm [<0000000000000000>] TJ\n"
Expand Down