2 Copyright (C) 2004, 2005 Nikolas Zimmermann <wildfox@kde.org>
3 2004, 2005 Rob Buis <buis@kde.org>
4 2006 Alexander Kellett <lypanov@kde.org>
6 This file is part of the KDE project
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
18 You should have received a copy of the GNU Library General Public License
19 aint with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA.
27 #include "CSSValueList.h"
29 #include "KCanvasRenderingStyle.h"
30 #include "KRenderingDevice.h"
31 #include "KRenderingFillPainter.h"
32 #include "KRenderingPaintServer.h"
33 #include "KRenderingPaintServerGradient.h"
34 #include "KRenderingPaintServerSolid.h"
35 #include "KRenderingStrokePainter.h"
36 #include "PlatformString.h"
37 #include "RenderObject.h"
38 #include "SVGLength.h"
39 #include "SVGRenderStyle.h"
40 #include "SVGStyledElement.h"
42 #include "RenderStyle.h"
46 static KRenderingPaintServerSolid* sharedSolidPaintServer()
48 static KRenderingPaintServerSolid* _sharedSolidPaintServer = 0;
49 if (!_sharedSolidPaintServer)
50 _sharedSolidPaintServer = static_cast<KRenderingPaintServerSolid *>(renderingDevice()->createPaintServer(PS_SOLID));
51 return _sharedSolidPaintServer;
54 bool KSVGPainterFactory::isFilled(const RenderStyle* style)
56 SVGPaint* fill = style->svgStyle()->fillPaint();
57 if (fill && fill->paintType() == SVGPaint::SVG_PAINTTYPE_NONE)
62 KRenderingPaintServer* KSVGPainterFactory::fillPaintServer(const RenderStyle* style, const RenderObject* item)
67 SVGPaint* fill = style->svgStyle()->fillPaint();
69 KRenderingPaintServer* fillPaintServer = 0;
70 if (fill && fill->paintType() == SVGPaint::SVG_PAINTTYPE_URI) {
71 fillPaintServer = getPaintServerById(item->document(), AtomicString(fill->uri().substring(1)));
72 if (item && fillPaintServer && item->isRenderPath())
73 fillPaintServer->addClient(static_cast<const RenderPath*>(item));
75 fillPaintServer = sharedSolidPaintServer();
76 KRenderingPaintServerSolid* fillPaintServerSolid = static_cast<KRenderingPaintServerSolid*>(fillPaintServer);
77 if (fill->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
78 fillPaintServerSolid->setColor(style->color());
80 fillPaintServerSolid->setColor(fill->color());
83 if (!fillPaintServer) {
84 // default value (black), see bug 11017
85 fillPaintServer = sharedSolidPaintServer();
86 static_cast<KRenderingPaintServerSolid *>(fillPaintServer)->setColor(Color::black);
89 return fillPaintServer;
93 bool KSVGPainterFactory::isStroked(const RenderStyle* style)
95 SVGPaint* stroke = style->svgStyle()->strokePaint();
96 if (!stroke || stroke->paintType() == SVGPaint::SVG_PAINTTYPE_NONE)
101 KRenderingPaintServer* KSVGPainterFactory::strokePaintServer(const RenderStyle* style, const RenderObject* item)
103 if (!isStroked(style))
106 SVGPaint* stroke = style->svgStyle()->strokePaint();
108 KRenderingPaintServer* strokePaintServer = 0;
109 if (stroke && stroke->paintType() == SVGPaint::SVG_PAINTTYPE_URI) {
110 strokePaintServer = getPaintServerById(item->document(), AtomicString(stroke->uri().substring(1)));
111 if(item && strokePaintServer && item->isRenderPath())
112 strokePaintServer->addClient(static_cast<const RenderPath*>(item));
114 strokePaintServer = sharedSolidPaintServer();
115 KRenderingPaintServerSolid *strokePaintServerSolid = static_cast<KRenderingPaintServerSolid *>(strokePaintServer);
116 if (stroke->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
117 strokePaintServerSolid->setColor(style->color());
119 strokePaintServerSolid->setColor(stroke->color());
122 return strokePaintServer;
125 double KSVGPainterFactory::cssPrimitiveToLength(const RenderObject* item, CSSValue *value, double defaultValue)
127 CSSPrimitiveValue *primitive = static_cast<CSSPrimitiveValue *>(value);
129 unsigned short cssType = (primitive ? primitive->primitiveType() : (unsigned short) CSSPrimitiveValue::CSS_UNKNOWN);
130 if(!(cssType > CSSPrimitiveValue::CSS_UNKNOWN && cssType <= CSSPrimitiveValue::CSS_PC))
133 if(cssType == CSSPrimitiveValue::CSS_PERCENTAGE)
135 SVGElement *element = static_cast<SVGElement *>(item->element());
136 SVGElement *viewportElement = (element ? element->viewportElement() : 0);
139 double result = primitive->getFloatValue() / 100.0;
140 return SVGHelper::PercentageOfViewport(result, viewportElement, LM_OTHER);
144 return primitive->computeLengthFloat(const_cast<RenderStyle *>(item->style()));
147 KRenderingStrokePainter KSVGPainterFactory::strokePainter(const RenderStyle* style, const RenderObject* item)
149 KRenderingStrokePainter strokePainter;
151 strokePainter.setOpacity(style->svgStyle()->strokeOpacity());
152 strokePainter.setStrokeWidth(KSVGPainterFactory::cssPrimitiveToLength(item, style->svgStyle()->strokeWidth(), 1.0));
154 CSSValueList *dashes = style->svgStyle()->strokeDashArray();
156 CSSPrimitiveValue *dash = 0;
158 unsigned long len = dashes->length();
159 for (unsigned long i = 0; i < len; i++) {
160 dash = static_cast<CSSPrimitiveValue *>(dashes->item(i));
162 array.append((float) dash->computeLengthFloat(const_cast<RenderStyle *>(style)));
165 strokePainter.setDashArray(array);
166 strokePainter.setDashOffset(KSVGPainterFactory::cssPrimitiveToLength(item, style->svgStyle()->strokeDashOffset(), 0.0));
169 strokePainter.setStrokeMiterLimit(style->svgStyle()->strokeMiterLimit());
170 strokePainter.setStrokeCapStyle((KCCapStyle) style->svgStyle()->capStyle());
171 strokePainter.setStrokeJoinStyle((KCJoinStyle) style->svgStyle()->joinStyle());
173 return strokePainter;
176 KRenderingFillPainter KSVGPainterFactory::fillPainter(const RenderStyle* style, const RenderObject* item)
178 KRenderingFillPainter fillPainter;
180 fillPainter.setFillRule(style->svgStyle()->fillRule());
181 fillPainter.setOpacity(style->svgStyle()->fillOpacity());
189 #endif // SVG_SUPPORT