@@ -229,7 +229,6 @@ PageContextProcessor reset(PageSize defaultPageSize, float[] defaultPageMargins)
229229
230230 marks = parseMarks (styles .get (CssConstants .MARKS ));
231231
232- // todo all of this art with margins, borders and paddings?
233232 parseMargins (styles , em , rem , defaultPageMargins );
234233 parseBorders (styles , em , rem );
235234 parsePaddings (styles , em , rem );
@@ -466,50 +465,65 @@ private void drawMarginBoxes(int pageNumber, PdfDocument pdfDocument, DocumentRe
466465 PageMarginBoxContextNode [] corners = new PageMarginBoxContextNode [4 ];
467466 for (PageMarginBoxContextNode marginBoxContentNode : properties .getResolvedPageMarginBoxes ()) {
468467 int marginBoxInd = mapMarginBoxNameToIndex (marginBoxContentNode .getMarginBoxName ());
469- if (marginBoxInd % 4 != 0 )
468+ if (marginBoxInd % 4 != 0 ) {
470469 sides [marginBoxInd / 4 ][marginBoxInd % 4 - 1 ] = marginBoxContentNode ;
471- else
470+ }
471+ else {
472472 corners [marginBoxInd / 4 ] = marginBoxContentNode ;
473+ }
473474 }
474475
475476 IElement [][] sideBoxElement = new IElement [4 ][3 ];
476477 IElement [] cornerBoxElement = new IElement [4 ];
477478 for (int i = 0 ; i < 4 ; i ++) {
478479 for (int j = 0 ; j < 3 ; j ++)
479- if (sides [i ][j ] != null )
480+ if (sides [i ][j ] != null ) {
480481 sideBoxElement [i ][j ] = processMarginBoxContent (sides [i ][j ], pageNumber , context );
481- if (corners [i ] != null )
482+ }
483+ if (corners [i ] != null ) {
482484 cornerBoxElement [i ] = processMarginBoxContent (corners [i ], pageNumber , context );
485+ }
483486 }
484487
485488 for (int i = 0 ; i < 4 ; i ++) {
486489 if (cornerBoxElement [i ] != null ) {
487- IRenderer cornerRenderer = funWithRenderer (cornerBoxElement [i ], documentRenderer , pdfDocument );
488- float rendererWidth = margins [i % 3 == 0 ? 3 : 1 ] - getWidthOfOneSide (cornerBoxElement [i ], Property .MARGIN_LEFT , Property .BORDER_LEFT , Property .PADDING_LEFT ) -
489- getWidthOfOneSide (cornerBoxElement [i ], Property .MARGIN_RIGHT , Property .BORDER_RIGHT , Property .PADDING_RIGHT );
490- float rendererHeight = margins [i > 1 ? 2 : 0 ] - getWidthOfOneSide (cornerBoxElement [i ], Property .MARGIN_TOP , Property .BORDER_TOP , Property .PADDING_TOP ) -
491- getWidthOfOneSide (cornerBoxElement [i ], Property .MARGIN_BOTTOM , Property .BORDER_BOTTOM , Property .PADDING_BOTTOM );
490+ IRenderer cornerRenderer = createRendererFromElement (cornerBoxElement [i ], documentRenderer , pdfDocument );
491+
492+ float rendererWidth =
493+ margins [i % 3 == 0 ? 3 : 1 ]
494+ - getSizeOfOneSide (cornerBoxElement [i ], Property .MARGIN_LEFT ,
495+ Property .BORDER_LEFT , Property .PADDING_LEFT )
496+ - getSizeOfOneSide (cornerBoxElement [i ], Property .MARGIN_RIGHT ,
497+ Property .BORDER_RIGHT , Property .PADDING_RIGHT );
498+
499+ float rendererHeight =
500+ margins [i > 1 ? 2 : 0 ]
501+ - getSizeOfOneSide (cornerBoxElement [i ], Property .MARGIN_TOP ,
502+ Property .BORDER_TOP , Property .PADDING_TOP )
503+ - getSizeOfOneSide (cornerBoxElement [i ], Property .MARGIN_BOTTOM ,
504+ Property .BORDER_BOTTOM , Property .PADDING_BOTTOM );
505+
492506 cornerRenderer .setProperty (Property .WIDTH , UnitValue .createPointValue (rendererWidth ));
493507 cornerRenderer .setProperty (Property .HEIGHT , UnitValue .createPointValue (rendererHeight ));
494508 draw (cornerRenderer , corners [i ], pdfDocument , page , documentRenderer , pageNumber );
495509 }
496510
497- IRenderer [] renderer = new IRenderer [3 ];
511+ IRenderer [] renderers = new IRenderer [3 ];
498512 for (int j = 0 ; j < 3 ; j ++) {
499513 if (sideBoxElement [i ][j ] != null ) {
500- renderer [j ] = funWithRenderer (sideBoxElement [i ][j ], documentRenderer , pdfDocument );
514+ renderers [j ] = createRendererFromElement (sideBoxElement [i ][j ], documentRenderer , pdfDocument );
501515 }
502516 }
503- determineSizes (sides [i ], renderer , sideBoxElement [i ], i );
517+ determineSizes (sides [i ], renderers , sideBoxElement [i ], i );
504518 for (int j = 0 ; j < 3 ; j ++) {
505- if (renderer [j ] != null ) {
506- draw (renderer [j ], sides [i ][j ], pdfDocument , page , documentRenderer , pageNumber );
519+ if (renderers [j ] != null ) {
520+ draw (renderers [j ], sides [i ][j ], pdfDocument , page , documentRenderer , pageNumber );
507521 }
508522 }
509523 }
510524 }
511525
512- private IRenderer funWithRenderer (IElement element , DocumentRenderer documentRenderer , PdfDocument pdfDocument ) {
526+ private IRenderer createRendererFromElement (IElement element , DocumentRenderer documentRenderer , PdfDocument pdfDocument ) {
513527 IRenderer renderer = element .createRendererSubTree ();
514528 removeAreaBreaks (renderer );
515529 renderer .setParent (documentRenderer );
@@ -625,8 +639,6 @@ private void prepareMarginBoxesSizing(List<PageMarginBoxContextNode> resolvedPag
625639 }
626640 }
627641
628- // todo don't forget to apply MBP to corners!!!
629-
630642 private IElement processMarginBoxContent (PageMarginBoxContextNode marginBoxContentNode , int pageNumber , ProcessorContext context ) {
631643 IElementNode dummyMarginBoxNode = new PageMarginBoxDummyElement ();
632644 dummyMarginBoxNode .setStyles (marginBoxContentNode .getStyles ());
@@ -719,37 +731,55 @@ private void determineSizes(PageMarginBoxContextNode[] resolvedPageMarginBoxes,
719731 float [][] marginsBordersPaddingsWidths = new float [3 ][4 ];
720732 for (int i = 0 ; i < 3 ; i ++) {
721733 if (elements [i ] != null ) {
722- marginsBordersPaddingsWidths [i ][0 ] = getWidthOfOneSide (elements [i ], Property .MARGIN_TOP , Property .BORDER_TOP , Property .PADDING_TOP );
723- marginsBordersPaddingsWidths [i ][1 ] = getWidthOfOneSide (elements [i ], Property .MARGIN_RIGHT , Property .BORDER_RIGHT , Property .PADDING_RIGHT );
724- marginsBordersPaddingsWidths [i ][2 ] = getWidthOfOneSide (elements [i ], Property .MARGIN_BOTTOM , Property .BORDER_BOTTOM , Property .PADDING_BOTTOM );
725- marginsBordersPaddingsWidths [i ][3 ] = getWidthOfOneSide (elements [i ], Property .MARGIN_LEFT , Property .BORDER_LEFT , Property .PADDING_LEFT );
734+ marginsBordersPaddingsWidths [i ][0 ] = getSizeOfOneSide (elements [i ], Property .MARGIN_TOP , Property .BORDER_TOP , Property .PADDING_TOP );
735+ marginsBordersPaddingsWidths [i ][1 ] = getSizeOfOneSide (elements [i ], Property .MARGIN_RIGHT , Property .BORDER_RIGHT , Property .PADDING_RIGHT );
736+ marginsBordersPaddingsWidths [i ][2 ] = getSizeOfOneSide (elements [i ], Property .MARGIN_BOTTOM , Property .BORDER_BOTTOM , Property .PADDING_BOTTOM );
737+ marginsBordersPaddingsWidths [i ][3 ] = getSizeOfOneSide (elements [i ], Property .MARGIN_LEFT , Property .BORDER_LEFT , Property .PADDING_LEFT );
726738 }
727739 }
728740 Rectangle withoutMargins = pageSize .clone ().applyMargins (margins [0 ], margins [1 ], margins [2 ], margins [3 ], false );
729741 Map <String , PageMarginBoxContextNode > resolvedPMBMap = new HashMap <>();
730742 for (PageMarginBoxContextNode node : resolvedPageMarginBoxes ) {
731- if (node != null )
743+ if (node != null ) {
732744 resolvedPMBMap .put (node .getMarginBoxName (), node );
745+ }
733746 }
734747 DimensionContainer [] dims = new DimensionContainer [3 ];
735748 String [] cssRuleName = getRuleNames (side );
749+ float withoutMarginsWidthOrHeight = side % 2 == 0 ? withoutMargins .getWidth () : withoutMargins .getHeight ();
736750 for (int i = 0 ; i < 3 ; i ++)
737- if (side % 2 == 0 )
738- dims [i ] = retrievePageMarginBoxWidths (resolvedPMBMap .get (cssRuleName [i ]), renderers [i ], side % 2 == 0 ? withoutMargins . getWidth () : withoutMargins . getHeight () ,
751+ if (side % 2 == 0 ) {
752+ dims [i ] = retrievePageMarginBoxWidths (resolvedPMBMap .get (cssRuleName [i ]), renderers [i ], withoutMarginsWidthOrHeight ,
739753 marginsBordersPaddingsWidths [i ][1 ] + marginsBordersPaddingsWidths [i ][3 ]);
740- else
754+ }
755+ else {
741756 dims [i ] = retrievePageMarginBoxHeights (resolvedPMBMap .get (cssRuleName [i ]), renderers [i ], margins [side ],
742- side % 2 == 0 ? withoutMargins .getWidth () : withoutMargins .getHeight (), marginsBordersPaddingsWidths [i ][1 ] + marginsBordersPaddingsWidths [i ][3 ]);
743- float [] widthOfHeightResults = calculatePageMarginBoxDimensions (dims [0 ], dims [1 ], dims [2 ], side % 2 == 0 ? withoutMargins .getWidth () : withoutMargins .getHeight ());
744- float centerOrMiddleCoord = getStartCoordForCenterOrMiddleBox (side % 2 == 0 ? withoutMargins .getWidth () : withoutMargins .getHeight (),
745- widthOfHeightResults [1 ],
746- side % 2 == 0 ? withoutMargins .getLeft () : withoutMargins .getBottom ());
757+ withoutMarginsWidthOrHeight , marginsBordersPaddingsWidths [i ][0 ] + marginsBordersPaddingsWidths [i ][2 ]);
758+
759+ }
760+
761+ float centerOrMiddleCoord , widthOfHeightResults [];
762+ widthOfHeightResults = calculatePageMarginBoxDimensions (dims [0 ], dims [1 ], dims [2 ], withoutMarginsWidthOrHeight );
763+ if (side % 2 == 0 ) {
764+ centerOrMiddleCoord = getStartCoordForCenterOrMiddleBox (withoutMarginsWidthOrHeight ,
765+ widthOfHeightResults [1 ], withoutMargins .getLeft ());
766+ } else {
767+ centerOrMiddleCoord = getStartCoordForCenterOrMiddleBox (withoutMarginsWidthOrHeight ,
768+ widthOfHeightResults [1 ], withoutMargins .getBottom ());
769+ }
770+
747771 Rectangle [] result = getRectangles (side , withoutMargins , centerOrMiddleCoord , widthOfHeightResults , marginsBordersPaddingsWidths );
748772 for (int i = 0 ; i < 3 ; i ++)
749773 if (resolvedPageMarginBoxes [i ] != null ) {
750774 resolvedPageMarginBoxes [i ].setPageMarginBoxRectangle (result [i ]);
751- renderers [i ].setProperty (Property .WIDTH , UnitValue .createPointValue (result [i ].getWidth () - marginsBordersPaddingsWidths [i ][1 ] - marginsBordersPaddingsWidths [i ][3 ]));
752- renderers [i ].setProperty (Property .HEIGHT , UnitValue .createPointValue (result [i ].getHeight () - marginsBordersPaddingsWidths [i ][0 ] - marginsBordersPaddingsWidths [i ][2 ]));
775+ UnitValue width = UnitValue .createPointValue (result [i ].getWidth () - marginsBordersPaddingsWidths [i ][1 ] - marginsBordersPaddingsWidths [i ][3 ]);
776+ UnitValue height = UnitValue .createPointValue (result [i ].getHeight () - marginsBordersPaddingsWidths [i ][0 ] - marginsBordersPaddingsWidths [i ][2 ]);
777+ if (Math .abs (width .getValue ()) < 1e-3 || Math .abs (height .getValue ()) < 1e-3 ) {
778+ renderers [i ] = null ;
779+ } else {
780+ renderers [i ].setProperty (Property .WIDTH , width );
781+ renderers [i ].setProperty (Property .HEIGHT , height );
782+ }
753783 }
754784 }
755785
@@ -804,21 +834,23 @@ private Rectangle[] getRectangles(int side, Rectangle withoutMargins, float cent
804834 return new Rectangle [3 ];
805835 }
806836
807- // todo importance of order! Border is different from margin or padding!
808- // todo make sure it's always top, right, bottom and left and not generic
809- // todo make sure margin/padding is always UnitValue
810- private float getWidthOfOneSide (IElement element , int marginProperty , int borderProperty , int paddingProperty ) {
811- // todo extract the damn Property accurately
837+ private float getSizeOfOneSide (IElement element , int marginProperty , int borderProperty , int paddingProperty ) {
812838 float marginWidth = 0 , paddingWidth = 0 , borderWidth = 0 ;
839+
813840 UnitValue temp = element .<UnitValue >getProperty (marginProperty );
814- if (null != temp )
841+ if (null != temp ) {
815842 marginWidth = temp .getValue ();
843+ }
844+
816845 temp = element .<UnitValue >getProperty (paddingProperty );
817- if (null != temp )
846+ if (null != temp ) {
818847 paddingWidth = temp .getValue ();
848+ }
849+
819850 Border border = element .<Border >getProperty (borderProperty );
820- if (null != border )
851+ if (null != border ) {
821852 borderWidth = border .getWidth ();
853+ }
822854 return marginWidth + paddingWidth + borderWidth ;
823855 }
824856
@@ -850,22 +882,22 @@ private float[] calculatePageMarginBoxDimensions(DimensionContainer dimA, Dimens
850882 maxContentDimensionC = 0 , minContentDimensionC = 0 ;
851883 float [] dimensions = new float [3 ];
852884
853- if (dimA == null && dimB == null && dimC == null ) {
885+ if (isContainerEmpty ( dimA ) && isContainerEmpty ( dimB ) && isContainerEmpty ( dimC ) ) {
854886 return dimensions ;
855887 }
856888
857889 //Calculate widths
858890 //Check if B is present
859- if (dimB == null ) {
891+ if (isContainerEmpty ( dimB ) ) {
860892 //Single box present
861- if (dimA == null ) {
893+ if (isContainerEmpty ( dimA ) ) {
862894 if (dimC .isAutoDimension ()) {
863895 //Allocate everything to C
864896 dimensions [2 ] = availableDimension ;
865897 } else {
866898 dimensions [2 ] = dimC .dimension ;
867899 }
868- } else if (dimC == null ) {
900+ } else if (isContainerEmpty ( dimC ) ) {
869901 if (dimA .isAutoDimension ()) {
870902 //Allocate everything to A
871903 dimensions [0 ] = availableDimension ;
@@ -896,7 +928,7 @@ private float[] calculatePageMarginBoxDimensions(DimensionContainer dimA, Dimens
896928 }
897929 } else {
898930 //Check for edge cases
899- if (dimA != null ) {
931+ if (! isContainerEmpty ( dimA ) ) {
900932 if (dimA .isAutoDimension ()) {
901933 maxContentDimensionA = dimA .maxContentDimension ;
902934 minContentDimensionA = dimA .minContentDimension ;
@@ -905,7 +937,7 @@ private float[] calculatePageMarginBoxDimensions(DimensionContainer dimA, Dimens
905937 minContentDimensionA = dimA .dimension ;
906938 }
907939 }
908- if (dimC != null ) {
940+ if (! isContainerEmpty ( dimC ) ) {
909941 if (dimC .isAutoDimension ()) {
910942 maxContentDimensionC = dimC .maxContentDimension ;
911943 minContentDimensionC = dimC .minContentDimension ;
@@ -940,7 +972,10 @@ private float[] calculatePageMarginBoxDimensions(DimensionContainer dimA, Dimens
940972 } else {
941973 dimensions [1 ] = dimB .dimension ;
942974 float newAvailableDimension = (availableDimension - dimensions [1 ]) / 2 ;
943- // todo make sure it's not tooooo big float
975+
976+ if (newAvailableDimension > Float .MAX_VALUE - MinMaxWidthUtils .getEps ()) {
977+ newAvailableDimension = Float .MAX_VALUE - MinMaxWidthUtils .getEps ();
978+ }
944979 dimensions [0 ] = Math .min (maxContentDimensionA , newAvailableDimension ) + MinMaxWidthUtils .getEps ();
945980 dimensions [2 ] = Math .min (maxContentDimensionC , newAvailableDimension ) + MinMaxWidthUtils .getEps ();
946981 }
@@ -957,6 +992,10 @@ private float[] calculatePageMarginBoxDimensions(DimensionContainer dimA, Dimens
957992 return dimensions ;
958993 }
959994
995+ private boolean isContainerEmpty (DimensionContainer container ) {
996+ return container == null || Math .abs (container .maxContentDimension ) < 1e-3 ;
997+ }
998+
960999 private void removeNegativeValues (float [] dimensions ) {
9611000 for (int i = 0 ; i < dimensions .length ; i ++) {
9621001 if (dimensions [i ] < 0 ) {
0 commit comments