Home | History | Annotate | Download | only in style
      1 /*
      2     Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org>
      3                   2004, 2005 Rob Buis <buis (at) kde.org>
      4     Copyright (C) 2005, 2006 Apple Computer, Inc.
      5     Copyright (C) Research In Motion Limited 2010. All rights reserved.
      6 
      7     This library is free software; you can redistribute it and/or
      8     modify it under the terms of the GNU Library General Public
      9     License as published by the Free Software Foundation; either
     10     version 2 of the License, or (at your option) any later version.
     11 
     12     This library is distributed in the hope that it will be useful,
     13     but WITHOUT ANY WARRANTY; without even the implied warranty of
     14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     15     Library General Public License for more details.
     16 
     17     You should have received a copy of the GNU Library General Public License
     18     along with this library; see the file COPYING.LIB.  If not, write to
     19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     20     Boston, MA 02110-1301, USA.
     21 */
     22 
     23 #ifndef SVGRenderStyle_h
     24 #define SVGRenderStyle_h
     25 
     26 #include "bindings/core/v8/ExceptionStatePlaceholder.h"
     27 #include "core/css/CSSValueList.h"
     28 #include "core/rendering/style/DataRef.h"
     29 #include "core/rendering/style/RenderStyleConstants.h"
     30 #include "core/rendering/style/SVGRenderStyleDefs.h"
     31 #include "core/rendering/style/StyleDifference.h"
     32 #include "platform/graphics/GraphicsTypes.h"
     33 #include "platform/graphics/Path.h"
     34 
     35 namespace blink {
     36 
     37 class SVGRenderStyle : public RefCounted<SVGRenderStyle> {
     38 public:
     39     static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); }
     40     PassRefPtr<SVGRenderStyle> copy() const { return adoptRef(new SVGRenderStyle(*this));}
     41     ~SVGRenderStyle();
     42 
     43     bool inheritedNotEqual(const SVGRenderStyle*) const;
     44     void inheritFrom(const SVGRenderStyle*);
     45     void copyNonInheritedFrom(const SVGRenderStyle*);
     46 
     47     StyleDifference diff(const SVGRenderStyle*) const;
     48 
     49     bool operator==(const SVGRenderStyle&) const;
     50     bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); }
     51 
     52     // Initial values for all the properties
     53     static EAlignmentBaseline initialAlignmentBaseline() { return AB_AUTO; }
     54     static EDominantBaseline initialDominantBaseline() { return DB_AUTO; }
     55     static EBaselineShift initialBaselineShift() { return BS_BASELINE; }
     56     static EVectorEffect initialVectorEffect() { return VE_NONE; }
     57     static EBufferedRendering initialBufferedRendering() { return BR_AUTO; }
     58     static LineCap initialCapStyle() { return ButtCap; }
     59     static WindRule initialClipRule() { return RULE_NONZERO; }
     60     static EColorInterpolation initialColorInterpolation() { return CI_SRGB; }
     61     static EColorInterpolation initialColorInterpolationFilters() { return CI_LINEARRGB; }
     62     static EColorRendering initialColorRendering() { return CR_AUTO; }
     63     static WindRule initialFillRule() { return RULE_NONZERO; }
     64     static LineJoin initialJoinStyle() { return MiterJoin; }
     65     static EShapeRendering initialShapeRendering() { return SR_AUTO; }
     66     static ETextAnchor initialTextAnchor() { return TA_START; }
     67     static SVGWritingMode initialWritingMode() { return WM_LRTB; }
     68     static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; }
     69     static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; }
     70     static float initialFillOpacity() { return 1; }
     71     static SVGPaintType initialFillPaintType() { return SVG_PAINTTYPE_RGBCOLOR; }
     72     static Color initialFillPaintColor() { return Color::black; }
     73     static String initialFillPaintUri() { return String(); }
     74     static float initialStrokeOpacity() { return 1; }
     75     static SVGPaintType initialStrokePaintType() { return SVG_PAINTTYPE_NONE; }
     76     static Color initialStrokePaintColor() { return Color(); }
     77     static String initialStrokePaintUri() { return String(); }
     78     static PassRefPtr<SVGLengthList> initialStrokeDashArray() { return SVGLengthList::create(); }
     79     static float initialStrokeMiterLimit() { return 4; }
     80     static float initialStopOpacity() { return 1; }
     81     static Color initialStopColor() { return Color(0, 0, 0); }
     82     static float initialFloodOpacity() { return 1; }
     83     static Color initialFloodColor() { return Color(0, 0, 0); }
     84     static Color initialLightingColor() { return Color(255, 255, 255); }
     85     static const AtomicString& initialClipperResource() { return nullAtom; }
     86     static const AtomicString& initialFilterResource() { return nullAtom; }
     87     static const AtomicString& initialMaskerResource() { return nullAtom; }
     88     static const AtomicString& initialMarkerStartResource() { return nullAtom; }
     89     static const AtomicString& initialMarkerMidResource() { return nullAtom; }
     90     static const AtomicString& initialMarkerEndResource() { return nullAtom; }
     91     static EMaskType initialMaskType() { return MT_LUMINANCE; }
     92     static EPaintOrder initialPaintOrder() { return PO_NORMAL; }
     93 
     94     static PassRefPtr<SVGLength> initialBaselineShiftValue()
     95     {
     96         RefPtr<SVGLength> length = SVGLength::create();
     97         length->newValueSpecifiedUnits(LengthTypeNumber, 0);
     98         return length.release();
     99     }
    100 
    101     static PassRefPtr<SVGLength> initialStrokeDashOffset()
    102     {
    103         RefPtr<SVGLength> length = SVGLength::create();
    104         length->newValueSpecifiedUnits(LengthTypeNumber, 0);
    105         return length.release();
    106     }
    107 
    108     static PassRefPtr<SVGLength> initialStrokeWidth()
    109     {
    110         RefPtr<SVGLength> length = SVGLength::create();
    111         length->newValueSpecifiedUnits(LengthTypeNumber, 1);
    112         return length.release();
    113     }
    114 
    115     // SVG CSS Property setters
    116     void setAlignmentBaseline(EAlignmentBaseline val) { svg_noninherited_flags.f._alignmentBaseline = val; }
    117     void setDominantBaseline(EDominantBaseline val) { svg_noninherited_flags.f._dominantBaseline = val; }
    118     void setBaselineShift(EBaselineShift val) { svg_noninherited_flags.f._baselineShift = val; }
    119     void setVectorEffect(EVectorEffect val) { svg_noninherited_flags.f._vectorEffect = val; }
    120     void setBufferedRendering(EBufferedRendering val) { svg_noninherited_flags.f.bufferedRendering = val; }
    121     void setCapStyle(LineCap val) { svg_inherited_flags._capStyle = val; }
    122     void setClipRule(WindRule val) { svg_inherited_flags._clipRule = val; }
    123     void setColorInterpolation(EColorInterpolation val) { svg_inherited_flags._colorInterpolation = val; }
    124     void setColorInterpolationFilters(EColorInterpolation val) { svg_inherited_flags._colorInterpolationFilters = val; }
    125     void setColorRendering(EColorRendering val) { svg_inherited_flags._colorRendering = val; }
    126     void setFillRule(WindRule val) { svg_inherited_flags._fillRule = val; }
    127     void setJoinStyle(LineJoin val) { svg_inherited_flags._joinStyle = val; }
    128     void setShapeRendering(EShapeRendering val) { svg_inherited_flags._shapeRendering = val; }
    129     void setTextAnchor(ETextAnchor val) { svg_inherited_flags._textAnchor = val; }
    130     void setWritingMode(SVGWritingMode val) { svg_inherited_flags._writingMode = val; }
    131     void setGlyphOrientationHorizontal(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationHorizontal = val; }
    132     void setGlyphOrientationVertical(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationVertical = val; }
    133     void setMaskType(EMaskType val) { svg_noninherited_flags.f.maskType = val; }
    134     void setPaintOrder(EPaintOrder val) { svg_inherited_flags._paintOrder = (int)val; }
    135 
    136     void setFillOpacity(float obj)
    137     {
    138         if (!(fill->opacity == obj))
    139             fill.access()->opacity = obj;
    140     }
    141 
    142     void setFillPaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false)
    143     {
    144         if (applyToRegularStyle) {
    145             if (!(fill->paintType == type))
    146                 fill.access()->paintType = type;
    147             if (!(fill->paintColor == color))
    148                 fill.access()->paintColor = color;
    149             if (!(fill->paintUri == uri))
    150                 fill.access()->paintUri = uri;
    151         }
    152         if (applyToVisitedLinkStyle) {
    153             if (!(fill->visitedLinkPaintType == type))
    154                 fill.access()->visitedLinkPaintType = type;
    155             if (!(fill->visitedLinkPaintColor == color))
    156                 fill.access()->visitedLinkPaintColor = color;
    157             if (!(fill->visitedLinkPaintUri == uri))
    158                 fill.access()->visitedLinkPaintUri = uri;
    159         }
    160     }
    161 
    162     void setStrokeOpacity(float obj)
    163     {
    164         if (!(stroke->opacity == obj))
    165             stroke.access()->opacity = obj;
    166     }
    167 
    168     void setStrokePaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false)
    169     {
    170         if (applyToRegularStyle) {
    171             if (!(stroke->paintType == type))
    172                 stroke.access()->paintType = type;
    173             if (!(stroke->paintColor == color))
    174                 stroke.access()->paintColor = color;
    175             if (!(stroke->paintUri == uri))
    176                 stroke.access()->paintUri = uri;
    177         }
    178         if (applyToVisitedLinkStyle) {
    179             if (!(stroke->visitedLinkPaintType == type))
    180                 stroke.access()->visitedLinkPaintType = type;
    181             if (!(stroke->visitedLinkPaintColor == color))
    182                 stroke.access()->visitedLinkPaintColor = color;
    183             if (!(stroke->visitedLinkPaintUri == uri))
    184                 stroke.access()->visitedLinkPaintUri = uri;
    185         }
    186     }
    187 
    188     void setStrokeDashArray(PassRefPtr<SVGLengthList> obj)
    189     {
    190         if (!(stroke->dashArray == obj))
    191             stroke.access()->dashArray = obj;
    192     }
    193 
    194     void setStrokeMiterLimit(float obj)
    195     {
    196         if (!(stroke->miterLimit == obj))
    197             stroke.access()->miterLimit = obj;
    198     }
    199 
    200     void setStrokeWidth(PassRefPtr<SVGLength> obj)
    201     {
    202         if (!(stroke->width == obj))
    203             stroke.access()->width = obj;
    204     }
    205 
    206     void setStrokeDashOffset(PassRefPtr<SVGLength> obj)
    207     {
    208         if (!(stroke->dashOffset == obj))
    209             stroke.access()->dashOffset = obj;
    210     }
    211 
    212     void setStopOpacity(float obj)
    213     {
    214         if (!(stops->opacity == obj))
    215             stops.access()->opacity = obj;
    216     }
    217 
    218     void setStopColor(const Color& obj)
    219     {
    220         if (!(stops->color == obj))
    221             stops.access()->color = obj;
    222     }
    223 
    224     void setFloodOpacity(float obj)
    225     {
    226         if (!(misc->floodOpacity == obj))
    227             misc.access()->floodOpacity = obj;
    228     }
    229 
    230     void setFloodColor(const Color& obj)
    231     {
    232         if (!(misc->floodColor == obj))
    233             misc.access()->floodColor = obj;
    234     }
    235 
    236     void setLightingColor(const Color& obj)
    237     {
    238         if (!(misc->lightingColor == obj))
    239             misc.access()->lightingColor = obj;
    240     }
    241 
    242     void setBaselineShiftValue(PassRefPtr<SVGLength> obj)
    243     {
    244         if (!(misc->baselineShiftValue == obj))
    245             misc.access()->baselineShiftValue = obj;
    246     }
    247 
    248     // Setters for non-inherited resources
    249     void setClipperResource(const AtomicString& obj)
    250     {
    251         if (!(resources->clipper == obj))
    252             resources.access()->clipper = obj;
    253     }
    254 
    255     void setFilterResource(const AtomicString& obj)
    256     {
    257         if (!(resources->filter == obj))
    258             resources.access()->filter = obj;
    259     }
    260 
    261     void setMaskerResource(const AtomicString& obj)
    262     {
    263         if (!(resources->masker == obj))
    264             resources.access()->masker = obj;
    265     }
    266 
    267     // Setters for inherited resources
    268     void setMarkerStartResource(const AtomicString& obj)
    269     {
    270         if (!(inheritedResources->markerStart == obj))
    271             inheritedResources.access()->markerStart = obj;
    272     }
    273 
    274     void setMarkerMidResource(const AtomicString& obj)
    275     {
    276         if (!(inheritedResources->markerMid == obj))
    277             inheritedResources.access()->markerMid = obj;
    278     }
    279 
    280     void setMarkerEndResource(const AtomicString& obj)
    281     {
    282         if (!(inheritedResources->markerEnd == obj))
    283             inheritedResources.access()->markerEnd = obj;
    284     }
    285 
    286     // Read accessors for all the properties
    287     EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) svg_noninherited_flags.f._alignmentBaseline; }
    288     EDominantBaseline dominantBaseline() const { return (EDominantBaseline) svg_noninherited_flags.f._dominantBaseline; }
    289     EBaselineShift baselineShift() const { return (EBaselineShift) svg_noninherited_flags.f._baselineShift; }
    290     EVectorEffect vectorEffect() const { return (EVectorEffect) svg_noninherited_flags.f._vectorEffect; }
    291     EBufferedRendering bufferedRendering() const { return (EBufferedRendering) svg_noninherited_flags.f.bufferedRendering; }
    292     LineCap capStyle() const { return (LineCap) svg_inherited_flags._capStyle; }
    293     WindRule clipRule() const { return (WindRule) svg_inherited_flags._clipRule; }
    294     EColorInterpolation colorInterpolation() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolation; }
    295     EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolationFilters; }
    296     EColorRendering colorRendering() const { return (EColorRendering) svg_inherited_flags._colorRendering; }
    297     WindRule fillRule() const { return (WindRule) svg_inherited_flags._fillRule; }
    298     LineJoin joinStyle() const { return (LineJoin) svg_inherited_flags._joinStyle; }
    299     EShapeRendering shapeRendering() const { return (EShapeRendering) svg_inherited_flags._shapeRendering; }
    300     ETextAnchor textAnchor() const { return (ETextAnchor) svg_inherited_flags._textAnchor; }
    301     SVGWritingMode writingMode() const { return (SVGWritingMode) svg_inherited_flags._writingMode; }
    302     EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; }
    303     EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; }
    304     float fillOpacity() const { return fill->opacity; }
    305     const SVGPaintType& fillPaintType() const { return fill->paintType; }
    306     const Color& fillPaintColor() const { return fill->paintColor; }
    307     const String& fillPaintUri() const { return fill->paintUri; }
    308     float strokeOpacity() const { return stroke->opacity; }
    309     const SVGPaintType& strokePaintType() const { return stroke->paintType; }
    310     const Color& strokePaintColor() const { return stroke->paintColor; }
    311     const String& strokePaintUri() const { return stroke->paintUri; }
    312     SVGLengthList* strokeDashArray() const { return stroke->dashArray.get(); }
    313     float strokeMiterLimit() const { return stroke->miterLimit; }
    314     SVGLength* strokeWidth() const { return stroke->width.get(); }
    315     SVGLength* strokeDashOffset() const { return stroke->dashOffset.get(); }
    316     float stopOpacity() const { return stops->opacity; }
    317     const Color& stopColor() const { return stops->color; }
    318     float floodOpacity() const { return misc->floodOpacity; }
    319     const Color& floodColor() const { return misc->floodColor; }
    320     const Color& lightingColor() const { return misc->lightingColor; }
    321     SVGLength* baselineShiftValue() const { return misc->baselineShiftValue.get(); }
    322     const AtomicString& clipperResource() const { return resources->clipper; }
    323     const AtomicString& filterResource() const { return resources->filter; }
    324     const AtomicString& maskerResource() const { return resources->masker; }
    325     const AtomicString& markerStartResource() const { return inheritedResources->markerStart; }
    326     const AtomicString& markerMidResource() const { return inheritedResources->markerMid; }
    327     const AtomicString& markerEndResource() const { return inheritedResources->markerEnd; }
    328     EMaskType maskType() const { return (EMaskType) svg_noninherited_flags.f.maskType; }
    329     EPaintOrder paintOrder() const { return (EPaintOrder) svg_inherited_flags._paintOrder; }
    330     EPaintOrderType paintOrderType(unsigned index) const;
    331 
    332     const SVGPaintType& visitedLinkFillPaintType() const { return fill->visitedLinkPaintType; }
    333     const Color& visitedLinkFillPaintColor() const { return fill->visitedLinkPaintColor; }
    334     const String& visitedLinkFillPaintUri() const { return fill->visitedLinkPaintUri; }
    335     const SVGPaintType& visitedLinkStrokePaintType() const { return stroke->visitedLinkPaintType; }
    336     const Color& visitedLinkStrokePaintColor() const { return stroke->visitedLinkPaintColor; }
    337     const String& visitedLinkStrokePaintUri() const { return stroke->visitedLinkPaintUri; }
    338 
    339     // convenience
    340     bool hasClipper() const { return !clipperResource().isEmpty(); }
    341     bool hasMasker() const { return !maskerResource().isEmpty(); }
    342     bool hasFilter() const { return !filterResource().isEmpty(); }
    343     bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
    344     bool hasStroke() const { return strokePaintType() != SVG_PAINTTYPE_NONE; }
    345     bool hasVisibleStroke() const { return hasStroke() && !strokeWidth()->isZero(); }
    346     bool hasFill() const { return fillPaintType() != SVG_PAINTTYPE_NONE; }
    347     bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; }
    348 
    349 protected:
    350     // inherit
    351     struct InheritedFlags {
    352         bool operator==(const InheritedFlags& other) const
    353         {
    354             return (_colorRendering == other._colorRendering)
    355                 && (_shapeRendering == other._shapeRendering)
    356                 && (_clipRule == other._clipRule)
    357                 && (_fillRule == other._fillRule)
    358                 && (_capStyle == other._capStyle)
    359                 && (_joinStyle == other._joinStyle)
    360                 && (_textAnchor == other._textAnchor)
    361                 && (_colorInterpolation == other._colorInterpolation)
    362                 && (_colorInterpolationFilters == other._colorInterpolationFilters)
    363                 && (_writingMode == other._writingMode)
    364                 && (_glyphOrientationHorizontal == other._glyphOrientationHorizontal)
    365                 && (_glyphOrientationVertical == other._glyphOrientationVertical)
    366                 && (_paintOrder == other._paintOrder);
    367         }
    368 
    369         bool operator!=(const InheritedFlags& other) const
    370         {
    371             return !(*this == other);
    372         }
    373 
    374         unsigned _colorRendering : 2; // EColorRendering
    375         unsigned _shapeRendering : 2; // EShapeRendering
    376         unsigned _clipRule : 1; // WindRule
    377         unsigned _fillRule : 1; // WindRule
    378         unsigned _capStyle : 2; // LineCap
    379         unsigned _joinStyle : 2; // LineJoin
    380         unsigned _textAnchor : 2; // ETextAnchor
    381         unsigned _colorInterpolation : 2; // EColorInterpolation
    382         unsigned _colorInterpolationFilters : 2; // EColorInterpolation
    383         unsigned _writingMode : 3; // SVGWritingMode
    384         unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation
    385         unsigned _glyphOrientationVertical : 3; // EGlyphOrientation
    386         unsigned _paintOrder : 6; // EPaintOrder
    387     } svg_inherited_flags;
    388 
    389     // don't inherit
    390     struct NonInheritedFlags {
    391         // 32 bit non-inherited, don't add to the struct, or the operator will break.
    392         bool operator==(const NonInheritedFlags &other) const { return _niflags == other._niflags; }
    393         bool operator!=(const NonInheritedFlags &other) const { return _niflags != other._niflags; }
    394 
    395         union {
    396             struct {
    397                 unsigned _alignmentBaseline : 4; // EAlignmentBaseline
    398                 unsigned _dominantBaseline : 4; // EDominantBaseline
    399                 unsigned _baselineShift : 2; // EBaselineShift
    400                 unsigned _vectorEffect: 1; // EVectorEffect
    401                 unsigned bufferedRendering: 2; // EBufferedRendering
    402                 unsigned maskType: 1; // EMaskType
    403                 // 18 bits unused
    404             } f;
    405             uint32_t _niflags;
    406         };
    407     } svg_noninherited_flags;
    408 
    409     // inherited attributes
    410     DataRef<StyleFillData> fill;
    411     DataRef<StyleStrokeData> stroke;
    412     DataRef<StyleInheritedResourceData> inheritedResources;
    413 
    414     // non-inherited attributes
    415     DataRef<StyleStopData> stops;
    416     DataRef<StyleMiscData> misc;
    417     DataRef<StyleResourceData> resources;
    418 
    419 private:
    420     enum CreateDefaultType { CreateDefault };
    421 
    422     SVGRenderStyle();
    423     SVGRenderStyle(const SVGRenderStyle&);
    424     SVGRenderStyle(CreateDefaultType); // Used to create the default style.
    425 
    426     bool diffNeedsLayoutAndPaintInvalidation(const SVGRenderStyle* other) const;
    427     bool diffNeedsPaintInvalidation(const SVGRenderStyle* other) const;
    428 
    429     void setBitDefaults()
    430     {
    431         svg_inherited_flags._clipRule = initialClipRule();
    432         svg_inherited_flags._colorRendering = initialColorRendering();
    433         svg_inherited_flags._fillRule = initialFillRule();
    434         svg_inherited_flags._shapeRendering = initialShapeRendering();
    435         svg_inherited_flags._textAnchor = initialTextAnchor();
    436         svg_inherited_flags._capStyle = initialCapStyle();
    437         svg_inherited_flags._joinStyle = initialJoinStyle();
    438         svg_inherited_flags._colorInterpolation = initialColorInterpolation();
    439         svg_inherited_flags._colorInterpolationFilters = initialColorInterpolationFilters();
    440         svg_inherited_flags._writingMode = initialWritingMode();
    441         svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal();
    442         svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical();
    443         svg_inherited_flags._paintOrder = initialPaintOrder();
    444 
    445         svg_noninherited_flags._niflags = 0;
    446         svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline();
    447         svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline();
    448         svg_noninherited_flags.f._baselineShift = initialBaselineShift();
    449         svg_noninherited_flags.f._vectorEffect = initialVectorEffect();
    450         svg_noninherited_flags.f.bufferedRendering = initialBufferedRendering();
    451         svg_noninherited_flags.f.maskType = initialMaskType();
    452     }
    453 };
    454 
    455 } // namespace blink
    456 
    457 #endif // SVGRenderStyle_h
    458