Skip to content

Commit

Permalink
#649 Support for multiple items in background-size
Browse files Browse the repository at this point in the history
  • Loading branch information
danfickle committed Feb 15, 2021
1 parent 2dbce9b commit 20798b0
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -104,72 +104,62 @@ protected List<PropertyValue> processValue(CSSName cssName, PropertyValue value)
public static class BackgroundColor extends GenericColor {
}

public static class BackgroundSize extends AbstractPropertyBuilder {
private static final BitSet ALL_ALLOWED = PrimitivePropertyBuilders.setFor(new IdentValue[] {
public static class BackgroundSize extends MultipleBackgroundValueBuilder {
private static final BitSet ALL_ALLOWED = setOf(
IdentValue.AUTO, IdentValue.CONTAIN, IdentValue.COVER
});
);

@Override
public List<PropertyDeclaration> buildDeclarations(CSSName cssName, List<PropertyValue> values, int origin, boolean important, boolean inheritAllowed) {
checkValueCount(cssName, 1, 2, values.size());
protected List<PropertyValue> processValue(CSSName cssName, PropertyValue first) {
checkIdentLengthOrPercentType(cssName, first);

PropertyValue first = values.get(0);
PropertyValue second = null;
if (values.size() == 2) {
second = values.get(1);
}
if (first.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
IdentValue firstIdent = checkIdent(cssName, first);
checkValidity(cssName, ALL_ALLOWED, firstIdent);

checkInheritAllowed(first, inheritAllowed);
if (values.size() == 1 &&
first.getCssValueType() == CSSValue.CSS_INHERIT) {
return Collections.singletonList(
new PropertyDeclaration(cssName, first, important, origin));
}
assert firstIdent == IdentValue.AUTO ||
firstIdent == IdentValue.COVER ||
firstIdent == IdentValue.CONTAIN;

// Items are expected to always return a pair so just repeat the ident.
return Arrays.asList(first, first);
} else {
assert isLength(first) || first.getPrimitiveType() == CSSPrimitiveValue.CSS_PERCENTAGE;

if (second != null) {
checkInheritAllowed(second, false);
return Arrays.asList(first, new PropertyValue(IdentValue.AUTO));
}
}

@Override
protected List<PropertyValue> processValues(CSSName cssName, PropertyValue first, PropertyValue second) {
checkIdentLengthOrPercentType(cssName, first);
if (second == null) {
if (first.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
IdentValue firstIdent = checkIdent(cssName, first);
checkValidity(cssName, ALL_ALLOWED, firstIdent);

if (firstIdent == IdentValue.CONTAIN || firstIdent == IdentValue.COVER) {
return Collections.singletonList(
new PropertyDeclaration(cssName, first, important, origin));
} else {
return PrimitivePropertyBuilders.createTwoValueResponse(CSSName.BACKGROUND_SIZE, first, first, origin, important);
}
} else {
return PrimitivePropertyBuilders.createTwoValueResponse(CSSName.BACKGROUND_SIZE, first, new PropertyValue(IdentValue.AUTO), origin, important);
}
} else {
checkIdentLengthOrPercentType(cssName, second);
checkIdentLengthOrPercentType(cssName, second);

if (first.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
IdentValue firstIdent = checkIdent(cssName, first);
if (firstIdent != IdentValue.AUTO) {
throw new CSSParseException("The only ident value allowed here is 'auto'", -1);
}
} else if (first.getFloatValue() < 0.0f) {
throw new CSSParseException(cssName + " values cannot be negative", -1);
if (first.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
IdentValue firstIdent = checkIdent(cssName, first);
if (firstIdent != IdentValue.AUTO) {
throw new CSSParseException("The only ident value allowed here is 'auto'", -1);
}
} else if (first.getFloatValue() < 0.0f) {
throw new CSSParseException(cssName + " values cannot be negative", -1);
}

if (second.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
IdentValue secondIdent = checkIdent(cssName, second);
if (secondIdent != IdentValue.AUTO) {
throw new CSSParseException("The only ident value allowed here is 'auto'", -1);
}
} else if (second.getFloatValue() < 0.0f) {
throw new CSSParseException(cssName + " values cannot be negative", -1);
if (second.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
IdentValue secondIdent = checkIdent(cssName, second);
if (secondIdent != IdentValue.AUTO) {
throw new CSSParseException("The only ident value allowed here is 'auto'", -1);
}

return PrimitivePropertyBuilders.createTwoValueResponse(CSSName.BACKGROUND_SIZE, first, second, origin, important);
} else if (second.getFloatValue() < 0.0f) {
throw new CSSParseException(cssName + " values cannot be negative", -1);
}

return Arrays.asList(first, second);
}

@Override
protected boolean allowsTwoValueItems() {
return true;
}
}

public static class BackgroundPosition extends MultipleBackgroundValueBuilder {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,38 +19,29 @@
*/
package com.openhtmltopdf.css.style;

import com.openhtmltopdf.css.constants.IdentValue;
import com.openhtmltopdf.css.parser.PropertyValue;

public class BackgroundSize {
private boolean _contain;
private boolean _cover;
private boolean _bothAuto;

private PropertyValue _width;
private PropertyValue _height;


public BackgroundSize(boolean contain, boolean cover, boolean bothAuto) {
_contain = contain;
_cover = cover;
_bothAuto = bothAuto;
}
private final PropertyValue _width;
private final PropertyValue _height;

public BackgroundSize(PropertyValue width, PropertyValue height) {
_width = width;
_height = height;
}

public boolean isContain() {
return _contain;
return _width.getIdentValue() == IdentValue.CONTAIN;
}

public boolean isCover() {
return _cover;
return _width.getIdentValue() == IdentValue.COVER;
}

public boolean isBothAuto() {
return _bothAuto;
return _width.getIdentValue() == IdentValue.AUTO &&
_height.getIdentValue() == IdentValue.AUTO;
}

public PropertyValue getWidth() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,39 +313,6 @@ public FSColor getBackgroundColor() {
}
}

public BackgroundSize getBackgroundSize() {
if (_backgroundSize == null) {
_backgroundSize = createBackgroundSize();
}

return _backgroundSize;
}

private BackgroundSize createBackgroundSize() {
FSDerivedValue value = valueByName(CSSName.BACKGROUND_SIZE);
if (value instanceof IdentValue) {
IdentValue ident = (IdentValue)value;
if (ident == IdentValue.COVER) {
return new BackgroundSize(false, true, false);
} else if (ident == IdentValue.CONTAIN) {
return new BackgroundSize(true, false, false);
}
} else {
ListValue valueList = (ListValue)value;
List<PropertyValue> values = valueList.getValues();
boolean firstAuto = values.get(0).getIdentValue() == IdentValue.AUTO;
boolean secondAuto = values.get(1).getIdentValue() == IdentValue.AUTO;

if (firstAuto && secondAuto) {
return new BackgroundSize(false, false, true);
} else {
return new BackgroundSize(values.get(0), values.get(1));
}
}

throw new RuntimeException("internal error");
}

public List<CounterData> getCounterReset() {
FSDerivedValue value = valueByName(CSSName.COUNTER_RESET);

Expand Down Expand Up @@ -1402,6 +1369,7 @@ public static class BackgroundContainer {
public PropertyValue imageGradientOrNone;

public BackgroundPosition backgroundPosition;
public BackgroundSize backgroundSize;
public PropertyValue backgroundRepeat;
}

Expand All @@ -1424,14 +1392,21 @@ public List<BackgroundContainer> getBackgroundImages() {
List<PropertyValue> images = ((ListValue) valueByName(CSSName.BACKGROUND_IMAGE)).getValues();
List<PropertyValue> positions = ((ListValue) valueByName(CSSName.BACKGROUND_POSITION)).getValues();
List<PropertyValue> repeats = ((ListValue) valueByName(CSSName.BACKGROUND_REPEAT)).getValues();
List<PropertyValue> sizes = ((ListValue) valueByName(CSSName.BACKGROUND_SIZE)).getValues();

assert positions.size() % 2 == 0;
assert sizes.size() % 2 == 0;

List<BackgroundPosition> posPairs = new ArrayList<>(positions.size() / 2);
for (int i = 0; i < positions.size(); i += 2) {
posPairs.add(new BackgroundPosition(positions.get(i), positions.get(i + 1)));
}

List<BackgroundSize> sizePairs = new ArrayList<>(sizes.size() / 2);
for (int i = 0; i < sizes.size(); i += 2) {
sizePairs.add(new BackgroundSize(sizes.get(i), sizes.get(i + 1)));
}

List<BackgroundContainer> backgrounds = new ArrayList<>(images.size());

for (int i = 0; i < images.size(); i++) {
Expand All @@ -1451,6 +1426,7 @@ public List<BackgroundContainer> getBackgroundImages() {
// If less background-position values are provided than images,
// they must repeat.
bg.backgroundPosition = posPairs.get(i % posPairs.size());
bg.backgroundSize = sizePairs.get(i % sizePairs.size());
bg.backgroundRepeat = repeats.get(i % repeats.size());

backgrounds.add(bg);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ private void drawBgImage(

Rectangle localBGImageContainer = bgImageContainer;

scaleBackgroundImage(c, style, localBGImageContainer, backgroundImage);
scaleBackgroundImage(c, style, localBGImageContainer, backgroundImage, bgImage);

float imageWidth = backgroundImage.getWidth();
float imageHeight = backgroundImage.getHeight();
Expand Down Expand Up @@ -444,8 +444,8 @@ private int calcOffset(CssContext c, CalculatedStyle style, PropertyValue value,
}
}

private void scaleBackgroundImage(CssContext c, CalculatedStyle style, Rectangle backgroundContainer, FSImage image) {
BackgroundSize backgroundSize = style.getBackgroundSize();
private void scaleBackgroundImage(CssContext c, CalculatedStyle style, Rectangle backgroundContainer, FSImage image, BackgroundContainer bgImage) {
BackgroundSize backgroundSize = bgImage.backgroundSize;

if (! backgroundSize.isBothAuto()) {
if (backgroundSize.isCover() || backgroundSize.isContain()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,14 @@
background-position: right;
background-attachment: scroll;
}
#six {
height: 200px;
background-image: url(../../demos/images/cc0-cat.png), url(../../demos/images/flyingsaucer.png), none;
background-repeat: no-repeat;
background-position: left, right;
background-attachment: scroll;
background-size: cover, 25% 70%;
}
</style>
</head>
<body>
Expand All @@ -54,5 +62,7 @@

<div id="five"></div>

<div id="six"></div>

</body>
</html>

0 comments on commit 20798b0

Please sign in to comment.