Home | History | Annotate | Download | only in style
      1 /*
      2     Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org>
      3                   2004, 2005, 2010 Rob Buis <buis (at) kde.org>
      4     Copyright (C) Research In Motion Limited 2010. All rights reserved.
      5 
      6     Based on khtml code by:
      7     Copyright (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      8     Copyright (C) 1999-2003 Lars Knoll (knoll (at) kde.org)
      9     Copyright (C) 2002-2003 Dirk Mueller (mueller (at) kde.org)
     10     Copyright (C) 2002 Apple Computer, Inc.
     11 
     12     This library is free software; you can redistribute it and/or
     13     modify it under the terms of the GNU Library General Public
     14     License as published by the Free Software Foundation; either
     15     version 2 of the License, or (at your option) any later version.
     16 
     17     This library is distributed in the hope that it will be useful,
     18     but WITHOUT ANY WARRANTY; without even the implied warranty of
     19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     20     Library General Public License for more details.
     21 
     22     You should have received a copy of the GNU Library General Public License
     23     along with this library; see the file COPYING.LIB.  If not, write to
     24     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     25     Boston, MA 02110-1301, USA.
     26 */
     27 
     28 #include "config.h"
     29 
     30 #include "core/rendering/style/SVGRenderStyle.h"
     31 
     32 namespace blink {
     33 
     34 SVGRenderStyle::SVGRenderStyle()
     35 {
     36     static SVGRenderStyle* defaultStyle = new SVGRenderStyle(CreateDefault);
     37 
     38     fill = defaultStyle->fill;
     39     stroke = defaultStyle->stroke;
     40     stops = defaultStyle->stops;
     41     misc = defaultStyle->misc;
     42     inheritedResources = defaultStyle->inheritedResources;
     43     resources = defaultStyle->resources;
     44 
     45     setBitDefaults();
     46 }
     47 
     48 SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
     49 {
     50     setBitDefaults();
     51 
     52     fill.init();
     53     stroke.init();
     54     stops.init();
     55     misc.init();
     56     inheritedResources.init();
     57     resources.init();
     58 }
     59 
     60 SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
     61     : RefCounted<SVGRenderStyle>()
     62 {
     63     fill = other.fill;
     64     stroke = other.stroke;
     65     stops = other.stops;
     66     misc = other.misc;
     67     inheritedResources = other.inheritedResources;
     68     resources = other.resources;
     69 
     70     svg_inherited_flags = other.svg_inherited_flags;
     71     svg_noninherited_flags = other.svg_noninherited_flags;
     72 }
     73 
     74 SVGRenderStyle::~SVGRenderStyle()
     75 {
     76 }
     77 
     78 bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const
     79 {
     80     return fill == other.fill
     81         && stroke == other.stroke
     82         && stops == other.stops
     83         && misc == other.misc
     84         && inheritedResources == other.inheritedResources
     85         && resources == other.resources
     86         && svg_inherited_flags == other.svg_inherited_flags
     87         && svg_noninherited_flags == other.svg_noninherited_flags;
     88 }
     89 
     90 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
     91 {
     92     return fill != other->fill
     93         || stroke != other->stroke
     94         || inheritedResources != other->inheritedResources
     95         || svg_inherited_flags != other->svg_inherited_flags;
     96 }
     97 
     98 void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
     99 {
    100     if (!svgInheritParent)
    101         return;
    102 
    103     fill = svgInheritParent->fill;
    104     stroke = svgInheritParent->stroke;
    105     inheritedResources = svgInheritParent->inheritedResources;
    106 
    107     svg_inherited_flags = svgInheritParent->svg_inherited_flags;
    108 }
    109 
    110 void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other)
    111 {
    112     svg_noninherited_flags = other->svg_noninherited_flags;
    113     stops = other->stops;
    114     misc = other->misc;
    115     resources = other->resources;
    116 }
    117 
    118 StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
    119 {
    120     StyleDifference styleDifference;
    121 
    122     if (diffNeedsLayoutAndPaintInvalidation(other)) {
    123         styleDifference.setNeedsFullLayout();
    124         styleDifference.setNeedsPaintInvalidationObject();
    125     } else if (diffNeedsPaintInvalidation(other)) {
    126         styleDifference.setNeedsPaintInvalidationObject();
    127     }
    128 
    129     return styleDifference;
    130 }
    131 
    132 bool SVGRenderStyle::diffNeedsLayoutAndPaintInvalidation(const SVGRenderStyle* other) const
    133 {
    134     // If resources change, we need a relayout, as the presence of resources influences the paint invalidation rect.
    135     if (resources != other->resources)
    136         return true;
    137 
    138     // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath.
    139     if (inheritedResources != other->inheritedResources)
    140         return true;
    141 
    142     // All text related properties influence layout.
    143     if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor
    144         || svg_inherited_flags._writingMode != other->svg_inherited_flags._writingMode
    145         || svg_inherited_flags._glyphOrientationHorizontal != other->svg_inherited_flags._glyphOrientationHorizontal
    146         || svg_inherited_flags._glyphOrientationVertical != other->svg_inherited_flags._glyphOrientationVertical
    147         || svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline
    148         || svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline
    149         || svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift)
    150         return true;
    151 
    152     // Text related properties influence layout.
    153     if (misc->baselineShiftValue != other->misc->baselineShiftValue)
    154         return true;
    155 
    156     // These properties affect the cached stroke bounding box rects.
    157     if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle
    158         || svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle)
    159         return true;
    160 
    161     // vector-effect changes require a re-layout.
    162     if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect)
    163         return true;
    164 
    165     // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
    166     if (stroke.get() != other->stroke.get()) {
    167         if (stroke->width != other->stroke->width
    168             || stroke->paintType != other->stroke->paintType
    169             || stroke->paintColor != other->stroke->paintColor
    170             || stroke->paintUri != other->stroke->paintUri
    171             || stroke->miterLimit != other->stroke->miterLimit
    172             || stroke->dashArray != other->stroke->dashArray
    173             || stroke->dashOffset != other->stroke->dashOffset
    174             || stroke->visitedLinkPaintColor != other->stroke->visitedLinkPaintColor
    175             || stroke->visitedLinkPaintUri != other->stroke->visitedLinkPaintUri
    176             || stroke->visitedLinkPaintType != other->stroke->visitedLinkPaintType)
    177             return true;
    178     }
    179 
    180     return false;
    181 }
    182 
    183 bool SVGRenderStyle::diffNeedsPaintInvalidation(const SVGRenderStyle* other) const
    184 {
    185     if (stroke->opacity != other->stroke->opacity)
    186         return true;
    187 
    188     // Painting related properties only need paint invalidation.
    189     if (misc.get() != other->misc.get()) {
    190         if (misc->floodColor != other->misc->floodColor
    191             || misc->floodOpacity != other->misc->floodOpacity
    192             || misc->lightingColor != other->misc->lightingColor)
    193             return true;
    194     }
    195 
    196     // If fill changes, we just need to issue paint invalidations. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains.
    197     if (fill.get() != other->fill.get()) {
    198         if (fill->paintType != other->fill->paintType
    199             || fill->paintColor != other->fill->paintColor
    200             || fill->paintUri != other->fill->paintUri
    201             || fill->opacity != other->fill->opacity)
    202             return true;
    203     }
    204 
    205     // If gradient stops change, we just need to issue paint invalidations. Style updates are already handled through RenderSVGGradientSTop.
    206     if (stops != other->stops)
    207         return true;
    208 
    209     // Changes of these flags only cause paint invalidations.
    210     if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering
    211         || svg_inherited_flags._shapeRendering != other->svg_inherited_flags._shapeRendering
    212         || svg_inherited_flags._clipRule != other->svg_inherited_flags._clipRule
    213         || svg_inherited_flags._fillRule != other->svg_inherited_flags._fillRule
    214         || svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation
    215         || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters
    216         || svg_inherited_flags._paintOrder != other->svg_inherited_flags._paintOrder)
    217         return true;
    218 
    219     if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering)
    220         return true;
    221 
    222     if (svg_noninherited_flags.f.maskType != other->svg_noninherited_flags.f.maskType)
    223         return true;
    224 
    225     return false;
    226 }
    227 
    228 EPaintOrderType SVGRenderStyle::paintOrderType(unsigned index) const
    229 {
    230     ASSERT(index < ((1 << kPaintOrderBitwidth)-1));
    231     unsigned pt = (paintOrder() >> (kPaintOrderBitwidth*index)) & ((1u << kPaintOrderBitwidth) - 1);
    232     return (EPaintOrderType)pt;
    233 }
    234 
    235 }
    236