@@ -81,6 +81,7 @@ This file is part of the iText (R) project.
81
81
import com .itextpdf .layout .property .Background ;
82
82
import com .itextpdf .layout .property .BackgroundImage ;
83
83
import com .itextpdf .layout .property .BaseDirection ;
84
+ import com .itextpdf .layout .property .BoxSizingPropertyValue ;
84
85
import com .itextpdf .layout .property .HorizontalAlignment ;
85
86
import com .itextpdf .layout .property .Property ;
86
87
import com .itextpdf .layout .property .TransparentColor ;
@@ -704,20 +705,112 @@ protected void applyDestinationsAndAnnotation(DrawContext drawContext) {
704
705
applyLinkAnnotation (drawContext .getDocument ());
705
706
}
706
707
708
+ static boolean isBorderBoxSizing (IRenderer renderer ) {
709
+ BoxSizingPropertyValue boxSizing = renderer .<BoxSizingPropertyValue >getProperty (Property .BOX_SIZING );
710
+ return boxSizing != null && boxSizing .equals (BoxSizingPropertyValue .BORDER_BOX );
711
+ }
712
+
713
+ /**
714
+ * Retrieves element's fixed content box width, if it's set.
715
+ * Takes into account {@link Property#BOX_SIZING} property value.
716
+ * @param parentBoxWidth width of the parent element content box.
717
+ * If element has relative width, it will be
718
+ * calculated relatively to this parameter.
719
+ * @return element's fixed content box width or null if it's not set.
720
+ */
707
721
protected Float retrieveWidth (float parentBoxWidth ) {
708
- return retrieveUnitValue (parentBoxWidth , Property .WIDTH );
722
+ Float width = retrieveUnitValue (parentBoxWidth , Property .WIDTH );
723
+ if (width != null && isBorderBoxSizing (this )) {
724
+ width = Math .max (0 , (float )width - calculatePaddingBorderWidth (this ));
725
+ }
726
+ return width ;
709
727
}
710
728
729
+ /**
730
+ * Updates fixed content box width value for this renderer.
731
+ * Takes into account {@link Property#BOX_SIZING} property value.
732
+ * @param updatedWidthValue element's new fixed content box width.
733
+ */
734
+ protected void updateWidth (UnitValue updatedWidthValue ) {
735
+ if (updatedWidthValue .isPointValue () && isBorderBoxSizing (this )) {
736
+ updatedWidthValue .setValue (updatedWidthValue .getValue () + calculatePaddingBorderWidth (this ));
737
+ }
738
+ setProperty (Property .WIDTH , updatedWidthValue );
739
+ }
740
+
741
+ /**
742
+ * Retrieves element's fixed content box height, if it's set.
743
+ * Takes into account {@link Property#BOX_SIZING} property value.
744
+ * @return element's fixed content box height or null if it's not set.
745
+ */
711
746
protected Float retrieveHeight () {
712
- return this .<Float >getProperty (Property .HEIGHT );
747
+ Float height = this .<Float >getProperty (Property .HEIGHT );
748
+ if (height != null && isBorderBoxSizing (this )) {
749
+ height = Math .max (0 , (float )height - calculatePaddingBorderHeight (this ));
750
+ }
751
+ return height ;
713
752
}
714
753
754
+ /**
755
+ * Updates fixed content box height value for this renderer.
756
+ * Takes into account {@link Property#BOX_SIZING} property value.
757
+ * @param updatedHeightValue element's new fixed content box height, shall be not null.
758
+ */
759
+ protected void updateHeight (Float updatedHeightValue ) {
760
+ if (isBorderBoxSizing (this )) {
761
+ updatedHeightValue += calculatePaddingBorderHeight (this );
762
+ }
763
+ setProperty (Property .HEIGHT , updatedHeightValue );
764
+ }
765
+
766
+ /**
767
+ * Retrieves element's content box max-height, if it's set.
768
+ * Takes into account {@link Property#BOX_SIZING} property value.
769
+ * @return element's content box max-height or null if it's not set.
770
+ */
715
771
protected Float retrieveMaxHeight () {
716
- return this .<Float >getProperty (Property .MAX_HEIGHT );
772
+ Float maxHeight = this .<Float >getProperty (Property .MAX_HEIGHT );
773
+ if (maxHeight != null && isBorderBoxSizing (this )) {
774
+ maxHeight = Math .max (0 , (float )maxHeight - calculatePaddingBorderHeight (this ));
775
+ }
776
+ return maxHeight ;
717
777
}
718
778
779
+ /**
780
+ * Updates content box max-height value for this renderer.
781
+ * Takes into account {@link Property#BOX_SIZING} property value.
782
+ * @param updatedMaxHeightValue element's new content box max-height, shall be not null.
783
+ */
784
+ protected void updateMaxHeight (Float updatedMaxHeightValue ) {
785
+ if (isBorderBoxSizing (this )) {
786
+ updatedMaxHeightValue += calculatePaddingBorderHeight (this );
787
+ }
788
+ setProperty (Property .MAX_HEIGHT , updatedMaxHeightValue );
789
+ }
790
+
791
+ /**
792
+ * Retrieves element's content box max-height, if it's set.
793
+ * Takes into account {@link Property#BOX_SIZING} property value.
794
+ * @return element's content box min-height or null if it's not set.
795
+ */
719
796
protected Float retrieveMinHeight () {
720
- return this .<Float >getProperty (Property .MIN_HEIGHT );
797
+ Float minHeight = this .<Float >getProperty (Property .MIN_HEIGHT );
798
+ if (minHeight != null && isBorderBoxSizing (this )) {
799
+ minHeight = Math .max (0 , (float )minHeight - calculatePaddingBorderHeight (this ));
800
+ }
801
+ return minHeight ;
802
+ }
803
+
804
+ /**
805
+ * Updates content box min-height value for this renderer.
806
+ * Takes into account {@link Property#BOX_SIZING} property value.
807
+ * @param updatedMinHeightValue element's new content box min-height, shall be not null.
808
+ */
809
+ protected void updateMinHeight (Float updatedMinHeightValue ) {
810
+ if (isBorderBoxSizing (this )) {
811
+ updatedMinHeightValue += calculatePaddingBorderHeight (this );
812
+ }
813
+ setProperty (Property .MIN_HEIGHT , updatedMinHeightValue );
721
814
}
722
815
723
816
protected Float retrieveUnitValue (float basePercentValue , int property ) {
@@ -973,6 +1066,17 @@ protected MinMaxWidth getMinMaxWidth(float availableWidth) {
973
1066
return MinMaxWidthUtils .countDefaultMinMaxWidth (this , availableWidth );
974
1067
}
975
1068
1069
+ protected boolean setMinMaxWidthBasedOnFixedWidth (MinMaxWidth minMaxWidth ) {
1070
+ UnitValue widthProp = this .<UnitValue >getProperty (Property .WIDTH );
1071
+ Float width = retrieveWidth (0 );
1072
+ if (width != null && widthProp != null && !widthProp .isPercentValue ()) {
1073
+ minMaxWidth .setChildrenMaxWidth ((float ) width );
1074
+ minMaxWidth .setChildrenMinWidth ((float ) width );
1075
+ return true ;
1076
+ }
1077
+ return false ;
1078
+ }
1079
+
976
1080
protected boolean isNotFittingHeight (LayoutArea layoutArea ) {
977
1081
return !isPositioned () && occupiedArea .getBBox ().getHeight () > layoutArea .getBBox ().getHeight ();
978
1082
}
@@ -1253,6 +1357,14 @@ RootRenderer getRootRenderer() {
1253
1357
return null ;
1254
1358
}
1255
1359
1360
+ static float calculateAdditionalWidth (AbstractRenderer renderer ) {
1361
+ Rectangle dummy = new Rectangle (0 , 0 );
1362
+ renderer .applyMargins (dummy , true );
1363
+ renderer .applyBorderBox (dummy , true );
1364
+ renderer .applyPaddings (dummy , true );
1365
+ return dummy .getWidth ();
1366
+ }
1367
+
1256
1368
static boolean noAbsolutePositionInfo (IRenderer renderer ) {
1257
1369
return !renderer .hasProperty (Property .TOP ) && !renderer .hasProperty (Property .BOTTOM ) && !renderer .hasProperty (Property .LEFT ) && !renderer .hasProperty (Property .RIGHT );
1258
1370
}
@@ -1391,4 +1503,18 @@ private void adjustPositionedRendererLayoutBoxWidth(IRenderer renderer, Rectangl
1391
1503
}
1392
1504
}
1393
1505
1506
+ private static float calculatePaddingBorderWidth (AbstractRenderer renderer ) {
1507
+ Rectangle dummy = new Rectangle (0 , 0 );
1508
+ renderer .applyBorderBox (dummy , true );
1509
+ renderer .applyPaddings (dummy , true );
1510
+ return dummy .getWidth ();
1511
+ }
1512
+
1513
+ private static float calculatePaddingBorderHeight (AbstractRenderer renderer ) {
1514
+ Rectangle dummy = new Rectangle (0 , 0 );
1515
+ renderer .applyBorderBox (dummy , true );
1516
+ renderer .applyPaddings (dummy , true );
1517
+ return dummy .getHeight ();
1518
+ }
1519
+
1394
1520
}
0 commit comments