зеркало из https://github.com/mozilla/pjs.git
Bug 263550 - respect overflow attribute of <svg:svg>. r=scootermorris
This commit is contained in:
Родитель
b76a576db8
Коммит
ea52aa688f
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче