Skip to content

Commit a965dee

Browse files
Merge branch 'feature/box_sizing_prop' into develop
2 parents 80b48ab + 1f3e72a commit a965dee

24 files changed

+409
-169
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.itextpdf.layout.property;
2+
3+
/**
4+
* A specialized enum containing potential property values for {@link
5+
* Property#BOX_SIZING}.
6+
*/
7+
public enum BoxSizingPropertyValue {
8+
CONTENT_BOX,
9+
BORDER_BOX
10+
}

layout/src/main/java/com/itextpdf/layout/property/Property.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ private Property() {
7272
public static final int BORDER_RIGHT = 12;
7373
public static final int BORDER_TOP = 13;
7474
public static final int BOTTOM = 14;
75+
public static final int BOX_SIZING = 105;
7576
public static final int CHARACTER_SPACING = 15;
7677
public static final int CLEAR = 100;
7778
public static final int COLLAPSING_MARGINS = 89;

layout/src/main/java/com/itextpdf/layout/renderer/AbstractRenderer.java

Lines changed: 130 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ This file is part of the iText (R) project.
8181
import com.itextpdf.layout.property.Background;
8282
import com.itextpdf.layout.property.BackgroundImage;
8383
import com.itextpdf.layout.property.BaseDirection;
84+
import com.itextpdf.layout.property.BoxSizingPropertyValue;
8485
import com.itextpdf.layout.property.HorizontalAlignment;
8586
import com.itextpdf.layout.property.Property;
8687
import com.itextpdf.layout.property.TransparentColor;
@@ -983,20 +984,112 @@ protected void applyDestinationsAndAnnotation(DrawContext drawContext) {
983984
applyLinkAnnotation(drawContext.getDocument());
984985
}
985986

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+
*/
9861000
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;
9881006
}
9891007

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+
*/
9901025
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;
9921031
}
9931032

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+
*/
9941050
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;
9961056
}
9971057

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+
*/
9981075
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);
10001093
}
10011094

10021095
protected Float retrieveUnitValue(float basePercentValue, int property) {
@@ -1252,6 +1345,17 @@ protected MinMaxWidth getMinMaxWidth(float availableWidth) {
12521345
return MinMaxWidthUtils.countDefaultMinMaxWidth(this, availableWidth);
12531346
}
12541347

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+
12551359
protected boolean isNotFittingHeight(LayoutArea layoutArea) {
12561360
return !isPositioned() && occupiedArea.getBBox().getHeight() > layoutArea.getBBox().getHeight();
12571361
}
@@ -1537,6 +1641,14 @@ RootRenderer getRootRenderer() {
15371641
return null;
15381642
}
15391643

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+
15401652
static boolean noAbsolutePositionInfo(IRenderer renderer) {
15411653
return !renderer.hasProperty(Property.TOP) && !renderer.hasProperty(Property.BOTTOM) && !renderer.hasProperty(Property.LEFT) && !renderer.hasProperty(Property.RIGHT);
15421654
}
@@ -1675,4 +1787,18 @@ private void adjustPositionedRendererLayoutBoxWidth(IRenderer renderer, Rectangl
16751787
}
16761788
}
16771789

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+
16781804
}

0 commit comments

Comments
 (0)