mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-14 12:13:22 +00:00
Bug 772017, part 2 - Have the visual overflow rect for SVG frames include non-rendering stroke when 'pointer-events' demands it. r=roc.
This commit is contained in:
parent
a5d221fbdb
commit
1a49fcfa1a
@ -442,10 +442,22 @@ nsSVGGlyphFrame::UpdateBounds()
|
||||
|
||||
mRect.SetEmpty();
|
||||
|
||||
gfxRect extent = GetBBoxContribution(gfxMatrix(),
|
||||
nsSVGUtils::eBBoxIncludeFill | nsSVGUtils::eBBoxIgnoreFillIfNone |
|
||||
nsSVGUtils::eBBoxIncludeStroke | nsSVGUtils::eBBoxIgnoreStrokeIfNone |
|
||||
nsSVGUtils::eBBoxIncludeMarkers);
|
||||
PRUint32 flags = nsSVGUtils::eBBoxIncludeFill |
|
||||
nsSVGUtils::eBBoxIncludeStroke |
|
||||
nsSVGUtils::eBBoxIncludeMarkers;
|
||||
// Our "visual" overflow rect needs to be valid for building display lists
|
||||
// for hit testing, which means that for certain values of 'pointer-events'
|
||||
// it needs to include the geometry of the fill or stroke even when the fill/
|
||||
// stroke don't actually render (e.g. when stroke="none" or
|
||||
// stroke-opacity="0"). GetHitTestFlags() accounts for 'pointer-events'.
|
||||
PRUint16 hitTestFlags = GetHitTestFlags();
|
||||
if ((hitTestFlags & SVG_HIT_TEST_FILL)) {
|
||||
flags |= nsSVGUtils::eBBoxIncludeFillGeometry;
|
||||
}
|
||||
if ((hitTestFlags & SVG_HIT_TEST_STROKE)) {
|
||||
flags |= nsSVGUtils::eBBoxIncludeStrokeGeometry;
|
||||
}
|
||||
gfxRect extent = GetBBoxContribution(gfxMatrix(), flags);
|
||||
|
||||
if (!extent.IsEmpty()) {
|
||||
mRect = nsLayoutUtils::RoundGfxRectToAppRect(extent,
|
||||
@ -590,15 +602,15 @@ nsSVGGlyphFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
gfxRect pathExtents = tmpCtx->GetUserPathExtent();
|
||||
|
||||
// Account for fill:
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeFill) != 0 &&
|
||||
((aFlags & nsSVGUtils::eBBoxIgnoreFillIfNone) == 0 ||
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeFillGeometry) ||
|
||||
((aFlags & nsSVGUtils::eBBoxIncludeFill) &&
|
||||
GetStyleSVG()->mFill.mType != eStyleSVGPaintType_None)) {
|
||||
bbox = pathExtents;
|
||||
}
|
||||
|
||||
// Account for stroke:
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeStroke) != 0 &&
|
||||
((aFlags & nsSVGUtils::eBBoxIgnoreStrokeIfNone) == 0 || HasStroke())) {
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeStrokeGeometry) ||
|
||||
((aFlags & nsSVGUtils::eBBoxIncludeStroke) && HasStroke())) {
|
||||
bbox =
|
||||
bbox.Union(nsSVGUtils::PathExtentsToMaxStrokeExtents(pathExtents,
|
||||
this,
|
||||
|
@ -225,17 +225,17 @@ nsSVGPathGeometryFrame::UpdateBounds()
|
||||
PRUint32 flags = nsSVGUtils::eBBoxIncludeFill |
|
||||
nsSVGUtils::eBBoxIncludeStroke |
|
||||
nsSVGUtils::eBBoxIncludeMarkers;
|
||||
PRUint32 pointerEvents = GetStyleVisibility()->mPointerEvents;
|
||||
if (pointerEvents == NS_STYLE_POINTER_EVENTS_AUTO ||
|
||||
pointerEvents == NS_STYLE_POINTER_EVENTS_VISIBLEPAINTED ||
|
||||
pointerEvents == NS_STYLE_POINTER_EVENTS_PAINTED ||
|
||||
pointerEvents == NS_STYLE_POINTER_EVENTS_NONE) {
|
||||
// We can only ignore 'none' stroke if the value of the pointer-events
|
||||
// property doesn't require us to include it in our "visual" overflow rect
|
||||
// so that our visual overflow rect is valid for building display lists for
|
||||
// hit-testing.
|
||||
flags |= nsSVGUtils::eBBoxIgnoreStrokeIfNone |
|
||||
nsSVGUtils::eBBoxIgnoreFillIfNone;
|
||||
// Our "visual" overflow rect needs to be valid for building display lists
|
||||
// for hit testing, which means that for certain values of 'pointer-events'
|
||||
// it needs to include the geometry of the fill or stroke even when the fill/
|
||||
// stroke don't actually render (e.g. when stroke="none" or
|
||||
// stroke-opacity="0"). GetHitTestFlags() accounts for 'pointer-events'.
|
||||
PRUint16 hitTestFlags = GetHitTestFlags();
|
||||
if ((hitTestFlags & SVG_HIT_TEST_FILL)) {
|
||||
flags |= nsSVGUtils::eBBoxIncludeFillGeometry;
|
||||
}
|
||||
if ((hitTestFlags & SVG_HIT_TEST_STROKE)) {
|
||||
flags |= nsSVGUtils::eBBoxIncludeStrokeGeometry;
|
||||
}
|
||||
gfxRect extent = GetBBoxContribution(gfxMatrix(), flags);
|
||||
mRect = nsLayoutUtils::RoundGfxRectToAppRect(extent,
|
||||
@ -324,15 +324,15 @@ nsSVGPathGeometryFrame::GetBBoxContribution(const gfxMatrix &aToBBoxUserspace,
|
||||
gfxRect pathExtents = tmpCtx->GetUserPathExtent();
|
||||
|
||||
// Account for fill:
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeFill) != 0 &&
|
||||
((aFlags & nsSVGUtils::eBBoxIgnoreFillIfNone) == 0 ||
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeFillGeometry) ||
|
||||
((aFlags & nsSVGUtils::eBBoxIncludeFill) &&
|
||||
GetStyleSVG()->mFill.mType != eStyleSVGPaintType_None)) {
|
||||
bbox = pathExtents;
|
||||
}
|
||||
|
||||
// Account for stroke:
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeStroke) != 0 &&
|
||||
((aFlags & nsSVGUtils::eBBoxIgnoreStrokeIfNone) == 0 || HasStroke())) {
|
||||
if ((aFlags & nsSVGUtils::eBBoxIncludeStrokeGeometry) ||
|
||||
((aFlags & nsSVGUtils::eBBoxIncludeStroke) && HasStroke())) {
|
||||
// We can't use tmpCtx->GetUserStrokeExtent() since it doesn't work for
|
||||
// device space extents. Instead we approximate the stroke extents from
|
||||
// pathExtents using PathExtentsToMaxStrokeExtents.
|
||||
|
@ -592,16 +592,17 @@ public:
|
||||
|
||||
enum BBoxFlags {
|
||||
eBBoxIncludeFill = 1 << 0,
|
||||
eBBoxIgnoreFillIfNone = 1 << 1,
|
||||
eBBoxIncludeFillGeometry = 1 << 1,
|
||||
eBBoxIncludeStroke = 1 << 2,
|
||||
eBBoxIgnoreStrokeIfNone = 1 << 3,
|
||||
eBBoxIncludeStrokeGeometry = 1 << 3,
|
||||
eBBoxIncludeMarkers = 1 << 4
|
||||
};
|
||||
/**
|
||||
* Get the SVG bbox (the SVG spec's simplified idea of bounds) of aFrame in
|
||||
* aFrame's userspace.
|
||||
*/
|
||||
static gfxRect GetBBox(nsIFrame *aFrame, PRUint32 aFlags = eBBoxIncludeFill);
|
||||
static gfxRect GetBBox(nsIFrame *aFrame,
|
||||
PRUint32 aFlags = eBBoxIncludeFillGeometry);
|
||||
|
||||
/**
|
||||
* Convert a userSpaceOnUse/objectBoundingBoxUnits rectangle that's specified
|
||||
|
Loading…
x
Reference in New Issue
Block a user