Skip to content

Commit ee42409

Browse files
author
Artyom Yanchevsky
committed
Add background size support
DEVSIX-1708
1 parent 80d432a commit ee42409

15 files changed

+718
-18
lines changed

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

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -68,28 +68,31 @@ public class BackgroundImage {
6868
*/
6969
@Deprecated
7070
protected boolean repeatY;
71-
7271
protected AbstractLinearGradientBuilder linearGradientBuilder;
7372

7473
private BlendMode blendMode = DEFAULT_BLEND_MODE;
7574

7675
private BackgroundPosition position;
76+
private BackgroundSize backgroundSize;
7777

7878
/**
7979
* Creates a new {@link BackgroundImage} instance.
8080
*
8181
* @param image background-image property. {@link PdfXObject} instance.
8282
* @param repeat background-repeat property. {@link BackgroundRepeat} instance.
8383
* @param position background-position property. {@link BackgroundPosition} instance.
84+
* @param backgroundSize background-size property. {@link BackgroundSize} instance.
8485
* @param linearGradientBuilder background-image property. {@link AbstractLinearGradientBuilder} instance.
8586
* @param blendMode the image's blend mode. {@link BlendMode} instance.
8687
*/
8788
protected BackgroundImage(PdfXObject image, BackgroundRepeat repeat, BackgroundPosition position,
88-
AbstractLinearGradientBuilder linearGradientBuilder, BlendMode blendMode) {
89+
BackgroundSize backgroundSize, AbstractLinearGradientBuilder linearGradientBuilder,
90+
BlendMode blendMode) {
8991
this.image = image;
9092
this.repeatX = repeat.isRepeatX();
9193
this.repeatY = repeat.isRepeatY();
9294
this.position = position;
95+
this.backgroundSize = backgroundSize;
9396
this.linearGradientBuilder = linearGradientBuilder;
9497
if (blendMode != null) {
9598
this.blendMode = blendMode;
@@ -106,7 +109,7 @@ protected BackgroundImage(PdfXObject image, BackgroundRepeat repeat, BackgroundP
106109
*/
107110
@Deprecated
108111
public BackgroundImage(final PdfImageXObject image, final BackgroundRepeat repeat, final BlendMode blendMode) {
109-
this(image, repeat, new BackgroundPosition(), null, blendMode);
112+
this(image, repeat, new BackgroundPosition(), new BackgroundSize(), null, blendMode);
110113
}
111114

112115
/**
@@ -119,7 +122,7 @@ public BackgroundImage(final PdfImageXObject image, final BackgroundRepeat repea
119122
*/
120123
@Deprecated
121124
public BackgroundImage(final PdfFormXObject image, final BackgroundRepeat repeat, final BlendMode blendMode) {
122-
this(image, repeat, new BackgroundPosition(), null, blendMode);
125+
this(image, repeat, new BackgroundPosition(), new BackgroundSize(), null, blendMode);
123126
}
124127

125128
/**
@@ -131,7 +134,7 @@ public BackgroundImage(final PdfFormXObject image, final BackgroundRepeat repeat
131134
*/
132135
@Deprecated
133136
public BackgroundImage(final PdfImageXObject image, final BackgroundRepeat repeat) {
134-
this(image, repeat, new BackgroundPosition(), null, DEFAULT_BLEND_MODE);
137+
this(image, repeat, new BackgroundPosition(), new BackgroundSize(), null, DEFAULT_BLEND_MODE);
135138
}
136139

137140
/**
@@ -143,7 +146,7 @@ public BackgroundImage(final PdfImageXObject image, final BackgroundRepeat repea
143146
*/
144147
@Deprecated
145148
public BackgroundImage(final PdfFormXObject image, final BackgroundRepeat repeat) {
146-
this(image, repeat, new BackgroundPosition(), null, DEFAULT_BLEND_MODE);
149+
this(image, repeat, new BackgroundPosition(), new BackgroundSize(), null, DEFAULT_BLEND_MODE);
147150
}
148151

149152
/**
@@ -154,7 +157,7 @@ public BackgroundImage(final PdfFormXObject image, final BackgroundRepeat repeat
154157
*/
155158
@Deprecated
156159
public BackgroundImage(final PdfImageXObject image) {
157-
this(image, new BackgroundRepeat(), new BackgroundPosition(), null, DEFAULT_BLEND_MODE);
160+
this(image, new BackgroundRepeat(), new BackgroundPosition(), new BackgroundSize(), null, DEFAULT_BLEND_MODE);
158161
}
159162

160163
/**
@@ -165,7 +168,7 @@ public BackgroundImage(final PdfImageXObject image) {
165168
*/
166169
@Deprecated
167170
public BackgroundImage(final PdfFormXObject image) {
168-
this(image, new BackgroundRepeat(), new BackgroundPosition(), null, DEFAULT_BLEND_MODE);
171+
this(image, new BackgroundRepeat(), new BackgroundPosition(), new BackgroundSize(), null, DEFAULT_BLEND_MODE);
169172
}
170173

171174
/**
@@ -178,7 +181,8 @@ public BackgroundImage(final PdfFormXObject image) {
178181
*/
179182
@Deprecated
180183
public BackgroundImage(final PdfImageXObject image, final boolean repeatX, final boolean repeatY) {
181-
this(image, new BackgroundRepeat(repeatX, repeatY), new BackgroundPosition(), null, DEFAULT_BLEND_MODE);
184+
this(image, new BackgroundRepeat(repeatX, repeatY), new BackgroundPosition(), new BackgroundSize(),
185+
null, DEFAULT_BLEND_MODE);
182186
}
183187

184188
/**
@@ -191,7 +195,8 @@ public BackgroundImage(final PdfImageXObject image, final boolean repeatX, final
191195
*/
192196
@Deprecated
193197
public BackgroundImage(final PdfFormXObject image, final boolean repeatX, final boolean repeatY) {
194-
this(image, new BackgroundRepeat(repeatX, repeatY), new BackgroundPosition(), null, DEFAULT_BLEND_MODE);
198+
this(image, new BackgroundRepeat(repeatX, repeatY), new BackgroundPosition(), new BackgroundSize(),
199+
null, DEFAULT_BLEND_MODE);
195200
}
196201

197202
/**
@@ -216,7 +221,8 @@ public BackgroundImage(final AbstractLinearGradientBuilder linearGradientBuilder
216221
*/
217222
@Deprecated
218223
public BackgroundImage(final AbstractLinearGradientBuilder linearGradientBuilder, final BlendMode blendMode) {
219-
this(null, new BackgroundRepeat(false, false), new BackgroundPosition(), linearGradientBuilder, blendMode);
224+
this(null, new BackgroundRepeat(false, false), new BackgroundPosition(), new BackgroundSize()
225+
, linearGradientBuilder, blendMode);
220226
}
221227

222228
public PdfImageXObject getImage() {
@@ -252,10 +258,45 @@ public boolean isRepeatY() {
252258
return repeatY;
253259
}
254260

261+
/**
262+
* Gets the background size property.
263+
*
264+
* @return {@link BackgroundSize} instance
265+
*/
266+
public BackgroundSize getBackgroundSize() {
267+
return backgroundSize;
268+
}
269+
270+
/**
271+
* Gets initial image width.
272+
*/
273+
public float getImageWidth() {
274+
return (float) image.getWidth();
275+
}
276+
277+
/**
278+
* Gets initial image height.
279+
*/
280+
public float getImageHeight() {
281+
return (float) image.getHeight();
282+
}
283+
284+
/**
285+
* Gets initial image width.
286+
*
287+
* @deprecated To be removed in 7.2. Use {@link BackgroundImage#getImageWidth()} instead.
288+
*/
289+
@Deprecated
255290
public float getWidth() {
256291
return (float) image.getWidth();
257292
}
258293

294+
/**
295+
* Gets initial image height.
296+
*
297+
* @deprecated To be removed in 7.2. Use {@link BackgroundImage#getImageHeight()} instead.
298+
*/
299+
@Deprecated
259300
public float getHeight() {
260301
return (float) image.getHeight();
261302
}
@@ -279,6 +320,7 @@ public static class Builder {
279320
private BackgroundPosition position = new BackgroundPosition();
280321
private BackgroundRepeat repeat = new BackgroundRepeat();
281322
private BlendMode blendMode = DEFAULT_BLEND_MODE;
323+
private BackgroundSize backgroundSize = new BackgroundSize();
282324

283325
public Builder() {
284326
}
@@ -347,13 +389,26 @@ public Builder setBackgroundBlendMode(BlendMode blendMode) {
347389
return this;
348390
}
349391

392+
/**
393+
* Set the image's backgroundSize.
394+
*
395+
* @param backgroundSize {@link BackgroundSize} to be set.
396+
* @return this {@link Builder}.
397+
*/
398+
public Builder setBackgroundSize(BackgroundSize backgroundSize) {
399+
if (backgroundSize != null) {
400+
this.backgroundSize = backgroundSize;
401+
}
402+
return this;
403+
}
404+
350405
/**
351406
* Builds new {@link BackgroundImage} using set fields.
352407
*
353408
* @return new {@link BackgroundImage}.
354409
*/
355410
public BackgroundImage build() {
356-
return new BackgroundImage(image, repeat, position, linearGradientBuilder, blendMode);
411+
return new BackgroundImage(image, repeat, position, backgroundSize, linearGradientBuilder, blendMode);
357412
}
358413
}
359414
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
This file is part of the iText (R) project.
3+
Copyright (c) 1998-2020 iText Group NV
4+
Authors: iText Software.
5+
6+
This program is offered under a commercial and under the AGPL license.
7+
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
8+
9+
AGPL licensing:
10+
This program is free software: you can redistribute it and/or modify
11+
it under the terms of the GNU Affero General Public License as published by
12+
the Free Software Foundation, either version 3 of the License, or
13+
(at your option) any later version.
14+
15+
This program is distributed in the hope that it will be useful,
16+
but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
GNU Affero General Public License for more details.
19+
20+
You should have received a copy of the GNU Affero General Public License
21+
along with this program. If not, see <https://www.gnu.org/licenses/>.
22+
*/
23+
package com.itextpdf.layout.property;
24+
25+
/**
26+
* Class to hold background-size property.
27+
*/
28+
public class BackgroundSize {
29+
30+
/**
31+
* Width size for this image. If {@link UnitValue} is in percent, then width depends on the area of the element.
32+
*/
33+
private UnitValue backgroundWidthSize;
34+
/**
35+
* Height size for this image. If {@link UnitValue} is in percent, then height depends on the area of the element.
36+
*/
37+
private UnitValue backgroundHeightSize;
38+
/**
39+
* Image covers the entire area and its size may be more than the area.
40+
*/
41+
private boolean cover;
42+
/**
43+
* Image hsd a maximum size but not larger than the area.
44+
*/
45+
private boolean contain;
46+
47+
public BackgroundSize() {
48+
cover = false;
49+
contain = false;
50+
}
51+
52+
/**
53+
* Clear all current properties and sets new width and height values.
54+
* One of the parameters can be null. Note that in this case CalculationUtil will scale null property
55+
* so that it becomes proportionally equals with the not null value.
56+
* If both parameters are set to null, that the default image size will be used.
57+
*
58+
* @param width a {@link UnitValue} object
59+
* @param height a {@link UnitValue} object
60+
* @see com.itextpdf.layout.renderer.BackgroundSizeCalculationUtil#calculateBackgroundImageSize
61+
*/
62+
public void setBackgroundSizeToValues(UnitValue width, UnitValue height) {
63+
clear();
64+
this.backgroundWidthSize = width;
65+
this.backgroundHeightSize = height;
66+
}
67+
68+
/**
69+
* Clears all size values and sets the "contain" property {@code true}.
70+
*
71+
* @see BackgroundSize#contain
72+
*/
73+
public void setBackgroundSizeToContain() {
74+
clear();
75+
contain = true;
76+
}
77+
78+
/**
79+
* Clears all size values and sets the "cover" property {@code true}.
80+
*
81+
* @see BackgroundSize#cover
82+
*/
83+
public void setBackgroundSizeToCover() {
84+
clear();
85+
cover = true;
86+
}
87+
88+
/**
89+
* Gets the background width property of the image.
90+
*
91+
* @return the {@link UnitValue} width for this image.
92+
* @see BackgroundSize#backgroundWidthSize
93+
*/
94+
public UnitValue getBackgroundWidthSize() {
95+
return backgroundWidthSize;
96+
}
97+
98+
/**
99+
* Gets the background height property of the image.
100+
*
101+
* @return the {@link UnitValue} height for this image.
102+
* @see BackgroundSize#backgroundHeightSize
103+
*/
104+
public UnitValue getBackgroundHeightSize() {
105+
return backgroundHeightSize;
106+
}
107+
108+
/**
109+
* Returns is size has specific property.
110+
*
111+
* @return {@code true} if size set to "contain" or "cover", otherwise false.
112+
*/
113+
public boolean isSpecificSize() {
114+
return contain || cover;
115+
}
116+
117+
/**
118+
* Returns value of the "contain" property.
119+
*
120+
* @return {@code true} if property "contain" is set to the size, otherwise false.
121+
* @see BackgroundSize#contain
122+
*/
123+
public boolean isContain() {
124+
return contain;
125+
}
126+
127+
/**
128+
* Returns value of the "cover" property.
129+
*
130+
* @return {@code true} if property "cover" is set to the size, otherwise false.
131+
* @see BackgroundSize#cover
132+
*/
133+
public boolean isCover() {
134+
return cover;
135+
}
136+
137+
private void clear() {
138+
contain = false;
139+
cover = false;
140+
backgroundWidthSize = null;
141+
backgroundHeightSize = null;
142+
}
143+
}

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ private boolean drawBackgroundImagesList(final List<BackgroundImage> backgroundI
567567
private void drawBackgroundImage(BackgroundImage backgroundImage,
568568
DrawContext drawContext, Rectangle backgroundArea) {
569569
applyBorderBox(backgroundArea, false);
570+
float[] imageWidthAndHeight = BackgroundSizeCalculationUtil.calculateBackgroundImageSize(
571+
backgroundImage, backgroundArea.getWidth(), backgroundArea.getHeight());
570572
PdfXObject backgroundXObject = backgroundImage.getImage();
571573
if (backgroundXObject == null) {
572574
backgroundXObject = backgroundImage.getForm();
@@ -583,15 +585,15 @@ private void drawBackgroundImage(BackgroundImage backgroundImage,
583585
backgroundImage.getBackgroundPosition().calculatePositionValues(0, 0, xPosition, yPosition);
584586
backgroundXObject = createXObject(gradientBuilder, backgroundArea, drawContext.getDocument());
585587
imageRectangle = new Rectangle(backgroundArea.getLeft() + xPosition.getValue(),
586-
backgroundArea.getTop() - backgroundXObject.getHeight() - yPosition.getValue(),
587-
backgroundXObject.getWidth(), backgroundXObject.getHeight());
588+
backgroundArea.getTop() - imageWidthAndHeight[1] - yPosition.getValue(),
589+
imageWidthAndHeight[0], imageWidthAndHeight[1]);
588590
} else {
589591
backgroundImage.getBackgroundPosition().calculatePositionValues(
590-
backgroundArea.getWidth() - backgroundImage.getWidth(),
591-
backgroundArea.getHeight() - backgroundImage.getHeight(), xPosition, yPosition);
592+
backgroundArea.getWidth() - imageWidthAndHeight[0],
593+
backgroundArea.getHeight() - imageWidthAndHeight[1], xPosition, yPosition);
592594
imageRectangle = new Rectangle(backgroundArea.getLeft() + xPosition.getValue(),
593-
backgroundArea.getTop() - backgroundImage.getHeight() - yPosition.getValue(),
594-
backgroundImage.getWidth(), backgroundImage.getHeight());
595+
backgroundArea.getTop() - imageWidthAndHeight[1] - yPosition.getValue(),
596+
imageWidthAndHeight[0], imageWidthAndHeight[1]);
595597
}
596598
if (imageRectangle.getWidth() <= 0 || imageRectangle.getHeight() <= 0) {
597599
Logger logger = LoggerFactory.getLogger(AbstractRenderer.class);

0 commit comments

Comments
 (0)