#include "config.h"
#if ENABLE(SVG)
#include "CSSInheritedValue.h"
#include "CSSInitialValue.h"
#include "CSSParser.h"
#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSQuirkPrimitiveValue.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "SVGPaint.h"
#include "ksvgcssproperties.c"
#include "ksvgcssvalues.c"
using namespace std;
namespace WebCore {
bool CSSParser::parseSVGValue(int propId, bool important)
{
Value* value = valueList->current();
if (!value)
return false;
int id = value->id;
bool valid_primitive = false;
CSSValue* parsedValue = 0;
switch (propId) {
case SVGCSS_PROP_ALIGNMENT_BASELINE:
if (id == CSS_VAL_AUTO || id == CSS_VAL_BASELINE || id == CSS_VAL_MIDDLE ||
(id >= SVGCSS_VAL_BEFORE_EDGE && id <= SVGCSS_VAL_MATHEMATICAL))
valid_primitive = true;
break;
case SVGCSS_PROP_BASELINE_SHIFT:
if (id == CSS_VAL_BASELINE || id == CSS_VAL_SUB ||
id >= CSS_VAL_SUPER)
valid_primitive = true;
else
valid_primitive = validUnit(value, FLength|FPercent, false);
break;
case SVGCSS_PROP_DOMINANT_BASELINE:
if (id == CSS_VAL_AUTO || id == CSS_VAL_MIDDLE ||
(id >= SVGCSS_VAL_USE_SCRIPT && id <= SVGCSS_VAL_RESET_SIZE) ||
(id >= SVGCSS_VAL_CENTRAL && id <= SVGCSS_VAL_MATHEMATICAL))
valid_primitive = true;
break;
case SVGCSS_PROP_ENABLE_BACKGROUND:
if (id == SVGCSS_VAL_ACCUMULATE) valid_primitive = true;
break;
case SVGCSS_PROP_MARKER_START:
case SVGCSS_PROP_MARKER_MID:
case SVGCSS_PROP_MARKER_END:
case SVGCSS_PROP_MASK:
if (id == CSS_VAL_NONE)
valid_primitive = true;
else if (value->unit == CSSPrimitiveValue::CSS_URI) {
parsedValue = new CSSPrimitiveValue(domString(value->string), CSSPrimitiveValue::CSS_URI);
if (parsedValue)
valueList->next();
}
break;
case SVGCSS_PROP_CLIP_RULE: case SVGCSS_PROP_FILL_RULE:
if (id == SVGCSS_VAL_NONZERO || id == SVGCSS_VAL_EVENODD)
valid_primitive = true;
break;
case SVGCSS_PROP_STROKE_MITERLIMIT: valid_primitive = validUnit(value, FNumber|FNonNeg, false);
break;
case SVGCSS_PROP_STROKE_LINEJOIN: if (id == SVGCSS_VAL_MITER || id == CSS_VAL_ROUND || id == SVGCSS_VAL_BEVEL)
valid_primitive = true;
break;
case SVGCSS_PROP_STROKE_LINECAP: if (id == SVGCSS_VAL_BUTT || id == CSS_VAL_ROUND || id == CSS_VAL_SQUARE)
valid_primitive = true;
break;
case SVGCSS_PROP_STROKE_OPACITY: case SVGCSS_PROP_FILL_OPACITY:
case SVGCSS_PROP_STOP_OPACITY:
case SVGCSS_PROP_FLOOD_OPACITY:
valid_primitive = (!id && validUnit(value, FNumber|FPercent, false));
break;
case SVGCSS_PROP_SHAPE_RENDERING:
if (id == CSS_VAL_AUTO || id == SVGCSS_VAL_OPTIMIZESPEED ||
id == SVGCSS_VAL_CRISPEDGES || id == SVGCSS_VAL_GEOMETRICPRECISION)
valid_primitive = true;
break;
case SVGCSS_PROP_TEXT_RENDERING: if (id == CSS_VAL_AUTO || id == SVGCSS_VAL_OPTIMIZESPEED || id == SVGCSS_VAL_OPTIMIZELEGIBILITY ||
id == SVGCSS_VAL_GEOMETRICPRECISION)
valid_primitive = true;
break;
case SVGCSS_PROP_IMAGE_RENDERING: case SVGCSS_PROP_COLOR_RENDERING: if (id == CSS_VAL_AUTO || id == SVGCSS_VAL_OPTIMIZESPEED ||
id == SVGCSS_VAL_OPTIMIZEQUALITY)
valid_primitive = true;
break;
case SVGCSS_PROP_COLOR_PROFILE: if (id == CSS_VAL_AUTO || id == SVGCSS_VAL_SRGB)
valid_primitive = true;
break;
case SVGCSS_PROP_COLOR_INTERPOLATION: case SVGCSS_PROP_COLOR_INTERPOLATION_FILTERS:
if (id == CSS_VAL_AUTO || id == SVGCSS_VAL_SRGB || id == SVGCSS_VAL_LINEARRGB)
valid_primitive = true;
break;
case SVGCSS_PROP_POINTER_EVENTS:
if (id == CSS_VAL_VISIBLE || id == CSS_VAL_NONE ||
(id >= SVGCSS_VAL_VISIBLEPAINTED && id <= SVGCSS_VAL_ALL))
valid_primitive = true;
break;
case SVGCSS_PROP_TEXT_ANCHOR: if (id == CSS_VAL_START || id == CSS_VAL_MIDDLE || id == CSS_VAL_END)
valid_primitive = true;
break;
case SVGCSS_PROP_GLYPH_ORIENTATION_VERTICAL: if (id == CSS_VAL_AUTO) {
valid_primitive = true;
break;
}
case SVGCSS_PROP_GLYPH_ORIENTATION_HORIZONTAL: if (value->unit == CSSPrimitiveValue::CSS_DEG)
parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_DEG);
else if (value->unit == CSSPrimitiveValue::CSS_GRAD)
parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_GRAD);
else if (value->unit == CSSPrimitiveValue::CSS_RAD)
parsedValue = new CSSPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_RAD);
break;
case SVGCSS_PROP_FILL: case SVGCSS_PROP_STROKE: {
if (id == CSS_VAL_NONE)
parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_NONE);
else if (id == SVGCSS_VAL_CURRENTCOLOR)
parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR);
else if (value->unit == CSSPrimitiveValue::CSS_URI)
parsedValue = new SVGPaint(SVGPaint::SVG_PAINTTYPE_URI, domString(value->string));
else
parsedValue = parseSVGPaint();
if (parsedValue)
valueList->next();
}
break;
case CSS_PROP_COLOR: if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
(id >= SVGCSS_VAL_ALICEBLUE && id <= SVGCSS_VAL_YELLOWGREEN))
parsedValue = new SVGColor(domString(value->string));
else
parsedValue = parseSVGColor();
if (parsedValue)
valueList->next();
break;
case SVGCSS_PROP_STOP_COLOR: case SVGCSS_PROP_FLOOD_COLOR:
case SVGCSS_PROP_LIGHTING_COLOR:
if ((id >= CSS_VAL_AQUA && id <= CSS_VAL_WINDOWTEXT) ||
(id >= SVGCSS_VAL_ALICEBLUE && id <= SVGCSS_VAL_YELLOWGREEN))
parsedValue = new SVGColor(domString(value->string));
else if (id == SVGCSS_VAL_CURRENTCOLOR)
parsedValue = new SVGColor(SVGColor::SVG_COLORTYPE_CURRENTCOLOR);
else parsedValue = parseSVGColor();
if (parsedValue)
valueList->next();
break;
case SVGCSS_PROP_WRITING_MODE:
if (id >= SVGCSS_VAL_LR_TB && id <= SVGCSS_VAL_TB)
valid_primitive = true;
break;
case SVGCSS_PROP_STROKE_WIDTH: case SVGCSS_PROP_STROKE_DASHOFFSET:
valid_primitive = validUnit(value, FLength | FPercent, false);
break;
case SVGCSS_PROP_STROKE_DASHARRAY: if (id == CSS_VAL_NONE)
valid_primitive = true;
else
parsedValue = parseSVGStrokeDasharray();
break;
case SVGCSS_PROP_KERNING: if (id == CSS_VAL_AUTO || id == CSS_VAL_NORMAL)
valid_primitive = true;
else
valid_primitive = validUnit(value, FLength, false);
break;
case SVGCSS_PROP_CLIP_PATH: case SVGCSS_PROP_FILTER:
if (id == CSS_VAL_NONE)
valid_primitive = true;
else if (value->unit == CSSPrimitiveValue::CSS_URI) {
parsedValue = new CSSPrimitiveValue(domString(value->string), (CSSPrimitiveValue::UnitTypes) value->unit);
if (parsedValue)
valueList->next();
}
break;
case SVGCSS_PROP_MARKER:
{
if (!parseValue(SVGCSS_PROP_MARKER_START, important))
return false;
CSSValue *value = parsedProperties[numParsedProperties - 1]->value();
m_implicitShorthand = true;
addProperty(SVGCSS_PROP_MARKER_MID, value, important);
addProperty(SVGCSS_PROP_MARKER_END, value, important);
m_implicitShorthand = false;
return true;
}
default:
return false;
}
if (valid_primitive) {
if (id != 0)
parsedValue = new CSSPrimitiveValue(id);
else if (value->unit == CSSPrimitiveValue::CSS_STRING)
parsedValue = new CSSPrimitiveValue(domString(value->string), (CSSPrimitiveValue::UnitTypes) value->unit);
else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
parsedValue = new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
else if (value->unit >= Value::Q_EMS)
parsedValue = new CSSQuirkPrimitiveValue(value->fValue, CSSPrimitiveValue::CSS_EMS);
valueList->next();
}
if (parsedValue) {
if (!valueList->current() || inShorthand()) {
addProperty(propId, parsedValue, important);
return true;
}
delete parsedValue;
}
return false;
}
CSSValue* CSSParser::parseSVGStrokeDasharray()
{
CSSValueList* ret = new CSSValueList;
Value* value = valueList->current();
bool valid_primitive = true;
while (value) {
valid_primitive = validUnit(value, FLength | FPercent |FNonNeg, false);
if (!valid_primitive)
break;
if (value->id != 0)
ret->append(new CSSPrimitiveValue(value->id));
else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
ret->append(new CSSPrimitiveValue(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
value = valueList->next();
if (value && value->unit == Value::Operator && value->iValue == ',')
value = valueList->next();
}
if (!valid_primitive) {
delete ret;
ret = 0;
}
return ret;
}
CSSValue* CSSParser::parseSVGPaint()
{
RGBA32 c = Color::transparent;
if (!parseColorFromValue(valueList->current(), c, true))
return new SVGPaint();
return new SVGPaint(Color(c));
}
CSSValue* CSSParser::parseSVGColor()
{
RGBA32 c = Color::transparent;
if (!parseColorFromValue(valueList->current(), c, true))
return 0;
return new SVGColor(Color(c));
}
}
#endif // ENABLE(SVG)