зеркало из https://github.com/mozilla/pjs.git
Bug 687830 - Simplify marker implementation by calculating viewbox on paint rather than attempting to cache it. r=roc
This commit is contained in:
Родитель
9d3a1beaf9
Коммит
1b60b340a7
|
@ -288,12 +288,7 @@ nsSVGMarkerElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
PRBool aNotify)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (aName == nsGkAtoms::viewBox && mCoordCtx) {
|
||||
mViewBox.SetBaseValue(0, 0, mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
|
||||
mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx),
|
||||
this, PR_FALSE);
|
||||
return nsGenericElement::UnsetAttr(aNamespaceID, aName, aNotify);
|
||||
} else if (aName == nsGkAtoms::orient) {
|
||||
if (aName == nsGkAtoms::orient) {
|
||||
mOrientType.SetBaseValue(SVG_MARKER_ORIENT_ANGLE);
|
||||
}
|
||||
}
|
||||
|
@ -304,48 +299,11 @@ nsSVGMarkerElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
//----------------------------------------------------------------------
|
||||
// nsSVGElement methods
|
||||
|
||||
void
|
||||
nsSVGMarkerElement::DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr)
|
||||
{
|
||||
nsSVGMarkerElementBase::DidChangeLength(aAttrEnum, aDoSetAttr);
|
||||
|
||||
mViewBoxToViewportTransform = nsnull;
|
||||
|
||||
if (mCoordCtx && !HasAttr(kNameSpaceID_None, nsGkAtoms::viewBox) &&
|
||||
(aAttrEnum == MARKERWIDTH || aAttrEnum == MARKERHEIGHT)) {
|
||||
mViewBox.SetBaseValue(0, 0, mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
|
||||
mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx),
|
||||
this, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGMarkerElement::DidChangeViewBox(PRBool aDoSetAttr)
|
||||
{
|
||||
nsSVGMarkerElementBase::DidChangeViewBox(aDoSetAttr);
|
||||
|
||||
mViewBoxToViewportTransform = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGMarkerElement::DidChangePreserveAspectRatio(PRBool aDoSetAttr)
|
||||
{
|
||||
nsSVGMarkerElementBase::DidChangePreserveAspectRatio(aDoSetAttr);
|
||||
|
||||
mViewBoxToViewportTransform = nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGMarkerElement::SetParentCoordCtxProvider(nsSVGSVGElement *aContext)
|
||||
{
|
||||
mCoordCtx = aContext;
|
||||
mViewBoxToViewportTransform = nsnull;
|
||||
|
||||
if (mCoordCtx && !HasAttr(kNameSpaceID_None, nsGkAtoms::viewBox)) {
|
||||
mViewBox.SetBaseValue(0, 0, mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
|
||||
mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx),
|
||||
this, PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
nsSVGElement::LengthAttributesInfo
|
||||
|
@ -388,20 +346,30 @@ gfxMatrix
|
|||
nsSVGMarkerElement::GetMarkerTransform(float aStrokeWidth,
|
||||
float aX, float aY, float aAutoAngle)
|
||||
{
|
||||
float scale = 1.0;
|
||||
if (mEnumAttributes[MARKERUNITS].GetAnimValue() ==
|
||||
SVG_MARKERUNITS_STROKEWIDTH)
|
||||
scale = aStrokeWidth;
|
||||
gfxFloat scale = mEnumAttributes[MARKERUNITS].GetAnimValue() ==
|
||||
SVG_MARKERUNITS_STROKEWIDTH ? aStrokeWidth : 1.0;
|
||||
|
||||
float angle = mOrientType.GetAnimValue() == SVG_MARKER_ORIENT_AUTO ?
|
||||
aAutoAngle :
|
||||
mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0;
|
||||
gfxFloat angle = mOrientType.GetAnimValue() == SVG_MARKER_ORIENT_AUTO ?
|
||||
aAutoAngle :
|
||||
mAngleAttributes[ORIENT].GetAnimValue() * M_PI / 180.0;
|
||||
|
||||
return gfxMatrix(cos(angle) * scale, sin(angle) * scale,
|
||||
-sin(angle) * scale, cos(angle) * scale,
|
||||
aX, aY);
|
||||
}
|
||||
|
||||
nsSVGViewBoxRect
|
||||
nsSVGMarkerElement::GetViewBoxRect()
|
||||
{
|
||||
if (mViewBox.IsValid()) {
|
||||
return mViewBox.GetAnimValue();
|
||||
}
|
||||
return nsSVGViewBoxRect(
|
||||
0, 0,
|
||||
mLengthAttributes[MARKERWIDTH].GetAnimValue(mCoordCtx),
|
||||
mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx));
|
||||
}
|
||||
|
||||
gfxMatrix
|
||||
nsSVGMarkerElement::GetViewBoxTransform()
|
||||
{
|
||||
|
@ -411,14 +379,10 @@ nsSVGMarkerElement::GetViewBoxTransform()
|
|||
float viewportHeight =
|
||||
mLengthAttributes[MARKERHEIGHT].GetAnimValue(mCoordCtx);
|
||||
|
||||
const nsSVGViewBoxRect& viewbox = mViewBox.GetAnimValue();
|
||||
nsSVGViewBoxRect viewbox = GetViewBoxRect();
|
||||
|
||||
if (viewbox.width <= 0.0f || viewbox.height <= 0.0f) {
|
||||
return gfxMatrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); // invalid - don't paint element
|
||||
}
|
||||
|
||||
float refX = mLengthAttributes[REFX].GetAnimValue(mCoordCtx);
|
||||
float refY = mLengthAttributes[REFY].GetAnimValue(mCoordCtx);
|
||||
NS_ABORT_IF_FALSE(viewbox.width > 0.0f && viewbox.height > 0.0f,
|
||||
"Rendering should be disabled");
|
||||
|
||||
gfxMatrix viewBoxTM =
|
||||
nsSVGUtils::GetViewBoxTransform(this,
|
||||
|
@ -427,6 +391,9 @@ nsSVGMarkerElement::GetViewBoxTransform()
|
|||
viewbox.width, viewbox.height,
|
||||
mPreserveAspectRatio);
|
||||
|
||||
float refX = mLengthAttributes[REFX].GetAnimValue(mCoordCtx);
|
||||
float refY = mLengthAttributes[REFY].GetAnimValue(mCoordCtx);
|
||||
|
||||
gfxPoint ref = viewBoxTM.Transform(gfxPoint(refX, refY));
|
||||
|
||||
gfxMatrix TM = viewBoxTM * gfxMatrix().Translate(gfxPoint(-ref.x, -ref.y));
|
||||
|
|
|
@ -132,14 +132,10 @@ public:
|
|||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
// nsSVGElement specializations:
|
||||
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
|
||||
virtual void DidChangeViewBox(PRBool aDoSetAttr);
|
||||
virtual void DidChangePreserveAspectRatio(PRBool aDoSetAttr);
|
||||
|
||||
// public helpers
|
||||
gfxMatrix GetMarkerTransform(float aStrokeWidth,
|
||||
float aX, float aY, float aAutoAngle);
|
||||
nsSVGViewBoxRect GetViewBoxRect();
|
||||
gfxMatrix GetViewBoxTransform();
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
|
|
@ -132,29 +132,17 @@ nsSVGMarkerFrame::PaintMark(nsSVGRenderState *aContext,
|
|||
if (mInUse)
|
||||
return NS_OK;
|
||||
|
||||
AutoMarkerReferencer markerRef(this, aMarkedFrame);
|
||||
|
||||
nsSVGMarkerElement *marker = static_cast<nsSVGMarkerElement*>(mContent);
|
||||
|
||||
nsCOMPtr<nsIDOMSVGAnimatedRect> arect;
|
||||
nsresult rv = marker->GetViewBox(getter_AddRefs(arect));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
const nsSVGViewBoxRect viewBox = marker->GetViewBoxRect();
|
||||
|
||||
nsCOMPtr<nsIDOMSVGRect> rect;
|
||||
rv = arect->GetAnimVal(getter_AddRefs(rect));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
float x, y, width, height;
|
||||
rect->GetX(&x);
|
||||
rect->GetY(&y);
|
||||
rect->GetWidth(&width);
|
||||
rect->GetHeight(&height);
|
||||
|
||||
if (width <= 0.0f || height <= 0.0f) {
|
||||
if (viewBox.width <= 0.0f || viewBox.height <= 0.0f) {
|
||||
// We must disable rendering if the viewBox width or height are zero.
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AutoMarkerReferencer markerRef(this, aMarkedFrame);
|
||||
|
||||
mStrokeWidth = aStrokeWidth;
|
||||
mX = aMark->x;
|
||||
mY = aMark->y;
|
||||
|
@ -165,7 +153,8 @@ nsSVGMarkerFrame::PaintMark(nsSVGRenderState *aContext,
|
|||
if (GetStyleDisplay()->IsScrollableOverflow()) {
|
||||
gfx->Save();
|
||||
gfxRect clipRect =
|
||||
nsSVGUtils::GetClipRectForFrame(this, x, y, width, height);
|
||||
nsSVGUtils::GetClipRectForFrame(this, viewBox.x, viewBox.y,
|
||||
viewBox.width, viewBox.height);
|
||||
nsSVGUtils::SetClipRect(gfx, GetCanvasTM(), clipRect);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче