void SVGElementInstance::updateInstance(SVGElement* element) { ASSERT(element == m_element); ASSERT(m_shadowTreeElement); // TODO: Eventually come up with a more optimized updating logic for the cases below: // // <symbol>: We can't just clone the original element, we need to apply // the same "replace by generated content" logic that SVGUseElement does. // // <svg>: <use> on <svg> is too rare to actually implement it faster. // If someone still wants to do it: recloning, adjusting width/height attributes is enough. // // <use>: Too hard to get it right in a fast way. Recloning seems the only option. if (m_element->hasTagName(SVGNames::symbolTag) || m_element->hasTagName(SVGNames::svgTag) || containsUseChildNode(m_element.get())) { m_useElement->buildPendingResource(); return; } // For all other nodes this logic is sufficient. RefPtr<Node> clone = m_element->cloneNode(true); SVGElement* svgClone = svg_dynamic_cast(clone.get()); ASSERT(svgClone); // Replace node in the <use> shadow tree ExceptionCode ec = 0; m_shadowTreeElement->parentNode()->replaceChild(clone.release(), m_shadowTreeElement, ec); ASSERT(ec == 0); m_shadowTreeElement = svgClone; }
void SVGTRefElement::updateReferencedText() { Element* targetElement = ownerDocument()->getElementById(SVGURIReference::getTarget(href())); SVGElement* target = svg_dynamic_cast(targetElement); if (target) { ExceptionCode ignore = 0; setTextContent(target->textContent(), ignore); } }
bool SVGSwitchElement::childShouldCreateRenderer(Node* child) const { for (Node* n = firstChild(); n != 0; n = n->nextSibling()) { SVGElement* element = svg_dynamic_cast(n); if (element && element->isValid()) return (n == child); // Only allow this child if it's the first valid child } return false; }
void SVGStyledElement::rebuildRenderer() const { if (!renderer() || !renderer()->isRenderPath()) return; RenderPath* renderPath = static_cast<RenderPath*>(renderer()); SVGElement* parentElement = svg_dynamic_cast(parentNode()); if (parentElement && parentElement->renderer() && parentElement->isStyled() && parentElement->childShouldCreateRenderer(const_cast<SVGStyledElement*>(this))) renderPath->setNeedsLayout(true); }
void SVGStyledElement::notifyResourceParentIfExistant() const { Node* node = parentNode(); while (node) { if (node->hasTagName(SVGNames::linearGradientTag) || node->hasTagName(SVGNames::radialGradientTag) || node->hasTagName(SVGNames::patternTag) || node->hasTagName(SVGNames::clipPathTag) || node->hasTagName(SVGNames::markerTag) || node->hasTagName(SVGNames::maskTag)) { SVGElement* element = svg_dynamic_cast(node); ASSERT(element); element->notifyAttributeChange(); } node = node->parentNode(); } }
void SVGPatternElement::drawPatternContentIntoTile(const SVGPatternElement* target, const IntSize& newSize, KCanvasMatrix patternTransformMatrix) const { KRenderingDevice* device = renderingDevice(); SVGStyledElement* activeElement = static_cast<SVGStyledElement*>(m_paintServer->activeClient()->element()); bool bbox = (patternUnits()->baseVal() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX); const SVGStyledElement* savedContext = 0; if (bbox) { if (width()->baseVal()->unitType() != SVGLength::SVG_LENGTHTYPE_PERCENTAGE) width()->baseVal()->newValueSpecifiedUnits(SVGLength::SVG_LENGTHTYPE_PERCENTAGE, width()->baseVal()->value() * 100.); if (height()->baseVal()->unitType() != SVGLength::SVG_LENGTHTYPE_PERCENTAGE) height()->baseVal()->newValueSpecifiedUnits(SVGLength::SVG_LENGTHTYPE_PERCENTAGE, height()->baseVal()->value() * 100.); if (activeElement) savedContext = const_cast<SVGPatternElement* >(this)->pushAttributeContext(activeElement); } delete m_tile; m_tile = static_cast<KCanvasImage*>(device->createResource(RS_IMAGE)); m_tile->init(newSize); KRenderingDeviceContext* patternContext = device->contextForImage(m_tile); device->pushContext(patternContext); FloatRect rect(x()->baseVal()->value(), y()->baseVal()->value(), width()->baseVal()->value(), height()->baseVal()->value()); m_paintServer->setBbox(rect); m_paintServer->setPatternTransform(patternTransformMatrix); m_paintServer->setTile(m_tile); OwnPtr<GraphicsContext> context(patternContext->createGraphicsContext()); for(Node *n = target->firstChild(); n != 0; n = n->nextSibling()) { SVGElement* elem = svg_dynamic_cast(n); if (!elem || !elem->isStyled()) continue; SVGStyledElement* e = static_cast<SVGStyledElement* >(elem); RenderObject *item = e->renderer(); if (!item) continue; #if 0 // FIXME: None of this code seems to be necessary // to pass the w3c tests (and infact breaks them) // However, I'm leaving it #if 0'd for now until // I can quiz WildFox on the subject -- ecs 11/24/05 // It's possible that W3C-SVG-1.1/coords-units-01-b // is failing due to lack of this code. KCanvasMatrix savedMatrix = item->localTransform(); const SVGStyledElement* savedContext = 0; if (patternContentUnits()->baseVal() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { if (activeElement) savedContext = e->pushAttributeContext(activeElement); } // Take into account viewportElement's viewBox, if existant... if (viewportElement() && viewportElement()->hasTagName(SVGNames::svgTag)) { SVGSVGElement* svgElement = static_cast<SVGSVGElement* >(viewportElement()); RefPtr<SVGMatrix> svgCTM = svgElement->getCTM(); RefPtr<SVGMatrix> ctm = getCTM(); KCanvasMatrix newMatrix(svgCTM->matrix()); newMatrix.multiply(savedMatrix); newMatrix.scale(1.0 / ctm->a(), 1.0 / ctm->d()); item->setLocalTransform(newMatrix.matrix()); } #endif RenderObject::PaintInfo info(context.get(), IntRect(), PaintPhaseForeground, 0, 0, 0); item->paint(info, 0, 0); #if 0 if (savedContext) e->pushAttributeContext(savedContext); item->setLocalTransform(savedMatrix.matrix()); #endif } if (savedContext) const_cast<SVGPatternElement* >(this)->pushAttributeContext(savedContext); device->popContext(); delete patternContext; }