String SVGViewSpec::preserveAspectRatioString() const { if (!preserveAspectRatio()) return String(); return preserveAspectRatio()->baseValue()->valueAsString(); }
void SVGViewSpec::reset() { resetZoomAndPan(); m_transform->baseValue()->clear(); updateViewBox(FloatRect()); ASSERT(preserveAspectRatio()); preserveAspectRatio()->baseValue()->setAlign(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID); preserveAspectRatio()->baseValue()->setMeetOrSlice(SVGPreserveAspectRatio::SVG_MEETORSLICE_MEET); m_viewTargetString = emptyString(); }
RenderObject* SVGSVGElement::createRenderer(RenderArena* arena, RenderStyle*) { RenderSVGContainer* rootContainer = new (arena) RenderSVGContainer(this); // FIXME: All this setup should be done after attributesChanged, not here. rootContainer->setViewBox(viewBox()); rootContainer->setAlign(KCAlign(preserveAspectRatio()->align() - 1)); rootContainer->setSlice(preserveAspectRatio()->meetOrSlice() == SVGPreserveAspectRatio::SVG_MEETORSLICE_SLICE); return rootContainer; }
void SVGViewSpec::reset() { resetZoomAndPan(); m_transform->baseValue()->clear(); updateViewBox(FloatRect()); ASSERT(preserveAspectRatio()); preserveAspectRatio()->baseValue()->setAlign( SVGPreserveAspectRatio::kSvgPreserveaspectratioXmidymid); preserveAspectRatio()->baseValue()->setMeetOrSlice( SVGPreserveAspectRatio::kSvgMeetorsliceMeet); m_viewTargetString = emptyString(); }
bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end) { if (!skipToken(ptr, end, "svgView")) return false; if (!skipExactly<CharType>(ptr, end, '(')) return false; while (ptr < end && *ptr != ')') { ViewSpecFunctionType functionType = scanViewSpecFunction(ptr, end); if (functionType == Unknown) return false; if (!skipExactly<CharType>(ptr, end, '(')) return false; switch (functionType) { case ViewBox: { float x = 0.0f; float y = 0.0f; float width = 0.0f; float height = 0.0f; if (!(parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, DisallowWhitespace))) return false; updateViewBox(FloatRect(x, y, width, height)); break; } case ViewTarget: { const CharType* viewTargetStart = ptr; skipUntil<CharType>(ptr, end, ')'); if (ptr == viewTargetStart) return false; m_viewTargetString = String(viewTargetStart, ptr - viewTargetStart); break; } case ZoomAndPan: if (!parseZoomAndPan(ptr, end)) return false; break; case PreserveAspectRatio: if (!preserveAspectRatio()->baseValue()->parse(ptr, end, false)) return false; break; case Transform: m_transform->baseValue()->parse(ptr, end); break; default: NOTREACHED(); break; } if (!skipExactly<CharType>(ptr, end, ')')) return false; skipExactly<CharType>(ptr, end, ';'); } return skipExactly<CharType>(ptr, end, ')'); }
void SVGSVGElement::inheritViewAttributes(SVGViewElement* viewElement) { setUseCurrentView(true); if (viewElement->hasAttribute(SVGNames::viewBoxAttr)) currentView()->setViewBox(viewElement->viewBox()); else currentView()->setViewBox(viewBox()); if (viewElement->hasAttribute(SVGNames::preserveAspectRatioAttr)) { currentView()->preserveAspectRatio()->setAlign(viewElement->preserveAspectRatio()->align()); currentView()->preserveAspectRatio()->setMeetOrSlice(viewElement->preserveAspectRatio()->meetOrSlice()); } else { currentView()->preserveAspectRatio()->setAlign(preserveAspectRatio()->align()); currentView()->preserveAspectRatio()->setMeetOrSlice(preserveAspectRatio()->meetOrSlice()); } if (viewElement->hasAttribute(SVGNames::zoomAndPanAttr)) currentView()->setZoomAndPan(viewElement->zoomAndPan()); renderer()->setNeedsLayout(true); }
TransformationMatrix SVGFitToViewBox::viewBoxToViewTransform(float viewWidth, float viewHeight) const { FloatRect viewBoxRect = viewBox(); if (!viewBoxRect.width() || !viewBoxRect.height()) return TransformationMatrix(); return preserveAspectRatio()->getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), 0, 0, viewWidth, viewHeight); }
SVGPreserveAspectRatio* SVGSVGElement::currentPreserveAspectRatio() const { if (m_viewSpec) return m_viewSpec->preserveAspectRatio(); if (!viewBox()->currentValue()->isValid() && shouldSynthesizeViewBox()) { // If no viewBox is specified and we're embedded through SVGImage, then // synthesize a pAR with the value 'none'. SVGPreserveAspectRatio* synthesizedPAR = SVGPreserveAspectRatio::create(); synthesizedPAR->setAlign( SVGPreserveAspectRatio::kSvgPreserveaspectratioNone); return synthesizedPAR; } return preserveAspectRatio()->currentValue(); }
AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const { FloatRect viewBoxRect; if (useCurrentView()) { if (currentView()) // what if we should use it but it is not set? viewBoxRect = currentView()->viewBox(); } else viewBoxRect = viewBox(); AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(viewBoxRect, preserveAspectRatio(), viewWidth, viewHeight); if (useCurrentView() && currentView()) return currentView()->transform()->concatenate().matrix() * ctm; return ctm; }
AffineTransform SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const { if (!m_useCurrentView || !m_viewSpec) return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), preserveAspectRatio()->currentValue(), viewWidth, viewHeight); AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), m_viewSpec->preserveAspectRatio()->currentValue(), viewWidth, viewHeight); RefPtrWillBeRawPtr<SVGTransformList> transformList = m_viewSpec->transform(); if (transformList->isEmpty()) return ctm; AffineTransform transform; if (transformList->concatenate(transform)) ctm *= transform; return ctm; }
SVGViewSpec::SVGViewSpec(SVGSVGElement* contextElement) // Note: addToPropertyMap is not needed, as SVGViewSpec do not correspond to an element. // Note: We make tear-offs' contextElement the target element of SVGViewSpec. // This contextElement will be only used for keeping this alive from the tearoff. // SVGSVGElement holds a strong-ref to this SVGViewSpec, so this is kept alive as: // AnimatedProperty tearoff -(contextElement)-> SVGSVGElement -(RefPtr)-> SVGViewSpec. : SVGFitToViewBox(contextElement, PropertyMapPolicySkip) , m_contextElement(contextElement) , m_transform(SVGAnimatedTransformList::create(contextElement, SVGNames::transformAttr, SVGTransformList::create())) { ASSERT(m_contextElement); viewBox()->setReadOnly(); preserveAspectRatio()->setReadOnly(); m_transform->setReadOnly(); // Note: addToPropertyMap is not needed, as SVGViewSpec do not correspond to an element. }
TransformationMatrix SVGSVGElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const { FloatRect viewBoxRect; if (useCurrentView()) { if (currentView()) // what if we should use it but it is not set? viewBoxRect = currentView()->viewBox(); } else viewBoxRect = viewBox(); if (!viewBoxRect.width() || !viewBoxRect.height()) return TransformationMatrix(); TransformationMatrix ctm = preserveAspectRatio()->getCTM(viewBoxRect.x(), viewBoxRect.y(), viewBoxRect.width(), viewBoxRect.height(), 0, 0, viewWidth, viewHeight); if (useCurrentView() && currentView()) return currentView()->transform()->concatenate().matrix() * ctm; return ctm; }
AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const { return SVGFitToViewBox::viewBoxToViewTransform(viewBox(), preserveAspectRatio(), viewWidth, viewHeight); }
bool SVGViewSpec::parseViewSpecInternal(const CharType* ptr, const CharType* end) { if (!skipString(ptr, end, svgViewSpec, WTF_ARRAY_LENGTH(svgViewSpec))) return false; if (ptr >= end || *ptr != '(') return false; ptr++; while (ptr < end && *ptr != ')') { if (*ptr == 'v') { if (skipString(ptr, end, viewBoxSpec, WTF_ARRAY_LENGTH(viewBoxSpec))) { if (ptr >= end || *ptr != '(') return false; ptr++; float x = 0.0f; float y = 0.0f; float width = 0.0f; float height = 0.0f; if (!(parseNumber(ptr, end, x) && parseNumber(ptr, end, y) && parseNumber(ptr, end, width) && parseNumber(ptr, end, height, DisallowWhitespace))) return false; updateViewBox(FloatRect(x, y, width, height)); if (ptr >= end || *ptr != ')') return false; ptr++; } else if (skipString(ptr, end, viewTargetSpec, WTF_ARRAY_LENGTH(viewTargetSpec))) { if (ptr >= end || *ptr != '(') return false; const CharType* viewTargetStart = ++ptr; while (ptr < end && *ptr != ')') ptr++; if (ptr >= end) return false; m_viewTargetString = String(viewTargetStart, ptr - viewTargetStart); ptr++; } else return false; } else if (*ptr == 'z') { if (!skipString(ptr, end, zoomAndPanSpec, WTF_ARRAY_LENGTH(zoomAndPanSpec))) return false; if (ptr >= end || *ptr != '(') return false; ptr++; if (!parseZoomAndPan(ptr, end)) return false; if (ptr >= end || *ptr != ')') return false; ptr++; } else if (*ptr == 'p') { if (!skipString(ptr, end, preserveAspectRatioSpec, WTF_ARRAY_LENGTH(preserveAspectRatioSpec))) return false; if (ptr >= end || *ptr != '(') return false; ptr++; if (!preserveAspectRatio()->baseValue()->parse(ptr, end, false)) return false; if (ptr >= end || *ptr != ')') return false; ptr++; } else if (*ptr == 't') { if (!skipString(ptr, end, transformSpec, WTF_ARRAY_LENGTH(transformSpec))) return false; if (ptr >= end || *ptr != '(') return false; ptr++; m_transform->baseValue()->parse(ptr, end); if (ptr >= end || *ptr != ')') return false; ptr++; } else return false; if (ptr < end && *ptr == ';') ptr++; } if (ptr >= end || *ptr != ')') return false; return true; }