add support for viewBox attribute.
git-svn-id: svn://10.0.0.236/branches/SVG_20020806_BRANCH@137533 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -112,6 +112,7 @@ SVG_BRANCH_MODIFIED_FILES = \
|
||||
content/svg/content/src/nsSVGPathSeg.h \
|
||||
content/svg/content/src/nsSVGPathSegList.cpp \
|
||||
content/svg/content/src/nsSVGPointList.cpp \
|
||||
content/svg/content/src/nsSVGRect.cpp \
|
||||
content/svg/content/src/nsSVGRectElement.cpp \
|
||||
content/svg/content/src/nsSVGSVGElement.cpp \
|
||||
content/svg/content/src/nsSVGTransformList.cpp \
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "nsSVGRect.h"
|
||||
#include "prdtoa.h"
|
||||
#include "nsSVGValue.h"
|
||||
#include "nsTextFormatter.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsSVGRect class
|
||||
@@ -108,13 +110,51 @@ NS_INTERFACE_MAP_END
|
||||
NS_IMETHODIMP
|
||||
nsSVGRect::SetValueString(const nsAString& aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
WillModify();
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
char* str = ToNewCString(aValue);
|
||||
|
||||
char* rest = str;
|
||||
char* token;
|
||||
const char* delimiters = ",\x20\x9\xD\xA";
|
||||
|
||||
double vals[4];
|
||||
int i;
|
||||
for (i=0;i<4;++i) {
|
||||
if (!(token = nsCRT::strtok(rest, delimiters, &rest))) break; // parse error
|
||||
|
||||
char *end;
|
||||
vals[i] = PR_strtod(token, &end);
|
||||
if (*end != '\0') break; // parse error
|
||||
}
|
||||
if (i!=4 || (nsCRT::strtok(rest, delimiters, &rest)!=0)) {
|
||||
// there was a parse error.
|
||||
// xxx is this the right thing to do?
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
else {
|
||||
mX = (double)vals[0];
|
||||
mY = (double)vals[1];
|
||||
mWidth = (double)vals[2];
|
||||
mHeight = (double)vals[3];
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGRect::GetValueString(nsAString& aValue)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
PRUnichar buf[200];
|
||||
nsTextFormatter::snprintf(buf, sizeof(buf)/sizeof(PRUnichar),
|
||||
NS_LITERAL_STRING("%g %g %g %g").get(),
|
||||
(double)mX, (double)mY,
|
||||
(double)mWidth, (double)mHeight);
|
||||
aValue.Append(buf);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include "nsISVGOuterSVGFrame.h" //XXX
|
||||
#include "nsSVGNumber.h"
|
||||
#include "nsSVGRect.h"
|
||||
#include "nsISVGValueUtils.h"
|
||||
|
||||
class nsSVGSVGElement : public nsSVGElement,
|
||||
public nsISVGSVGElement, // : nsIDOMSVGSVGElement
|
||||
@@ -93,7 +94,11 @@ public:
|
||||
|
||||
// nsISVGContent interface
|
||||
NS_IMETHOD IsPresentationAttribute(const nsIAtom* attribute, PRBool* retval);
|
||||
|
||||
|
||||
// nsISVGValueObserver
|
||||
NS_IMETHOD WillModifySVGObservable(nsISVGValue* observable);
|
||||
NS_IMETHOD DidModifySVGObservable (nsISVGValue* observable);
|
||||
|
||||
protected:
|
||||
|
||||
// implementation helpers:
|
||||
@@ -104,6 +109,7 @@ protected:
|
||||
nsCOMPtr<nsISVGViewportRect> mParentViewport;
|
||||
nsCOMPtr<nsISVGViewportRect> mViewport;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedRect> mViewBox;
|
||||
nsCOMPtr<nsIDOMSVGMatrix> mViewBoxToViewportTransform;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLength> mX;
|
||||
nsCOMPtr<nsIDOMSVGAnimatedLength> mY;
|
||||
|
||||
@@ -162,6 +168,12 @@ nsSVGSVGElement::nsSVGSVGElement()
|
||||
|
||||
nsSVGSVGElement::~nsSVGSVGElement()
|
||||
{
|
||||
if (mViewBox) {
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(mViewBox);
|
||||
}
|
||||
if (mViewport) {
|
||||
NS_REMOVE_SVGVALUE_OBSERVER(mViewport);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -311,6 +323,11 @@ nsSVGSVGElement::Init()
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
|
||||
// add observers -------------------------- :
|
||||
NS_ADD_SVGVALUE_OBSERVER(mViewport);
|
||||
NS_ADD_SVGVALUE_OBSERVER(mViewBox);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@@ -800,8 +817,50 @@ nsSVGSVGElement::GetElementById(const nsAString & elementId, nsIDOMElement **_re
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval)
|
||||
{
|
||||
// XXX
|
||||
return CreateSVGMatrix(_retval);
|
||||
if (!mViewBoxToViewportTransform) {
|
||||
float viewportWidth, viewportHeight;
|
||||
mViewport->GetWidth(&viewportWidth);
|
||||
mViewport->GetHeight(&viewportHeight);
|
||||
|
||||
float viewboxWidth, viewboxHeight, viewboxX, viewboxY;
|
||||
{
|
||||
nsCOMPtr<nsIDOMSVGRect> vb;
|
||||
mViewBox->GetAnimVal(getter_AddRefs(vb));
|
||||
NS_ASSERTION(vb, "could not get viewbox");
|
||||
vb->GetWidth(&viewboxWidth);
|
||||
vb->GetHeight(&viewboxHeight);
|
||||
vb->GetX(&viewboxX);
|
||||
vb->GetY(&viewboxY);
|
||||
}
|
||||
if (viewboxWidth==0.0f || viewboxHeight==0.0f) {
|
||||
NS_ERROR("XXX. We shouldn't get here. Viewbox width/height is set to 0. Need to disable display of element as per specs.");
|
||||
viewboxWidth = 1.0f;
|
||||
viewboxHeight = 1.0f;
|
||||
}
|
||||
|
||||
// case with preserveAspectRatio=none:
|
||||
float a, e, d, f;
|
||||
|
||||
a = viewportWidth/viewboxWidth;
|
||||
e = -a*viewboxX;
|
||||
|
||||
d = viewportHeight/viewboxHeight;
|
||||
f = -d*viewboxY;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("SVG Viewport=(0?,0?,%f,%f)\n", viewportWidth, viewportHeight);
|
||||
printf("SVG Viewbox=(%f,%f,%f,%f)\n", viewboxX, viewboxY, viewboxWidth, viewboxHeight);
|
||||
printf("SVG Viewbox->Viewport xform [a c e] = [%f, 0, %f]\n", a, e);
|
||||
printf(" [b d f] = [ 0, %f, %f]\n", d, f);
|
||||
#endif
|
||||
|
||||
nsSVGMatrix::Create(getter_AddRefs(mViewBoxToViewportTransform),
|
||||
a, 0, 0, d, e, f);
|
||||
}
|
||||
|
||||
*_retval = mViewBoxToViewportTransform;
|
||||
NS_IF_ADDREF(*_retval);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@@ -811,8 +870,9 @@ nsSVGSVGElement::GetViewboxToViewportTransform(nsIDOMSVGMatrix **_retval)
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
|
||||
{
|
||||
NS_NOTYETIMPLEMENTED("write me!");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
*aViewBox = mViewBox;
|
||||
NS_ADDREF(*aViewBox);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute nsIDOMSVGAnimatedPreserveAspectRatio preserveAspectRatio; */
|
||||
@@ -1089,6 +1149,51 @@ nsSVGSVGElement::IsPresentationAttribute(const nsIAtom* name, PRBool *retval)
|
||||
return nsSVGElement::IsPresentationAttribute(name, retval);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGValueObserver methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::WillModifySVGObservable(nsISVGValue* observable)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("viewport/viewbox will be changed\n");
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGSVGElement::DidModifySVGObservable (nsISVGValue* observable)
|
||||
{
|
||||
// either viewport or viewbox have changed
|
||||
// invalidate viewbox -> viewport xform & inform frames
|
||||
|
||||
mViewBoxToViewportTransform = nsnull;
|
||||
|
||||
if (!mDocument) return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIPresShell> presShell;
|
||||
mDocument->GetShellAt(0, getter_AddRefs(presShell));
|
||||
NS_ASSERTION(presShell, "no presShell");
|
||||
if (!presShell) return NS_ERROR_FAILURE;
|
||||
|
||||
nsIFrame* frame;
|
||||
presShell->GetPrimaryFrameFor(NS_STATIC_CAST(nsIStyledContent*, this), &frame);
|
||||
if (frame) {
|
||||
nsISVGOuterSVGFrame* svgframe;
|
||||
CallQueryInterface(frame, &svgframe);
|
||||
NS_ASSERTION(svgframe, "wrong frame type");
|
||||
if (svgframe) {
|
||||
svgframe->NotifyViewportChange();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("viewport/viewbox have been changed\n");
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// implementation helpers
|
||||
void nsSVGSVGElement::GetScreenPosition(PRInt32 &x, PRInt32 &y)
|
||||
|
||||
@@ -61,6 +61,7 @@ public:
|
||||
NS_IMETHOD GetRenderer(nsISVGRenderer**renderer)=0;
|
||||
NS_IMETHOD GetPresContext(nsIPresContext**presContext)=0;
|
||||
NS_IMETHOD CreateSVGRect(nsIDOMSVGRect **_retval)=0;
|
||||
NS_IMETHOD NotifyViewportChange()=0; // called by our correspoding content element
|
||||
};
|
||||
|
||||
#endif // __NS_ISVGOUTERSVGFRAME_H__
|
||||
|
||||
@@ -234,6 +234,8 @@ public:
|
||||
NS_IMETHOD GetRenderer(nsISVGRenderer**renderer);
|
||||
NS_IMETHOD GetPresContext(nsIPresContext**presContext);
|
||||
NS_IMETHOD CreateSVGRect(nsIDOMSVGRect **_retval);
|
||||
NS_IMETHOD NotifyViewportChange();
|
||||
|
||||
// nsISVGContainerFrame interface:
|
||||
NS_IMETHOD_(nsISVGOuterSVGFrame*) GetOuterSVGFrame();
|
||||
|
||||
@@ -1074,6 +1076,27 @@ nsSVGOuterSVGFrame::CreateSVGRect(nsIDOMSVGRect **_retval)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGOuterSVGFrame::NotifyViewportChange()
|
||||
{
|
||||
// no point in doing anything when were not init'ed yet:
|
||||
if (!mViewportInitialized) return NS_OK;
|
||||
|
||||
// inform children
|
||||
// XXX we should have an nsISVGChildFrame:NotifyViewportChange() function
|
||||
SuspendRedraw();
|
||||
nsIFrame* kid = mFrames.FirstChild();
|
||||
while (kid) {
|
||||
nsISVGChildFrame* SVGFrame=nsnull;
|
||||
kid->QueryInterface(NS_GET_IID(nsISVGChildFrame),(void**)&SVGFrame);
|
||||
if (SVGFrame)
|
||||
SVGFrame->NotifyCTMChanged();
|
||||
kid->GetNextSibling(&kid);
|
||||
}
|
||||
UnsuspendRedraw();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsISVGContainerFrame methods:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user