Bug 263550 - respect overflow attribute of <svg:svg>. r=scootermorris

This commit is contained in:
tor%cs.brown.edu 2004-10-27 00:25:08 +00:00
Родитель b76a576db8
Коммит ea52aa688f
11 изменённых файлов: 242 добавлений и 2 удалений

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

@ -82,6 +82,7 @@ SVG_ATOM(tspan, "tspan")
SVG_ATOM(alignment_baseline, "alignment-baseline")
SVG_ATOM(baseline_shift, "baseline-shift")
SVG_ATOM(_class, "class")
SVG_ATOM(clip, "clip")
SVG_ATOM(clip_path, "clip-path")
SVG_ATOM(clip_rule, "clip-rule")
SVG_ATOM(color, "color")
@ -126,6 +127,7 @@ SVG_ATOM(onmousemove, "onmousemove")
SVG_ATOM(onmouseout, "onmouseout")
SVG_ATOM(onload, "onload")
SVG_ATOM(opacity, "opacity")
SVG_ATOM(overflow, "overflow")
SVG_ATOM(pathLength, "pathLength")
SVG_ATOM(pointer_events, "pointer-events")
SVG_ATOM(points, "points")

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

@ -82,6 +82,7 @@ SVG_ATOM(tspan, "tspan")
SVG_ATOM(alignment_baseline, "alignment-baseline")
SVG_ATOM(baseline_shift, "baseline-shift")
SVG_ATOM(_class, "class")
SVG_ATOM(clip, "clip")
SVG_ATOM(clip_path, "clip-path")
SVG_ATOM(clip_rule, "clip-rule")
SVG_ATOM(color, "color")
@ -126,6 +127,7 @@ SVG_ATOM(onmousemove, "onmousemove")
SVG_ATOM(onmouseout, "onmouseout")
SVG_ATOM(onload, "onload")
SVG_ATOM(opacity, "opacity")
SVG_ATOM(overflow, "overflow")
SVG_ATOM(pathLength, "pathLength")
SVG_ATOM(pointer_events, "pointer-events")
SVG_ATOM(points, "points")

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

@ -428,6 +428,14 @@ nsSVGElement::sGradientStopMap[] = {
{ nsnull }
};
// PresentationAttributes-Viewports
/* static */ const nsGenericElement::MappedAttributeEntry
nsSVGElement::sViewportsMap[] = {
{ &nsSVGAtoms::overflow },
{ &nsSVGAtoms::clip },
{ nsnull }
};
//----------------------------------------------------------------------
// nsIDOMNode methods

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

@ -98,6 +98,7 @@ public:
static const MappedAttributeEntry sTextContentElementsMap[];
static const MappedAttributeEntry sFontSpecificationMap[];
static const MappedAttributeEntry sGradientStopMap[];
static const MappedAttributeEntry sViewportsMap[];
// nsIDOMNode
NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, PRBool* aReturn);

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

@ -1120,7 +1120,8 @@ nsSVGSVGElement::IsAttributeMapped(const nsIAtom* name) const
sFillStrokeMap,
sGraphicsMap,
sTextContentElementsMap,
sFontSpecificationMap
sFontSpecificationMap,
sViewportsMap
};
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||

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

@ -46,6 +46,8 @@
#include "nsIDOMSVGSVGElement.h"
#include "nsISVGSVGElement.h"
#include "nsIDOMSVGAnimatedLength.h"
#include "nsIDOMSVGAnimatedRect.h"
#include "nsIDOMSVGFitToViewBox.h"
#include "nsSVGLength.h"
#include "nsISVGValue.h"
#include "nsISVGValueObserver.h"
@ -349,6 +351,29 @@ nsSVGInnerSVGFrame::Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectT
#ifdef DEBUG
// printf("nsSVGInnerSVG(%p)::Paint\n", this);
#endif
canvas->PushClip();
if (GetStyleDisplay()->IsScrollableOverflow()) {
nsCOMPtr<nsIDOMSVGRect> vb;
nsCOMPtr<nsIDOMSVGAnimatedRect> viewBox;
nsCOMPtr<nsIDOMSVGFitToViewBox> svgElement = do_QueryInterface(mContent);
if (svgElement)
svgElement->GetViewBox(getter_AddRefs(viewBox));
if (viewBox)
viewBox->GetAnimVal(getter_AddRefs(vb));
if (vb) {
float x, y, width, height;
vb->GetX(&x);
vb->GetY(&y);
vb->GetWidth(&width);
vb->GetHeight(&height);
nsCOMPtr<nsIDOMSVGMatrix> ctm = GetCanvasTM();
canvas->SetClipRect(ctm, x, y, width, height);
}
}
for (nsIFrame* kid = mFrames.FirstChild(); kid;
kid = kid->GetNextSibling()) {
nsISVGChildFrame* SVGFrame=nsnull;
@ -357,6 +382,8 @@ nsSVGInnerSVGFrame::Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectT
SVGFrame->Paint(canvas, dirtyRectTwips);
}
canvas->PopClip();
return NS_OK;
}

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

@ -61,3 +61,6 @@ svg {
style {
display: none;
}
svg, symbol, image, marker, pattern, foreignObject { overflow: hidden }

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

@ -49,6 +49,7 @@ typedef PRUint32 nscolor;
interface nsIRenderingContext;
interface nsPresContext;
interface nsIDOMSVGMatrix;
/**
* \addtogroup renderer_interfaces Rendering Engine Interfaces
@ -67,7 +68,7 @@ interface nsPresContext;
* Mozilla-native rendering object with a call to
* nsISVGRenderer::createCanvas().
*/
[scriptable, uuid(a1d9f15e-ee63-4ce1-9fe7-b6cdb09a48a0)]
[scriptable, uuid(90be3072-6a88-4dc3-a3f0-c8f2907078d8)]
interface nsISVGRendererCanvas : nsISupports
{
/**
@ -104,6 +105,18 @@ interface nsISVGRendererCanvas : nsISupports
* Mozilla-native rendering context.
*/
void flush();
/**
* Push/Pop clip path.
*/
void pushClip();
void popClip();
/**
* Set rectangular clip region.
*/
void setClipRect(in nsIDOMSVGMatrix canvasTM, in float x, in float y,
in float width, in float height);
};
/** @} */

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

@ -42,6 +42,7 @@
#include "nsCOMPtr.h"
#include "nsSVGCairoCanvas.h"
#include "nsISVGCairoCanvas.h"
#include "nsIDOMSVGMatrix.h"
#include "nsIRenderingContext.h"
#include "nsIDeviceContext.h"
#include "nsTransform2D.h"
@ -217,3 +218,89 @@ nsSVGCairoCanvas::Flush()
{
return NS_OK;
}
/** Implements pushClip(); */
NS_IMETHODIMP
nsSVGCairoCanvas::PushClip()
{
cairo_save(mCR);
return NS_OK;
}
/** Implements popClip(); */
NS_IMETHODIMP
nsSVGCairoCanvas::PopClip()
{
cairo_restore(mCR);
return NS_OK;
}
/** Implements setClipRect(in nsIDOMSVGMatrix canvasTM, in float x, in float y,
in float width, in float height); */
NS_IMETHODIMP
nsSVGCairoCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
float aWidth, float aHeight)
{
if (!aCTM)
return NS_ERROR_FAILURE;
cairo_save(mCR);
float m[6];
float val;
aCTM->GetA(&val);
m[0] = val;
aCTM->GetB(&val);
m[1] = val;
aCTM->GetC(&val);
m[2] = val;
aCTM->GetD(&val);
m[3] = val;
aCTM->GetE(&val);
m[4] = val;
aCTM->GetF(&val);
m[5] = val;
cairo_matrix_t *matrix = cairo_matrix_create();
if (!matrix) {
cairo_restore(mCR);
return NS_ERROR_FAILURE;
}
cairo_matrix_set_affine(matrix, m[0], m[1], m[2], m[3], m[4], m[5]);
cairo_concat_matrix(mCR, matrix);
cairo_matrix_destroy(matrix);
double x[4], y[4];
x[0] = aX;
y[0] = aY;
x[1] = aX + aWidth;
y[1] = aY;
x[2] = aX + aWidth;
y[2] = aY + aHeight;
x[3] = aX;
y[3] = aY + aHeight;
cairo_transform_point(mCR, &x[0], &y[0]);
cairo_transform_point(mCR, &x[1], &y[1]);
cairo_transform_point(mCR, &x[2], &y[2]);
cairo_transform_point(mCR, &x[3], &y[3]);
cairo_restore(mCR);
cairo_new_path(mCR);
cairo_move_to(mCR, x[0], y[0]);
cairo_line_to(mCR, x[1], y[1]);
cairo_line_to(mCR, x[2], y[2]);
cairo_line_to(mCR, x[3], y[3]);
cairo_close_path(mCR);
cairo_clip(mCR);
cairo_new_path(mCR);
return NS_OK;
}

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

@ -53,6 +53,7 @@ using namespace Gdiplus;
#include "nsPresContext.h"
#include "nsRect.h"
#include "nsIRenderingContextWin.h"
#include "nsIDOMSVGMatrix.h"
/**
* \addtogroup gdiplus_renderer GDI+ Rendering Engine
@ -84,6 +85,8 @@ private:
nsCOMPtr<nsIRenderingContext> mMozContext;
nsCOMPtr<nsPresContext> mPresContext;
Graphics *mGraphics;
nsVoidArray mClipStack;
#ifdef SVG_GDIPLUS_ENABLE_OFFSCREEN_BUFFER
Bitmap *mOffscreenBitmap;
Graphics *mOffscreenGraphics;
@ -319,4 +322,71 @@ nsSVGGDIPlusCanvas::GetGraphics()
#endif
}
/** Implements pushClip(); */
NS_IMETHODIMP
nsSVGGDIPlusCanvas::PushClip()
{
Region *region = new Region;
if (region)
mGraphics->GetClip(region);
// append even if we failed to allocate the region so push/pop match
mClipStack.AppendElement((void *)region);
return NS_OK;
}
/** Implements popClip(); */
NS_IMETHODIMP
nsSVGGDIPlusCanvas::PopClip()
{
PRUint32 count = mClipStack.Count();
if (count == 0)
return NS_OK;
Region *region = (Region *)mClipStack[count-1];
if (region) {
mGraphics->SetClip(region);
delete region;
}
mClipStack.RemoveElementAt(count-1);
return NS_OK;
}
/** Implements setClipRect(in nsIDOMSVGMatrix canvasTM, in float x, in float y,
in float width, in float height); */
NS_IMETHODIMP
nsSVGGDIPlusCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
float aWidth, float aHeight)
{
if (!aCTM)
return NS_ERROR_FAILURE;
float m[6];
float val;
aCTM->GetA(&val);
m[0] = val;
aCTM->GetB(&val);
m[1] = val;
aCTM->GetC(&val);
m[2] = val;
aCTM->GetD(&val);
m[3] = val;
aCTM->GetE(&val);
m[4] = val;
aCTM->GetF(&val);
m[5] = val;
Matrix matrix(m[0], m[1], m[2], m[3], m[4], m[5]);
RectF rect(aX, aY, aWidth, aHeight);
Region clip(rect);
clip.Transform(&matrix);
mGraphics->SetClip(&clip, CombineModeIntersect);
return NS_OK;
}

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

@ -313,3 +313,29 @@ nsSVGLibartCanvas::GetArtColor(nscolor rgb, ArtColor& artColor)
}
}
/** Implements void flush(); */
NS_IMETHODIMP
nsSVGLibartCanvas::PushClip()
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}
/** Implements pushClip(); */
NS_IMETHODIMP
nsSVGLibartCanvas::PopClip()
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}
/** Implements setClipRect(in nsIDOMSVGMatrix canvasTM, in float x, in float y,
in float width, in float height); */
NS_IMETHODIMP
nsSVGLibartCanvas::SetClipRect(nsIDOMSVGMatrix *aCTM, float aX, float aY,
float aWidth, float aHeight)
{
// XXX
return NS_ERROR_NOT_IMPLEMENTED;
}