mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 20:05:49 +00:00
Bug 474230. Cleanup scale and translate in nsSVGElement similar to the new style SVG classes. r=jwatt
This commit is contained in:
parent
59514b8d37
commit
381741da91
@ -80,23 +80,21 @@ nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(nsPresContext* aPresContext,
|
||||
// properties will be left null which is probably what we want.
|
||||
nsCOMPtr<nsIDOMSVGSVGElement> svgElement = do_QueryInterface(rootContent);
|
||||
if (svgElement) {
|
||||
svgElement->GetCurrentScale(&mNewScale);
|
||||
float x, y;
|
||||
nsCOMPtr<nsIDOMSVGPoint> currentTranslate;
|
||||
svgElement->GetCurrentTranslate(getter_AddRefs(currentTranslate));
|
||||
currentTranslate->GetX(&x);
|
||||
currentTranslate->GetY(&y);
|
||||
NS_NewSVGReadonlyPoint(getter_AddRefs(mNewTranslate), x, y);
|
||||
|
||||
nsSVGSVGElement *SVGSVGElement =
|
||||
static_cast<nsSVGSVGElement*>(rootContent);
|
||||
|
||||
mNewScale = SVGSVGElement->GetCurrentScale();
|
||||
mPreviousScale = SVGSVGElement->GetPreviousScale();
|
||||
|
||||
const nsSVGTranslatePoint& translate =
|
||||
SVGSVGElement->GetCurrentTranslate();
|
||||
NS_NewSVGReadonlyPoint(getter_AddRefs(mNewTranslate),
|
||||
translate.GetX(), translate.GetY());
|
||||
|
||||
const nsSVGTranslatePoint& prevTranslate =
|
||||
SVGSVGElement->GetPreviousTranslate();
|
||||
NS_NewSVGReadonlyPoint(getter_AddRefs(mPreviousTranslate),
|
||||
SVGSVGElement->GetPreviousTranslate_x(),
|
||||
SVGSVGElement->GetPreviousTranslate_y());
|
||||
// Important: we call RecordCurrentST() here to make sure that
|
||||
// scripts that create an SVGZoomEvent won't get our "Previous" data
|
||||
SVGSVGElement->RecordCurrentScaleTranslate();
|
||||
prevTranslate.GetX(), prevTranslate.GetY());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -71,6 +71,64 @@
|
||||
nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
NS_SVG_VAL_IMPL_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal, mElement)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGTranslatePoint::DOMVal)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGTranslatePoint::DOMVal)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMSVGPoint)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(SVGPoint)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
nsresult
|
||||
nsSVGTranslatePoint::ToDOMVal(nsSVGSVGElement *aElement,
|
||||
nsIDOMSVGPoint **aResult)
|
||||
{
|
||||
*aResult = new DOMVal(this, aElement);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGTranslatePoint::DOMVal::SetX(float aValue)
|
||||
{
|
||||
NS_ENSURE_FINITE(aValue, NS_ERROR_ILLEGAL_VALUE);
|
||||
return mElement->SetCurrentTranslate(aValue, mVal->GetY());
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGTranslatePoint::DOMVal::SetY(float aValue)
|
||||
{
|
||||
NS_ENSURE_FINITE(aValue, NS_ERROR_ILLEGAL_VALUE);
|
||||
return mElement->SetCurrentTranslate(mVal->GetX(), aValue);
|
||||
}
|
||||
|
||||
/* nsIDOMSVGPoint matrixTransform (in nsIDOMSVGMatrix matrix); */
|
||||
NS_IMETHODIMP
|
||||
nsSVGTranslatePoint::DOMVal::MatrixTransform(nsIDOMSVGMatrix *matrix,
|
||||
nsIDOMSVGPoint **_retval)
|
||||
{
|
||||
if (!matrix)
|
||||
return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR;
|
||||
|
||||
float a, b, c, d, e, f;
|
||||
matrix->GetA(&a);
|
||||
matrix->GetB(&b);
|
||||
matrix->GetC(&c);
|
||||
matrix->GetD(&d);
|
||||
matrix->GetE(&e);
|
||||
matrix->GetF(&f);
|
||||
|
||||
float x = mVal->GetX();
|
||||
float y = mVal->GetY();
|
||||
|
||||
return NS_NewSVGPoint(_retval, a*x + c*y + e, b*x + d*y + f);
|
||||
}
|
||||
|
||||
nsSVGElement::LengthInfo nsSVGSVGElement::sLengthInfo[4] =
|
||||
{
|
||||
@ -140,44 +198,17 @@ nsSVGSVGElement::nsSVGSVGElement(nsINodeInfo* aNodeInfo, PRBool aFromParser)
|
||||
mViewportWidth(0),
|
||||
mViewportHeight(0),
|
||||
mCoordCtxMmPerPx(0),
|
||||
mPreviousTranslate_x(0),
|
||||
mPreviousTranslate_y(0),
|
||||
mPreviousScale(0),
|
||||
mRedrawSuspendCount(0),
|
||||
mDispatchEvent(PR_FALSE)
|
||||
mCurrentTranslate(0.0f, 0.0f),
|
||||
mCurrentScale(1.0f),
|
||||
mPreviousTranslate(0.0f, 0.0f),
|
||||
mPreviousScale(1.0f),
|
||||
mRedrawSuspendCount(0)
|
||||
#ifdef MOZ_SMIL
|
||||
,mStartAnimationOnBindToTree(!aFromParser)
|
||||
#endif // MOZ_SMIL
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSVGSVGElement::Init()
|
||||
{
|
||||
nsresult rv = nsSVGSVGElementBase::Init();
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
// DOM property: currentScale
|
||||
{
|
||||
rv = NS_NewSVGNumber(getter_AddRefs(mCurrentScale), 1.0f);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
NS_ADD_SVGVALUE_OBSERVER(mCurrentScale);
|
||||
}
|
||||
|
||||
// DOM property: currentTranslate
|
||||
{
|
||||
rv = NS_NewSVGPoint(getter_AddRefs(mCurrentTranslate));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
NS_ADD_SVGVALUE_OBSERVER(mCurrentTranslate);
|
||||
}
|
||||
|
||||
// initialise "Previous" values
|
||||
RecordCurrentScaleTranslate();
|
||||
mDispatchEvent = PR_TRUE;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIDOMNode methods
|
||||
|
||||
@ -343,7 +374,8 @@ nsSVGSVGElement::GetCurrentView(nsIDOMSVGViewSpec * *aCurrentView)
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetCurrentScale(float *aCurrentScale)
|
||||
{
|
||||
return mCurrentScale->GetValue(aCurrentScale);
|
||||
*aCurrentScale = mCurrentScale;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#define CURRENT_SCALE_MAX 16.0f
|
||||
@ -352,27 +384,15 @@ nsSVGSVGElement::GetCurrentScale(float *aCurrentScale)
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::SetCurrentScale(float aCurrentScale)
|
||||
{
|
||||
NS_ENSURE_FINITE(aCurrentScale, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// Prevent bizarre behaviour and maxing out of CPU and memory by clamping
|
||||
if (aCurrentScale < CURRENT_SCALE_MIN)
|
||||
aCurrentScale = CURRENT_SCALE_MIN;
|
||||
else if (aCurrentScale > CURRENT_SCALE_MAX)
|
||||
aCurrentScale = CURRENT_SCALE_MAX;
|
||||
|
||||
return mCurrentScale->SetValue(aCurrentScale);
|
||||
|
||||
// We have to dispatch the required SVGZoom event from DidModifySVGObservable
|
||||
// since dispatching it here is too late (i.e. after repaint)
|
||||
return SetCurrentScaleTranslate(aCurrentScale,
|
||||
mCurrentTranslate.GetX(), mCurrentTranslate.GetY());
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGPoint currentTranslate; */
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetCurrentTranslate(nsIDOMSVGPoint * *aCurrentTranslate)
|
||||
{
|
||||
*aCurrentTranslate = mCurrentTranslate;
|
||||
NS_ADDREF(*aCurrentTranslate);
|
||||
return NS_OK;
|
||||
return mCurrentTranslate.ToDOMVal(this, aCurrentTranslate);
|
||||
}
|
||||
|
||||
/* unsigned long suspendRedraw (in unsigned long max_wait_milliseconds); */
|
||||
@ -811,9 +831,9 @@ nsSVGSVGElement::GetCTM(nsIDOMSVGMatrix **_retval)
|
||||
float s=1, x=0, y=0;
|
||||
if (IsRoot()) {
|
||||
// we're the root element. get our currentScale and currentTranslate vals
|
||||
mCurrentScale->GetValue(&s);
|
||||
mCurrentTranslate->GetX(&x);
|
||||
mCurrentTranslate->GetY(&y);
|
||||
s = mCurrentScale;
|
||||
x = mCurrentTranslate.GetX();
|
||||
y = mCurrentTranslate.GetY();
|
||||
}
|
||||
else {
|
||||
// we're inline in some non-SVG content. get our offset from the root
|
||||
@ -908,9 +928,9 @@ nsSVGSVGElement::GetScreenCTM(nsIDOMSVGMatrix **_retval)
|
||||
float s=1, x=0, y=0;
|
||||
if (IsRoot()) {
|
||||
// we're the root element. get our currentScale and currentTranslate vals
|
||||
mCurrentScale->GetValue(&s);
|
||||
mCurrentTranslate->GetX(&x);
|
||||
mCurrentTranslate->GetY(&y);
|
||||
s = mCurrentScale;
|
||||
x = mCurrentTranslate.GetX();
|
||||
y = mCurrentTranslate.GetY();
|
||||
}
|
||||
else {
|
||||
// we're inline in some non-SVG content. get our offset from the root
|
||||
@ -1011,66 +1031,22 @@ nsSVGSVGElement::SetZoomAndPan(PRUint16 aZoomAndPan)
|
||||
//----------------------------------------------------------------------
|
||||
// helper methods for implementing SVGZoomEvent:
|
||||
|
||||
nsresult
|
||||
nsSVGSVGElement::GetCurrentScaleNumber(nsIDOMSVGNumber **aResult)
|
||||
{
|
||||
*aResult = mCurrentScale;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::SetCurrentScaleTranslate(float s, float x, float y)
|
||||
{
|
||||
RecordCurrentScaleTranslate();
|
||||
mDispatchEvent = PR_FALSE;
|
||||
SetCurrentScale(s); // clamps! don't call mCurrentScale->SetValue() directly
|
||||
mCurrentTranslate->SetX(x);
|
||||
mCurrentTranslate->SetY(y);
|
||||
mDispatchEvent = PR_TRUE;
|
||||
NS_ENSURE_FINITE3(s, x, y, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// now dispatch an SVGZoom event if we are the root element
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
NS_ASSERTION(presShell, "no presShell");
|
||||
if (presShell && IsRoot()) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsGUIEvent event(PR_TRUE, NS_SVG_ZOOM, 0);
|
||||
event.eventStructType = NS_SVGZOOM_EVENT;
|
||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
}
|
||||
if (s == mCurrentScale &&
|
||||
x == mCurrentTranslate.GetX() && y == mCurrentTranslate.GetY()) {
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::SetCurrentTranslate(float x, float y)
|
||||
{
|
||||
RecordCurrentScaleTranslate();
|
||||
mDispatchEvent = PR_FALSE;
|
||||
mCurrentTranslate->SetX(x);
|
||||
mCurrentTranslate->SetY(y);
|
||||
mDispatchEvent = PR_TRUE;
|
||||
|
||||
// now dispatch an SVGScroll event if we are the root element
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
NS_ASSERTION(presShell, "no presShell");
|
||||
if (presShell && IsRoot()) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_SVG_SCROLL);
|
||||
event.eventStructType = NS_SVG_EVENT;
|
||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGSVGElement::RecordCurrentScaleTranslate()
|
||||
{
|
||||
// Prevent bizarre behaviour and maxing out of CPU and memory by clamping
|
||||
if (s < CURRENT_SCALE_MIN)
|
||||
s = CURRENT_SCALE_MIN;
|
||||
else if (s > CURRENT_SCALE_MAX)
|
||||
s = CURRENT_SCALE_MAX;
|
||||
|
||||
// IMPORTANT: If either mCurrentTranslate *or* mCurrentScale is changed then
|
||||
// mPreviousTranslate_x, mPreviousTranslate_y *and* mPreviousScale must all
|
||||
// be updated otherwise SVGZoomEvents will end up with invalid data. I.e. an
|
||||
@ -1079,9 +1055,33 @@ nsSVGSVGElement::RecordCurrentScaleTranslate()
|
||||
// change that caused the event's dispatch, which is *not* necessarily the
|
||||
// same thing as the values of currentScale and currentTranslate prior to
|
||||
// their own last change.
|
||||
mCurrentScale->GetValue(&mPreviousScale);
|
||||
mCurrentTranslate->GetX(&mPreviousTranslate_x);
|
||||
mCurrentTranslate->GetY(&mPreviousTranslate_y);
|
||||
mPreviousScale = mCurrentScale;
|
||||
mPreviousTranslate = mCurrentTranslate;
|
||||
|
||||
mCurrentScale = s;
|
||||
mCurrentTranslate = nsSVGTranslatePoint(x, y);
|
||||
|
||||
// now dispatch the appropriate event if we are the root element
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
NS_ASSERTION(presShell, "no presShell");
|
||||
if (presShell && IsRoot()) {
|
||||
PRBool scaling = (s != mCurrentScale);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsGUIEvent event(PR_TRUE, scaling ? NS_SVG_ZOOM : NS_SVG_SCROLL, 0);
|
||||
event.eventStructType = scaling ? NS_SVGZOOM_EVENT : NS_SVG_EVENT;
|
||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
InvalidateTransformNotifyFrame();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::SetCurrentTranslate(float x, float y)
|
||||
{
|
||||
return SetCurrentScaleTranslate(mCurrentScale, x, y);
|
||||
}
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
@ -1149,75 +1149,6 @@ nsSVGSVGElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
}
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGValueObserver methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::WillModifySVGObservable(nsISVGValue* observable,
|
||||
nsISVGValue::modificationType aModType)
|
||||
{
|
||||
if (mDispatchEvent) {
|
||||
// Modification isn't due to calling SetCurrent[Scale]Translate, so if
|
||||
// currentScale or currentTranslate is about to change we must record their
|
||||
// current values.
|
||||
nsCOMPtr<nsIDOMSVGNumber> n = do_QueryInterface(observable);
|
||||
if (n && n==mCurrentScale) {
|
||||
RecordCurrentScaleTranslate();
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDOMSVGPoint> p = do_QueryInterface(observable);
|
||||
if (p && p==mCurrentTranslate) {
|
||||
RecordCurrentScaleTranslate();
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::DidModifySVGObservable (nsISVGValue* observable,
|
||||
nsISVGValue::modificationType aModType)
|
||||
{
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (!doc) return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
NS_ASSERTION(presShell, "no presShell");
|
||||
if (!presShell) return NS_ERROR_FAILURE;
|
||||
|
||||
// If currentScale or currentTranslate has changed, we are the root element,
|
||||
// and the changes wasn't caused by SetCurrent[Scale]Translate then we must
|
||||
// dispatch an SVGZoom or SVGScroll DOM event before repainting
|
||||
nsCOMPtr<nsIDOMSVGNumber> n = do_QueryInterface(observable);
|
||||
if (n && n==mCurrentScale) {
|
||||
if (mDispatchEvent && IsRoot()) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsGUIEvent event(PR_TRUE, NS_SVG_ZOOM, 0);
|
||||
event.eventStructType = NS_SVGZOOM_EVENT;
|
||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
}
|
||||
else {
|
||||
return NS_OK; // we don't care about currentScale changes on non-root
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsIDOMSVGPoint> p = do_QueryInterface(observable);
|
||||
if (p && p==mCurrentTranslate) {
|
||||
if (mDispatchEvent && IsRoot()) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_SVG_SCROLL);
|
||||
event.eventStructType = NS_SVG_EVENT;
|
||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
}
|
||||
else {
|
||||
return NS_OK; // we don't care about currentScale changes on non-root
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateTransformNotifyFrame();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsSVGElement overrides
|
||||
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "nsIDOMSVGLocatable.h"
|
||||
#include "nsIDOMSVGZoomAndPan.h"
|
||||
#include "nsIDOMSVGMatrix.h"
|
||||
#include "nsIDOMSVGPoint.h"
|
||||
#include "nsSVGLength2.h"
|
||||
#include "nsSVGEnum.h"
|
||||
#include "nsSVGViewBox.h"
|
||||
@ -61,6 +62,52 @@ class nsSMILTimeContainer;
|
||||
|
||||
typedef nsSVGStylableElement nsSVGSVGElementBase;
|
||||
|
||||
class nsSVGSVGElement;
|
||||
|
||||
class nsSVGTranslatePoint {
|
||||
public:
|
||||
nsSVGTranslatePoint(float aX, float aY) :
|
||||
mX(aX), mY(aY) {}
|
||||
|
||||
void SetX(float aX)
|
||||
{ mX = aX; }
|
||||
void SetY(float aY)
|
||||
{ mY = aY; }
|
||||
float GetX() const
|
||||
{ return mX; }
|
||||
float GetY() const
|
||||
{ return mY; }
|
||||
|
||||
nsresult ToDOMVal(nsSVGSVGElement *aElement, nsIDOMSVGPoint **aResult);
|
||||
|
||||
private:
|
||||
|
||||
struct DOMVal : public nsIDOMSVGPoint {
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(DOMVal)
|
||||
|
||||
DOMVal(nsSVGTranslatePoint* aVal, nsSVGSVGElement *aElement)
|
||||
: mVal(aVal), mElement(aElement) {}
|
||||
|
||||
NS_IMETHOD GetX(float *aValue)
|
||||
{ *aValue = mVal->GetX(); return NS_OK; }
|
||||
NS_IMETHOD GetY(float *aValue)
|
||||
{ *aValue = mVal->GetY(); return NS_OK; }
|
||||
|
||||
NS_IMETHOD SetX(float aValue);
|
||||
NS_IMETHOD SetY(float aValue);
|
||||
|
||||
NS_IMETHOD MatrixTransform(nsIDOMSVGMatrix *matrix,
|
||||
nsIDOMSVGPoint **_retval);
|
||||
|
||||
nsSVGTranslatePoint *mVal; // kept alive because it belongs to mElement
|
||||
nsRefPtr<nsSVGSVGElement> mElement;
|
||||
};
|
||||
|
||||
float mX;
|
||||
float mY;
|
||||
};
|
||||
|
||||
class svgFloatSize {
|
||||
public:
|
||||
svgFloatSize(float aWidth, float aHeight)
|
||||
@ -88,7 +135,6 @@ protected:
|
||||
nsINodeInfo *aNodeInfo,
|
||||
PRBool aFromParser);
|
||||
nsSVGSVGElement(nsINodeInfo* aNodeInfo, PRBool aFromParser);
|
||||
nsresult Init();
|
||||
|
||||
public:
|
||||
|
||||
@ -104,9 +150,6 @@ public:
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGSVGElementBase::)
|
||||
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGSVGElementBase::)
|
||||
|
||||
// helper methods for implementing SVGZoomEvent:
|
||||
nsresult GetCurrentScaleNumber(nsIDOMSVGNumber **aResult);
|
||||
|
||||
/**
|
||||
* For use by zoom controls to allow currentScale, currentTranslate.x and
|
||||
* currentTranslate.y to be set by a single operation that dispatches a
|
||||
@ -122,17 +165,16 @@ public:
|
||||
NS_IMETHOD SetCurrentTranslate(float x, float y);
|
||||
|
||||
/**
|
||||
* Record the current values of currentScale, currentTranslate.x and
|
||||
* currentTranslate.y prior to changing the value of one of them.
|
||||
* Retrieve the value of currentScale and currentTranslate.
|
||||
*/
|
||||
void RecordCurrentScaleTranslate();
|
||||
const nsSVGTranslatePoint& GetCurrentTranslate() { return mCurrentTranslate; }
|
||||
float GetCurrentScale() { return mCurrentScale; }
|
||||
|
||||
/**
|
||||
* Retrieve the value of currentScale, currentTranslate.x or
|
||||
* currentTranslate.y prior to the last change made to any one of them.
|
||||
*/
|
||||
float GetPreviousTranslate_x() { return mPreviousTranslate_x; }
|
||||
float GetPreviousTranslate_y() { return mPreviousTranslate_y; }
|
||||
const nsSVGTranslatePoint& GetPreviousTranslate() { return mPreviousTranslate; }
|
||||
float GetPreviousScale() { return mPreviousScale; }
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
@ -145,12 +187,6 @@ public:
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
// nsISVGValueObserver
|
||||
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable,
|
||||
nsISVGValue::modificationType aModType);
|
||||
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable,
|
||||
nsISVGValue::modificationType aModType);
|
||||
|
||||
// nsSVGElement specializations:
|
||||
virtual void DidChangeLength(PRUint8 aAttrEnum, PRBool aDoSetAttr);
|
||||
virtual void DidChangeEnum(PRUint8 aAttrEnum, PRBool aDoSetAttr);
|
||||
@ -253,15 +289,13 @@ protected:
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
// zoom and pan
|
||||
// IMPORTANT: only RecordCurrentScaleTranslate should change the "mPreviousX"
|
||||
// members below - see the comment in RecordCurrentScaleTranslate
|
||||
nsCOMPtr<nsIDOMSVGPoint> mCurrentTranslate;
|
||||
nsCOMPtr<nsIDOMSVGNumber> mCurrentScale;
|
||||
float mPreviousTranslate_x;
|
||||
float mPreviousTranslate_y;
|
||||
// IMPORTANT: see the comment in RecordCurrentScaleTranslate before writing
|
||||
// code to change any of these!
|
||||
nsSVGTranslatePoint mCurrentTranslate;
|
||||
float mCurrentScale;
|
||||
nsSVGTranslatePoint mPreviousTranslate;
|
||||
float mPreviousScale;
|
||||
PRInt32 mRedrawSuspendCount;
|
||||
PRPackedBool mDispatchEvent;
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// For outermost <svg> elements created from parsing, animation is started by
|
||||
|
@ -149,6 +149,7 @@ nsSVGOuterSVGFrame::nsSVGOuterSVGFrame(nsStyleContext* aContext)
|
||||
#ifdef XP_MACOSX
|
||||
, mEnableBitmapFallback(PR_FALSE)
|
||||
#endif
|
||||
, mIsRootContent(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@ -170,9 +171,7 @@ nsSVGOuterSVGFrame::Init(nsIContent* aContent,
|
||||
if (doc) {
|
||||
// we only care about our content's zoom and pan values if it's the root element
|
||||
if (doc->GetRootContent() == mContent) {
|
||||
nsSVGSVGElement *SVGElement = static_cast<nsSVGSVGElement*>(mContent);
|
||||
SVGElement->GetCurrentTranslate(getter_AddRefs(mCurrentTranslate));
|
||||
SVGElement->GetCurrentScaleNumber(getter_AddRefs(mCurrentScale));
|
||||
mIsRootContent = PR_TRUE;
|
||||
}
|
||||
// AddMutationObserver checks that the observer is not already added.
|
||||
// sSVGMutationObserver has the same lifetime as the document so does
|
||||
@ -774,16 +773,14 @@ nsSVGOuterSVGFrame::GetCanvasTM()
|
||||
|
||||
// our content is the document element so we must premultiply the values
|
||||
// of its currentScale and currentTranslate properties
|
||||
if (mCurrentScale &&
|
||||
mCurrentTranslate) {
|
||||
if (mIsRootContent) {
|
||||
nsCOMPtr<nsIDOMSVGMatrix> zoomPanMatrix;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> temp;
|
||||
float scale, x, y;
|
||||
mCurrentScale->GetValue(&scale);
|
||||
mCurrentTranslate->GetX(&x);
|
||||
mCurrentTranslate->GetY(&y);
|
||||
float scale = svgElement->GetCurrentScale();
|
||||
const nsSVGTranslatePoint& translate = svgElement->GetCurrentTranslate();
|
||||
|
||||
svgElement->CreateSVGMatrix(getter_AddRefs(zoomPanMatrix));
|
||||
zoomPanMatrix->Translate(x, y, getter_AddRefs(temp));
|
||||
zoomPanMatrix->Translate(translate.GetX(), translate.GetY(), getter_AddRefs(temp));
|
||||
temp->Scale(scale, getter_AddRefs(zoomPanMatrix));
|
||||
zoomPanMatrix->Multiply(mCanvasTM, getter_AddRefs(temp));
|
||||
temp.swap(mCanvasTM);
|
||||
|
@ -166,16 +166,13 @@ protected:
|
||||
PRUint32 mRedrawSuspendCount;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mCanvasTM;
|
||||
|
||||
// zoom and pan
|
||||
nsCOMPtr<nsIDOMSVGPoint> mCurrentTranslate;
|
||||
nsCOMPtr<nsIDOMSVGNumber> mCurrentScale;
|
||||
|
||||
float mFullZoom;
|
||||
|
||||
PRPackedBool mViewportInitialized;
|
||||
#ifdef XP_MACOSX
|
||||
PRPackedBool mEnableBitmapFallback;
|
||||
#endif
|
||||
PRPackedBool mIsRootContent;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user