1 /*
2  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
3  *               2007 Rob Buis <buis@kde.org>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "wtf/Platform.h"
28 
29 #if ENABLE(SVG)
30 #include "SVGPaintServer.h"
31 
32 #include "SVGPaintServerSolid.h"
33 #include "SVGStyledElement.h"
34 #include "SVGURIReference.h"
35 
36 namespace WebCore
37 {
38 
SVGPaintServer()39 SVGPaintServer::SVGPaintServer()
40 {
41 }
42 
~SVGPaintServer()43 SVGPaintServer::~SVGPaintServer()
44 {
45 }
46 
47 /*TextStream& operator<<(TextStream& ts, const SVGPaintServer& paintServer)
48 {
49     return paintServer.externalRepresentation(ts);
50 }*/
51 
getPaintServerById(Document * document,const AtomicString & id)52 SVGPaintServer *getPaintServerById(Document *document, const AtomicString &id)
53 {
54     SVGResource *resource = getResourceById(document, id);
55     if (resource && resource->isPaintServer()) {
56         return static_cast<SVGPaintServer *>(resource);
57     }
58 
59     return nullptr;
60 }
61 
sharedSolidPaintServer()62 SVGPaintServerSolid *SVGPaintServer::sharedSolidPaintServer()
63 {
64     static SVGPaintServerSolid *_sharedSolidPaintServer = SVGPaintServerSolid::create().releaseRef();
65 
66     return _sharedSolidPaintServer;
67 }
68 
fillPaintServer(const RenderStyle * style,const RenderObject * item)69 SVGPaintServer *SVGPaintServer::fillPaintServer(const RenderStyle *style, const RenderObject *item)
70 {
71     if (!style->svgStyle()->hasFill()) {
72         return nullptr;
73     }
74 
75     SVGPaintImpl *fill = style->svgStyle()->fillPaint();
76 
77     SVGPaintServer *fillPaintServer = nullptr;
78     SVGPaintImpl::SVGPaintType paintType = fill->paintType();
79     if (paintType == SVGPaintImpl::SVG_PAINTTYPE_URI ||
80             paintType == SVGPaintImpl::SVG_PAINTTYPE_URI_RGBCOLOR) {
81         AtomicString id(SVGURIReference::getTarget(fill->uri()));
82         fillPaintServer = getPaintServerById(item->document(), id);
83         SVGElement *svgElement = static_cast<SVGElement *>(item->element());
84         ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
85 
86         if (item->isRenderPath() && fillPaintServer) {
87             fillPaintServer->addClient(static_cast<SVGStyledElement *>(svgElement));
88         } else if (!fillPaintServer && paintType == SVGPaintImpl::SVG_PAINTTYPE_URI) {
89             svgElement->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement *>(svgElement));
90         }
91     }
92     if (paintType != SVGPaintImpl::SVG_PAINTTYPE_URI && !fillPaintServer) {
93         fillPaintServer = sharedSolidPaintServer();
94         SVGPaintServerSolid *fillPaintServerSolid = static_cast<SVGPaintServerSolid *>(fillPaintServer);
95         if (paintType == SVGPaintImpl::SVG_PAINTTYPE_CURRENTCOLOR) {
96             fillPaintServerSolid->setColor(style->color());
97         } else {
98             fillPaintServerSolid->setColor(fill->color());
99         }
100         // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
101         if (!fillPaintServerSolid->color().isValid()) {
102             fillPaintServer = nullptr;
103         }
104     }
105     if (!fillPaintServer) {
106         // default value (black), see bug 11017
107         fillPaintServer = sharedSolidPaintServer();
108         static_cast<SVGPaintServerSolid *>(fillPaintServer)->setColor(/*Color::black*/Qt::black);
109     }
110     return fillPaintServer;
111 }
112 
strokePaintServer(const RenderStyle * style,const RenderObject * item)113 SVGPaintServer *SVGPaintServer::strokePaintServer(const RenderStyle *style, const RenderObject *item)
114 {
115     if (!style->svgStyle()->hasStroke()) {
116         return nullptr;
117     }
118 
119     SVGPaintImpl *stroke = style->svgStyle()->strokePaint();
120 
121     SVGPaintServer *strokePaintServer = nullptr;
122     SVGPaintImpl::SVGPaintType paintType = stroke->paintType();
123     if (paintType == SVGPaintImpl::SVG_PAINTTYPE_URI ||
124             paintType == SVGPaintImpl::SVG_PAINTTYPE_URI_RGBCOLOR) {
125         AtomicString id(SVGURIReference::getTarget(stroke->uri()));
126         strokePaintServer = getPaintServerById(item->document(), id);
127 
128         SVGElement *svgElement = static_cast<SVGElement *>(item->element());
129         ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
130 
131         if (item->isRenderPath() && strokePaintServer) {
132             strokePaintServer->addClient(static_cast<SVGStyledElement *>(svgElement));
133         } else if (!strokePaintServer && paintType == SVGPaintImpl::SVG_PAINTTYPE_URI) {
134             svgElement->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement *>(svgElement));
135         }
136     }
137     if (paintType != SVGPaintImpl::SVG_PAINTTYPE_URI && !strokePaintServer) {
138         strokePaintServer = sharedSolidPaintServer();
139         SVGPaintServerSolid *strokePaintServerSolid = static_cast<SVGPaintServerSolid *>(strokePaintServer);
140         if (paintType == SVGPaintImpl::SVG_PAINTTYPE_CURRENTCOLOR) {
141             strokePaintServerSolid->setColor(style->color());
142         } else {
143             strokePaintServerSolid->setColor(stroke->color());
144         }
145         // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
146         if (!strokePaintServerSolid->color().isValid()) {
147             strokePaintServer = nullptr;
148         }
149     }
150 
151     return strokePaintServer;
152 }
153 
dashArrayFromRenderingStyle(const RenderStyle * style)154 DashArray dashArrayFromRenderingStyle(const RenderStyle *style)
155 {
156     Q_UNUSED(style);
157     DashArray array;
158 
159     /*CSSValueList* dashes = style->svgStyle()->strokeDashArray();
160     if (dashes) {
161         CSSPrimitiveValue* dash = 0;
162         unsigned long len = dashes->length();
163         for (unsigned long i = 0; i < len; i++) {
164             dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i));
165             if (!dash)
166                 continue;
167 
168             array.append((float) dash->computeLengthFloat(const_cast<RenderStyle*>(style)));
169         }
170     }*/
171 
172     return array;
173 }
174 
175 } // namespace WebCore
176 
177 #endif
178