Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#1062: Call LayoutProcessor.disable() after Test-Runs #1064

Merged
merged 1 commit into from
Feb 20, 2024
Merged
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
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