RenderSVGResource.cpp [plain text]
#include "config.h"
#if ENABLE(SVG)
#include "RenderSVGResource.h"
#include "RenderSVGResourceContainer.h"
#include "RenderSVGResourceSolidColor.h"
#include "SVGURIReference.h"
namespace WebCore {
static inline void registerPendingResource(const AtomicString& id, const SVGPaint::SVGPaintType& paintType, const RenderObject* object)
{
if (paintType != SVGPaint::SVG_PAINTTYPE_URI)
return;
SVGElement* svgElement = static_cast<SVGElement*>(object->node());
ASSERT(svgElement);
ASSERT(svgElement->isStyled());
object->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement*>(svgElement));
}
inline void RenderSVGResource::adjustColorForPseudoRules(const RenderStyle* style, bool useFillPaint, Color& color)
{
if (style->insideLink() != InsideVisitedLink)
return;
RenderStyle* visitedStyle = style->getCachedPseudoStyle(VISITED_LINK);
SVGPaint* visitedPaint = useFillPaint ? visitedStyle->svgStyle()->fillPaint() : visitedStyle->svgStyle()->strokePaint();
if (visitedPaint->paintType() == SVGPaint::SVG_PAINTTYPE_URI)
return;
Color visitedColor;
if (visitedPaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
visitedColor = visitedStyle->color();
else
visitedColor = visitedPaint->color();
if (visitedColor.isValid())
color = Color(visitedColor.red(), visitedColor.green(), visitedColor.blue(), color.alpha());
}
RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* object, const RenderStyle* style)
{
ASSERT(object);
ASSERT(style);
const SVGRenderStyle* svgStyle = style->svgStyle();
if (!svgStyle || !svgStyle->hasFill())
return 0;
SVGPaint* fillPaint = svgStyle->fillPaint();
ASSERT(fillPaint);
RenderSVGResource* fillPaintingResource = 0;
SVGPaint::SVGPaintType paintType = fillPaint->paintType();
if (paintType == SVGPaint::SVG_PAINTTYPE_URI
|| paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) {
AtomicString id(SVGURIReference::getTarget(fillPaint->uri()));
fillPaintingResource = getRenderSVGResourceContainerById(object->document(), id);
if (!fillPaintingResource)
registerPendingResource(id, paintType, object);
}
if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !fillPaintingResource) {
RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
fillPaintingResource = solidResource;
Color fillColor;
if (fillPaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
fillColor = style->visitedDependentColor(CSSPropertyColor);
else
fillColor = fillPaint->color();
adjustColorForPseudoRules(style, true , fillColor);
if (fillColor.isValid())
solidResource->setColor(fillColor);
else
fillPaintingResource = 0;
}
if (!fillPaintingResource) {
RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
solidResource->setColor(Color::black);
fillPaintingResource = solidResource;
}
return fillPaintingResource;
}
RenderSVGResource* RenderSVGResource::strokePaintingResource(const RenderObject* object, const RenderStyle* style)
{
ASSERT(object);
ASSERT(style);
const SVGRenderStyle* svgStyle = style->svgStyle();
if (!svgStyle || !svgStyle->hasStroke())
return 0;
SVGPaint* strokePaint = svgStyle->strokePaint();
ASSERT(strokePaint);
RenderSVGResource* strokePaintingResource = 0;
FloatRect objectBoundingBox = object->objectBoundingBox();
SVGPaint::SVGPaintType paintType = strokePaint->paintType();
if (!objectBoundingBox.isEmpty()
&& (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)) {
AtomicString id(SVGURIReference::getTarget(strokePaint->uri()));
strokePaintingResource = getRenderSVGResourceContainerById(object->document(), id);
if (!strokePaintingResource)
registerPendingResource(id, paintType, object);
}
if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !strokePaintingResource) {
RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
strokePaintingResource = solidResource;
Color strokeColor;
if (strokePaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR)
strokeColor = style->visitedDependentColor(CSSPropertyColor);
else
strokeColor = strokePaint->color();
adjustColorForPseudoRules(style, false , strokeColor);
if (strokeColor.isValid())
solidResource->setColor(strokeColor);
else
strokePaintingResource = 0;
}
if (!strokePaintingResource) {
RenderSVGResourceSolidColor* solidResource = sharedSolidPaintingResource();
solidResource->setColor(Color::black);
strokePaintingResource = solidResource;
}
return strokePaintingResource;
}
RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
{
static RenderSVGResourceSolidColor* s_sharedSolidPaintingResource = 0;
if (!s_sharedSolidPaintingResource)
s_sharedSolidPaintingResource = new RenderSVGResourceSolidColor;
return s_sharedSolidPaintingResource;
}
void RenderSVGResource::markForLayoutAndResourceInvalidation(RenderObject* object)
{
ASSERT(object);
ASSERT(object->node());
ASSERT(object->node()->isSVGElement());
object->setNeedsLayout(true);
SVGElement* element = static_cast<SVGElement*>(object->node());
if (!element->isStyled())
return;
static_cast<SVGStyledElement*>(element)->invalidateResourcesInAncestorChain();
}
}
#endif