
w3c.css.values.CssLength Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of cssvalidator Show documentation
Show all versions of cssvalidator Show documentation
Backend for the W3C CSS Validation Service
// $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.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));
}
// redefinitions for some error messages.
/**
* check if the value is equal to zero
*
* @param ac the validation context
* @param callername the String value of the object it is defined in
* @throws InvalidParamException
*/
public void checkEqualsZero(ApplContext ac, String callername)
throws InvalidParamException {
checkEqualsZero(ac, new String[]{"length", toString(), callername});
}
/**
* warn if the value is not zero
*
* @param ac the validation context
* @param callername the String value of the object it is defined in
*/
public void warnEqualsZero(ApplContext ac, String callername) {
warnEqualsZero(ac, new String[]{"length", callername});
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy