@@ -492,7 +492,7 @@ public void drawBackground(DrawContext drawContext) {
492492 Rectangle backgroundArea = applyMargins (bBox , false );
493493 if (backgroundArea .getWidth () <= 0 || backgroundArea .getHeight () <= 0 ) {
494494 Logger logger = LoggerFactory .getLogger (AbstractRenderer .class );
495- logger .error (MessageFormatUtil .format (LogMessageConstant .RECTANGLE_HAS_NEGATIVE_OR_ZERO_SIZES , "background" ));
495+ logger .warn (MessageFormatUtil .format (LogMessageConstant .RECTANGLE_HAS_NEGATIVE_OR_ZERO_SIZES , "background" ));
496496 return ;
497497 }
498498 boolean backgroundAreaIsClipped = false ;
@@ -517,7 +517,7 @@ public void drawBackground(DrawContext drawContext) {
517517 backgroundImage .getImage ().getWidth (), backgroundImage .getImage ().getHeight ());
518518 if (imageRectangle .getWidth () <= 0 || imageRectangle .getHeight () <= 0 ) {
519519 Logger logger = LoggerFactory .getLogger (AbstractRenderer .class );
520- logger .error (MessageFormatUtil .format (LogMessageConstant .RECTANGLE_HAS_NEGATIVE_OR_ZERO_SIZES , "background-image" ));
520+ logger .warn (MessageFormatUtil .format (LogMessageConstant .RECTANGLE_HAS_NEGATIVE_OR_ZERO_SIZES , "background-image" ));
521521 return ;
522522 }
523523 applyBorderBox (backgroundArea , true );
@@ -991,26 +991,93 @@ static boolean isBorderBoxSizing(IRenderer renderer) {
991991
992992 /**
993993 * Retrieves element's fixed content box width, if it's set.
994- * Takes into account {@link Property#BOX_SIZING} property value.
994+ * Takes into account {@link Property#BOX_SIZING}, {@link Property#MIN_WIDTH},
995+ * and {@link Property#MAX_WIDTH} properties.
995996 * @param parentBoxWidth width of the parent element content box.
996997 * If element has relative width, it will be
997998 * calculated relatively to this parameter.
998999 * @return element's fixed content box width or null if it's not set.
1000+ * @see AbstractRenderer#hasAbsoluteUnitValue(int)
9991001 */
10001002 protected Float retrieveWidth (float parentBoxWidth ) {
1003+ Float minWidth = retrieveUnitValue (parentBoxWidth , Property .MIN_WIDTH );
1004+
1005+ Float maxWidth = retrieveUnitValue (parentBoxWidth , Property .MAX_WIDTH );
1006+ if (maxWidth != null && minWidth != null && minWidth > maxWidth ) {
1007+ maxWidth = minWidth ;
1008+ }
1009+
10011010 Float width = retrieveUnitValue (parentBoxWidth , Property .WIDTH );
1011+ if (width != null ) {
1012+ if (maxWidth != null ) {
1013+ width = width > maxWidth ? maxWidth : width ;
1014+ } else if (minWidth != null ) {
1015+ width = width < minWidth ? minWidth : width ;
1016+ }
1017+ } else if (maxWidth != null ) {
1018+ width = maxWidth < parentBoxWidth ? maxWidth : null ;
1019+ }
1020+
10021021 if (width != null && isBorderBoxSizing (this )) {
1003- width = Math .max (0 , (float )width - calculatePaddingBorderWidth (this ));
1022+ width -= calculatePaddingBorderWidth (this );
1023+ }
1024+
1025+ return width != null ? Math .max (0 , (float ) width ) : null ;
1026+ }
1027+
1028+ /**
1029+ * Retrieves element's fixed content box max width, if it's set.
1030+ * Takes into account {@link Property#BOX_SIZING} and {@link Property#MIN_WIDTH} properties.
1031+ * @param parentBoxWidth width of the parent element content box.
1032+ * If element has relative width, it will be
1033+ * calculated relatively to this parameter.
1034+ * @return element's fixed content box max width or null if it's not set.
1035+ * @see AbstractRenderer#hasAbsoluteUnitValue(int)
1036+ */
1037+ protected Float retrieveMaxWidth (float parentBoxWidth ) {
1038+ Float maxWidth = retrieveUnitValue (parentBoxWidth , Property .MAX_WIDTH );
1039+ if (maxWidth != null ) {
1040+ Float minWidth = retrieveUnitValue (parentBoxWidth , Property .MIN_WIDTH );
1041+ if (minWidth != null && minWidth > maxWidth ) {
1042+ maxWidth = minWidth ;
1043+ }
1044+
1045+ if (isBorderBoxSizing (this )) {
1046+ maxWidth -= calculatePaddingBorderWidth (this );
1047+ }
1048+ return maxWidth > 0 ? maxWidth : 0 ;
1049+ } else {
1050+ return null ;
1051+ }
1052+ }
1053+
1054+ /**
1055+ * Retrieves element's fixed content box max width, if it's set.
1056+ * Takes into account {@link Property#BOX_SIZING} property value.
1057+ * @param parentBoxWidth width of the parent element content box.
1058+ * If element has relative width, it will be
1059+ * calculated relatively to this parameter.
1060+ * @return element's fixed content box max width or null if it's not set.
1061+ * @see AbstractRenderer#hasAbsoluteUnitValue(int)
1062+ */
1063+ protected Float retrieveMinWidth (float parentBoxWidth ) {
1064+ Float minWidth = retrieveUnitValue (parentBoxWidth , Property .MIN_WIDTH );
1065+ if (minWidth != null ) {
1066+ if (isBorderBoxSizing (this )) {
1067+ minWidth -= calculatePaddingBorderWidth (this );
1068+ }
1069+ return minWidth > 0 ? minWidth : 0 ;
1070+ } else {
1071+ return null ;
10041072 }
1005- return width ;
10061073 }
10071074
10081075 /**
10091076 * Updates fixed content box width value for this renderer.
10101077 * Takes into account {@link Property#BOX_SIZING} property value.
10111078 * @param updatedWidthValue element's new fixed content box width.
10121079 */
1013- protected void updateWidth (UnitValue updatedWidthValue ) {
1080+ void updateWidth (UnitValue updatedWidthValue ) {
10141081 if (updatedWidthValue .isPointValue () && isBorderBoxSizing (this )) {
10151082 updatedWidthValue .setValue (updatedWidthValue .getValue () + calculatePaddingBorderWidth (this ));
10161083 }
@@ -1035,7 +1102,7 @@ protected Float retrieveHeight() {
10351102 * Takes into account {@link Property#BOX_SIZING} property value.
10361103 * @param updatedHeightValue element's new fixed content box height, shall be not null.
10371104 */
1038- protected void updateHeight (Float updatedHeightValue ) {
1105+ void updateHeight (Float updatedHeightValue ) {
10391106 if (isBorderBoxSizing (this )) {
10401107 updatedHeightValue += calculatePaddingBorderHeight (this );
10411108 }
@@ -1060,7 +1127,7 @@ protected Float retrieveMaxHeight() {
10601127 * Takes into account {@link Property#BOX_SIZING} property value.
10611128 * @param updatedMaxHeightValue element's new content box max-height, shall be not null.
10621129 */
1063- protected void updateMaxHeight (Float updatedMaxHeightValue ) {
1130+ void updateMaxHeight (Float updatedMaxHeightValue ) {
10641131 if (isBorderBoxSizing (this )) {
10651132 updatedMaxHeightValue += calculatePaddingBorderHeight (this );
10661133 }
@@ -1085,7 +1152,7 @@ protected Float retrieveMinHeight() {
10851152 * Takes into account {@link Property#BOX_SIZING} property value.
10861153 * @param updatedMinHeightValue element's new content box min-height, shall be not null.
10871154 */
1088- protected void updateMinHeight (Float updatedMinHeightValue ) {
1155+ void updateMinHeight (Float updatedMinHeightValue ) {
10891156 if (isBorderBoxSizing (this )) {
10901157 updatedMinHeightValue += calculatePaddingBorderHeight (this );
10911158 }
@@ -1095,12 +1162,11 @@ protected void updateMinHeight(Float updatedMinHeightValue) {
10951162 protected Float retrieveUnitValue (float basePercentValue , int property ) {
10961163 UnitValue value = this .<UnitValue >getProperty (property );
10971164 if (value != null ) {
1098- if (value .getUnitType () == UnitValue .POINT ) {
1099- return value .getValue ();
1100- } else if (value .getUnitType () == UnitValue .PERCENT ) {
1165+ if (value .getUnitType () == UnitValue .PERCENT ) {
11011166 return value .getValue () * basePercentValue / 100 ;
11021167 } else {
1103- throw new IllegalStateException ("invalid unit type" );
1168+ assert value .getUnitType () == UnitValue .POINT ;
1169+ return value .getValue ();
11041170 }
11051171 } else {
11061172 return null ;
@@ -1346,12 +1412,15 @@ protected MinMaxWidth getMinMaxWidth(float availableWidth) {
13461412 }
13471413
13481414 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 ;
1415+ // retrieve returns max width, if there is no width.
1416+ if (hasAbsoluteUnitValue (Property .WIDTH )) {
1417+ //Renderer may override retrieveWidth, double check is required.
1418+ Float width = retrieveWidth (0 );
1419+ if (width != null ) {
1420+ minMaxWidth .setChildrenMaxWidth ((float ) width );
1421+ minMaxWidth .setChildrenMinWidth ((float ) width );
1422+ return true ;
1423+ }
13551424 }
13561425 return false ;
13571426 }
@@ -1618,6 +1687,17 @@ protected void overrideHeightProperties() {
16181687 }
16191688 }
16201689
1690+ /**
1691+ * Check if corresponding property has point value.
1692+ *
1693+ * @param property {@link Property}
1694+ * @return false if property value either null, or percent, otherwise true.
1695+ */
1696+ protected boolean hasAbsoluteUnitValue (int property ) {
1697+ UnitValue value = this .<UnitValue >getProperty (property );
1698+ return value != null && value .isPointValue ();
1699+ }
1700+
16211701 boolean isFirstOnRootArea () {
16221702 boolean isFirstOnRootArea = true ;
16231703 AbstractRenderer ancestor = this ;
0 commit comments