@@ -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 ;
@@ -983,20 +984,112 @@ protected void applyDestinationsAndAnnotation(DrawContext drawContext) {
983
984
applyLinkAnnotation (drawContext .getDocument ());
984
985
}
985
986
987
+ static boolean isBorderBoxSizing (IRenderer renderer ) {
988
+ BoxSizingPropertyValue boxSizing = renderer .<BoxSizingPropertyValue >getProperty (Property .BOX_SIZING );
989
+ return boxSizing != null && boxSizing .equals (BoxSizingPropertyValue .BORDER_BOX );
990
+ }
991
+
992
+ /**
993
+ * Retrieves element's fixed content box width, if it's set.
994
+ * Takes into account {@link Property#BOX_SIZING} property value.
995
+ * @param parentBoxWidth width of the parent element content box.
996
+ * If element has relative width, it will be
997
+ * calculated relatively to this parameter.
998
+ * @return element's fixed content box width or null if it's not set.
999
+ */
986
1000
protected Float retrieveWidth (float parentBoxWidth ) {
987
- return retrieveUnitValue (parentBoxWidth , Property .WIDTH );
1001
+ Float width = retrieveUnitValue (parentBoxWidth , Property .WIDTH );
1002
+ if (width != null && isBorderBoxSizing (this )) {
1003
+ width = Math .max (0 , (float )width - calculatePaddingBorderWidth (this ));
1004
+ }
1005
+ return width ;
988
1006
}
989
1007
1008
+ /**
1009
+ * Updates fixed content box width value for this renderer.
1010
+ * Takes into account {@link Property#BOX_SIZING} property value.
1011
+ * @param updatedWidthValue element's new fixed content box width.
1012
+ */
1013
+ protected void updateWidth (UnitValue updatedWidthValue ) {
1014
+ if (updatedWidthValue .isPointValue () && isBorderBoxSizing (this )) {
1015
+ updatedWidthValue .setValue (updatedWidthValue .getValue () + calculatePaddingBorderWidth (this ));
1016
+ }
1017
+ setProperty (Property .WIDTH , updatedWidthValue );
1018
+ }
1019
+
1020
+ /**
1021
+ * Retrieves element's fixed content box height, if it's set.
1022
+ * Takes into account {@link Property#BOX_SIZING} property value.
1023
+ * @return element's fixed content box height or null if it's not set.
1024
+ */
990
1025
protected Float retrieveHeight () {
991
- return this .<Float >getProperty (Property .HEIGHT );
1026
+ Float height = this .<Float >getProperty (Property .HEIGHT );
1027
+ if (height != null && isBorderBoxSizing (this )) {
1028
+ height = Math .max (0 , (float )height - calculatePaddingBorderHeight (this ));
1029
+ }
1030
+ return height ;
992
1031
}
993
1032
1033
+ /**
1034
+ * Updates fixed content box height value for this renderer.
1035
+ * Takes into account {@link Property#BOX_SIZING} property value.
1036
+ * @param updatedHeightValue element's new fixed content box height, shall be not null.
1037
+ */
1038
+ protected void updateHeight (Float updatedHeightValue ) {
1039
+ if (isBorderBoxSizing (this )) {
1040
+ updatedHeightValue += calculatePaddingBorderHeight (this );
1041
+ }
1042
+ setProperty (Property .HEIGHT , updatedHeightValue );
1043
+ }
1044
+
1045
+ /**
1046
+ * Retrieves element's content box max-height, if it's set.
1047
+ * Takes into account {@link Property#BOX_SIZING} property value.
1048
+ * @return element's content box max-height or null if it's not set.
1049
+ */
994
1050
protected Float retrieveMaxHeight () {
995
- return this .<Float >getProperty (Property .MAX_HEIGHT );
1051
+ Float maxHeight = this .<Float >getProperty (Property .MAX_HEIGHT );
1052
+ if (maxHeight != null && isBorderBoxSizing (this )) {
1053
+ maxHeight = Math .max (0 , (float )maxHeight - calculatePaddingBorderHeight (this ));
1054
+ }
1055
+ return maxHeight ;
996
1056
}
997
1057
1058
+ /**
1059
+ * Updates content box max-height value for this renderer.
1060
+ * Takes into account {@link Property#BOX_SIZING} property value.
1061
+ * @param updatedMaxHeightValue element's new content box max-height, shall be not null.
1062
+ */
1063
+ protected void updateMaxHeight (Float updatedMaxHeightValue ) {
1064
+ if (isBorderBoxSizing (this )) {
1065
+ updatedMaxHeightValue += calculatePaddingBorderHeight (this );
1066
+ }
1067
+ setProperty (Property .MAX_HEIGHT , updatedMaxHeightValue );
1068
+ }
1069
+
1070
+ /**
1071
+ * Retrieves element's content box max-height, if it's set.
1072
+ * Takes into account {@link Property#BOX_SIZING} property value.
1073
+ * @return element's content box min-height or null if it's not set.
1074
+ */
998
1075
protected Float retrieveMinHeight () {
999
- return this .<Float >getProperty (Property .MIN_HEIGHT );
1076
+ Float minHeight = this .<Float >getProperty (Property .MIN_HEIGHT );
1077
+ if (minHeight != null && isBorderBoxSizing (this )) {
1078
+ minHeight = Math .max (0 , (float )minHeight - calculatePaddingBorderHeight (this ));
1079
+ }
1080
+ return minHeight ;
1081
+ }
1082
+
1083
+ /**
1084
+ * Updates content box min-height value for this renderer.
1085
+ * Takes into account {@link Property#BOX_SIZING} property value.
1086
+ * @param updatedMinHeightValue element's new content box min-height, shall be not null.
1087
+ */
1088
+ protected void updateMinHeight (Float updatedMinHeightValue ) {
1089
+ if (isBorderBoxSizing (this )) {
1090
+ updatedMinHeightValue += calculatePaddingBorderHeight (this );
1091
+ }
1092
+ setProperty (Property .MIN_HEIGHT , updatedMinHeightValue );
1000
1093
}
1001
1094
1002
1095
protected Float retrieveUnitValue (float basePercentValue , int property ) {
@@ -1252,6 +1345,17 @@ protected MinMaxWidth getMinMaxWidth(float availableWidth) {
1252
1345
return MinMaxWidthUtils .countDefaultMinMaxWidth (this , availableWidth );
1253
1346
}
1254
1347
1348
+ protected boolean setMinMaxWidthBasedOnFixedWidth (MinMaxWidth minMaxWidth ) {
1349
+ UnitValue widthProp = this .<UnitValue >getProperty (Property .WIDTH );
1350
+ Float width = retrieveWidth (0 );
1351
+ if (width != null && widthProp != null && !widthProp .isPercentValue ()) {
1352
+ minMaxWidth .setChildrenMaxWidth ((float ) width );
1353
+ minMaxWidth .setChildrenMinWidth ((float ) width );
1354
+ return true ;
1355
+ }
1356
+ return false ;
1357
+ }
1358
+
1255
1359
protected boolean isNotFittingHeight (LayoutArea layoutArea ) {
1256
1360
return !isPositioned () && occupiedArea .getBBox ().getHeight () > layoutArea .getBBox ().getHeight ();
1257
1361
}
@@ -1537,6 +1641,14 @@ RootRenderer getRootRenderer() {
1537
1641
return null ;
1538
1642
}
1539
1643
1644
+ static float calculateAdditionalWidth (AbstractRenderer renderer ) {
1645
+ Rectangle dummy = new Rectangle (0 , 0 );
1646
+ renderer .applyMargins (dummy , true );
1647
+ renderer .applyBorderBox (dummy , true );
1648
+ renderer .applyPaddings (dummy , true );
1649
+ return dummy .getWidth ();
1650
+ }
1651
+
1540
1652
static boolean noAbsolutePositionInfo (IRenderer renderer ) {
1541
1653
return !renderer .hasProperty (Property .TOP ) && !renderer .hasProperty (Property .BOTTOM ) && !renderer .hasProperty (Property .LEFT ) && !renderer .hasProperty (Property .RIGHT );
1542
1654
}
@@ -1675,4 +1787,18 @@ private void adjustPositionedRendererLayoutBoxWidth(IRenderer renderer, Rectangl
1675
1787
}
1676
1788
}
1677
1789
1790
+ private static float calculatePaddingBorderWidth (AbstractRenderer renderer ) {
1791
+ Rectangle dummy = new Rectangle (0 , 0 );
1792
+ renderer .applyBorderBox (dummy , true );
1793
+ renderer .applyPaddings (dummy , true );
1794
+ return dummy .getWidth ();
1795
+ }
1796
+
1797
+ private static float calculatePaddingBorderHeight (AbstractRenderer renderer ) {
1798
+ Rectangle dummy = new Rectangle (0 , 0 );
1799
+ renderer .applyBorderBox (dummy , true );
1800
+ renderer .applyPaddings (dummy , true );
1801
+ return dummy .getHeight ();
1802
+ }
1803
+
1678
1804
}
0 commit comments