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 
     33 using namespace std;
     34 
     35 namespace WebCore {
     36 
     37 SVGRenderStyle::SVGRenderStyle()
     38 {
     39     static SVGRenderStyle* defaultStyle = new SVGRenderStyle(CreateDefault);
     40 
     41     fill = defaultStyle->fill;
     42     stroke = defaultStyle->stroke;
     43     stops = defaultStyle->stops;
     44     misc = defaultStyle->misc;
     45     inheritedResources = defaultStyle->inheritedResources;
     46     resources = defaultStyle->resources;
     47 
     48     setBitDefaults();
     49 }
     50 
     51 SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
     52 {
     53     setBitDefaults();
     54 
     55     fill.init();
     56     stroke.init();
     57     stops.init();
     58     misc.init();
     59     inheritedResources.init();
     60     resources.init();
     61 }
     62 
     63 SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
     64     : RefCounted<SVGRenderStyle>()
     65 {
     66     fill = other.fill;
     67     stroke = other.stroke;
     68     stops = other.stops;
     69     misc = other.misc;
     70     inheritedResources = other.inheritedResources;
     71     resources = other.resources;
     72 
     73     svg_inherited_flags = other.svg_inherited_flags;
     74     svg_noninherited_flags = other.svg_noninherited_flags;
     75 }
     76 
     77 SVGRenderStyle::~SVGRenderStyle()
     78 {
     79 }
     80 
     81 bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const
     82 {
     83     return fill == other.fill
     84         && stroke == other.stroke
     85         && stops == other.stops
     86         && misc == other.misc
     87         && inheritedResources == other.inheritedResources
     88         && resources == other.resources
     89         && svg_inherited_flags == other.svg_inherited_flags
     90         && svg_noninherited_flags == other.svg_noninherited_flags;
     91 }
     92 
     93 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
     94 {
     95     return fill != other->fill
     96         || stroke != other->stroke
     97         || inheritedResources != other->inheritedResources
     98         || svg_inherited_flags != other->svg_inherited_flags;
     99 }
    100 
    101 void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
    102 {
    103     if (!svgInheritParent)
    104         return;
    105 
    106     fill = svgInheritParent->fill;
    107     stroke = svgInheritParent->stroke;
    108     inheritedResources = svgInheritParent->inheritedResources;
    109 
    110     svg_inherited_flags = svgInheritParent->svg_inherited_flags;
    111 }
    112 
    113 void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other)
    114 {
    115     svg_noninherited_flags = other->svg_noninherited_flags;
    116     stops = other->stops;
    117     misc = other->misc;
    118     resources = other->resources;
    119 }
    120 
    121 StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
    122 {
    123     StyleDifference styleDifference;
    124 
    125     if (diffNeedsLayoutAndRepaint(other)) {
    126         styleDifference.setNeedsFullLayout();
    127         styleDifference.setNeedsRepaintObject();
    128     } else if (diffNeedsRepaint(other)) {
    129         styleDifference.setNeedsRepaintObject();
    130     }
    131 
    132     return styleDifference;
    133 }
    134 
    135 bool SVGRenderStyle::diffNeedsLayoutAndRepaint(const SVGRenderStyle* other) const
    136 {
    137     // If resources change, we need a relayout, as the presence of resources influences the repaint rect.
    138     if (resources != other->resources)
    139         return true;
    140 
    141     // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath.
    142     if (inheritedResources != other->inheritedResources)
    143         return true;
    144 
    145     // All text related properties influence layout.
    146     if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor
    147         || svg_inherited_flags._writingMode != other->svg_inherited_flags._writingMode
    148         || svg_inherited_flags._glyphOrientationHorizontal != other->svg_inherited_flags._glyphOrientationHorizontal
    149         || svg_inherited_flags._glyphOrientationVertical != other->svg_inherited_flags._glyphOrientationVertical
    150         || svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline
    151         || svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline
    152         || svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift)
    153         return true;
    154 
    155     // Text related properties influence layout.
    156     if (misc->baselineShiftValue != other->misc->baselineShiftValue)
    157         return true;
    158 
    159     // These properties affect the cached stroke bounding box rects.
    160     if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle
    161         || svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle)
    162         return true;
    163 
    164     // vector-effect changes require a re-layout.
    165     if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect)
    166         return true;
    167 
    168     // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
    169     if (stroke.get() != other->stroke.get()) {
    170         if (stroke->width != other->stroke->width
    171             || stroke->paintType != other->stroke->paintType
    172             || stroke->paintColor != other->stroke->paintColor
    173             || stroke->paintUri != other->stroke->paintUri
    174             || stroke->miterLimit != other->stroke->miterLimit
    175             || stroke->dashArray != other->stroke->dashArray
    176             || stroke->dashOffset != other->stroke->dashOffset
    177             || stroke->visitedLinkPaintColor != other->stroke->visitedLinkPaintColor
    178             || stroke->visitedLinkPaintUri != other->stroke->visitedLinkPaintUri
    179             || stroke->visitedLinkPaintType != other->stroke->visitedLinkPaintType)
    180             return true;
    181     }
    182 
    183     return false;
    184 }
    185 
    186 bool SVGRenderStyle::diffNeedsRepaint(const SVGRenderStyle* other) const
    187 {
    188     if (stroke->opacity != other->stroke->opacity)
    189         return true;
    190 
    191     // Painting related properties only need repaints.
    192     if (misc.get() != other->misc.get()) {
    193         if (misc->floodColor != other->misc->floodColor
    194             || misc->floodOpacity != other->misc->floodOpacity
    195             || misc->lightingColor != other->misc->lightingColor)
    196             return true;
    197     }
    198 
    199     // If fill changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains.
    200     if (fill.get() != other->fill.get()) {
    201         if (fill->paintType != other->fill->paintType
    202             || fill->paintColor != other->fill->paintColor
    203             || fill->paintUri != other->fill->paintUri
    204             || fill->opacity != other->fill->opacity)
    205             return true;
    206     }
    207 
    208     // If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop.
    209     if (stops != other->stops)
    210         return true;
    211 
    212     // Changes of these flags only cause repaints.
    213     if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering
    214         || svg_inherited_flags._shapeRendering != other->svg_inherited_flags._shapeRendering
    215         || svg_inherited_flags._clipRule != other->svg_inherited_flags._clipRule
    216         || svg_inherited_flags._fillRule != other->svg_inherited_flags._fillRule
    217         || svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation
    218         || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters
    219         || svg_inherited_flags._paintOrder != other->svg_inherited_flags._paintOrder)
    220         return true;
    221 
    222     if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering)
    223         return true;
    224 
    225     if (svg_noninherited_flags.f.maskType != other->svg_noninherited_flags.f.maskType)
    226         return true;
    227 
    228     return false;
    229 }
    230 
    231 EPaintOrderType SVGRenderStyle::paintOrderType(unsigned index) const
    232 {
    233     ASSERT(index < ((1 << kPaintOrderBitwidth)-1));
    234     unsigned pt = (paintOrder() >> (kPaintOrderBitwidth*index)) & ((1u << kPaintOrderBitwidth) - 1);
    235     return (EPaintOrderType)pt;
    236 }
    237 
    238 }
    239