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 
      5     Based on khtml code by:
      6     Copyright (C) 1999 Antti Koivisto (koivisto (at) kde.org)
      7     Copyright (C) 1999-2003 Lars Knoll (knoll (at) kde.org)
      8     Copyright (C) 2002-2003 Dirk Mueller (mueller (at) kde.org)
      9     Copyright (C) 2002 Apple Computer, Inc.
     10 
     11     This library is free software; you can redistribute it and/or
     12     modify it under the terms of the GNU Library General Public
     13     License as published by the Free Software Foundation; either
     14     version 2 of the License, or (at your option) any later version.
     15 
     16     This library is distributed in the hope that it will be useful,
     17     but WITHOUT ANY WARRANTY; without even the implied warranty of
     18     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     19     Library General Public License for more details.
     20 
     21     You should have received a copy of the GNU Library General Public License
     22     along with this library; see the file COPYING.LIB.  If not, write to
     23     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
     24     Boston, MA 02110-1301, USA.
     25 */
     26 
     27 #include "config.h"
     28 #if ENABLE(SVG)
     29 #include "SVGRenderStyle.h"
     30 
     31 #include "CSSPrimitiveValue.h"
     32 #include "CSSValueList.h"
     33 #include "IntRect.h"
     34 #include "NodeRenderStyle.h"
     35 #include "RenderObject.h"
     36 #include "RenderStyle.h"
     37 #include "SVGStyledElement.h"
     38 
     39 using namespace std;
     40 
     41 namespace WebCore {
     42 
     43 SVGRenderStyle::SVGRenderStyle()
     44 {
     45     static SVGRenderStyle* defaultStyle = new SVGRenderStyle(CreateDefault);
     46 
     47     fill = defaultStyle->fill;
     48     stroke = defaultStyle->stroke;
     49     text = defaultStyle->text;
     50     stops = defaultStyle->stops;
     51     clip = defaultStyle->clip;
     52     mask = defaultStyle->mask;
     53     misc = defaultStyle->misc;
     54     markers = defaultStyle->markers;
     55     shadowSVG = defaultStyle->shadowSVG;
     56 
     57     setBitDefaults();
     58 }
     59 
     60 SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
     61 {
     62     setBitDefaults();
     63 
     64     fill.init();
     65     stroke.init();
     66     text.init();
     67     stops.init();
     68     clip.init();
     69     mask.init();
     70     misc.init();
     71     markers.init();
     72     shadowSVG.init();
     73 }
     74 
     75 SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
     76     : RefCounted<SVGRenderStyle>()
     77 {
     78     fill = other.fill;
     79     stroke = other.stroke;
     80     text = other.text;
     81     stops = other.stops;
     82     clip = other.clip;
     83     mask = other.mask;
     84     misc = other.misc;
     85     markers = other.markers;
     86     shadowSVG = other.shadowSVG;
     87 
     88     svg_inherited_flags = other.svg_inherited_flags;
     89     svg_noninherited_flags = other.svg_noninherited_flags;
     90 }
     91 
     92 SVGRenderStyle::~SVGRenderStyle()
     93 {
     94 }
     95 
     96 bool SVGRenderStyle::operator==(const SVGRenderStyle& o) const
     97 {
     98     return (fill == o.fill && stroke == o.stroke && text == o.text &&
     99         stops == o.stops && clip == o.clip && mask == o.mask &&
    100         misc == o.misc && markers == o.markers && shadowSVG == o.shadowSVG &&
    101         svg_inherited_flags == o.svg_inherited_flags &&
    102         svg_noninherited_flags == o.svg_noninherited_flags);
    103 }
    104 
    105 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
    106 {
    107     return (fill != other->fill
    108             || stroke != other->stroke
    109             || markers != other->markers
    110             || text != other->text
    111             || svg_inherited_flags != other->svg_inherited_flags);
    112 }
    113 
    114 void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
    115 {
    116     if (!svgInheritParent)
    117         return;
    118 
    119     fill = svgInheritParent->fill;
    120     stroke = svgInheritParent->stroke;
    121     markers = svgInheritParent->markers;
    122     text = svgInheritParent->text;
    123 
    124     svg_inherited_flags = svgInheritParent->svg_inherited_flags;
    125 }
    126 
    127 float SVGRenderStyle::cssPrimitiveToLength(const RenderObject* item, CSSValue* value, float defaultValue)
    128 {
    129     CSSPrimitiveValue* primitive = static_cast<CSSPrimitiveValue*>(value);
    130 
    131     unsigned short cssType = (primitive ? primitive->primitiveType() : (unsigned short) CSSPrimitiveValue::CSS_UNKNOWN);
    132     if (!(cssType > CSSPrimitiveValue::CSS_UNKNOWN && cssType <= CSSPrimitiveValue::CSS_PC))
    133         return defaultValue;
    134 
    135     if (cssType == CSSPrimitiveValue::CSS_PERCENTAGE) {
    136         SVGStyledElement* element = static_cast<SVGStyledElement*>(item->node());
    137         SVGElement* viewportElement = (element ? element->viewportElement() : 0);
    138         if (viewportElement) {
    139             float result = primitive->getFloatValue() / 100.0f;
    140             return SVGLength::PercentageOfViewport(result, element, LengthModeOther);
    141         }
    142     }
    143 
    144     return primitive->computeLengthFloat(const_cast<RenderStyle*>(item->style()), item->document()->documentElement()->renderStyle());
    145 }
    146 
    147 
    148 static void getSVGShadowExtent(ShadowData* shadow, int& top, int& right, int& bottom, int& left)
    149 {
    150     top = 0;
    151     right = 0;
    152     bottom = 0;
    153     left = 0;
    154 
    155     int blurAndSpread = shadow->blur + shadow->spread;
    156 
    157     top = min(top, shadow->y - blurAndSpread);
    158     right = max(right, shadow->x + blurAndSpread);
    159     bottom = max(bottom, shadow->y + blurAndSpread);
    160     left = min(left, shadow->x - blurAndSpread);
    161 }
    162 
    163 void SVGRenderStyle::inflateForShadow(IntRect& repaintRect) const
    164 {
    165     ShadowData* svgShadow = shadow();
    166     if (!svgShadow)
    167         return;
    168 
    169     FloatRect repaintFloatRect = FloatRect(repaintRect);
    170     inflateForShadow(repaintFloatRect);
    171     repaintRect = enclosingIntRect(repaintFloatRect);
    172 }
    173 
    174 void SVGRenderStyle::inflateForShadow(FloatRect& repaintRect) const
    175 {
    176     ShadowData* svgShadow = shadow();
    177     if (!svgShadow)
    178         return;
    179 
    180     int shadowTop;
    181     int shadowRight;
    182     int shadowBottom;
    183     int shadowLeft;
    184     getSVGShadowExtent(svgShadow, shadowTop, shadowRight, shadowBottom, shadowLeft);
    185 
    186     int overflowLeft = repaintRect.x() + shadowLeft;
    187     int overflowRight = repaintRect.right() + shadowRight;
    188     int overflowTop = repaintRect.y() + shadowTop;
    189     int overflowBottom = repaintRect.bottom() + shadowBottom;
    190 
    191     repaintRect.setX(overflowLeft);
    192     repaintRect.setY(overflowTop);
    193     repaintRect.setWidth(overflowRight - overflowLeft);
    194     repaintRect.setHeight(overflowBottom - overflowTop);
    195 }
    196 
    197 }
    198 
    199 #endif // ENABLE(SVG)
    200 
    201 // vim:ts=4:noet
    202