blob: a4f2c06887a9a9ff3515ced9e14e0e4fc0804074 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2008 Innoopract Informationssysteme GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innoopract Informationssysteme GmbH - initial API and implementation
******************************************************************************/
package org.eclipse.rwt.internal.theme.css;
import java.util.*;
import org.eclipse.rwt.internal.theme.*;
import org.w3c.css.sac.LexicalUnit;
public class PropertyResolver {
private static final String BOLD = "bold";
private static final String ITALIC = "italic";
private static final String NORMAL = "normal";
private static final String NONE = "none";
private static final String HIDDEN = "hidden";
private static final String DOTTED = "dotted";
private static final String DASHED = "dashed";
private static final String SOLID = "solid";
private static final String DOUBLE = "double";
private static final String GROOVE = "groove";
private static final String RIDGE = "ridge";
private static final String INSET = "inset";
private static final String OUTSET = "outset";
/** A thin border. */
private static final String THIN = "thin";
/** A medium border. */
private static final String MEDIUM = "medium";
/** A thick border. */
private static final String THICK = "thick";
private static final String TRANSPARENT = "transparent";
private static final Map NAMED_COLORS = new HashMap();
private static final List BORDER_STYLES = new ArrayList();
/** Width value for "thin" identifier. */
public static final int THIN_VALUE = 1;
/** Width value for "medium" identifier. */
public static final int MEDIUM_VALUE = 3;
/** Width value for "thick" identifier. */
public static final int THICK_VALUE = 5;
static {
// register 16 standard HTML colors
NAMED_COLORS.put( "black", new int[] { 0, 0, 0 } );
NAMED_COLORS.put( "gray", new int[] { 128, 128, 128 } );
NAMED_COLORS.put( "silver", new int[] { 192, 192, 192 } );
NAMED_COLORS.put( "white", new int[] { 255, 255, 255 } );
NAMED_COLORS.put( "maroon", new int[] { 128, 0, 0 } );
NAMED_COLORS.put( "red", new int[] { 255, 0, 0 } );
NAMED_COLORS.put( "purple", new int[] { 128, 0, 128 } );
NAMED_COLORS.put( "fuchsia", new int[] { 255, 0, 255 } );
NAMED_COLORS.put( "green", new int[] { 0, 128, 0 } );
NAMED_COLORS.put( "lime", new int[] { 0, 255, 0 } );
NAMED_COLORS.put( "navy", new int[] { 0, 0, 128 } );
NAMED_COLORS.put( "blue", new int[] { 0, 0, 255 } );
NAMED_COLORS.put( "olive", new int[] { 128, 128, 0 } );
NAMED_COLORS.put( "yellow", new int[] { 255, 255, 0 } );
NAMED_COLORS.put( "teal", new int[] { 0, 128, 128 } );
NAMED_COLORS.put( "aqua", new int[] { 0, 255, 255 } );
// register border styles
BORDER_STYLES.add( NONE ); // No border; the computed border width is zero.
BORDER_STYLES.add( HIDDEN ); // Same as 'none', except in terms of border conflict resolution for table elements.
BORDER_STYLES.add( DOTTED ); // The border is a series of dots.
BORDER_STYLES.add( DASHED ); // The border is a series of short line segments.
BORDER_STYLES.add( SOLID ); // The border is a single line segment.
BORDER_STYLES.add( DOUBLE ); // The border is two solid lines. The sum of the two lines and the space between them equals the value of 'border-width'.
BORDER_STYLES.add( GROOVE ); // The border looks as though it were carved into the canvas.
BORDER_STYLES.add( RIDGE ); // The opposite of 'groove': the border looks as though it were coming out of the canvas.
BORDER_STYLES.add( INSET ); // The border makes the box look as though it were embedded in the canvas.
BORDER_STYLES.add( OUTSET ); // The opposite of 'inset': the border makes the box look as though it were coming out of the canvas.
}
public static QxColor readColor( final LexicalUnit input ) {
QxColor result = null;
short type = input.getLexicalUnitType();
if( type == LexicalUnit.SAC_RGBCOLOR ) {
LexicalUnit redParam = input.getParameters();
LexicalUnit greenParam = redParam.getNextLexicalUnit().getNextLexicalUnit();
LexicalUnit blueParam = greenParam.getNextLexicalUnit().getNextLexicalUnit();
short valueType = redParam.getLexicalUnitType();
if( greenParam.getLexicalUnitType() == valueType
|| blueParam.getLexicalUnitType() == valueType )
{
if( valueType == LexicalUnit.SAC_INTEGER ) {
int red = normalizeRGBValue( redParam.getIntegerValue() );
int green = normalizeRGBValue( greenParam.getIntegerValue() );
int blue = normalizeRGBValue( blueParam.getIntegerValue() );
result = QxColor.create( red, green, blue );
} else if( valueType == LexicalUnit.SAC_PERCENTAGE ) {
float redPercent = normalizePercentValue( redParam.getFloatValue() );
float greenPercent = normalizePercentValue( greenParam.getFloatValue() );
float bluePercent = normalizePercentValue( blueParam.getFloatValue() );
int red = ( int )( 255 * redPercent / 100 );
int green = ( int )( 255 * greenPercent / 100 );
int blue = ( int )( 255 * bluePercent / 100 );
result = QxColor.create( red, green, blue );
}
}
} else if( type == LexicalUnit.SAC_IDENT ) {
String string = input.getStringValue();
if( TRANSPARENT.equals( string ) ) {
result = QxColor.TRANSPARENT;
} else if( NAMED_COLORS.containsKey( string.toLowerCase() ) ) {
int[] values = ( int[] )NAMED_COLORS.get( string.toLowerCase() );
result = QxColor.create( values[ 0 ], values[ 1 ], values[ 2 ] );
}
}
return result;
}
public static QxDimension readDimension( final LexicalUnit unit ) {
QxDimension result = null;
Integer length = readSingleLengthUnit( unit );
if( length != null ) {
result = QxDimension.create( length.intValue() );
}
return result;
}
public static QxBoxDimensions readBoxDimensions( final LexicalUnit unit ) {
QxBoxDimensions result = null;
Integer value1 = readSingleLengthUnit( unit );
if( value1 != null ) {
int top, right, left, bottom;
top = right = bottom = left = value1.intValue();
LexicalUnit nextUnit = unit.getNextLexicalUnit();
boolean ok = true;
int pos = 1;
while( nextUnit != null && ok ) {
pos++;
Integer nextValue = readSingleLengthUnit( nextUnit );
ok &= nextValue != null && pos <= 4;
if( ok ) {
if( pos == 2 ) {
right = left = nextValue.intValue();
} else if( pos == 3 ) {
bottom = nextValue.intValue();
} else if( pos == 4 ) {
left = nextValue.intValue();
}
}
nextUnit = nextUnit.getNextLexicalUnit();
}
ok &= nextUnit == null;
if( ok ) {
result = QxBoxDimensions.create( top, right, bottom, left );
}
}
return result;
}
public static String readBorderStyle( final LexicalUnit unit ) {
String result = null;
short type = unit.getLexicalUnitType();
if( type == LexicalUnit.SAC_IDENT ) {
String string = unit.getStringValue();
if( BORDER_STYLES.contains( string ) ) {
result = string;
}
}
return result;
}
public static int readBorderWidth( final LexicalUnit unit ) {
int result = -1;
short type = unit.getLexicalUnitType();
if( type == LexicalUnit.SAC_IDENT ) {
String string = unit.getStringValue();
if( THIN.equals( string ) ) {
result = THIN_VALUE;
} else if( MEDIUM.equals( string ) ) {
result = MEDIUM_VALUE;
} else if( THICK.equals( string ) ) {
result = THICK_VALUE;
}
} else if( type == LexicalUnit.SAC_PIXEL ) {
float value = unit.getFloatValue();
if( value >= 0f ) {
result = Math.round( value );
}
}
return result;
}
public static QxBorder readBorder( final LexicalUnit unit ) {
QxBorder result = null;
QxColor color = null;
String style = null;
int width = -1;
LexicalUnit nextUnit = unit;
boolean consumed = false;
while( nextUnit != null ) {
consumed = false;
if( !consumed && width == -1 ) {
width = readBorderWidth( nextUnit );
consumed |= width != -1;
}
if( !consumed && style == null ) {
style = readBorderStyle( nextUnit );
consumed |= style != null;
}
if( !consumed && color == null ) {
color = readColor( nextUnit );
consumed |= color != null;
}
nextUnit = consumed ? nextUnit.getNextLexicalUnit() : null;
}
if( consumed ) {
// TODO [rst] create should take a QxColor
result = QxBorder.create( width == -1 ? 0 : width,
style,
color != null ? color.toDefaultString() : null );
}
return result;
}
public static String readFontStyle( final LexicalUnit unit ) {
String result = null;
short type = unit.getLexicalUnitType();
if( type == LexicalUnit.SAC_IDENT ) {
String value = unit.getStringValue();
if( NORMAL.equals( value ) ) {
result = value;
} else if( ITALIC.equals( value ) ) {
result = value;
}
}
return result;
}
public static String readFontWeight( final LexicalUnit unit ) {
String result = null;
short type = unit.getLexicalUnitType();
if( type == LexicalUnit.SAC_IDENT ) {
String value = unit.getStringValue();
if( NORMAL.equals( value ) ) {
result = value;
} else if( BOLD.equals( value ) ) {
result = value;
}
}
return result;
}
public static int readFontSize( final LexicalUnit unit ) {
int result = -1;
Integer length = readSingleLengthUnit( unit );
if( length != null ) {
int value = length.intValue();
if( value >= 0 ) {
result = value;
}
}
return result;
}
public static String[] readFontFamily( final LexicalUnit unit ) {
List list = new ArrayList();
LexicalUnit nextUnit = unit;
boolean ok = true;
String buffer = "";
while( nextUnit != null && ok ) {
short type = nextUnit.getLexicalUnitType();
if( type == LexicalUnit.SAC_STRING_VALUE
|| type == LexicalUnit.SAC_IDENT )
{
if( buffer.length() > 0 ) {
buffer += " ";
}
buffer += nextUnit.getStringValue();
} else if( type == LexicalUnit.SAC_OPERATOR_COMMA ) {
if( buffer.length() > 0 ) {
list.add( buffer );
} else {
ok = false;
}
buffer = "";
}
nextUnit = nextUnit.getNextLexicalUnit();
}
String[] result = null;
if( buffer.length() > 0 ) {
list.add( buffer );
result = new String[ list.size() ];
list.toArray( result );
}
return result;
}
// The format of a URI value is 'url(' followed by optional whitespace
// followed by an optional single quote (') or double quote (") character
// followed by the URI itself, followed by an optional single quote (') or
// double quote (") character followed by optional whitespace followed by ')'.
// The two quote characters must be the same.
public static QxFont readFont( final LexicalUnit unit ) {
QxFont result = null;
String[] family = null;
String style = null;
String weight = null;
int size = -1;
boolean consumed = false;
boolean consumedSize = false;
boolean consumedFamily = false;
LexicalUnit nextUnit = unit;
while( nextUnit != null && !consumedFamily ) {
consumed = false;
if( !consumed && !consumedSize && style == null ) {
style = readFontStyle( nextUnit );
consumed |= style != null;
}
if( !consumed && !consumedSize && weight == null ) {
weight = readFontWeight( nextUnit );
consumed |= weight != null;
}
if( !consumed && !consumedFamily && size == -1 ) {
size = readFontSize( nextUnit );
consumedSize = size != -1;
consumed |= consumedSize;
}
if( !consumed && consumedSize && family == null ) {
family = readFontFamily( nextUnit );
consumedFamily = family != null;
consumed |= consumedFamily;
}
nextUnit = consumed ? nextUnit.getNextLexicalUnit() : null;
}
if( consumed && consumedSize && consumedFamily ) {
boolean bold = BOLD.equals( weight );
boolean italic = ITALIC.equals( style );
result = QxFont.create( family, size, bold, italic );
}
return result;
}
public static String readUrl( final LexicalUnit unit ) {
String result = null;
short type = unit.getLexicalUnitType();
if( type == LexicalUnit.SAC_URI ) {
result = unit.getStringValue();
}
return result;
}
public static QxImage readBackgroundImage( final LexicalUnit unit,
final ResourceLoader loader ) {
QxImage result = null;
short type = unit.getLexicalUnitType();
if( type == LexicalUnit.SAC_URI ) {
String value = unit.getStringValue();
result = QxImage.valueOf( value, loader );
} else if( type == LexicalUnit.SAC_IDENT ) {
String value = unit.getStringValue();
if( NONE.equals( value ) ) {
result = QxImage.NONE;
}
}
return result;
}
private static Integer readSingleLengthUnit( final LexicalUnit unit ) {
Integer result = null;
short type = unit.getLexicalUnitType();
if( type == LexicalUnit.SAC_PIXEL ) {
result = new Integer( ( int )unit.getFloatValue() );
}
return result;
}
private static int normalizeRGBValue( final int input ) {
int result = input;
if( input < 0 ) {
result = 0;
} else if( input > 255 ) {
result = 255;
}
return result;
}
private static float normalizePercentValue( final float input ) {
float result = input;
if( input < 0f ) {
result = 0f;
} else if( input > 100f ) {
result = 100f;
}
return result;
}
/*
* BEGIN Modification for Theme Editor
* Returns an QxType out of a LexicalUnit.
*/
public static QxType getQxType( final String cssProperty,
final LexicalUnit unit )
{
QxType result = null;
if( unit != null ) {
// IPropertyWrapper wrapper = PropertyWrapperFactory.createPropertyWrapper( cssProperty,
// unit,
// null );
// if ( wrapper != null ) {
// result = wrapper.getQxType();
// }
}
return result;
}
/*
* Returns the color value of a border unit.
*/
public static QxColor readBorderColor( final LexicalUnit unit ) {
QxColor result = null;
String style = null;
int width = -1;
LexicalUnit nextUnit = unit;
boolean consumed = false;
while( nextUnit != null ) {
consumed = false;
if( !consumed && width == -1 ) {
width = readBorderWidth( nextUnit );
consumed |= width != -1;
}
if( !consumed && style == null ) {
style = readBorderStyle( nextUnit );
consumed |= style != null;
}
if( !consumed && result == null ) {
result = readColor( nextUnit );
consumed |= result != null;
}
nextUnit = consumed
? nextUnit.getNextLexicalUnit()
: null;
}
return result;
}
/*
* END Modification for Theme Editor
*/
}