Skip to content

Commit cd57084

Browse files
tomas-sexenianBeta Bot
authored andcommitted
Revert branch 'genexuslabs:PDFBoxMemoryUsage' into beta
1 parent ea0ea05 commit cd57084

File tree

2 files changed

+56
-101
lines changed

2 files changed

+56
-101
lines changed

java/pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@
115115
<dependency>
116116
<groupId>org.apache.pdfbox</groupId>
117117
<artifactId>pdfbox</artifactId>
118-
<version>3.0.3</version>
118+
<version>2.0.27</version>
119119
</dependency>
120120
<dependency>
121121
<groupId>org.jsoup</groupId>

java/src/main/java/com/genexus/reports/PDFReportPDFBox.java

Lines changed: 55 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44
import java.awt.image.BufferedImage;
55
import java.io.*;
66
import java.net.URL;
7-
import java.util.*;
7+
import java.util.ArrayList;
8+
import java.util.HashSet;
9+
import java.util.List;
10+
import java.util.Set;
811
import java.util.concurrent.ConcurrentHashMap;
912

1013
import com.genexus.ApplicationContext;
@@ -44,6 +47,7 @@
4447
public class PDFReportPDFBox extends GXReportPDFCommons{
4548
private PDRectangle pageSize;
4649
private PDFont baseFont;
50+
private String baseFontName;
4751
private BitMatrix barcode = null;
4852
private String barcodeType = null;
4953
private PDDocument document;
@@ -83,6 +87,10 @@ protected void init() {
8387
}
8488
}
8589

90+
private PDPageContentStream getNewPDPageContentStream() throws IOException {
91+
return new PDPageContentStream(document, document.getPage(page - 1), PDPageContentStream.AppendMode.APPEND,false);
92+
}
93+
8694
private void drawRectangle(PDPageContentStream cb, float x, float y, float w, float h,
8795
int styleTop, int styleBottom, int styleRight, int styleLeft,
8896
float radioTL, float radioTR, float radioBL, float radioBR, float penAux, boolean hideCorners) {
@@ -223,7 +231,7 @@ public void GxDrawRect(int left, int top, int right, int bottom, int pen, int fo
223231
int styleTop, int styleBottom, int styleRight, int styleLeft, int cornerRadioTL, int cornerRadioTR, int cornerRadioBL, int cornerRadioBR) {
224232
PDPageContentStream cb = null;
225233
try{
226-
cb = useAuxContentStream ? auxContentStream : currentPageContentStream;
234+
cb = useAuxContentStream ? auxContentStream : getNewPDPageContentStream();
227235
float penAux = (float) convertScale(pen);
228236
float rightAux = (float) convertScale(right);
229237
float bottomAux = (float) convertScale(bottom);
@@ -314,7 +322,7 @@ else if (useAuxContentStream)
314322
}
315323

316324
public void GxDrawLine(int left, int top, int right, int bottom, int width, int foreRed, int foreGreen, int foreBlue, int style) {
317-
try (PDPageContentStream cb = currentPageContentStream){
325+
try (PDPageContentStream cb = getNewPDPageContentStream()){
318326

319327
float widthAux = (float)convertScale(width);
320328
float rightAux = (float)convertScale(right);
@@ -353,7 +361,7 @@ public void GxDrawLine(int left, int top, int right, int bottom, int width, int
353361
}
354362

355363
public void GxDrawBitMap(String bitmap, int left, int top, int right, int bottom, int aspectRatio) {
356-
try (PDPageContentStream cb = currentPageContentStream){
364+
try (PDPageContentStream cb = getNewPDPageContentStream()){
357365
PDImageXObject image;
358366
try {
359367
if (documentImages != null && documentImages.containsKey(bitmap)) {
@@ -419,31 +427,6 @@ public void GxDrawBitMap(String bitmap, int left, int top, int right, int bottom
419427
}
420428
}
421429

422-
private static final int MAX_FONT_CACHE_SIZE = 50;
423-
private final Map<String, PDFont> fontCache = new LinkedHashMap<String, PDFont>(MAX_FONT_CACHE_SIZE, 0.75f, true) {
424-
@Override
425-
protected boolean removeEldestEntry(Map.Entry<String, PDFont> eldest) {
426-
return size() > MAX_FONT_CACHE_SIZE;
427-
}
428-
};
429-
430-
private PDFont getCachedFont(String fontName, PDDocument document) throws IOException {
431-
PDFont font = fontCache.get(fontName);
432-
if (font == null) {
433-
File fontFile = new File(getFontLocation(fontName));
434-
if (fontFile.exists()) {
435-
font = PDType0Font.load(document, fontFile);
436-
} else {
437-
font = createPDType1FontFromName(fontName);
438-
if (font == null) {
439-
font = new PDType1Font(Standard14Fonts.FontName.HELVETICA);
440-
}
441-
}
442-
fontCache.put(fontName, font);
443-
}
444-
return font;
445-
}
446-
447430
public void GxAttris(String fontName, int fontSize, boolean fontBold, boolean fontItalic, boolean fontUnderline, boolean fontStrikethru, int Pen, int foreRed, int foreGreen, int foreBlue, int backMode, int backRed, int backGreen, int backBlue) {
448431
boolean isCJK = false;
449432
boolean embeedFont = isEmbeddedFont(fontName);
@@ -509,8 +492,11 @@ public void GxAttris(String fontName, int fontSize, boolean fontBold, boolean fo
509492
}
510493
}
511494
baseFont = createPDType1FontFromName(fontName);
495+
if (baseFont != null)
496+
baseFontName = baseFont.getName();
512497
if (baseFont == null){
513-
baseFont = getCachedFont(fontName, document);
498+
baseFont = PDType0Font.load(document, new File(getFontLocation(fontName)));
499+
baseFontName = fontName;
514500
}
515501

516502
}
@@ -532,14 +518,19 @@ public void GxAttris(String fontName, int fontSize, boolean fontBold, boolean fo
532518
if (fontPath.equals("")) {
533519
fontPath = PDFFontDescriptor.getTrueTypeFontLocation(fontName, props);
534520
if (fontPath.equals("")) {
535-
baseFont = new PDType1Font(Standard14Fonts.FontName.HELVETICA);
521+
baseFont = PDType1Font.HELVETICA;
522+
baseFontName = baseFont.getName();
536523
foundFont = false;
537524
}
538525
}
539526
if (foundFont){
540527
baseFont = createPDType1FontFromName(fontName);
541-
if (baseFont == null)
542-
baseFont = getCachedFont(fontName, document);
528+
if (baseFont != null)
529+
baseFontName = baseFont.getName();
530+
else{
531+
baseFont = PDType0Font.load(document, new File(getFontLocation(fontName)));
532+
baseFontName = fontName;
533+
}
543534
}
544535
}
545536
}
@@ -551,33 +542,33 @@ public void GxAttris(String fontName, int fontSize, boolean fontBold, boolean fo
551542
private static PDType1Font createPDType1FontFromName(String fontName) {
552543
switch (fontName) {
553544
case "Times-Roman":
554-
return new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN);
545+
return PDType1Font.TIMES_ROMAN;
555546
case "Times-Bold":
556-
return new PDType1Font(Standard14Fonts.FontName.TIMES_BOLD);
547+
return PDType1Font.TIMES_BOLD;
557548
case "Times-Italic":
558-
return new PDType1Font(Standard14Fonts.FontName.TIMES_ITALIC);
549+
return PDType1Font.TIMES_ITALIC;
559550
case "Times-BoldItalic":
560-
return new PDType1Font(Standard14Fonts.FontName.TIMES_BOLD_ITALIC);
551+
return PDType1Font.TIMES_BOLD_ITALIC;
561552
case "Helvetica":
562-
return new PDType1Font(Standard14Fonts.FontName.HELVETICA);
553+
return PDType1Font.HELVETICA;
563554
case "Helvetica-Bold":
564-
return new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD);
555+
return PDType1Font.HELVETICA_BOLD;
565556
case "Helvetica-Oblique":
566-
return new PDType1Font(Standard14Fonts.FontName.HELVETICA_OBLIQUE);
557+
return PDType1Font.HELVETICA_OBLIQUE;
567558
case "Helvetica-BoldOblique":
568-
return new PDType1Font(Standard14Fonts.FontName.HELVETICA_BOLD_OBLIQUE);
559+
return PDType1Font.HELVETICA_BOLD_OBLIQUE;
569560
case "Courier":
570-
return new PDType1Font(Standard14Fonts.FontName.COURIER);
561+
return PDType1Font.COURIER;
571562
case "Courier-Bold":
572-
return new PDType1Font(Standard14Fonts.FontName.COURIER_BOLD);
563+
return PDType1Font.COURIER_BOLD;
573564
case "Courier-Oblique":
574-
return new PDType1Font(Standard14Fonts.FontName.COURIER_OBLIQUE);
565+
return PDType1Font.COURIER_OBLIQUE;
575566
case "Courier-BoldOblique":
576-
return new PDType1Font(Standard14Fonts.FontName.COURIER_BOLD_OBLIQUE);
567+
return PDType1Font.COURIER_BOLD_OBLIQUE;
577568
case "Symbol":
578-
return new PDType1Font(Standard14Fonts.FontName.SYMBOL);
569+
return PDType1Font.SYMBOL;
579570
case "ZapfDingbats":
580-
return new PDType1Font(Standard14Fonts.FontName.ZAPF_DINGBATS);
571+
return PDType1Font.ZAPF_DINGBATS;
581572
default:
582573
return null;
583574
}
@@ -587,34 +578,17 @@ public void setAsianFont(String fontName, String style) {
587578
try {
588579
String fontPath = getFontLocation(fontName);
589580
baseFont = PDType0Font.load(document, new File(fontPath));
581+
baseFontName = fontName;
590582
}
591583
catch(Exception e) {
592584
log.error("setAsianFont failed: ", e);
593585
}
594586
}
595587

596-
private PDFont getOrLoadFont(String fontName, PDDocument doc) throws IOException {
597-
PDFont cachedFont = fontCache.get(fontName);
598-
if (cachedFont != null) {
599-
return cachedFont;
600-
}
601-
PDFont font = createPDType1FontFromName(fontName);
602-
if (font == null) {
603-
String fontPath = getFontLocation(fontName);
604-
if (!fontPath.isEmpty()) {
605-
font = PDType0Font.load(doc, new File(fontPath));
606-
} else {
607-
font = new PDType1Font(Standard14Fonts.FontName.HELVETICA);
608-
}
609-
}
610-
fontCache.put(fontName, font);
611-
return font;
612-
}
613-
614588
public void GxDrawText(String sTxt, int left, int top, int right, int bottom, int align, int htmlformat, int border, int valign) {
615589
PDPageContentStream cb = null;
616590
try {
617-
cb = currentPageContentStream;
591+
cb = getNewPDPageContentStream();
618592
boolean printRectangle = false;
619593
if (props.getBooleanGeneralProperty(Const.BACK_FILL_IN_CONTROLS, true))
620594
printRectangle = true;
@@ -627,8 +601,9 @@ public void GxDrawText(String sTxt, int left, int top, int right, int bottom, in
627601

628602
sTxt = CommonUtil.rtrim(sTxt);
629603

630-
String descriptorFontName = baseFont.getFontDescriptor().getFontName();
631-
PDFont font = getOrLoadFont(descriptorFontName, document);
604+
PDFont font = createPDType1FontFromName(baseFont.getFontDescriptor().getFontName());
605+
if (font == null)
606+
font = PDType0Font.load(document, new File(getFontLocation(baseFontName)));
632607

633608
cb.setFont(font,fontSize);
634609
cb.setNonStrokingColor(foreColor);
@@ -694,7 +669,7 @@ else if (valign == PDFReportPDFBox.VerticalAlign.BOTTOM.value())
694669
GxStartPage();
695670

696671
cb.close();
697-
cb = currentPageContentStream;
672+
cb = getNewPDPageContentStream();
698673
}
699674
if (this.supportedHTMLTags.contains(element.normalName()))
700675
processHTMLElement(cb, htmlRectangle, spaceHandler, element);
@@ -809,7 +784,7 @@ else if (valign == PDFReportPDFBox.VerticalAlign.BOTTOM.value())
809784
underline.setUpperRightY(this.pageSize.getUpperRightY() - bottomAux - topMargin -bottomMargin + startHeight - underlineHeight);
810785
break;
811786
}
812-
PDPageContentStream contentStream = currentPageContentStream;
787+
PDPageContentStream contentStream = getNewPDPageContentStream();
813788
contentStream.setNonStrokingColor(foreColor);
814789
contentStream.addRect(underline.getLowerLeftX(), underline.getLowerLeftY(),underline.getWidth(), underline.getHeight());
815790
contentStream.fill();
@@ -840,7 +815,7 @@ else if (valign == PDFReportPDFBox.VerticalAlign.BOTTOM.value())
840815
underline.setUpperRightY(this.pageSize.getUpperRightY() - bottomAux - topMargin -bottomMargin + startHeight - underlineHeight + strikethruSeparation);
841816
break;
842817
}
843-
PDPageContentStream contentStream = currentPageContentStream;
818+
PDPageContentStream contentStream = getNewPDPageContentStream();
844819
contentStream.setNonStrokingColor(foreColor);
845820
contentStream.addRect(underline.getLowerLeftX(), underline.getLowerLeftY() - strikethruSeparation * 1/3, underline.getWidth(), underline.getHeight());
846821
contentStream.fill();
@@ -928,7 +903,7 @@ private void loadSupportedHTMLTags(){
928903
private void processHTMLElement(PDPageContentStream cb, PDRectangle htmlRectangle, SpaceHandler spaceHandler, Element blockElement) throws Exception{
929904
this.fontBold = false;
930905
String tagName = blockElement.normalName();
931-
PDFont htmlFont = new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN);
906+
PDFont htmlFont = PDType1Font.TIMES_ROMAN;
932907

933908
if (tagName.equals("div") || tagName.equals("span")) {
934909
for (Node child : blockElement.childNodes())
@@ -941,7 +916,7 @@ private void processHTMLElement(PDPageContentStream cb, PDRectangle htmlRectangl
941916
return;
942917
}
943918

944-
float lineHeight = (new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN).getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize) * DEFAULT_PDFBOX_LEADING;
919+
float lineHeight = (PDType1Font.TIMES_ROMAN.getFontDescriptor().getFontBoundingBox().getHeight() / 1000 * fontSize) * DEFAULT_PDFBOX_LEADING;
945920
float leading = (float)(Double.valueOf(props.getGeneralProperty(Const.LEADING)).doubleValue());
946921

947922
float llx = htmlRectangle.getLowerLeftX();
@@ -1065,7 +1040,7 @@ public void setAvailableSpace(float availableSpace) {
10651040

10661041
private float renderHTMLContent(PDPageContentStream contentStream, String text, float fontSize, float llx, float lly, float urx, float ury) {
10671042
try {
1068-
PDFont defaultHTMLFont = new PDType1Font(Standard14Fonts.FontName.TIMES_ROMAN);
1043+
PDFont defaultHTMLFont = PDType1Font.TIMES_ROMAN;
10691044
List<String> lines = new ArrayList<>();
10701045
String[] words = text.split(" ");
10711046
StringBuilder currentLine = new StringBuilder();
@@ -1118,18 +1093,18 @@ private void resolveTextStyling(PDPageContentStream contentStream, String text,
11181093
contentStream.setLineWidth(fontSize * 0.05f);
11191094
contentStream.setRenderingMode(RenderingMode.FILL_STROKE);
11201095
contentStream.beginText();
1121-
contentStream.newLineAtOffset(x, y);
1096+
contentStream.moveTextPositionByAmount(x, y);
11221097
contentStream.setTextMatrix(new Matrix(1, 0, 0.2f, 1, x + 0.2f * y, y));
11231098
contentStream.newLineAtOffset(-0.2f * y, 0);
11241099
} else if (this.fontBold && !this.fontItalic){
11251100
contentStream.setStrokingColor(foreColor);
11261101
contentStream.setLineWidth(fontSize * 0.05f);
11271102
contentStream.setRenderingMode(RenderingMode.FILL_STROKE);
11281103
contentStream.beginText();
1129-
contentStream.newLineAtOffset(x, y);
1104+
contentStream.moveTextPositionByAmount(x, y);
11301105
} else if (!this.fontBold && this.fontItalic){
11311106
contentStream.beginText();
1132-
contentStream.newLineAtOffset(x, y);
1107+
contentStream.moveTextPositionByAmount(x, y);
11331108
contentStream.setTextMatrix(new Matrix(1, 0, 0.2f, 1, x + 0.2f * y, y));
11341109
contentStream.newLineAtOffset(-0.2f * y, 0);
11351110
} else {
@@ -1397,30 +1372,10 @@ public void GxEndDocument() {
13971372
log.error("GxEndDocument failed: ", e);;
13981373
}
13991374
}
1400-
1401-
private PDPageContentStream currentPageContentStream;
1402-
14031375
public void GxStartPage() {
1404-
PDPage page = new PDPage(this.pageSize);
1405-
document.addPage(page);
1406-
pages++;
1407-
this.page++;
1408-
try {
1409-
currentPageContentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, false);
1410-
} catch (IOException e) {
1411-
log.error("Failed to start page content stream: ", e);
1412-
}
1413-
}
1414-
1415-
public void GxEndPage() {
1416-
try {
1417-
if (currentPageContentStream != null) {
1418-
currentPageContentStream.close();
1419-
currentPageContentStream = null;
1420-
}
1421-
} catch (IOException e) {
1422-
log.error("Failed to close page content stream: ", e);
1423-
}
1376+
document.addPage(new PDPage(this.pageSize));
1377+
pages = pages + 1;
1378+
page = page + 1;
14241379
}
14251380

14261381
}

0 commit comments

Comments
 (0)