
w3c.css.values.CssLength Maven / Gradle / Ivy
// $Id$
// From Philippe Le Hegaret ([email protected])
// Updated September 25th 2000 Sijtsche de Jong ([email protected])
// Updated 2012 by Yves Lafon
//
// (c) COPYRIGHT MIT, ERCIM and Keio University, 1997.
// Please first read the full copyright statement in file COPYRIGHT.html
package org.w3c.css.values;
import org.w3c.css.properties.css.CssProperty;
import org.w3c.css.util.ApplContext;
import org.w3c.css.util.InvalidParamException;
import java.math.BigDecimal;
/**
*
* Length units
*
*
* The format of a length value is an optional sign character ('+' or '-', with
* '+' being the default) immediately followed by a number (with or without
* a decimal point) immediately followed by a unit identifier (a two-letter
* abbreviation). After a '0' number, the unit identifier is optional.
*
* Some properties allow negative length units, but this may complicate the
* formatting model and there may be implementation-specific limits. If a negative
* length value cannot be supported, it should be clipped to the nearest value
* that can be supported.
*
* There are two types of length units: relative and absolute. Relative units
* specify a length relative to another length property. Style sheets that use
* relative units will more easily scale from one medium to another (e.g. from
* a computer display to a laser printer). Percentage
* units (described below) and keyword values (e.g. 'x-large') offer similar
* advantages.
*
* These relative units are supported:
*
* H1 { margin: 0.5em } /* ems, the height of the element's font * /
* H1 { margin: 1ex } /* x-height, ~ the height of the letter 'x' * /
* P { font-size: 12px } /* pixels, relative to canvas * /
* P { layout-grid: strict both 20 pt 15 pt; margin 1gd 3gd 1gd 2gd } /* grid units * /
*
*
* The relative units 'em' and 'ex' are relative to the font size of the element
* itself. The only exception to this rule in CSS1 is the 'font-size' property
* where 'em' and 'ex' values refer to the font size of the parent element.
*
* The existence of a grid in an element makes it possible and very useful to express various
* measurements in that element in terms of grid units. Grid units are used very frequently
* in East Asian typography, especially for the left, right, top and bottom element margins.
* Therefore a new length unit is necessary: gd to enable the author to specify the various
* measurements in terms of the grid.
*
* Pixel units, as used in the last rule, are relative to the resolution of
* the canvas, i.e. most often a computer display. If the pixel density of the
* output device is very different from that of a typical computer display,
* the UA should rescale pixel values. The suggested reference pixel
* is the visual angle of one pixel on a device with a pixel density of 90dpi
* and a distance from the reader of an arm's length. For a nominal arm's length
* of 28 inches, the visual angle is about 0.0227 degrees.
*
* Child elements inherit the computed value, not the relative value:
*
* BODY {
* font-size: 12pt;
* text-indent: 3em; /* i.e. 36pt * /
* }
* H1 { font-size: 15pt }
*
*
* In the example above, the 'text-indent' value of 'H1' elements will be 36pt,
* not 45pt.
*
* Absolute length units are only useful when the physical properties of the
* output medium are known. These absolute units are supported:
*
* H1 { margin: 0.5in } /* inches, 1in = 2.54cm * /
* H2 { line-height: 3cm } /* centimeters * /
* H3 { word-spacing: 4mm } /* millimeters * /
* H4 { font-size: 12pt } /* points, 1pt = 1/72 in * /
* H4 { font-size: 1pc } /* picas, 1pc = 12pt * /
*
*
* In cases where the specified length cannot be supported, UAs should try to
* approximate. For all CSS1 properties, further computations and inheritance
* should be based on the approximated value.
*
* @version $Revision$
* @see CssPercentage
*/
public class CssLength extends CssCheckableValue {
public static final int type = CssTypes.CSS_LENGTH;
public final int getType() {
return type;
}
private BigDecimal value;
protected String unit;
protected boolean absolute = false;
/**
* Create a new CssLength
*/
public CssLength() {
value = BigDecimal.ZERO;
}
/**
* Set the value of this length.
*
* @param s the string representation of the length.
* @throws InvalidParamException The unit is incorrect
*/
public void set(String s, ApplContext ac) throws InvalidParamException {
String low_s = s.toLowerCase();
int length = low_s.length();
int unitIdx = length - 1;
char c = low_s.charAt(unitIdx);
while (unitIdx > 0 && c <= 'z' && c >= 'a') {
c = low_s.charAt(--unitIdx);
}
if (unitIdx == length - 1) {
throw new InvalidParamException("unit", s, ac);
}
// we go back to the beginning of the unit
unitIdx++;
String unit_str = low_s.substring(unitIdx, length);
// let's test the unit
// TODO check the if (!BigDecimal.ZERO.equals(value))) test
// that was here earlier
// seems legit to always test the unit no matter the value
switch (ac.getCssVersion()) {
case CSS1:
CssUnitsCSS1.parseLengthUnit(unit_str, this, ac);
break;
case CSS2:
CssUnitsCSS2.parseLengthUnit(unit_str, this, ac);
break;
case CSS21:
CssUnitsCSS21.parseLengthUnit(unit_str, this, ac);
break;
case CSS3:
CssUnitsCSS3.parseLengthUnit(unit_str, this, ac);
break;
default:
throw new InvalidParamException("unit", s, ac);
}
try {
value = new BigDecimal(low_s.substring(0, unitIdx));
} catch (NumberFormatException nex) {
throw new InvalidParamException("invalid-number",
low_s.substring(0, unitIdx), ac);
}
}
/**
* set the native value
*
* @param v the BigDecimal
*/
public void setValue(BigDecimal v) {
value = v;
}
// return self
public CssLength getLength() throws InvalidParamException {
return this;
}
/**
* Returns the current value
*/
public Object get() {
// TODO this is old ugly crap, needed for not breaking everything
// remove as soon as reference to get is removed...
return new Float(value.floatValue());
}
/**
* return the float value
*/
public float floatValue() {
return value.floatValue();
}
/**
* Returns true is the value is positive of null
*
* @return a boolean
*/
public boolean isPositive() {
return (value.signum() >= 0);
}
/**
* Returns true is the value is positive of null
*
* @return a boolean
*/
public boolean isStrictlyPositive() {
return (value.signum() == 1);
}
/**
* Returns true is the value is zero
*
* @return a boolean
*/
public boolean isZero() {
return (BigDecimal.ZERO.compareTo(value) == 0);
}
/**
* Returns the current value
*/
public String getUnit() {
return unit;
}
/**
* tells if it is relative or not
*/
public boolean isRelative() {
return !absolute;
}
/**
* tells if it is absolute or not
*/
public boolean isAbsolute() {
return absolute;
}
/**
* Returns a string representation of the object.
*/
public String toString() {
if (BigDecimal.ZERO.compareTo(value) == 0) {
return BigDecimal.ZERO.toPlainString();
}
return value.toPlainString() + unit;
}
/**
* Compares two values for equality.
*
* @param value The other value.
*/
public boolean equals(Object value) {
return (value instanceof CssLength &&
this.value.equals(((CssLength) value).value) &&
unit.equals(((CssLength) value).unit));
}
/**
* check if the value is positive or null
*
* @param ac the validation context
* @param property the property the value is defined in
* @throws InvalidParamException
*/
public void checkPositiveness(ApplContext ac, CssProperty property)
throws InvalidParamException {
if (!isPositive()) {
throw new InvalidParamException("negative-value",
toString(), property.getPropertyName(), ac);
}
}
/**
* check if the value is strictly positive
*
* @param ac the validation context
* @param property the property the value is defined in
* @throws InvalidParamException
*/
public void checkStrictPositiveness(ApplContext ac, CssProperty property)
throws InvalidParamException {
if (!isStrictlyPositive()) {
throw new InvalidParamException("strictly-positive",
toString(), property.getPropertyName(), ac);
}
}
/**
* warn if the value is not positive or null
*
* @param ac the validation context
* @param property the property the value is defined in
*/
public void warnPositiveness(ApplContext ac, CssProperty property) {
if (!isPositive()) {
ac.getFrame().addWarning("negative", toString());
}
}
/**
* check if the value is equal to zero
*
* @param ac the validation context
* @param property the property the value is defined in
* @throws InvalidParamException
*/
public void checkEqualsZero(ApplContext ac, CssProperty property)
throws InvalidParamException {
if (!isZero()) {
throw new InvalidParamException("zero",
toString(),
"length", ac);
}
}
/**
* warn if the value is not zero
*
* @param ac the validation context
* @param property the property the value is defined in
*/
public void warnEqualsZero(ApplContext ac, CssProperty property) {
if (!isZero()) {
ac.getFrame().addWarning("zero", "length");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy