123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618 |
- /*
- Copyright (C) 2005 Apple Computer, Inc.
- Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 2004, 2005, 2008 Rob Buis <buis@kde.org>
- Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
- Based on khtml css code by:
- Copyright(C) 1999-2003 Lars Knoll(knoll@kde.org)
- (C) 2003 Apple Computer, Inc.
- (C) 2004 Allan Sandfeld Jensen(kde@carewolf.com)
- (C) 2004 Germain Garand(germain@ebooksfrance.org)
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Library General Public
- License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
- This library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Library General Public License for more details.
- You should have received a copy of the GNU Library General Public License
- along with this library; see the file COPYING.LIB. If not, write to
- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- Boston, MA 02110-1301, USA.
- */
- #include "config.h"
- #if ENABLE(SVG)
- #include "StyleResolver.h"
- #include "CSSPrimitiveValueMappings.h"
- #include "CSSPropertyNames.h"
- #include "CSSValueList.h"
- #include "Document.h"
- #include "ShadowValue.h"
- #include "SVGColor.h"
- #include "SVGNames.h"
- #include "SVGPaint.h"
- #include "SVGRenderStyle.h"
- #include "SVGRenderStyleDefs.h"
- #include "SVGStyledElement.h"
- #include "SVGURIReference.h"
- #include <stdlib.h>
- #include <wtf/MathExtras.h>
- #define HANDLE_INHERIT(prop, Prop) \
- if (isInherit) \
- { \
- svgstyle->set##Prop(state.parentStyle()->svgStyle()->prop()); \
- return; \
- }
- #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
- HANDLE_INHERIT(prop, Prop) \
- if (isInitial) { \
- svgstyle->set##Prop(SVGRenderStyle::initial##Prop()); \
- return; \
- }
- namespace WebCore {
- static float roundToNearestGlyphOrientationAngle(float angle)
- {
- angle = fabsf(fmodf(angle, 360.0f));
- if (angle <= 45.0f || angle > 315.0f)
- return 0.0f;
- else if (angle > 45.0f && angle <= 135.0f)
- return 90.0f;
- else if (angle > 135.0f && angle <= 225.0f)
- return 180.0f;
- return 270.0f;
- }
- static int angleToGlyphOrientation(float angle)
- {
- angle = roundToNearestGlyphOrientationAngle(angle);
- if (angle == 0.0f)
- return GO_0DEG;
- else if (angle == 90.0f)
- return GO_90DEG;
- else if (angle == 180.0f)
- return GO_180DEG;
- else if (angle == 270.0f)
- return GO_270DEG;
- return -1;
- }
- static Color colorFromSVGColorCSSValue(SVGColor* svgColor, const Color& fgColor)
- {
- Color color;
- if (svgColor->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
- color = fgColor;
- else
- color = svgColor->color();
- return color;
- }
- void StyleResolver::applySVGProperty(CSSPropertyID id, CSSValue* value)
- {
- ASSERT(value);
- CSSPrimitiveValue* primitiveValue = 0;
- if (value->isPrimitiveValue())
- primitiveValue = static_cast<CSSPrimitiveValue*>(value);
- const State& state = m_state;
- SVGRenderStyle* svgstyle = state.style()->accessSVGStyle();
- bool isInherit = state.parentNode() && value->isInheritedValue();
- bool isInitial = value->isInitialValue() || (!state.parentNode() && value->isInheritedValue());
- // What follows is a list that maps the CSS properties into their
- // corresponding front-end RenderStyle values. Shorthands(e.g. border,
- // background) occur in this list as well and are only hit when mapping
- // "inherit" or "initial" into front-end values.
- switch (id)
- {
- // ident only properties
- case CSSPropertyAlignmentBaseline:
- {
- HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
- if (!primitiveValue)
- break;
- svgstyle->setAlignmentBaseline(*primitiveValue);
- break;
- }
- case CSSPropertyBaselineShift:
- {
- HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
- if (!primitiveValue)
- break;
- if (primitiveValue->getIdent()) {
- switch (primitiveValue->getIdent()) {
- case CSSValueBaseline:
- svgstyle->setBaselineShift(BS_BASELINE);
- break;
- case CSSValueSub:
- svgstyle->setBaselineShift(BS_SUB);
- break;
- case CSSValueSuper:
- svgstyle->setBaselineShift(BS_SUPER);
- break;
- default:
- break;
- }
- } else {
- svgstyle->setBaselineShift(BS_LENGTH);
- svgstyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
- }
- break;
- }
- case CSSPropertyKerning:
- {
- HANDLE_INHERIT_AND_INITIAL(kerning, Kerning);
- if (primitiveValue)
- svgstyle->setKerning(SVGLength::fromCSSPrimitiveValue(primitiveValue));
- break;
- }
- case CSSPropertyDominantBaseline:
- {
- HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
- if (primitiveValue)
- svgstyle->setDominantBaseline(*primitiveValue);
- break;
- }
- case CSSPropertyColorInterpolation:
- {
- HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation)
- if (primitiveValue)
- svgstyle->setColorInterpolation(*primitiveValue);
- break;
- }
- case CSSPropertyColorInterpolationFilters:
- {
- HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
- if (primitiveValue)
- svgstyle->setColorInterpolationFilters(*primitiveValue);
- break;
- }
- case CSSPropertyColorProfile:
- {
- // Not implemented.
- break;
- }
- case CSSPropertyColorRendering:
- {
- HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering)
- if (primitiveValue)
- svgstyle->setColorRendering(*primitiveValue);
- break;
- }
- case CSSPropertyClipRule:
- {
- HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
- if (primitiveValue)
- svgstyle->setClipRule(*primitiveValue);
- break;
- }
- case CSSPropertyFillRule:
- {
- HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
- if (primitiveValue)
- svgstyle->setFillRule(*primitiveValue);
- break;
- }
- case CSSPropertyStrokeLinejoin:
- {
- HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
- if (primitiveValue)
- svgstyle->setJoinStyle(*primitiveValue);
- break;
- }
- case CSSPropertyShapeRendering:
- {
- HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering)
- if (primitiveValue)
- svgstyle->setShapeRendering(*primitiveValue);
- break;
- }
- // end of ident only properties
- case CSSPropertyFill:
- {
- if (isInherit) {
- const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle();
- svgstyle->setFillPaint(svgParentStyle->fillPaintType(), svgParentStyle->fillPaintColor(), svgParentStyle->fillPaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle());
- return;
- }
- if (isInitial) {
- svgstyle->setFillPaint(SVGRenderStyle::initialFillPaintType(), SVGRenderStyle::initialFillPaintColor(), SVGRenderStyle::initialFillPaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle());
- return;
- }
- if (value->isSVGPaint()) {
- SVGPaint* svgPaint = static_cast<SVGPaint*>(value);
- svgstyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle());
- }
- break;
- }
- case CSSPropertyStroke:
- {
- if (isInherit) {
- const SVGRenderStyle* svgParentStyle = state.parentStyle()->svgStyle();
- svgstyle->setStrokePaint(svgParentStyle->strokePaintType(), svgParentStyle->strokePaintColor(), svgParentStyle->strokePaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle());
- return;
- }
- if (isInitial) {
- svgstyle->setStrokePaint(SVGRenderStyle::initialStrokePaintType(), SVGRenderStyle::initialStrokePaintColor(), SVGRenderStyle::initialStrokePaintUri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle());
- return;
- }
- if (value->isSVGPaint()) {
- SVGPaint* svgPaint = static_cast<SVGPaint*>(value);
- svgstyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), applyPropertyToRegularStyle(), applyPropertyToVisitedLinkStyle());
- }
- break;
- }
- case CSSPropertyStrokeWidth:
- {
- HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
- if (primitiveValue)
- svgstyle->setStrokeWidth(SVGLength::fromCSSPrimitiveValue(primitiveValue));
- break;
- }
- case CSSPropertyStrokeDasharray:
- {
- HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
- if (!value->isValueList()) {
- svgstyle->setStrokeDashArray(SVGRenderStyle::initialStrokeDashArray());
- break;
- }
- CSSValueList* dashes = static_cast<CSSValueList*>(value);
- Vector<SVGLength> array;
- size_t length = dashes->length();
- for (size_t i = 0; i < length; ++i) {
- CSSValue* currValue = dashes->itemWithoutBoundsCheck(i);
- if (!currValue->isPrimitiveValue())
- continue;
- CSSPrimitiveValue* dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i));
- array.append(SVGLength::fromCSSPrimitiveValue(dash));
- }
- svgstyle->setStrokeDashArray(array);
- break;
- }
- case CSSPropertyStrokeDashoffset:
- {
- HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
- if (primitiveValue)
- svgstyle->setStrokeDashOffset(SVGLength::fromCSSPrimitiveValue(primitiveValue));
- break;
- }
- case CSSPropertyFillOpacity:
- {
- HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
- if (!primitiveValue)
- return;
- float f = 0.0f;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- f = primitiveValue->getFloatValue() / 100.0f;
- else if (type == CSSPrimitiveValue::CSS_NUMBER)
- f = primitiveValue->getFloatValue();
- else
- return;
- svgstyle->setFillOpacity(f);
- break;
- }
- case CSSPropertyStrokeOpacity:
- {
- HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
- if (!primitiveValue)
- return;
- float f = 0.0f;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- f = primitiveValue->getFloatValue() / 100.0f;
- else if (type == CSSPrimitiveValue::CSS_NUMBER)
- f = primitiveValue->getFloatValue();
- else
- return;
- svgstyle->setStrokeOpacity(f);
- break;
- }
- case CSSPropertyStopOpacity:
- {
- HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
- if (!primitiveValue)
- return;
- float f = 0.0f;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- f = primitiveValue->getFloatValue() / 100.0f;
- else if (type == CSSPrimitiveValue::CSS_NUMBER)
- f = primitiveValue->getFloatValue();
- else
- return;
- svgstyle->setStopOpacity(f);
- break;
- }
- case CSSPropertyMarkerStart:
- {
- HANDLE_INHERIT_AND_INITIAL(markerStartResource, MarkerStartResource)
- if (!primitiveValue)
- return;
- String s;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_URI)
- s = primitiveValue->getStringValue();
- svgstyle->setMarkerStartResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document()));
- break;
- }
- case CSSPropertyMarkerMid:
- {
- HANDLE_INHERIT_AND_INITIAL(markerMidResource, MarkerMidResource)
- if (!primitiveValue)
- return;
- String s;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_URI)
- s = primitiveValue->getStringValue();
- svgstyle->setMarkerMidResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document()));
- break;
- }
- case CSSPropertyMarkerEnd:
- {
- HANDLE_INHERIT_AND_INITIAL(markerEndResource, MarkerEndResource)
- if (!primitiveValue)
- return;
- String s;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_URI)
- s = primitiveValue->getStringValue();
- svgstyle->setMarkerEndResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document()));
- break;
- }
- case CSSPropertyStrokeLinecap:
- {
- HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
- if (primitiveValue)
- svgstyle->setCapStyle(*primitiveValue);
- break;
- }
- case CSSPropertyStrokeMiterlimit:
- {
- HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
- if (!primitiveValue)
- return;
- float f = 0.0f;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_NUMBER)
- f = primitiveValue->getFloatValue();
- else
- return;
- svgstyle->setStrokeMiterLimit(f);
- break;
- }
- case CSSPropertyFilter:
- {
- HANDLE_INHERIT_AND_INITIAL(filterResource, FilterResource)
- if (!primitiveValue)
- return;
- String s;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_URI)
- s = primitiveValue->getStringValue();
- svgstyle->setFilterResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document()));
- break;
- }
- case CSSPropertyMask:
- {
- HANDLE_INHERIT_AND_INITIAL(maskerResource, MaskerResource)
- if (!primitiveValue)
- return;
- String s;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_URI)
- s = primitiveValue->getStringValue();
- svgstyle->setMaskerResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document()));
- break;
- }
- case CSSPropertyClipPath:
- {
- HANDLE_INHERIT_AND_INITIAL(clipperResource, ClipperResource)
- if (!primitiveValue)
- return;
- String s;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_URI)
- s = primitiveValue->getStringValue();
- svgstyle->setClipperResource(SVGURIReference::fragmentIdentifierFromIRIString(s, state.document()));
- break;
- }
- case CSSPropertyTextAnchor:
- {
- HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
- if (primitiveValue)
- svgstyle->setTextAnchor(*primitiveValue);
- break;
- }
- case CSSPropertyWritingMode:
- {
- HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
- if (primitiveValue)
- svgstyle->setWritingMode(*primitiveValue);
- break;
- }
- case CSSPropertyStopColor:
- {
- HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
- if (value->isSVGColor())
- svgstyle->setStopColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color()));
- break;
- }
- case CSSPropertyLightingColor:
- {
- HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
- if (value->isSVGColor())
- svgstyle->setLightingColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color()));
- break;
- }
- case CSSPropertyFloodOpacity:
- {
- HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
- if (!primitiveValue)
- return;
- float f = 0.0f;
- int type = primitiveValue->primitiveType();
- if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
- f = primitiveValue->getFloatValue() / 100.0f;
- else if (type == CSSPrimitiveValue::CSS_NUMBER)
- f = primitiveValue->getFloatValue();
- else
- return;
- svgstyle->setFloodOpacity(f);
- break;
- }
- case CSSPropertyFloodColor:
- {
- HANDLE_INHERIT_AND_INITIAL(floodColor, FloodColor);
- if (value->isSVGColor())
- svgstyle->setFloodColor(colorFromSVGColorCSSValue(static_cast<SVGColor*>(value), state.style()->color()));
- break;
- }
- case CSSPropertyGlyphOrientationHorizontal:
- {
- HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
- if (!primitiveValue)
- return;
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
- int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
- ASSERT(orientation != -1);
- svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation);
- }
- break;
- }
- case CSSPropertyGlyphOrientationVertical:
- {
- HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
- if (!primitiveValue)
- return;
- if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
- int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
- ASSERT(orientation != -1);
- svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation);
- } else if (primitiveValue->getIdent() == CSSValueAuto)
- svgstyle->setGlyphOrientationVertical(GO_AUTO);
- break;
- }
- case CSSPropertyEnableBackground:
- // Silently ignoring this property for now
- // http://bugs.webkit.org/show_bug.cgi?id=6022
- break;
- case CSSPropertyWebkitSvgShadow: {
- if (isInherit)
- return svgstyle->setShadow(adoptPtr(state.parentStyle()->svgStyle()->shadow() ? new ShadowData(*state.parentStyle()->svgStyle()->shadow()) : 0));
- if (isInitial || primitiveValue) // initial | none
- return svgstyle->setShadow(nullptr);
- if (!value->isValueList())
- return;
- CSSValueList *list = static_cast<CSSValueList*>(value);
- if (!list->length())
- return;
- CSSValue* firstValue = list->itemWithoutBoundsCheck(0);
- if (!firstValue->isShadowValue())
- return;
- ShadowValue* item = static_cast<ShadowValue*>(firstValue);
- IntPoint location(item->x->computeLength<int>(state.style(), state.rootElementStyle()),
- item->y->computeLength<int>(state.style(), state.rootElementStyle()));
- int blur = item->blur ? item->blur->computeLength<int>(state.style(), state.rootElementStyle()) : 0;
- Color color;
- if (item->color)
- color = colorFromPrimitiveValue(item->color.get());
- // -webkit-svg-shadow does should not have a spread or style
- ASSERT(!item->spread);
- ASSERT(!item->style);
- OwnPtr<ShadowData> shadowData = adoptPtr(new ShadowData(location, blur, 0, Normal, false, color.isValid() ? color : Color::transparent));
- svgstyle->setShadow(shadowData.release());
- return;
- }
- case CSSPropertyVectorEffect: {
- HANDLE_INHERIT_AND_INITIAL(vectorEffect, VectorEffect)
- if (!primitiveValue)
- break;
- svgstyle->setVectorEffect(*primitiveValue);
- break;
- }
- case CSSPropertyBufferedRendering: {
- HANDLE_INHERIT_AND_INITIAL(bufferedRendering, BufferedRendering)
- if (!primitiveValue)
- break;
- svgstyle->setBufferedRendering(*primitiveValue);
- break;
- }
- case CSSPropertyMaskType: {
- HANDLE_INHERIT_AND_INITIAL(maskType, MaskType)
- if (!primitiveValue)
- break;
- svgstyle->setMaskType(*primitiveValue);
- break;
- }
- default:
- // If you crash here, it's because you added a css property and are not handling it
- // in either this switch statement or the one in StyleResolver::applyProperty
- ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id);
- return;
- }
- }
- }
- #endif
|