All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.w3c.css.properties.css2.CssBackgroundPositionCSS2 Maven / Gradle / Ivy

The newest version!
//
// $Id: CssBackgroundPositionCSS2.java,v 1.2 2010-01-05 19:49:51 ylafon Exp $
// From Philippe Le Hegaret ([email protected])
//
// (c) COPYRIGHT MIT and INRIA, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.properties.css2;

import org.w3c.css.parser.CssStyle;
import org.w3c.css.properties.css.CssBackgroundPosition;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.properties.css1.Css1Style;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.InvalidParamException;
import org.w3c.css.values.CssExpression;
import org.w3c.css.values.CssIdent;
import org.w3c.css.values.CssNumber;
import org.w3c.css.values.CssPercentage;
import org.w3c.css.values.CssTypes;
import org.w3c.css.values.CssValue;

import java.util.HashMap;

import static org.w3c.css.values.CssOperator.SPACE;

/**
 * 

*    'background-position' *

*

* Value: [<percentage> | <length>]{1,2} | [top | center * | bottom] || [left | center | right]
* Initial: 0% 0%
* Applies to: block-level and replaced elements
* Inherited: no
* Percentage values: refer to the size of the element itself
*

If a background image has been specified, the value of * 'background-position' specifies its initial position. *

With a value pair of '0% 0%', the upper left corner of the image is * placed in the upper left corner of the box that surrounds the content of * the element (i.e., not the box that surrounds the padding, border or * margin). A value pair of '100% 100%' places the lower right corner of the * image in the lower right corner of the element. With a value pair of '14% * 84%', the point 14% across and 84% down the image is to be placed at the * point 14% across and 84% down the element. *

With a value pair of '2cm 2cm', the upper left corner of the image is * placed 2cm to the right and 2cm below the upper left corner of the element. *

If only one percentage or length value is given, it sets the horizontal * position only, the vertical position will be 50%. If two values are given, * the horizontal position comes first. Combinations of length and percentage * values are allowed, e.g. '50% 2cm'. Negative positions are allowed. *

One can also use keyword values to indicate the position of the * background image. Keywords cannot be combined with percentage values, or * length values. The possible combinations of keywords and their * interpretations are as follows: *

*

    *
  • * 'top left' and 'left top' both mean the same as '0% 0%'. *
  • * 'top', 'top center' and 'center top' mean the same as '50% 0%'. *
  • * 'right top' and 'top right' mean the same as '100% 0%'. *
  • * 'left', 'left center' and 'center left' mean the same as '0% 50%'. *
  • * 'center' and 'center center' mean the same as '50% 50%'. *
  • * 'right', 'right center' and 'center right' mean the same as '100% 50%'. *
  • * 'bottom left' and 'left bottom' mean the same as '0% 100%'. *
  • * 'bottom', 'bottom center' and 'center bottom' mean the same as * '50% 100%'. *
  • * 'bottom right' and 'right bottom' mean the same as '100% 100%'. *
*

* examples: *

 * BODY { background: url(banner.jpeg) right top }    / * 100%   0% * /
 * BODY { background: url(banner.jpeg) top center }   / *  50%   0% * /
 * BODY { background: url(banner.jpeg) center }       / *  50%  50% * /
 * BODY { background: url(banner.jpeg) bottom }       / *  50% 100% * /
 * 
*

* If the background image is fixed with regard to the canvas (see the * 'background-attachment' property above), the image is placed relative to * the canvas instead of the element. E.g.: *

 * BODY {
 * background-image: url(logo.png);
 * background-attachment: fixed;
 * background-position: 100% 100%;
 * }
 * 
*

* In the example above, the image is placed in the lower right corner of the * canvas. * * @version $Revision: 1.2 $ * @see org.w3c.css.properties.css.CssBackgroundAttachment */ public class CssBackgroundPositionCSS2 extends CssBackgroundPosition { public static boolean checkMatchingIdent(CssIdent ident) { return allowed_values.containsValue(ident); } private static final String propertyName = "background-position"; public static HashMap allowed_values; public static CssIdent center, top, bottom, left, right; private static CssPercentage defaultPercent0, defaultPercent50; private static CssPercentage defaultPercent100; static { top = CssIdent.getIdent("top"); bottom = CssIdent.getIdent("bottom"); left = CssIdent.getIdent("left"); right = CssIdent.getIdent("right"); center = CssIdent.getIdent("center"); allowed_values = new HashMap(); allowed_values.put("top", top); allowed_values.put("bottom", bottom); allowed_values.put("left", left); allowed_values.put("right", right); allowed_values.put("center", center); defaultPercent0 = new CssPercentage(0); defaultPercent50 = new CssPercentage(50); defaultPercent100 = new CssPercentage(100); } public CssValue value; /** * Create a new CssBackgroundPositionCSS2 */ public CssBackgroundPositionCSS2() { super(); } /** * Creates a new CssBackgroundPositionCSS2 * * @param expression The expression for this property * @throws InvalidParamException Values are incorrect */ public CssBackgroundPositionCSS2(ApplContext ac, CssExpression expression, boolean check) throws InvalidParamException { int nb_val = expression.getCount(); if (check && nb_val > 2) { throw new InvalidParamException("unrecognize", ac); } setByUser(); setByUser(); CssValue val; CssBackgroundPositionValue b_val = null; char op; // we just accumulate values and check at validation while (!expression.end()) { val = expression.getValue(); op = expression.getOperator(); if (inherit.equals(val)) { if (expression.getCount() > 1) { throw new InvalidParamException("value", val, getPropertyName(), ac); } value = inherit; expression.next(); return; } if (b_val == null) { b_val = new CssBackgroundPositionValue(); } // we will check later b_val.add(val); expression.next(); if (op != SPACE) { throw new InvalidParamException("operator", ((new Character(op)).toString()), ac); } } // if we reach the end in a value that can come in pair if (b_val != null) { check(b_val, ac); value = b_val; } } // check the value public void check(CssBackgroundPositionValue v, ApplContext ac) throws InvalidParamException { int nb_keyword = 0; int nb_percentage = 0; int nb_length = 0; int nb_values = v.value.size(); if (nb_values > 2) { throw new InvalidParamException("unrecognize", ac); } // basic check for (CssValue aValue : v.value) { switch (aValue.getType()) { case CssTypes.CSS_NUMBER: aValue = ((CssNumber) aValue).getLength(); case CssTypes.CSS_LENGTH: nb_length++; break; case CssTypes.CSS_PERCENTAGE: nb_percentage++; break; case CssTypes.CSS_IDENT: nb_keyword++; break; default: throw new InvalidParamException("unrecognize", aValue, ac); } } // this is unnecessary complex, blame it on the CSS3 spec. switch (nb_keyword) { case 0: // no keyword, so it's easy, it depends on the number // of values :) switch (nb_values) { case 1: // If only one value is specified, the second value // is assumed to be 'center'. v.horizontal = v.value.get(0); if (v.horizontal.getType() == CssTypes.CSS_NUMBER) { v.horizontal = defaultPercent0; } v.val_horizontal = v.horizontal; v.val_vertical = defaultPercent50; break; case 2: v.horizontal = v.value.get(0); if (v.horizontal.getType() == CssTypes.CSS_NUMBER) { v.horizontal = defaultPercent0; } v.val_horizontal = v.horizontal; v.vertical = v.value.get(1); if (v.vertical.getType() == CssTypes.CSS_NUMBER) { v.vertical = defaultPercent0; } v.val_vertical = v.vertical; break; default: // should never happen throw new InvalidParamException("unrecognize", ac); } break; // we got one keyword... let's have fun... case 1: switch (nb_values) { case 1: CssIdent ident = (CssIdent) v.value.get(0); // ugly as we need to set values for equality tests v.val_vertical = defaultPercent50; v.val_horizontal = defaultPercent50; ident = allowed_values.get(ident.toString()); if (ident != null) { if (isVertical(ident)) { v.vertical = ident; v.val_vertical = identToPercent(ident); } else { // horizontal || center v.horizontal = ident; v.val_horizontal = identToPercent(ident); } break; } throw new InvalidParamException("unrecognize", ident, propertyName, ac); case 2: // one ident, two values... first MUST be horizontal // and second vertical CssValue val0 = v.value.get(0); if (val0.getType() == CssTypes.CSS_IDENT) { ident = allowed_values.get(val0.toString()); if (ident == null) { throw new InvalidParamException("unrecognize", ident, propertyName, ac); } if (isVertical(ident)) { throw new InvalidParamException("incompatible", ident, v.value.get(1), ac); } v.horizontal = ident; v.val_horizontal = identToPercent(ident); // and the vertical value... v.vertical = v.value.get(1); if (v.vertical.getType() == CssTypes.CSS_NUMBER) { v.vertical = defaultPercent0; } v.val_vertical = v.vertical; } else { ident = allowed_values.get(v.value.get(1).toString()); if (ident == null) { throw new InvalidParamException("unrecognize", ident, propertyName, ac); } if (isHorizontal(ident)) { throw new InvalidParamException("incompatible", val0, v.value.get(1), ac); } v.vertical = ident; v.val_vertical = identToPercent(ident); // and the first value v.horizontal = val0; if (v.horizontal.getType() == CssTypes.CSS_NUMBER) { v.horizontal = defaultPercent0; } v.val_horizontal = v.horizontal; } break; default: // one ident, 3 or 4 values is not allowed throw new InvalidParamException("unrecognize", ac); } break; default: // we got two keywords for two values, yeah! CssIdent id1 = (CssIdent) v.value.get(0); CssIdent id2 = (CssIdent) v.value.get(1); if (((isVertical(id1) && isVertical(id2))) || (isHorizontal(id1) && isHorizontal(id2))) { throw new InvalidParamException("incompatible", id1, id2, ac); } if (isVertical(id1) || isHorizontal(id2)) { v.horizontal = id2; v.val_horizontal = identToPercent(id2); v.vertical = id1; v.val_vertical = identToPercent(id1); } else { v.horizontal = id1; v.val_horizontal = identToPercent(id1); v.vertical = id2; v.val_vertical = identToPercent(id2); } } } public CssBackgroundPositionCSS2(ApplContext ac, CssExpression expression) throws InvalidParamException { this(ac, expression, false); } public String toString() { return value.toString(); } /** * Add this property to the CssStyle. * * @param style The CssStyle */ public void addToStyle(ApplContext ac, CssStyle style) { CssBackgroundCSS2 cssBackground = ((Css1Style) style).cssBackgroundCSS2; if (cssBackground.position != null) style.addRedefinitionWarning(ac, this); cssBackground.position = this; } /** * Get this property in the style. * * @param style The style where the property is * @param resolve if true, resolve the style to find this property */ public CssProperty getPropertyInStyle(CssStyle style, boolean resolve) { if (resolve) { return ((Css1Style) style).getBackgroundPositionCSS2(); } else { return ((Css1Style) style).cssBackgroundCSS2.position; } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy