зеркало из https://github.com/mozilla/gecko-dev.git
Bug 263550 - respect overflow attribute of <svg:svg>. r=scootermorris
This commit is contained in:
Родитель
79f808676a
Коммит
a539e481c1
|
@ -82,6 +82,7 @@ SVG_ATOM(tspan, "tspan")
|
||||||
SVG_ATOM(alignment_baseline, "alignment-baseline")
|
SVG_ATOM(alignment_baseline, "alignment-baseline")
|
||||||
SVG_ATOM(baseline_shift, "baseline-shift")
|
SVG_ATOM(baseline_shift, "baseline-shift")
|
||||||
SVG_ATOM(_class, "class")
|
SVG_ATOM(_class, "class")
|
||||||
|
SVG_ATOM(clip, "clip")
|
||||||
SVG_ATOM(clip_path, "clip-path")
|
SVG_ATOM(clip_path, "clip-path")
|
||||||
SVG_ATOM(clip_rule, "clip-rule")
|
SVG_ATOM(clip_rule, "clip-rule")
|
||||||
SVG_ATOM(color, "color")
|
SVG_ATOM(color, "color")
|
||||||
|
@ -126,6 +127,7 @@ SVG_ATOM(onmousemove, "onmousemove")
|
||||||
SVG_ATOM(onmouseout, "onmouseout")
|
SVG_ATOM(onmouseout, "onmouseout")
|
||||||
SVG_ATOM(onload, "onload")
|
SVG_ATOM(onload, "onload")
|
||||||
SVG_ATOM(opacity, "opacity")
|
SVG_ATOM(opacity, "opacity")
|
||||||
|
SVG_ATOM(overflow, "overflow")
|
||||||
SVG_ATOM(pathLength, "pathLength")
|
SVG_ATOM(pathLength, "pathLength")
|
||||||
SVG_ATOM(pointer_events, "pointer-events")
|
SVG_ATOM(pointer_events, "pointer-events")
|
||||||
SVG_ATOM(points, "points")
|
SVG_ATOM(points, "points")
|
||||||
|
|
|
@ -82,6 +82,7 @@ SVG_ATOM(tspan, "tspan")
|
||||||
SVG_ATOM(alignment_baseline, "alignment-baseline")
|
SVG_ATOM(alignment_baseline, "alignment-baseline")
|
||||||
SVG_ATOM(baseline_shift, "baseline-shift")
|
SVG_ATOM(baseline_shift, "baseline-shift")
|
||||||
SVG_ATOM(_class, "class")
|
SVG_ATOM(_class, "class")
|
||||||
|
SVG_ATOM(clip, "clip")
|
||||||
SVG_ATOM(clip_path, "clip-path")
|
SVG_ATOM(clip_path, "clip-path")
|
||||||
SVG_ATOM(clip_rule, "clip-rule")
|
SVG_ATOM(clip_rule, "clip-rule")
|
||||||
SVG_ATOM(color, "color")
|
SVG_ATOM(color, "color")
|
||||||
|
@ -126,6 +127,7 @@ SVG_ATOM(onmousemove, "onmousemove")
|
||||||
SVG_ATOM(onmouseout, "onmouseout")
|
SVG_ATOM(onmouseout, "onmouseout")
|
||||||
SVG_ATOM(onload, "onload")
|
SVG_ATOM(onload, "onload")
|
||||||
SVG_ATOM(opacity, "opacity")
|
SVG_ATOM(opacity, "opacity")
|
||||||
|
SVG_ATOM(overflow, "overflow")
|
||||||
SVG_ATOM(pathLength, "pathLength")
|
SVG_ATOM(pathLength, "pathLength")
|
||||||
SVG_ATOM(pointer_events, "pointer-events")
|
SVG_ATOM(pointer_events, "pointer-events")
|
||||||
SVG_ATOM(points, "points")
|
SVG_ATOM(points, "points")
|
||||||
|
|
|
@ -428,6 +428,14 @@ nsSVGElement::sGradientStopMap[] = {
|
||||||
{ nsnull }
|
{ nsnull }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// PresentationAttributes-Viewports
|
||||||
|
/* static */ const nsGenericElement::MappedAttributeEntry
|
||||||
|
nsSVGElement::sViewportsMap[] = {
|
||||||
|
{ &nsSVGAtoms::overflow },
|
||||||
|
{ &nsSVGAtoms::clip },
|
||||||
|
{ nsnull }
|
||||||
|
};
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// nsIDOMNode methods
|
// nsIDOMNode methods
|
||||||
|
|
||||||
|
|
|
@ -98,6 +98,7 @@ public:
|
||||||
static const MappedAttributeEntry sTextContentElementsMap[];
|
static const MappedAttributeEntry sTextContentElementsMap[];
|
||||||
static const MappedAttributeEntry sFontSpecificationMap[];
|
static const MappedAttributeEntry sFontSpecificationMap[];
|
||||||
static const MappedAttributeEntry sGradientStopMap[];
|
static const MappedAttributeEntry sGradientStopMap[];
|
||||||
|
static const MappedAttributeEntry sViewportsMap[];
|
||||||
|
|
||||||
// nsIDOMNode
|
// nsIDOMNode
|
||||||
NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, PRBool* aReturn);
|
NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, PRBool* aReturn);
|
||||||
|
|
|
@ -1120,7 +1120,8 @@ nsSVGSVGElement::IsAttributeMapped(const nsIAtom* name) const
|
||||||
sFillStrokeMap,
|
sFillStrokeMap,
|
||||||
sGraphicsMap,
|
sGraphicsMap,
|
||||||
sTextContentElementsMap,
|
sTextContentElementsMap,
|
||||||
sFontSpecificationMap
|
sFontSpecificationMap,
|
||||||
|
sViewportsMap
|
||||||
};
|
};
|
||||||
|
|
||||||
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
|
return FindAttributeDependence(name, map, NS_ARRAY_LENGTH(map)) ||
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
#include "nsIDOMSVGSVGElement.h"
|
#include "nsIDOMSVGSVGElement.h"
|
||||||
#include "nsISVGSVGElement.h"
|
#include "nsISVGSVGElement.h"
|
||||||
#include "nsIDOMSVGAnimatedLength.h"
|
#include "nsIDOMSVGAnimatedLength.h"
|
||||||
|
#include "nsIDOMSVGAnimatedRect.h"
|
||||||
|
#include "nsIDOMSVGFitToViewBox.h"
|
||||||
#include "nsSVGLength.h"
|
#include "nsSVGLength.h"
|
||||||
#include "nsISVGValue.h"
|
#include "nsISVGValue.h"
|
||||||
#include "nsISVGValueObserver.h"
|
#include "nsISVGValueObserver.h"
|
||||||
|
@ -349,6 +351,29 @@ nsSVGInnerSVGFrame::Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectT
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
// printf("nsSVGInnerSVG(%p)::Paint\n", this);
|
// printf("nsSVGInnerSVG(%p)::Paint\n", this);
|
||||||
#endif
|
#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;
|
for (nsIFrame* kid = mFrames.FirstChild(); kid;
|
||||||
kid = kid->GetNextSibling()) {
|
kid = kid->GetNextSibling()) {
|
||||||
nsISVGChildFrame* SVGFrame=nsnull;
|
nsISVGChildFrame* SVGFrame=nsnull;
|
||||||
|
@ -357,6 +382,8 @@ nsSVGInnerSVGFrame::Paint(nsISVGRendererCanvas* canvas, const nsRect& dirtyRectT
|
||||||
SVGFrame->Paint(canvas, dirtyRectTwips);
|
SVGFrame->Paint(canvas, dirtyRectTwips);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
canvas->PopClip();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,3 +61,6 @@ svg {
|
||||||
style {
|
style {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
svg, symbol, image, marker, pattern, foreignObject { overflow: hidden }
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ typedef PRUint32 nscolor;
|
||||||
|
|
||||||
interface nsIRenderingContext;
|
interface nsIRenderingContext;
|
||||||
interface nsPresContext;
|
interface nsPresContext;
|
||||||
|
interface nsIDOMSVGMatrix;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup renderer_interfaces Rendering Engine Interfaces
|
* \addtogroup renderer_interfaces Rendering Engine Interfaces
|
||||||
|
@ -67,7 +68,7 @@ interface nsPresContext;
|
||||||
* Mozilla-native rendering object with a call to
|
* Mozilla-native rendering object with a call to
|
||||||
* nsISVGRenderer::createCanvas().
|
* nsISVGRenderer::createCanvas().
|
||||||
*/
|
*/
|
||||||
[scriptable, uuid(a1d9f15e-ee63-4ce1-9fe7-b6cdb09a48a0)]
|
[scriptable, uuid(90be3072-6a88-4dc3-a3f0-c8f2907078d8)]
|
||||||
interface nsISVGRendererCanvas : nsISupports
|
interface nsISVGRendererCanvas : nsISupports
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
@ -104,6 +105,18 @@ interface nsISVGRendererCanvas : nsISupports
|
||||||
* Mozilla-native rendering context.
|
* Mozilla-native rendering context.
|
||||||
*/
|
*/
|
||||||
void flush();
|
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 "nsCOMPtr.h"
|
||||||
#include "nsSVGCairoCanvas.h"
|
#include "nsSVGCairoCanvas.h"
|
||||||
#include "nsISVGCairoCanvas.h"
|
#include "nsISVGCairoCanvas.h"
|
||||||
|
#include "nsIDOMSVGMatrix.h"
|
||||||
#include "nsIRenderingContext.h"
|
#include "nsIRenderingContext.h"
|
||||||
#include "nsIDeviceContext.h"
|
#include "nsIDeviceContext.h"
|
||||||
#include "nsTransform2D.h"
|
#include "nsTransform2D.h"
|
||||||
|
@ -217,3 +218,89 @@ nsSVGCairoCanvas::Flush()
|
||||||
{
|
{
|
||||||
return NS_OK;
|
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 "nsPresContext.h"
|
||||||
#include "nsRect.h"
|
#include "nsRect.h"
|
||||||
#include "nsIRenderingContextWin.h"
|
#include "nsIRenderingContextWin.h"
|
||||||
|
#include "nsIDOMSVGMatrix.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \addtogroup gdiplus_renderer GDI+ Rendering Engine
|
* \addtogroup gdiplus_renderer GDI+ Rendering Engine
|
||||||
|
@ -84,6 +85,8 @@ private:
|
||||||
nsCOMPtr<nsIRenderingContext> mMozContext;
|
nsCOMPtr<nsIRenderingContext> mMozContext;
|
||||||
nsCOMPtr<nsPresContext> mPresContext;
|
nsCOMPtr<nsPresContext> mPresContext;
|
||||||
Graphics *mGraphics;
|
Graphics *mGraphics;
|
||||||
|
nsVoidArray mClipStack;
|
||||||
|
|
||||||
#ifdef SVG_GDIPLUS_ENABLE_OFFSCREEN_BUFFER
|
#ifdef SVG_GDIPLUS_ENABLE_OFFSCREEN_BUFFER
|
||||||
Bitmap *mOffscreenBitmap;
|
Bitmap *mOffscreenBitmap;
|
||||||
Graphics *mOffscreenGraphics;
|
Graphics *mOffscreenGraphics;
|
||||||
|
@ -319,4 +322,71 @@ nsSVGGDIPlusCanvas::GetGraphics()
|
||||||
#endif
|
#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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче