File indexing completed on 2024-05-12 15:39:15

0001 /*
0002  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
0003  *               2007 Rob Buis <buis@kde.org>
0004  *
0005  * Redistribution and use in source and binary forms, with or without
0006  * modification, are permitted provided that the following conditions
0007  * are met:
0008  * 1. Redistributions of source code must retain the above copyright
0009  *    notice, this list of conditions and the following disclaimer.
0010  * 2. Redistributions in binary form must reproduce the above copyright
0011  *    notice, this list of conditions and the following disclaimer in the
0012  *    documentation and/or other materials provided with the distribution.
0013  *
0014  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
0015  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0016  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0017  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
0018  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0019  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0020  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0021  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
0022  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0023  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0024  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0025  */
0026 
0027 #include "wtf/Platform.h"
0028 
0029 #if ENABLE(SVG)
0030 #include "SVGPaintServer.h"
0031 
0032 #include "SVGPaintServerSolid.h"
0033 #include "SVGStyledElement.h"
0034 #include "SVGURIReference.h"
0035 
0036 namespace WebCore
0037 {
0038 
0039 SVGPaintServer::SVGPaintServer()
0040 {
0041 }
0042 
0043 SVGPaintServer::~SVGPaintServer()
0044 {
0045 }
0046 
0047 /*TextStream& operator<<(TextStream& ts, const SVGPaintServer& paintServer)
0048 {
0049     return paintServer.externalRepresentation(ts);
0050 }*/
0051 
0052 SVGPaintServer *getPaintServerById(Document *document, const AtomicString &id)
0053 {
0054     SVGResource *resource = getResourceById(document, id);
0055     if (resource && resource->isPaintServer()) {
0056         return static_cast<SVGPaintServer *>(resource);
0057     }
0058 
0059     return nullptr;
0060 }
0061 
0062 SVGPaintServerSolid *SVGPaintServer::sharedSolidPaintServer()
0063 {
0064     static SVGPaintServerSolid *_sharedSolidPaintServer = SVGPaintServerSolid::create().releaseRef();
0065 
0066     return _sharedSolidPaintServer;
0067 }
0068 
0069 SVGPaintServer *SVGPaintServer::fillPaintServer(const RenderStyle *style, const RenderObject *item)
0070 {
0071     if (!style->svgStyle()->hasFill()) {
0072         return nullptr;
0073     }
0074 
0075     SVGPaintImpl *fill = style->svgStyle()->fillPaint();
0076 
0077     SVGPaintServer *fillPaintServer = nullptr;
0078     SVGPaintImpl::SVGPaintType paintType = fill->paintType();
0079     if (paintType == SVGPaintImpl::SVG_PAINTTYPE_URI ||
0080             paintType == SVGPaintImpl::SVG_PAINTTYPE_URI_RGBCOLOR) {
0081         AtomicString id(SVGURIReference::getTarget(fill->uri()));
0082         fillPaintServer = getPaintServerById(item->document(), id);
0083         SVGElement *svgElement = static_cast<SVGElement *>(item->element());
0084         ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
0085 
0086         if (item->isRenderPath() && fillPaintServer) {
0087             fillPaintServer->addClient(static_cast<SVGStyledElement *>(svgElement));
0088         } else if (!fillPaintServer && paintType == SVGPaintImpl::SVG_PAINTTYPE_URI) {
0089             svgElement->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement *>(svgElement));
0090         }
0091     }
0092     if (paintType != SVGPaintImpl::SVG_PAINTTYPE_URI && !fillPaintServer) {
0093         fillPaintServer = sharedSolidPaintServer();
0094         SVGPaintServerSolid *fillPaintServerSolid = static_cast<SVGPaintServerSolid *>(fillPaintServer);
0095         if (paintType == SVGPaintImpl::SVG_PAINTTYPE_CURRENTCOLOR) {
0096             fillPaintServerSolid->setColor(style->color());
0097         } else {
0098             fillPaintServerSolid->setColor(fill->color());
0099         }
0100         // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
0101         if (!fillPaintServerSolid->color().isValid()) {
0102             fillPaintServer = nullptr;
0103         }
0104     }
0105     if (!fillPaintServer) {
0106         // default value (black), see bug 11017
0107         fillPaintServer = sharedSolidPaintServer();
0108         static_cast<SVGPaintServerSolid *>(fillPaintServer)->setColor(/*Color::black*/Qt::black);
0109     }
0110     return fillPaintServer;
0111 }
0112 
0113 SVGPaintServer *SVGPaintServer::strokePaintServer(const RenderStyle *style, const RenderObject *item)
0114 {
0115     if (!style->svgStyle()->hasStroke()) {
0116         return nullptr;
0117     }
0118 
0119     SVGPaintImpl *stroke = style->svgStyle()->strokePaint();
0120 
0121     SVGPaintServer *strokePaintServer = nullptr;
0122     SVGPaintImpl::SVGPaintType paintType = stroke->paintType();
0123     if (paintType == SVGPaintImpl::SVG_PAINTTYPE_URI ||
0124             paintType == SVGPaintImpl::SVG_PAINTTYPE_URI_RGBCOLOR) {
0125         AtomicString id(SVGURIReference::getTarget(stroke->uri()));
0126         strokePaintServer = getPaintServerById(item->document(), id);
0127 
0128         SVGElement *svgElement = static_cast<SVGElement *>(item->element());
0129         ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
0130 
0131         if (item->isRenderPath() && strokePaintServer) {
0132             strokePaintServer->addClient(static_cast<SVGStyledElement *>(svgElement));
0133         } else if (!strokePaintServer && paintType == SVGPaintImpl::SVG_PAINTTYPE_URI) {
0134             svgElement->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement *>(svgElement));
0135         }
0136     }
0137     if (paintType != SVGPaintImpl::SVG_PAINTTYPE_URI && !strokePaintServer) {
0138         strokePaintServer = sharedSolidPaintServer();
0139         SVGPaintServerSolid *strokePaintServerSolid = static_cast<SVGPaintServerSolid *>(strokePaintServer);
0140         if (paintType == SVGPaintImpl::SVG_PAINTTYPE_CURRENTCOLOR) {
0141             strokePaintServerSolid->setColor(style->color());
0142         } else {
0143             strokePaintServerSolid->setColor(stroke->color());
0144         }
0145         // FIXME: Ideally invalid colors would never get set on the RenderStyle and this could turn into an ASSERT
0146         if (!strokePaintServerSolid->color().isValid()) {
0147             strokePaintServer = nullptr;
0148         }
0149     }
0150 
0151     return strokePaintServer;
0152 }
0153 
0154 DashArray dashArrayFromRenderingStyle(const RenderStyle *style)
0155 {
0156     Q_UNUSED(style);
0157     DashArray array;
0158 
0159     /*CSSValueList* dashes = style->svgStyle()->strokeDashArray();
0160     if (dashes) {
0161         CSSPrimitiveValue* dash = 0;
0162         unsigned long len = dashes->length();
0163         for (unsigned long i = 0; i < len; i++) {
0164             dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i));
0165             if (!dash)
0166                 continue;
0167 
0168             array.append((float) dash->computeLengthFloat(const_cast<RenderStyle*>(style)));
0169         }
0170     }*/
0171 
0172     return array;
0173 }
0174 
0175 } // namespace WebCore
0176 
0177 #endif