44import java .awt .image .BufferedImage ;
55import java .io .*;
66import 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 ;
811import java .util .concurrent .ConcurrentHashMap ;
912
1013import com .genexus .ApplicationContext ;
4447public 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