SVGCSSStyleSelector.cpp [plain text]
#include "config.h"
#if SVG_SUPPORT
#include "cssstyleselector.h"
#include "SVGColor.h"
#include "SVGNames.h"
#include "SVGPaint.h"
#include "SVGRenderStyle.h"
#include "SVGRenderStyleDefs.h"
#include "SVGStyledElement.h"
#include "CSSValueKeywords.h"
#include "CSSValueList.h"
#include "ksvg.h"
#include "ksvgcssvalues.h"
#include "ksvgcssproperties.h"
#include <stdlib.h>
#define HANDLE_INHERIT(prop, Prop) \
if (isInherit) \
{\
svgstyle->set##Prop(parentStyle->svgStyle()->prop());\
return;\
}
#define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
HANDLE_INHERIT(prop, Prop) \
else if (isInitial) \
svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
#define HANDLE_INHERIT_AND_INITIAL_WITH_VALUE(prop, Prop, Value) \
HANDLE_INHERIT(prop, Prop) \
else if (isInitial) \
svgstyle->set##Prop(SVGRenderStyle::initial##Value());
#define HANDLE_INHERIT_COND(propID, prop, Prop) \
if (id == propID) \
{\
svgstyle->set##Prop(parentStyle->prop());\
return;\
}
#define HANDLE_INITIAL_COND(propID, Prop) \
if (id == propID) \
{\
svgstyle->set##Prop(SVGRenderStyle::initial##Prop());\
return;\
}
#define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
if (id == propID) \
{\
svgstyle->set##Prop(SVGRenderStyle::initial##Value());\
return;\
}
namespace WebCore {
void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
{
CSSPrimitiveValue* primitiveValue = 0;
if (value->isPrimitiveValue())
primitiveValue = static_cast<CSSPrimitiveValue*>(value);
Length l;
SVGRenderStyle* svgstyle = style->accessSVGStyle();
unsigned short valueType = value->cssValueType();
bool isInherit = parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT;
bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT);
switch (id)
{
case SVGCSS_PROP_ALIGNMENT_BASELINE:
{
HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case CSS_VAL_AUTO:
svgstyle->setAlignmentBaseline(AB_AUTO);
break;
case CSS_VAL_BASELINE:
svgstyle->setAlignmentBaseline(AB_BASELINE);
break;
case SVGCSS_VAL_BEFORE_EDGE:
svgstyle->setAlignmentBaseline(AB_BEFORE_EDGE);
break;
case SVGCSS_VAL_TEXT_BEFORE_EDGE:
svgstyle->setAlignmentBaseline(AB_TEXT_BEFORE_EDGE);
break;
case CSS_VAL_MIDDLE:
svgstyle->setAlignmentBaseline(AB_MIDDLE);
break;
case SVGCSS_VAL_CENTRAL:
svgstyle->setAlignmentBaseline(AB_CENTRAL);
break;
case SVGCSS_VAL_AFTER_EDGE:
svgstyle->setAlignmentBaseline(AB_AFTER_EDGE);
break;
case SVGCSS_VAL_TEXT_AFTER_EDGE:
svgstyle->setAlignmentBaseline(AB_TEXT_AFTER_EDGE);
break;
case SVGCSS_VAL_IDEOGRAPHIC:
svgstyle->setAlignmentBaseline(AB_IDEOGRAPHIC);
break;
case SVGCSS_VAL_ALPHABETIC:
svgstyle->setAlignmentBaseline(AB_ALPHABETIC);
break;
case SVGCSS_VAL_HANGING:
svgstyle->setAlignmentBaseline(AB_HANGING);
break;
case SVGCSS_VAL_MATHEMATICAL:
svgstyle->setAlignmentBaseline(AB_MATHEMATICAL);
break;
default:
return;
}
break;
}
case SVGCSS_PROP_POINTER_EVENTS:
{
HANDLE_INHERIT_AND_INITIAL(pointerEvents, PointerEvents)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_ALL:
svgstyle->setPointerEvents(PE_ALL);
break;
case CSS_VAL_NONE:
svgstyle->setPointerEvents(PE_NONE);
break;
case SVGCSS_VAL_VISIBLEPAINTED:
svgstyle->setPointerEvents(PE_VISIBLE_PAINTED);
break;
case SVGCSS_VAL_VISIBLEFILL:
svgstyle->setPointerEvents(PE_VISIBLE_FILL);
break;
case SVGCSS_VAL_VISIBLESTROKE:
svgstyle->setPointerEvents(PE_VISIBLE_STROKE);
break;
case CSS_VAL_VISIBLE:
svgstyle->setPointerEvents(PE_VISIBLE);
break;
case SVGCSS_VAL_PAINTED:
svgstyle->setPointerEvents(PE_PAINTED);
break;
case SVGCSS_VAL_FILL:
svgstyle->setPointerEvents(PE_FILL);
break;
case SVGCSS_VAL_STROKE:
svgstyle->setPointerEvents(PE_STROKE);
default:
return;
}
break;
}
case SVGCSS_PROP_DOMINANT_BASELINE:
{
HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case CSS_VAL_AUTO:
svgstyle->setDominantBaseline(DB_AUTO);
break;
case SVGCSS_VAL_USE_SCRIPT:
svgstyle->setDominantBaseline(DB_USE_SCRIPT);
break;
case SVGCSS_VAL_NO_CHANGE:
svgstyle->setDominantBaseline(DB_NO_CHANGE);
break;
case SVGCSS_VAL_RESET_SIZE:
svgstyle->setDominantBaseline(DB_RESET_SIZE);
break;
case SVGCSS_VAL_IDEOGRAPHIC:
svgstyle->setDominantBaseline(DB_IDEOGRAPHIC);
break;
case SVGCSS_VAL_ALPHABETIC:
svgstyle->setDominantBaseline(DB_ALPHABETIC);
break;
case SVGCSS_VAL_HANGING:
svgstyle->setDominantBaseline(DB_HANGING);
break;
case SVGCSS_VAL_MATHEMATICAL:
svgstyle->setDominantBaseline(DB_MATHEMATICAL);
break;
case SVGCSS_VAL_CENTRAL:
svgstyle->setDominantBaseline(DB_CENTRAL);
break;
case CSS_VAL_MIDDLE:
svgstyle->setDominantBaseline(DB_MIDDLE);
break;
case SVGCSS_VAL_TEXT_AFTER_EDGE:
svgstyle->setDominantBaseline(DB_TEXT_AFTER_EDGE);
break;
case SVGCSS_VAL_TEXT_BEFORE_EDGE:
svgstyle->setDominantBaseline(DB_TEXT_BEFORE_EDGE);
break;
default:
return;
}
break;
}
case SVGCSS_PROP_COLOR_INTERPOLATION:
{
HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation)
if (!primitiveValue)
return;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_SRGB:
svgstyle->setColorInterpolation(CI_SRGB);
break;
case SVGCSS_VAL_LINEARRGB:
svgstyle->setColorInterpolation(CI_LINEARRGB);
break;
case CSS_VAL_AUTO:
svgstyle->setColorInterpolation(CI_AUTO);
default:
return;
}
break;
}
case SVGCSS_PROP_COLOR_INTERPOLATION_FILTERS:
{
HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
if (!primitiveValue)
return;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_SRGB:
svgstyle->setColorInterpolationFilters(CI_SRGB);
break;
case SVGCSS_VAL_LINEARRGB:
svgstyle->setColorInterpolationFilters(CI_LINEARRGB);
break;
case CSS_VAL_AUTO:
svgstyle->setColorInterpolationFilters(CI_AUTO);
default:
return;
}
break;
}
case SVGCSS_PROP_CLIP_RULE:
{
HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_NONZERO:
svgstyle->setClipRule(WR_NONZERO);
break;
case SVGCSS_VAL_EVENODD:
svgstyle->setClipRule(WR_EVENODD);
break;
default:
break;
}
break;
}
case SVGCSS_PROP_FILL_RULE:
{
HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_NONZERO:
svgstyle->setFillRule(WR_NONZERO);
break;
case SVGCSS_VAL_EVENODD:
svgstyle->setFillRule(WR_EVENODD);
default:
return;
}
break;
}
case SVGCSS_PROP_STROKE_LINEJOIN:
{
HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_MITER:
svgstyle->setJoinStyle(JS_MITER);
break;
case CSS_VAL_ROUND:
svgstyle->setJoinStyle(JS_ROUND);
break;
case SVGCSS_VAL_BEVEL:
svgstyle->setJoinStyle(JS_BEVEL);
default:
return;
}
break;
}
case SVGCSS_PROP_IMAGE_RENDERING:
{
HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering)
if (!primitiveValue)
return;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_OPTIMIZESPEED:
svgstyle->setImageRendering(IR_OPTIMIZESPEED);
default:
return;
}
break;
}
case SVGCSS_PROP_FILL:
{
HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
if (!primitiveValue && value) {
SVGPaint *paint = static_cast<SVGPaint*>(value);
if (paint)
svgstyle->setFillPaint(paint);
}
break;
}
case SVGCSS_PROP_STROKE:
{
HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
if (!primitiveValue && value) {
SVGPaint *paint = static_cast<SVGPaint*>(value);
if (paint)
svgstyle->setStrokePaint(paint);
}
break;
}
case SVGCSS_PROP_STROKE_WIDTH:
{
HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
if (!primitiveValue)
return;
svgstyle->setStrokeWidth(primitiveValue);
break;
}
case SVGCSS_PROP_STROKE_DASHARRAY:
{
HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
if (!primitiveValue && value) {
CSSValueList* dashes = static_cast<CSSValueList*>(value);
if (dashes)
svgstyle->setStrokeDashArray(dashes);
}
break;
}
case SVGCSS_PROP_STROKE_DASHOFFSET:
{
HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
if (!primitiveValue)
return;
svgstyle->setStrokeDashOffset(primitiveValue);
break;
}
case SVGCSS_PROP_FILL_OPACITY:
{
HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
if (!primitiveValue)
return;
float f = 0.0;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
f = primitiveValue->getFloatValue() / 100.;
else if (type == CSSPrimitiveValue::CSS_NUMBER)
f = primitiveValue->getFloatValue();
else
return;
svgstyle->setFillOpacity(f);
break;
}
case SVGCSS_PROP_STROKE_OPACITY:
{
HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
if (!primitiveValue)
return;
float f = 0.0;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
f = primitiveValue->getFloatValue() / 100.;
else if (type == CSSPrimitiveValue::CSS_NUMBER)
f = primitiveValue->getFloatValue();
else
return;
svgstyle->setStrokeOpacity(f);
break;
}
case SVGCSS_PROP_STOP_OPACITY:
{
HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
if (!primitiveValue)
return;
float f = 0.0;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
f = primitiveValue->getFloatValue() / 100.;
else if (type == CSSPrimitiveValue::CSS_NUMBER)
f = primitiveValue->getFloatValue();
else
return;
svgstyle->setStopOpacity(f);
break;
}
case SVGCSS_PROP_MARKER_START:
{
HANDLE_INHERIT_AND_INITIAL(startMarker, StartMarker)
if (!primitiveValue)
return;
DeprecatedString s;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_URI)
s = primitiveValue->getStringValue().deprecatedString();
else
return;
svgstyle->setStartMarker(s);
break;
}
case SVGCSS_PROP_MARKER_MID:
{
HANDLE_INHERIT_AND_INITIAL(midMarker, MidMarker)
if (!primitiveValue)
return;
DeprecatedString s;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_URI)
s = primitiveValue->getStringValue().deprecatedString();
else
return;
svgstyle->setMidMarker(s);
break;
}
case SVGCSS_PROP_MARKER_END:
{
HANDLE_INHERIT_AND_INITIAL(endMarker, EndMarker)
if (!primitiveValue)
return;
DeprecatedString s;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_URI)
s = primitiveValue->getStringValue().deprecatedString();
else
return;
svgstyle->setEndMarker(s);
break;
}
case SVGCSS_PROP_STROKE_LINECAP:
{
HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case SVGCSS_VAL_BUTT:
svgstyle->setCapStyle(CS_BUTT);
break;
case CSS_VAL_ROUND:
svgstyle->setCapStyle(CS_ROUND);
break;
case CSS_VAL_SQUARE:
svgstyle->setCapStyle(CS_SQUARE);
default:
return;
}
break;
}
case SVGCSS_PROP_STROKE_MITERLIMIT:
{
HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
if (!primitiveValue)
return;
float f = 0.0;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_NUMBER)
f = primitiveValue->getFloatValue();
else
return;
svgstyle->setStrokeMiterLimit(lroundf(f));
break;
}
case SVGCSS_PROP_FILTER:
{
HANDLE_INHERIT_AND_INITIAL(filter, Filter)
if (!primitiveValue)
return;
DeprecatedString s;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_URI)
s = primitiveValue->getStringValue().deprecatedString();
else
return;
svgstyle->setFilter(s);
break;
}
case SVGCSS_PROP_MASK:
{
HANDLE_INHERIT_AND_INITIAL(maskElement, MaskElement)
if (!primitiveValue)
return;
DeprecatedString s;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_URI)
s = primitiveValue->getStringValue().deprecatedString();
else
return;
svgstyle->setMaskElement(s);
break;
}
case SVGCSS_PROP_CLIP_PATH:
{
HANDLE_INHERIT_AND_INITIAL(clipPath, ClipPath)
if (!primitiveValue)
return;
DeprecatedString s;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_URI)
s = primitiveValue->getStringValue().deprecatedString();
else
return;
svgstyle->setClipPath(s);
break;
}
case SVGCSS_PROP_TEXT_ANCHOR:
{
HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
if (!primitiveValue)
break;
switch (primitiveValue->getIdent())
{
case CSS_VAL_START:
svgstyle->setTextAnchor(TA_START);
break;
case CSS_VAL_MIDDLE:
svgstyle->setTextAnchor(TA_MIDDLE);
break;
case CSS_VAL_END:
svgstyle->setTextAnchor(TA_END);
default:
return;
}
break;
}
case SVGCSS_PROP_WRITING_MODE:
{
HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
if (primitiveValue)
svgstyle->setWritingMode((EWritingMode)(primitiveValue->getIdent() - SVGCSS_VAL_LR_TB));
break;
}
#if 0
case CSS_PROP_COLOR: {
Color col;
if (isInherit) {
HANDLE_INHERIT_COND(CSS_PROP_COLOR, color, Color)
return;
} else if (isInitial)
col = RenderStyle::initialColor();
else {
SVGColor *c = static_cast<SVGColor*>(value);
if (!c)
return CSSStyleSelector::applyProperty(id, value);
col = c->color();
}
svgstyle->setColor(col);
break;
}
#endif
case SVGCSS_PROP_STOP_COLOR:
{
Color col;
if (isInherit) {
style->setColor(parentStyle->color());
return;
} else if (isInitial)
col = SVGRenderStyle::initialStopColor();
else {
SVGColor *c = static_cast<SVGColor*>(value);
if (!c)
return CSSStyleSelector::applyProperty(id, value);
if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
col = style->color();
else
col = c->color();
}
svgstyle->setStopColor(col);
break;
}
case SVGCSS_PROP_FLOOD_OPACITY:
{
HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
if (!primitiveValue)
return;
float f = 0.0;
int type = primitiveValue->primitiveType();
if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
f = primitiveValue->getFloatValue() / 100.;
else if (type == CSSPrimitiveValue::CSS_NUMBER)
f = primitiveValue->getFloatValue();
else
return;
svgstyle->setFloodOpacity(f);
break;
}
case SVGCSS_PROP_FLOOD_COLOR:
{
Color col;
if (isInitial)
col = SVGRenderStyle::initialStopColor();
else {
SVGColor *c = static_cast<SVGColor*>(value);
if (!c)
return CSSStyleSelector::applyProperty(id, value);
if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
col = style->color();
else
col = c->color();
}
svgstyle->setFloodColor(col);
break;
}
default:
return;
}
}
}
#endif // SVG_SUPPORT