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 "KRenderingPaintServerGradient.h"
33 #include "KRenderingPaintServerSolid.h"
34 #include "KRenderingStrokePainter.h"
35 #include "RenderObject.h"
36 #include "SVGLength.h"
37 #include "SVGRenderStyle.h"
38 #include "SVGStyledElement.h"
43 static KRenderingPaintServerSolid* sharedSolidPaintServer()
45 static KRenderingPaintServerSolid* _sharedSolidPaintServer = 0;
46 if (!_sharedSolidPaintServer)
47 _sharedSolidPaintServer = static_cast<KRenderingPaintServerSolid*>(renderingDevice()->createPaintServer(PS_SOLID));
48 return _sharedSolidPaintServer;
51 bool KSVGPainterFactory::isFilled(const RenderStyle* style)
53 if (style->svgStyle()->fillPaint()->paintType() == SVGPaint::SVG_PAINTTYPE_NONE)
58 KRenderingPaintServer* KSVGPainterFactory::fillPaintServer(const RenderStyle* style, const RenderObject* item)
63 SVGPaint* fill = style->svgStyle()->fillPaint();
65 KRenderingPaintServer* fillPaintServer = 0;
66 if (fill->paintType() == SVGPaint::SVG_PAINTTYPE_URI) {
67 fillPaintServer = getPaintServerById(item->document(), AtomicString(fill->uri().substring(1)));
68 if (fillPaintServer && item->isRenderPath())
69 fillPaintServer->addClient(static_cast<const RenderPath*>(item));
70 if (!fillPaintServer) {
71 // default value (black), see bug 11017
72 fillPaintServer = sharedSolidPaintServer();
73 static_cast<KRenderingPaintServerSolid*>(fillPaintServer)->setColor(Color::black);
76 fillPaintServer = sharedSolidPaintServer();
77 KRenderingPaintServerSolid* fillPaintServerSolid = static_cast<KRenderingPaintServerSolid*>(fillPaintServer);
78 if (fill->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
79 fillPaintServerSolid->setColor(style->color());
81 fillPaintServerSolid->setColor(fill->color());
83 return fillPaintServer;
87 bool KSVGPainterFactory::isStroked(const RenderStyle* style)
89 if (style->svgStyle()->strokePaint()->paintType() == SVGPaint::SVG_PAINTTYPE_NONE)
94 KRenderingPaintServer* KSVGPainterFactory::strokePaintServer(const RenderStyle* style, const RenderObject* item)
96 if (!isStroked(style))
99 SVGPaint* stroke = style->svgStyle()->strokePaint();
101 KRenderingPaintServer* strokePaintServer = 0;
102 if (stroke->paintType() == SVGPaint::SVG_PAINTTYPE_URI) {
103 strokePaintServer = getPaintServerById(item->document(), AtomicString(stroke->uri().substring(1)));
104 if (item && strokePaintServer && item->isRenderPath())
105 strokePaintServer->addClient(static_cast<const RenderPath*>(item));
107 strokePaintServer = sharedSolidPaintServer();
108 KRenderingPaintServerSolid* strokePaintServerSolid = static_cast<KRenderingPaintServerSolid*>(strokePaintServer);
109 if (stroke->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
110 strokePaintServerSolid->setColor(style->color());
112 strokePaintServerSolid->setColor(stroke->color());
115 return strokePaintServer;
118 double KSVGPainterFactory::cssPrimitiveToLength(const RenderObject* item, CSSValue *value, double defaultValue)
120 CSSPrimitiveValue* primitive = static_cast<CSSPrimitiveValue*>(value);
122 unsigned short cssType = (primitive ? primitive->primitiveType() : (unsigned short) CSSPrimitiveValue::CSS_UNKNOWN);
123 if (!(cssType > CSSPrimitiveValue::CSS_UNKNOWN && cssType <= CSSPrimitiveValue::CSS_PC))
126 if (cssType == CSSPrimitiveValue::CSS_PERCENTAGE) {
127 SVGElement* element = static_cast<SVGElement*>(item->element());
128 SVGElement* viewportElement = (element ? element->viewportElement() : 0);
129 if (viewportElement) {
130 double result = primitive->getFloatValue() / 100.0;
131 return SVGHelper::PercentageOfViewport(result, viewportElement, LM_OTHER);
135 return primitive->computeLengthFloat(const_cast<RenderStyle*>(item->style()));
138 KRenderingStrokePainter KSVGPainterFactory::strokePainter(const RenderStyle* style, const RenderObject* item)
140 KRenderingStrokePainter strokePainter;
142 strokePainter.setOpacity(style->svgStyle()->strokeOpacity());
143 strokePainter.setStrokeWidth(KSVGPainterFactory::cssPrimitiveToLength(item, style->svgStyle()->strokeWidth(), 1.0));
145 CSSValueList* dashes = style->svgStyle()->strokeDashArray();
147 CSSPrimitiveValue* dash = 0;
149 unsigned long len = dashes->length();
150 for (unsigned long i = 0; i < len; i++) {
151 dash = static_cast<CSSPrimitiveValue*>(dashes->item(i));
153 array.append((float) dash->computeLengthFloat(const_cast<RenderStyle*>(style)));
156 strokePainter.setDashArray(array);
157 strokePainter.setDashOffset(KSVGPainterFactory::cssPrimitiveToLength(item, style->svgStyle()->strokeDashOffset(), 0.0));
160 strokePainter.setStrokeMiterLimit(style->svgStyle()->strokeMiterLimit());
161 strokePainter.setStrokeCapStyle((KCCapStyle) style->svgStyle()->capStyle());
162 strokePainter.setStrokeJoinStyle((KCJoinStyle) style->svgStyle()->joinStyle());
164 return strokePainter;
167 KRenderingFillPainter KSVGPainterFactory::fillPainter(const RenderStyle* style, const RenderObject* item)
169 KRenderingFillPainter fillPainter;
171 fillPainter.setFillRule(style->svgStyle()->fillRule());
172 fillPainter.setOpacity(style->svgStyle()->fillOpacity());
180 #endif // SVG_SUPPORT