Bug 801317 - Support transforms in SVG fragment identifiers. r=dholbert

This commit is contained in:
Robert Longson 2012-10-22 10:13:24 +01:00
Родитель fdfbe15385
Коммит 8dc4bfd15f
6 изменённых файлов: 53 добавлений и 3 удалений

Просмотреть файл

@ -7,6 +7,7 @@
#include "nsIDOMSVGDocument.h"
#include "nsSVGSVGElement.h"
#include "nsSVGViewElement.h"
#include "SVGAnimatedTransformList.h"
using namespace mozilla;
@ -91,6 +92,13 @@ SVGFragmentIdentifier::RestoreOldZoomAndPan(nsSVGSVGElement *root)
}
}
void
SVGFragmentIdentifier::ClearTransform(nsSVGSVGElement *root)
{
root->mFragmentIdentifierTransform = nullptr;
root->InvalidateTransformNotifyFrame();
}
bool
SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
nsSVGSVGElement *root)
@ -106,6 +114,7 @@ SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
bool viewBoxFound = false;
bool preserveAspectRatioFound = false;
bool transformFound = false;
bool zoomAndPanFound = false;
// Each token is a SVGViewAttribute
@ -144,6 +153,19 @@ SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
return false;
}
preserveAspectRatioFound = true;
} else if (IsMatchingParameter(token, NS_LITERAL_STRING("transform"))) {
SVGAnimatedTransformList transforms;
if (transformFound ||
NS_FAILED(transforms.SetBaseValueString(params))) {
return false;
}
if (!root->mFragmentIdentifierTransform) {
root->mFragmentIdentifierTransform = new gfxMatrix();
}
*root->mFragmentIdentifierTransform =
transforms.GetBaseValue().GetConsolidationMatrix();
root->InvalidateTransformNotifyFrame();
transformFound = true;
} else if (IsMatchingParameter(token, NS_LITERAL_STRING("zoomAndPan"))) {
if (zoomAndPanFound) {
return false;
@ -170,7 +192,7 @@ SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
}
zoomAndPanFound = true;
} else {
// We don't support transform or viewTarget currently
// We don't support viewTarget currently
return false;
}
} while (tokenizer.hasMoreTokens());
@ -178,6 +200,9 @@ SVGFragmentIdentifier::ProcessSVGViewSpec(const nsAString &aViewSpec,
if (root->mUseCurrentView) {
// A previous SVGViewSpec may have overridden some attributes.
// If they are no longer overridden we need to restore the old values.
if (!transformFound) {
ClearTransform(root);
}
if (!viewBoxFound) {
RestoreOldViewBox(root);
}
@ -233,6 +258,7 @@ SVGFragmentIdentifier::ProcessFragmentIdentifier(nsIDocument *aDocument,
rootElement->ClearPreserveAspectRatioProperty();
RestoreOldZoomAndPan(rootElement);
rootElement->ClearZoomAndPanProperty();
ClearTransform(rootElement);
if (wasOverridden) {
rootElement->InvalidateTransformNotifyFrame();
}

Просмотреть файл

@ -46,6 +46,7 @@ private:
static void RestoreOldViewBox(nsSVGSVGElement *root);
static void SaveOldZoomAndPan(nsSVGSVGElement *root);
static void RestoreOldZoomAndPan(nsSVGSVGElement *root);
static void ClearTransform(nsSVGSVGElement *root);
};
} // namespace mozilla

Просмотреть файл

@ -1234,7 +1234,9 @@ nsSVGSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
gfxMatrix zoomPanTM;
zoomPanTM.Translate(gfxPoint(mCurrentTranslate.GetX(), mCurrentTranslate.GetY()));
zoomPanTM.Scale(mCurrentScale, mCurrentScale);
return GetViewBoxTransform() * zoomPanTM * aMatrix;
gfxMatrix matrix = mFragmentIdentifierTransform ?
*mFragmentIdentifierTransform * aMatrix : aMatrix;
return GetViewBoxTransform() * zoomPanTM * matrix;
}
// outer-<svg>, but inline in some other content:

Просмотреть файл

@ -351,6 +351,7 @@ private:
nsSVGViewBox mViewBox;
SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
nsAutoPtr<gfxMatrix> mFragmentIdentifierTransform;
nsAutoPtr<nsString> mCurrentViewID;
// The size of the rectangular SVG viewport into which we render. This is

Просмотреть файл

@ -40,9 +40,17 @@ function runTests()
new Test("svgView(preserveAspectRatio(xMaxYMin slice))", true, null, "xMaxYMin slice", null),
new Test("svgView(viewBox(1,2,3,4);preserveAspectRatio(xMinYMax))", true, "1 2 3 4", "xMinYMax meet", null),
new Test("svgView(zoomAndPan(disable))", true, null, null, "disable"),
new Test("svgView(transform(translate(-10,-20) scale(2) rotate(45) translate(5,10)))", true, null, null, null),
// No duplicates allowed
new Test("svgView(zoomAndPan(disable);zoomAndPan(disable))", false, null, null, null),
new Test("svgView(viewBox(0,0,200,200);viewBox(0,0,200,200))", false, null, null, null),
new Test("svgView(preserveAspectRatio(xMaxYMin);preserveAspectRatio(xMaxYMin))", false, null, null, null),
new Test("svgView(transform(translate(0,200));transform(translate(0,200)))", false, null, null, null),
// No invalid values allowed
new Test("svgView(viewBox(bad)", false, null, null, null),
new Test("svgView(preserveAspectRatio(bad))", false, null, null, null),
new Test("svgView(zoomAndPan(bad))", false, null, null, null),
new Test("svgView(transform(bad))", false, null, null, null),
new Test("svgView", false, null, null, null),
new Test("svgView(", false, null, null, null),
new Test("svgView()", false, null, null, null),

Просмотреть файл

@ -1,4 +1,4 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<html xmlns="http://www.w3.org/1999/xhtml" class="reftest-wait">
<head>
<title>Testcases for SVG fragment identifiers</title>
</head>
@ -7,5 +7,17 @@
<object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#limeView" />
<object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100))" />
</div>
<div>
<object type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,200)))" />
<object id="replace" type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,0))" />
<object id="remove" type="image/svg+xml" width="100" height="100" data="fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100);transform(translate(0,200)))" />
</div>
<script type="text/javascript">
window.onload = function() {
document.getElementById("replace").setAttribute("data","fragmentIdentifier-rect-01.svg#svgView(viewBox(0,0,100,100);transform(translate(0,200)))");
document.getElementById("remove").setAttribute("data","fragmentIdentifier-rect-01.svg#svgView(viewBox(0,200,100,100))");
document.documentElement.removeAttribute("class");
}
</script>
</body>
</html>