Skip to content

Commit

Permalink
#1062: Call LayoutProcessor.disable() after Test-Runs
Browse files Browse the repository at this point in the history
- and some cleanups
  • Loading branch information
asturio committed Feb 20, 2024
1 parent 59ad70f commit 14fa6c9
Show file tree
Hide file tree
Showing 10 changed files with 348 additions and 354 deletions.
114 changes: 61 additions & 53 deletions openpdf/src/main/java/com/lowagie/text/pdf/LayoutProcessor.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,17 @@ private LayoutProcessor() {

/**
* Enables the processor.
* Kerning and ligatures are switched off.
*
* This method can only be called once.
* <p>
* Kerning and ligatures are switched off. This method can only be called once.
*/
public static void enable() {
enabled = true;
}

/**
* Enables the processor with the provided flags.
* Kerning and ligatures are switched off.
*
* This method can only be called once.
* <p>
* Kerning and ligatures are switched off. This method can only be called once.
*
* @param flags see java.awt.Font.layoutGlyphVector
*/
Expand All @@ -106,18 +104,17 @@ public static void enable(int flags) {

/**
* Enables the processor.
* Kerning and ligatures are switched on.
*
* This method can only be called once.
* <p>
* Kerning and ligatures are switched on. This method can only be called once.
*/
public static void enableKernLiga() {
enableKernLiga(DEFAULT_FLAGS);
}

/**
* Enables the processor with the provided flags.
* <p>
* Kerning and ligatures are switched on.
*
* This method can only be called once.
*
* @param flags see java.awt.Font.layoutGlyphVector
Expand All @@ -138,81 +135,87 @@ public static boolean isEnabled() {

/**
* Set kerning
* @see
* <a href="https://docs.oracle.com/javase/tutorial/2d/text/textattributes.html">
* Oracle: The Java™ Tutorials, Using Text Attributes to Style Text</a>
*
* @see <a href="https://docs.oracle.com/javase/tutorial/2d/text/textattributes.html">
* Oracle: The Java™ Tutorials, Using Text Attributes to Style Text</a>
*/
public static void setKerning() {
LayoutProcessor.globalTextAttributes.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
}

/**
* Set kerning for one font
*
* @param font The font for which kerning is to be turned on
* @see
* <a href="https://docs.oracle.com/javase/tutorial/2d/text/textattributes.html">
* Oracle: The Java™ Tutorials, Using Text Attributes to Style Text</a>
* @see <a href="https://docs.oracle.com/javase/tutorial/2d/text/textattributes.html">
* Oracle: The Java™ Tutorials, Using Text Attributes to Style Text</a>
*/
public static void setKerning(com.lowagie.text.Font font) {
public static void setKerning(com.lowagie.text.Font font) {
Map<TextAttribute, Object> textAttributes = new HashMap<>();
textAttributes.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
setTextAttributes(font, textAttributes);
}

/**
* Add ligatures
*/
public static void setLigatures() {
LayoutProcessor.globalTextAttributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
}

/**
* Set ligatures for one font
* @param font The font for which ligatures are to be turned on
*
* @param font The font for which ligatures are to be turned on
*/
public static void setLigatures(com.lowagie.text.Font font) {
public static void setLigatures(com.lowagie.text.Font font) {
Map<TextAttribute, Object> textAttributes = new HashMap<>();
textAttributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
setTextAttributes(font, textAttributes);
}

/**
* Set run direction for one font to RTL
* @param font The font for which the run direction is set
*
* @param font The font for which the run direction is set
*/
public static void setRunDirectionRtl(com.lowagie.text.Font font) {
public static void setRunDirectionRtl(com.lowagie.text.Font font) {
setRunDirection(font, TextAttribute.RUN_DIRECTION_RTL);
}

/**
* Set run direction for one font to LTR
* @param font The font for which the run direction is set
*
* @param font The font for which the run direction is set
*/
public static void setRunDirectionLtr(com.lowagie.text.Font font) {
public static void setRunDirectionLtr(com.lowagie.text.Font font) {
setRunDirection(font, TextAttribute.RUN_DIRECTION_LTR);
}

/**
* Set run direction for one font
* @param font The font for which the run direction is set
*
* @param font The font for which the run direction is set
*/
private static void setRunDirection(com.lowagie.text.Font font, Boolean runDirection) {
private static void setRunDirection(com.lowagie.text.Font font, Boolean runDirection) {
Map<TextAttribute, Object> textAttributes = new HashMap<>();
textAttributes.put(TextAttribute.RUN_DIRECTION, runDirection);
setTextAttributes(font, textAttributes);
}

/**
* Set text attributes to font
* The attributes are used only for glyph layout,
* and don't change the visual appearance of the font
* @param font The font for which kerning is to be turned on
* Set text attributes to font The attributes are used only for glyph layout, and don't change the visual appearance
* of the font
*
* @param font The font for which kerning is to be turned on
* @param textAttributes Map of text attributes to be set
* @see
* <a href="https://docs.oracle.com/javase/tutorial/2d/text/textattributes.html">
* Oracle: The Java™ Tutorials, Using Text Attributes to Style Text</a>*
* @see <a href="https://docs.oracle.com/javase/tutorial/2d/text/textattributes.html">
* Oracle: The Java™ Tutorials, Using Text Attributes to Style Text</a>*
*/
private static void setTextAttributes(com.lowagie.text.Font font, Map<TextAttribute, Object> textAttributes) {
private static void setTextAttributes(com.lowagie.text.Font font, Map<TextAttribute, Object> textAttributes) {
BaseFont baseFont = font.getBaseFont();
java.awt.Font awtFont = awtFontMap.get(baseFont);
if (awtFont!=null) {
if (awtFont != null) {
awtFont = awtFont.deriveFont(textAttributes);
awtFontMap.put(baseFont, awtFont);
}
Expand All @@ -233,9 +236,8 @@ public static boolean supportsFont(BaseFont baseFont) {
/**
* Loads the AWT font needed for layout
*
* @param baseFont OpenPdf base font
* @param baseFont OpenPdf base font
* @param filename of the font file
*
* @throws RuntimeException if font can not be loaded
*/
public static void loadFont(BaseFont baseFont, String filename) {
Expand All @@ -257,8 +259,8 @@ public static void loadFont(BaseFont baseFont, String filename) {
if (file.canRead()) {
inputStream = Files.newInputStream(file.toPath());
} else if (filename.startsWith("file:/") || filename.startsWith("http://")
|| filename.startsWith("https://") || filename.startsWith("jar:")
|| filename.startsWith("wsjar:")) {
|| filename.startsWith("https://") || filename.startsWith("jar:")
|| filename.startsWith("wsjar:")) {
inputStream = new URL(filename).openStream();
} else if ("-".equals(filename)) {
inputStream = System.in;
Expand All @@ -267,11 +269,11 @@ public static void loadFont(BaseFont baseFont, String filename) {
}
if (inputStream == null) {
throw new IOException(
MessageLocalization.getComposedMessage("1.not.found.as.file.or.resource", filename));
MessageLocalization.getComposedMessage("1.not.found.as.file.or.resource", filename));
}
awtFont = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FONT, inputStream);
if (awtFont != null) {
if (globalTextAttributes.size()>0) {
if (!globalTextAttributes.isEmpty()) {
awtFont = awtFont.deriveFont(LayoutProcessor.globalTextAttributes);
}
awtFontMap.put(baseFont, awtFont);
Expand All @@ -293,8 +295,8 @@ public static void loadFont(BaseFont baseFont, String filename) {
/**
* Computes glyph positioning
*
* @param baseFont OpenPdf base font
* @param text input text
* @param baseFont OpenPdf base font
* @param text input text
* @return glyph vector containing reordered text, width and positioning info
*/
public static GlyphVector computeGlyphVector(BaseFont baseFont, float fontSize, String text) {
Expand All @@ -311,23 +313,22 @@ public static GlyphVector computeGlyphVector(BaseFont baseFont, float fontSize,
}
java.awt.Font awtFont = LayoutProcessor.awtFontMap.get(baseFont).deriveFont(fontSize);
Map<TextAttribute, ?> textAttributes = awtFont.getAttributes();
if (textAttributes!=null) {
if (textAttributes != null) {
Object runDirection = textAttributes.get(TextAttribute.RUN_DIRECTION);
if (runDirection!=null) {
localFlags = runDirection==TextAttribute.RUN_DIRECTION_LTR ? java.awt.Font.LAYOUT_LEFT_TO_RIGHT :
java.awt.Font.LAYOUT_RIGHT_TO_LEFT;
if (runDirection != null) {
localFlags = runDirection == TextAttribute.RUN_DIRECTION_LTR ? java.awt.Font.LAYOUT_LEFT_TO_RIGHT :
java.awt.Font.LAYOUT_RIGHT_TO_LEFT;
}
}
return awtFont.layoutGlyphVector(fontRenderContext, chars, 0, chars.length, localFlags);
}

/**
* Checks if the glyphVector contains adjustments
* that make advanced layout necessary
*
* @param glyphVector glyph vector containing the positions
* @return true, if the glyphVector contains adjustments
*/
/**
* Checks if the glyphVector contains adjustments that make advanced layout necessary
*
* @param glyphVector glyph vector containing the positions
* @return true, if the glyphVector contains adjustments
*/
private static boolean hasAdjustments(GlyphVector glyphVector) {
boolean retVal = false;
float lastX = 0f;
Expand Down Expand Up @@ -392,4 +393,11 @@ public static Point2D showText(PdfContentByte cb, BaseFont baseFont, float fontS
cb.moveTextBasic(dx, -dy);
return new Point2D.Double(-p.getX(), p.getY());
}

public static void disable() {
enabled = false;
flags = DEFAULT_FLAGS;
awtFontMap.clear();
globalTextAttributes.clear();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,32 @@
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

public class CrossReferenceTableEncodingTest {

public static final String TEST_PDF = "/encodingTest.pdf";

private static String filterPdf(final String pdf) {
return pdf.replaceAll("<</ModDate.*?>>", "")
.replaceAll("<</CreationDate.*?>>", "")
.replaceAll("<</Info .*?>>", "<</Info XXXXX>>")
.replaceAll("startxref\\n(\\d+)\\n%%EOF", "startxref\nXXXXX\n%%EOF");
}

// This test was once red, even it was not easy to accomplish this. The test must be run with
// -Dfile.encoding=IBM273 from the IDE. Maven won't accept this property.
@Disabled("This test runs ok, if it is run alone. It fails when run with other tests in the IDE. Probably it is because some 'static' state in another class.")
@Test
public void testCrossReferenceTableEncoding() throws Exception {
void testCrossReferenceTableEncoding() throws Exception {
final String actualPDF = generateSimplePdf();
final String expectedPDF = readExpectedFile();
String actual = filterPdf(actualPDF);
String expected = filterPdf(expectedPDF);
assertThat(actual).isEqualTo(expected);
}

private static String filterPdf(final String pdf) {
return pdf.replaceAll("<</ModDate.*?>>", "")
.replaceAll("<</CreationDate.*?>>", "")
.replaceAll("<</Info .*?>>", "<</Info XXXXX>>")
.replaceAll("startxref\\n(\\d+)\\n%%EOF", "startxref\nXXXXX\n%%EOF");
}

private String readExpectedFile() throws IOException {
try (final InputStream expected = getClass().getResourceAsStream(TEST_PDF)) {
assertThat(expected).isNotNull();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.awt.Font;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand All @@ -24,13 +25,18 @@ static void beforeAll() {
LayoutProcessor.enable(java.awt.Font.LAYOUT_RIGHT_TO_LEFT);
}

@AfterAll
static void afterAll() {
LayoutProcessor.disable();
}

@BeforeEach
void beforeEach() {
assumeThat(LayoutProcessor.isSet(Font.LAYOUT_RIGHT_TO_LEFT)).isTrue();
}

@Test
public void whenLayoutRightToLeftLatin_thenRevertCharOrder() throws IOException {
void whenLayoutRightToLeftLatin_thenRevertCharOrder() throws IOException {
// given
Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
Expand Down Expand Up @@ -61,7 +67,7 @@ public void whenLayoutRightToLeftLatin_thenRevertCharOrder() throws IOException
}

@Test
public void whenLayoutRightToLeftHebrew_thenRevertCharOrder() throws IOException {
void whenLayoutRightToLeftHebrew_thenRevertCharOrder() throws IOException {
// given
Document document = new Document(PageSize.A4.rotate(), 10, 10, 10, 10);
ByteArrayOutputStream pdfOut = new ByteArrayOutputStream();
Expand Down
Loading

0 comments on commit 14fa6c9

Please sign in to comment.