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:
alex.fritze%crocodile-clips.com
2003-02-07 15:29:17 +00:00
parent 608f71a6e6
commit f8dfbe75d3
5 changed files with 177 additions and 7 deletions

View File

@@ -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 \

View File

@@ -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;
}
//----------------------------------------------------------------------

View File

@@ -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)

View File

@@ -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__

View File

@@ -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: