/* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org> 2004, 2005 Rob Buis <buis@kde.org> Copyright (C) 2005, 2006 Apple Computer, Inc. Copyright (C) Research In Motion Limited 2010. All rights reserved. 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. */ #ifndef SVGRenderStyle_h #define SVGRenderStyle_h #if ENABLE(SVG) #include "CSSValueList.h" #include "DataRef.h" #include "GraphicsTypes.h" #include "Path.h" #include "RenderStyleConstants.h" #include "SVGPaint.h" #include "SVGRenderStyleDefs.h" namespace WebCore { class FloatRect; class IntRect; class RenderObject; class SVGRenderStyle : public RefCounted<SVGRenderStyle> { public: static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); } PassRefPtr<SVGRenderStyle> copy() const { return adoptRef(new SVGRenderStyle(*this));} ~SVGRenderStyle(); bool inheritedNotEqual(const SVGRenderStyle*) const; void inheritFrom(const SVGRenderStyle*); StyleDifference diff(const SVGRenderStyle*) const; bool operator==(const SVGRenderStyle&) const; bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); } // Initial values for all the properties static EAlignmentBaseline initialAlignmentBaseline() { return AB_AUTO; } static EDominantBaseline initialDominantBaseline() { return DB_AUTO; } static EBaselineShift initialBaselineShift() { return BS_BASELINE; } static EVectorEffect initialVectorEffect() { return VE_NONE; } static LineCap initialCapStyle() { return ButtCap; } static WindRule initialClipRule() { return RULE_NONZERO; } static EColorInterpolation initialColorInterpolation() { return CI_SRGB; } static EColorInterpolation initialColorInterpolationFilters() { return CI_LINEARRGB; } static EColorRendering initialColorRendering() { return CR_AUTO; } static WindRule initialFillRule() { return RULE_NONZERO; } static EImageRendering initialImageRendering() { return IR_AUTO; } static LineJoin initialJoinStyle() { return MiterJoin; } static EShapeRendering initialShapeRendering() { return SR_AUTO; } static ETextAnchor initialTextAnchor() { return TA_START; } static SVGWritingMode initialWritingMode() { return WM_LRTB; } static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; } static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; } static float initialFillOpacity() { return 1.0f; } static SVGPaint* initialFillPaint() { return SVGPaint::defaultFill(); } static float initialStrokeOpacity() { return 1.0f; } static SVGPaint* initialStrokePaint() { return SVGPaint::defaultStroke(); } static Vector<SVGLength> initialStrokeDashArray() { return Vector<SVGLength>(); } static float initialStrokeMiterLimit() { return 4.0f; } static float initialStopOpacity() { return 1.0f; } static Color initialStopColor() { return Color(0, 0, 0); } static float initialFloodOpacity() { return 1.0f; } static Color initialFloodColor() { return Color(0, 0, 0); } static Color initialLightingColor() { return Color(255, 255, 255); } static ShadowData* initialShadow() { return 0; } static String initialClipperResource() { return String(); } static String initialFilterResource() { return String(); } static String initialMaskerResource() { return String(); } static String initialMarkerStartResource() { return String(); } static String initialMarkerMidResource() { return String(); } static String initialMarkerEndResource() { return String(); } static SVGLength initialBaselineShiftValue() { SVGLength length; ExceptionCode ec = 0; length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec); ASSERT(!ec); return length; } static SVGLength initialKerning() { SVGLength length; ExceptionCode ec = 0; length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec); ASSERT(!ec); return length; } static SVGLength initialStrokeDashOffset() { SVGLength length; ExceptionCode ec = 0; length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec); ASSERT(!ec); return length; } static SVGLength initialStrokeWidth() { SVGLength length; ExceptionCode ec = 0; length.newValueSpecifiedUnits(LengthTypeNumber, 1, ec); ASSERT(!ec); return length; } // SVG CSS Property setters void setAlignmentBaseline(EAlignmentBaseline val) { svg_noninherited_flags.f._alignmentBaseline = val; } void setDominantBaseline(EDominantBaseline val) { svg_noninherited_flags.f._dominantBaseline = val; } void setBaselineShift(EBaselineShift val) { svg_noninherited_flags.f._baselineShift = val; } void setVectorEffect(EVectorEffect val) { svg_noninherited_flags.f._vectorEffect = val; } void setCapStyle(LineCap val) { svg_inherited_flags._capStyle = val; } void setClipRule(WindRule val) { svg_inherited_flags._clipRule = val; } void setColorInterpolation(EColorInterpolation val) { svg_inherited_flags._colorInterpolation = val; } void setColorInterpolationFilters(EColorInterpolation val) { svg_inherited_flags._colorInterpolationFilters = val; } void setColorRendering(EColorRendering val) { svg_inherited_flags._colorRendering = val; } void setFillRule(WindRule val) { svg_inherited_flags._fillRule = val; } void setImageRendering(EImageRendering val) { svg_inherited_flags._imageRendering = val; } void setJoinStyle(LineJoin val) { svg_inherited_flags._joinStyle = val; } void setShapeRendering(EShapeRendering val) { svg_inherited_flags._shapeRendering = val; } void setTextAnchor(ETextAnchor val) { svg_inherited_flags._textAnchor = val; } void setWritingMode(SVGWritingMode val) { svg_inherited_flags._writingMode = val; } void setGlyphOrientationHorizontal(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationHorizontal = val; } void setGlyphOrientationVertical(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationVertical = val; } void setFillOpacity(float obj) { if (!(fill->opacity == obj)) fill.access()->opacity = obj; } void setFillPaint(PassRefPtr<SVGPaint> obj) { if (!(fill->paint == obj)) fill.access()->paint = obj; } void setStrokeOpacity(float obj) { if (!(stroke->opacity == obj)) stroke.access()->opacity = obj; } void setStrokePaint(PassRefPtr<SVGPaint> obj) { if (!(stroke->paint == obj)) stroke.access()->paint = obj; } void setStrokeDashArray(const Vector<SVGLength>& obj) { if (!(stroke->dashArray == obj)) stroke.access()->dashArray = obj; } void setStrokeMiterLimit(float obj) { if (!(stroke->miterLimit == obj)) stroke.access()->miterLimit = obj; } void setStrokeWidth(const SVGLength& obj) { if (!(stroke->width == obj)) stroke.access()->width = obj; } void setStrokeDashOffset(const SVGLength& obj) { if (!(stroke->dashOffset == obj)) stroke.access()->dashOffset = obj; } void setKerning(const SVGLength& obj) { if (!(text->kerning == obj)) text.access()->kerning = obj; } void setStopOpacity(float obj) { if (!(stops->opacity == obj)) stops.access()->opacity = obj; } void setStopColor(const Color& obj) { if (!(stops->color == obj)) stops.access()->color = obj; } void setFloodOpacity(float obj) { if (!(misc->floodOpacity == obj)) misc.access()->floodOpacity = obj; } void setFloodColor(const Color& obj) { if (!(misc->floodColor == obj)) misc.access()->floodColor = obj; } void setLightingColor(const Color& obj) { if (!(misc->lightingColor == obj)) misc.access()->lightingColor = obj; } void setBaselineShiftValue(const SVGLength& obj) { if (!(misc->baselineShiftValue == obj)) misc.access()->baselineShiftValue = obj; } void setShadow(PassOwnPtr<ShadowData> obj) { shadowSVG.access()->shadow = obj; } // Setters for non-inherited resources void setClipperResource(const String& obj) { if (!(resources->clipper == obj)) resources.access()->clipper = obj; } void setFilterResource(const String& obj) { if (!(resources->filter == obj)) resources.access()->filter = obj; } void setMaskerResource(const String& obj) { if (!(resources->masker == obj)) resources.access()->masker = obj; } // Setters for inherited resources void setMarkerStartResource(const String& obj) { if (!(inheritedResources->markerStart == obj)) inheritedResources.access()->markerStart = obj; } void setMarkerMidResource(const String& obj) { if (!(inheritedResources->markerMid == obj)) inheritedResources.access()->markerMid = obj; } void setMarkerEndResource(const String& obj) { if (!(inheritedResources->markerEnd == obj)) inheritedResources.access()->markerEnd = obj; } // Read accessors for all the properties EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) svg_noninherited_flags.f._alignmentBaseline; } EDominantBaseline dominantBaseline() const { return (EDominantBaseline) svg_noninherited_flags.f._dominantBaseline; } EBaselineShift baselineShift() const { return (EBaselineShift) svg_noninherited_flags.f._baselineShift; } EVectorEffect vectorEffect() const { return (EVectorEffect) svg_noninherited_flags.f._vectorEffect; } LineCap capStyle() const { return (LineCap) svg_inherited_flags._capStyle; } WindRule clipRule() const { return (WindRule) svg_inherited_flags._clipRule; } EColorInterpolation colorInterpolation() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolation; } EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolationFilters; } EColorRendering colorRendering() const { return (EColorRendering) svg_inherited_flags._colorRendering; } WindRule fillRule() const { return (WindRule) svg_inherited_flags._fillRule; } EImageRendering imageRendering() const { return (EImageRendering) svg_inherited_flags._imageRendering; } LineJoin joinStyle() const { return (LineJoin) svg_inherited_flags._joinStyle; } EShapeRendering shapeRendering() const { return (EShapeRendering) svg_inherited_flags._shapeRendering; } ETextAnchor textAnchor() const { return (ETextAnchor) svg_inherited_flags._textAnchor; } SVGWritingMode writingMode() const { return (SVGWritingMode) svg_inherited_flags._writingMode; } EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; } EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; } float fillOpacity() const { return fill->opacity; } SVGPaint* fillPaint() const { return fill->paint.get(); } float strokeOpacity() const { return stroke->opacity; } SVGPaint* strokePaint() const { return stroke->paint.get(); } Vector<SVGLength> strokeDashArray() const { return stroke->dashArray; } float strokeMiterLimit() const { return stroke->miterLimit; } SVGLength strokeWidth() const { return stroke->width; } SVGLength strokeDashOffset() const { return stroke->dashOffset; } SVGLength kerning() const { return text->kerning; } float stopOpacity() const { return stops->opacity; } Color stopColor() const { return stops->color; } float floodOpacity() const { return misc->floodOpacity; } Color floodColor() const { return misc->floodColor; } Color lightingColor() const { return misc->lightingColor; } SVGLength baselineShiftValue() const { return misc->baselineShiftValue; } ShadowData* shadow() const { return shadowSVG->shadow.get(); } String clipperResource() const { return resources->clipper; } String filterResource() const { return resources->filter; } String maskerResource() const { return resources->masker; } String markerStartResource() const { return inheritedResources->markerStart; } String markerMidResource() const { return inheritedResources->markerMid; } String markerEndResource() const { return inheritedResources->markerEnd; } // convenience bool hasClipper() const { return !clipperResource().isEmpty(); } bool hasMasker() const { return !maskerResource().isEmpty(); } bool hasFilter() const { return !filterResource().isEmpty(); } bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); } bool hasStroke() const { return strokePaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; } bool hasFill() const { return fillPaint()->paintType() != SVGPaint::SVG_PAINTTYPE_NONE; } bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; } protected: // inherit struct InheritedFlags { bool operator==(const InheritedFlags& other) const { return (_colorRendering == other._colorRendering) && (_imageRendering == other._imageRendering) && (_shapeRendering == other._shapeRendering) && (_clipRule == other._clipRule) && (_fillRule == other._fillRule) && (_capStyle == other._capStyle) && (_joinStyle == other._joinStyle) && (_textAnchor == other._textAnchor) && (_colorInterpolation == other._colorInterpolation) && (_colorInterpolationFilters == other._colorInterpolationFilters) && (_writingMode == other._writingMode) && (_glyphOrientationHorizontal == other._glyphOrientationHorizontal) && (_glyphOrientationVertical == other._glyphOrientationVertical); } bool operator!=(const InheritedFlags& other) const { return !(*this == other); } unsigned _colorRendering : 2; // EColorRendering unsigned _imageRendering : 2; // EImageRendering unsigned _shapeRendering : 2; // EShapeRendering unsigned _clipRule : 1; // WindRule unsigned _fillRule : 1; // WindRule unsigned _capStyle : 2; // LineCap unsigned _joinStyle : 2; // LineJoin unsigned _textAnchor : 2; // ETextAnchor unsigned _colorInterpolation : 2; // EColorInterpolation unsigned _colorInterpolationFilters : 2; // EColorInterpolation unsigned _writingMode : 3; // SVGWritingMode unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation unsigned _glyphOrientationVertical : 3; // EGlyphOrientation } svg_inherited_flags; // don't inherit struct NonInheritedFlags { // 32 bit non-inherited, don't add to the struct, or the operator will break. bool operator==(const NonInheritedFlags &other) const { return _niflags == other._niflags; } bool operator!=(const NonInheritedFlags &other) const { return _niflags != other._niflags; } union { struct { unsigned _alignmentBaseline : 4; // EAlignmentBaseline unsigned _dominantBaseline : 4; // EDominantBaseline unsigned _baselineShift : 2; // EBaselineShift unsigned _vectorEffect: 1; // EVectorEffect // 21 bits unused } f; uint32_t _niflags; }; } svg_noninherited_flags; // inherited attributes DataRef<StyleFillData> fill; DataRef<StyleStrokeData> stroke; DataRef<StyleTextData> text; DataRef<StyleInheritedResourceData> inheritedResources; // non-inherited attributes DataRef<StyleStopData> stops; DataRef<StyleMiscData> misc; DataRef<StyleShadowSVGData> shadowSVG; DataRef<StyleResourceData> resources; private: enum CreateDefaultType { CreateDefault }; SVGRenderStyle(); SVGRenderStyle(const SVGRenderStyle&); SVGRenderStyle(CreateDefaultType); // Used to create the default style. void setBitDefaults() { svg_inherited_flags._clipRule = initialClipRule(); svg_inherited_flags._colorRendering = initialColorRendering(); svg_inherited_flags._fillRule = initialFillRule(); svg_inherited_flags._imageRendering = initialImageRendering(); svg_inherited_flags._shapeRendering = initialShapeRendering(); svg_inherited_flags._textAnchor = initialTextAnchor(); svg_inherited_flags._capStyle = initialCapStyle(); svg_inherited_flags._joinStyle = initialJoinStyle(); svg_inherited_flags._colorInterpolation = initialColorInterpolation(); svg_inherited_flags._colorInterpolationFilters = initialColorInterpolationFilters(); svg_inherited_flags._writingMode = initialWritingMode(); svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal(); svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical(); svg_noninherited_flags._niflags = 0; svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline(); svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline(); svg_noninherited_flags.f._baselineShift = initialBaselineShift(); svg_noninherited_flags.f._vectorEffect = initialVectorEffect(); } }; } // namespace WebCore #endif // ENABLE(SVG) #endif // SVGRenderStyle_h