Merge mozilla-central into mozilla-inbound

This commit is contained in:
Ehsan Akhgari 2012-04-10 11:12:26 -04:00
commit 5203026f2f
43 changed files with 886 additions and 282 deletions

View File

@ -665,7 +665,7 @@ nsRange::ComparePoint(nsIDOMNode* aParent, PRInt32 aOffset, PRInt16* aResult)
return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
}
if (aOffset < 0 || aOffset > parent->Length()) {
if (aOffset < 0 || PRUint32(aOffset) > parent->Length()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
@ -929,7 +929,7 @@ nsRange::SetStart(nsINode* aParent, PRInt32 aOffset)
nsINode* newRoot = IsValidBoundary(aParent);
NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
if (aOffset < 0 || aOffset > aParent->Length()) {
if (aOffset < 0 || PRUint32(aOffset) > aParent->Length()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
@ -993,7 +993,7 @@ nsRange::SetEnd(nsINode* aParent, PRInt32 aOffset)
nsINode* newRoot = IsValidBoundary(aParent);
NS_ENSURE_TRUE(newRoot, NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
if (aOffset < 0 || aOffset > aParent->Length()) {
if (aOffset < 0 || PRUint32(aOffset) > aParent->Length()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}

View File

@ -560,15 +560,15 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
nsIContentSink* aSink)
{
if (!aCommand) {
MOZ_NOT_REACHED("Command is mandatory");
MOZ_ASSERT(false, "Command is mandatory");
return NS_ERROR_INVALID_POINTER;
}
if (aSink) {
MOZ_NOT_REACHED("Got a sink override. Should not happen for HTML doc.");
MOZ_ASSERT(false, "Got a sink override. Should not happen for HTML doc.");
return NS_ERROR_INVALID_ARG;
}
if (!mIsRegularHTML) {
MOZ_NOT_REACHED("Must not set HTML doc to XHTML mode before load start.");
MOZ_ASSERT(false, "Must not set HTML doc to XHTML mode before load start.");
return NS_ERROR_DOM_INVALID_STATE_ERR;
}
@ -580,7 +580,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
bool viewSource = !strcmp(aCommand, "view-source");
bool asData = !strcmp(aCommand, kLoadAsData);
if(!(view || viewSource || asData)) {
MOZ_NOT_REACHED("Bad parser command");
MOZ_ASSERT(false, "Bad parser command");
return NS_ERROR_INVALID_ARG;
}
@ -595,7 +595,7 @@ nsHTMLDocument::StartDocumentLoad(const char* aCommand,
contentType.EqualsLiteral(TEXT_JAVASCRIPT) ||
contentType.EqualsLiteral(APPLICATION_JSON));
if (!(html || xhtml || plainText || viewSource)) {
MOZ_NOT_REACHED("Channel with bad content type.");
MOZ_ASSERT(false, "Channel with bad content type.");
return NS_ERROR_INVALID_ARG;
}

View File

@ -372,8 +372,15 @@ nsScreen::MozLockOrientation(const nsAString& aOrientation, bool* aReturn)
}
if (!IsChromeType(GetOwner()->GetDocShell())) {
nsCOMPtr<nsIDOMDocument> doc;
GetOwner()->GetDocument(getter_AddRefs(doc));
if (!doc) {
*aReturn = false;
return NS_OK;
}
bool fullscreen;
GetOwner()->GetFullScreen(&fullscreen);
doc->GetMozFullScreen(&fullscreen);
if (!fullscreen) {
*aReturn = false;
return NS_OK;

View File

@ -46,10 +46,6 @@ const GLOBAL_SCOPE = this;
* SmsDatabaseService
*/
function SmsDatabaseService() {
// Prime the directory service's cache to ensure that the ProfD entry exists
// by the time IndexedDB queries for it off the main thread. (See bug 743635.)
Services.dirsvc.get("ProfD", Ci.nsIFile);
gIDBManager.initWindowless(GLOBAL_SCOPE);
let that = this;

View File

@ -234,6 +234,10 @@ ffs (int x)
}
#endif
#elif defined(__WIN32__) && defined(__GNUC__)
#define ffs(x) __builtin_ffs(x)
#endif
#if defined(_MSC_VER) && defined(_M_IX86)

View File

@ -0,0 +1,25 @@
diff --git a/gfx/cairo/cairo/src/cairo-compiler-private.h b/gfx/cairo/cairo/src/cairo-compiler-private.h
index ffac9ce..9a05831 100644
--- a/gfx/cairo/cairo/src/cairo-compiler-private.h
+++ b/gfx/cairo/cairo/src/cairo-compiler-private.h
@@ -229,16 +229,20 @@ ffs (int x)
if (_BitScanForward(&i, x) != 0)
return i + 1;
return 0;
}
#endif
+#elif defined(__WIN32__) && defined(__GNUC__)
+
+#define ffs(x) __builtin_ffs(x)
+
#endif
#if defined(_MSC_VER) && defined(_M_IX86)
/* When compiling with /Gy and /OPT:ICF identical functions will be folded in together.
The CAIRO_ENSURE_UNIQUE macro ensures that a function is always unique and
will never be folded into another one. Something like this might eventually
be needed for GCC but it seems fine for now. */
#define CAIRO_ENSURE_UNIQUE \

View File

@ -1500,24 +1500,25 @@ struct GlyphBufferAzure {
if (invFontMatrix) {
// The brush matrix needs to be multiplied with the inverted matrix
// as well, to move the brush into the space of the glyphs. Before
// the render target transformation
// as well, to move the brush into the space of the glyphs. Before
// the render target transformation
// This relies on the returned Pattern not to be reused by
// others, but regenerated on GetPattern calls. This is true!
Matrix *mat;
Matrix *mat = nsnull;
if (pat->GetType() == PATTERN_LINEAR_GRADIENT) {
mat = &static_cast<LinearGradientPattern*>(pat)->mMatrix;
} else if (pat->GetType() == PATTERN_RADIAL_GRADIENT) {
mat = &static_cast<LinearGradientPattern*>(pat)->mMatrix;
mat = &static_cast<RadialGradientPattern*>(pat)->mMatrix;
} else if (pat->GetType() == PATTERN_SURFACE) {
mat = &static_cast<LinearGradientPattern*>(pat)->mMatrix;
mat = &static_cast<SurfacePattern*>(pat)->mMatrix;
}
*mat = (*mat) * (*invFontMatrix);
if (mat) {
*mat = (*mat) * (*invFontMatrix);
}
}
aDT->FillGlyphs(aFont, buf, *pat,
DrawOptions(), aOptions);
} else if (state.sourceSurface) {

View File

@ -781,8 +781,6 @@ JSRuntime::JSRuntime()
thousandsSeparator(0),
decimalSeparator(0),
numGrouping(0),
anynameObject(NULL),
functionNamespaceObject(NULL),
waiveGCQuota(false),
dtoaState(NULL),
pendingProxyOperation(NULL),

View File

@ -566,16 +566,6 @@ struct JSRuntime : js::RuntimeFriendFields
const char *decimalSeparator;
const char *numGrouping;
/*
* Weak references to lazily-created, well-known XML singletons.
*
* NB: Singleton objects must be carefully disconnected from the rest of
* the object graph usually associated with a JSContext's global object,
* including the set of standard class objects. See jsxml.c for details.
*/
JSObject *anynameObject;
JSObject *functionNamespaceObject;
/*
* Flag indicating that we are waiving any soft limits on the GC heap
* because we want allocations to be infallible (except when we hit OOM).

View File

@ -145,6 +145,13 @@ public:
mNextFreeRecycledThebesLayer(0), mNextFreeRecycledColorLayer(0),
mNextFreeRecycledImageLayer(0), mInvalidateAllThebesContent(false)
{
nsPresContext* presContext = aContainerFrame->PresContext();
mAppUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
// When AllowResidualTranslation is false, display items will be drawn
// scaled with a translation by integer pixels, so we know how the snapping
// will work.
mSnappingEnabled = aManager->IsSnappingEffectiveTransforms() &&
!mParameters.AllowResidualTranslation();
CollectOldLayers();
}
@ -176,6 +183,30 @@ public:
nsRect GetChildrenBounds() { return mBounds; }
nscoord GetAppUnitsPerDevPixel() { return mAppUnitsPerDevPixel; }
nsIntRect ScaleToNearestPixels(const nsRect& aRect)
{
return aRect.ScaleToNearestPixels(mParameters.mXScale, mParameters.mYScale,
mAppUnitsPerDevPixel);
}
nsIntRect ScaleToOutsidePixels(const nsRect& aRect, bool aSnap)
{
if (aSnap && mSnappingEnabled) {
return ScaleToNearestPixels(aRect);
}
return aRect.ScaleToOutsidePixels(mParameters.mXScale, mParameters.mYScale,
mAppUnitsPerDevPixel);
}
nsIntRect ScaleToInsidePixels(const nsRect& aRect, bool aSnap)
{
if (aSnap && mSnappingEnabled) {
return ScaleToNearestPixels(aRect);
}
return aRect.ScaleToInsidePixels(mParameters.mXScale, mParameters.mYScale,
mAppUnitsPerDevPixel);
}
protected:
/**
* We keep a stack of these to represent the ThebesLayers that are
@ -391,7 +422,9 @@ protected:
PRUint32 mNextFreeRecycledThebesLayer;
PRUint32 mNextFreeRecycledColorLayer;
PRUint32 mNextFreeRecycledImageLayer;
nscoord mAppUnitsPerDevPixel;
bool mInvalidateAllThebesContent;
bool mSnappingEnabled;
};
class ThebesDisplayItemLayerUserData : public LayerUserData
@ -851,11 +884,7 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
}
data->mXScale = mParameters.mXScale;
data->mYScale = mParameters.mYScale;
// If we're in a transformed subtree, but no ancestor transform is actively
// changing, we'll use the residual translation when drawing into the
// ThebesLayer to ensure that snapping exactly matches the ideal transform.
layer->SetAllowResidualTranslation(
mParameters.mInTransformedSubtree && !mParameters.mInActiveTransformedSubtree);
layer->SetAllowResidualTranslation(mParameters.AllowResidualTranslation());
mBuilder->LayerBuilder()->SaveLastPaintOffset(layer);
@ -960,10 +989,8 @@ ContainerState::FindOpaqueBackgroundColorFor(PRInt32 aThebesLayerIndex)
// The candidate intersects our target. If any layer has a solid-color
// area behind our target, this must be it. Scan its display items.
nsPresContext* presContext = mContainerFrame->PresContext();
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
nsRect rect =
target->mVisibleRegion.GetBounds().ToAppUnits(appUnitsPerDevPixel);
target->mVisibleRegion.GetBounds().ToAppUnits(mAppUnitsPerDevPixel);
rect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale);
return mBuilder->LayerBuilder()->
FindOpaqueColorCovering(mBuilder, candidate->mLayer, rect);
@ -1009,10 +1036,7 @@ ContainerState::PopThebesLayerData()
NS_ASSERTION(data->mImageClip.mRoundedClipRects.IsEmpty(),
"How did we get rounded clip rects here?");
if (data->mImageClip.mHaveClipRect) {
nsPresContext* presContext = mContainerFrame->PresContext();
nscoord appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel();
nsIntRect clip = data->mImageClip.mClipRect.ScaleToNearestPixels(
mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel);
nsIntRect clip = ScaleToNearestPixels(data->mImageClip.mClipRect);
imageLayer->IntersectClipRect(clip);
}
layer = imageLayer;
@ -1178,10 +1202,17 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState,
// below) but don't draw anything. They'll return true for isUniform but
// a color with opacity 0.
if (!isUniform || NS_GET_A(uniformColor) > 0) {
if (isUniform &&
aItem->GetBounds(aState->mBuilder).ScaleToInsidePixels(
aState->mParameters.mXScale, aState->mParameters.mYScale,
AppUnitsPerDevPixel(aItem)).Contains(aVisibleRect)) {
// Make sure that the visible area is covered by uniform pixels. In
// particular this excludes cases where the edges of the item are not
// pixel-aligned (thus the item will not be truly uniform).
if (isUniform) {
bool snap;
nsRect bounds = aItem->GetBounds(aState->mBuilder, &snap);
if (!aState->ScaleToInsidePixels(bounds, snap).Contains(aVisibleRect)) {
isUniform = false;
}
}
if (isUniform) {
if (mVisibleRegion.IsEmpty()) {
// This color is all we have
mSolidColor = uniformColor;
@ -1203,20 +1234,20 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState,
mDrawRegion.SimplifyOutward(4);
}
bool forceTransparentSurface = false;
nsRegion opaque = aItem->GetOpaqueRegion(aState->mBuilder, &forceTransparentSurface);
bool forceTransparentSurface;
bool snap;
nsRegion opaque = aItem->GetOpaqueRegion(aState->mBuilder, &snap,
&forceTransparentSurface);
if (!opaque.IsEmpty()) {
nsRegionRectIterator iter(opaque);
nscoord appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
for (const nsRect* r = iter.Next(); r; r = iter.Next()) {
// We don't use SimplifyInward here since it's not defined exactly
// what it will discard. For our purposes the most important case
// is a large opaque background at the bottom of z-order (e.g.,
// a canvas background), so we need to make sure that the first rect
// we see doesn't get discarded.
nsIntRect rect = aClip.ApproximateIntersect(*r).ScaleToInsidePixels(
aState->mParameters.mXScale, aState->mParameters.mYScale,
appUnitsPerDevPixel);
nsIntRect rect =
aState->ScaleToInsidePixels(aClip.ApproximateIntersect(*r), snap);
nsIntRegion tmp;
tmp.Or(mOpaqueRegion, rect);
// Opaque display items in chrome documents whose window is partially
@ -1237,11 +1268,10 @@ ContainerState::ThebesLayerData::Accumulate(ContainerState* aState,
aItem->DisableComponentAlpha();
} else {
nsRect componentAlpha = aItem->GetComponentAlphaBounds(aState->mBuilder);
componentAlpha.IntersectRect(componentAlpha, aItem->GetVisibleRect());
if (!componentAlpha.IsEmpty()) {
nscoord appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
if (!mOpaqueRegion.Contains(componentAlpha.ScaleToOutsidePixels(
aState->mParameters.mXScale, aState->mParameters.mYScale, appUnitsPerDevPixel))) {
nsIntRect componentAlphaRect =
aState->ScaleToOutsidePixels(componentAlpha, false).Intersect(aVisibleRect);
if (!mOpaqueRegion.Contains(componentAlphaRect)) {
if (SuppressComponentAlpha(aState->mBuilder, aItem, componentAlpha)) {
aItem->DisableComponentAlpha();
} else {
@ -1398,9 +1428,6 @@ void
ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
FrameLayerBuilder::Clip& aClip)
{
PRInt32 appUnitsPerDevPixel =
mContainerFrame->PresContext()->AppUnitsPerDevPixel();
for (nsDisplayItem* item = aList.GetBottom(); item; item = item->GetAbove()) {
nsDisplayItem::Type type = item->GetType();
if (type == nsDisplayItem::TYPE_CLIP ||
@ -1410,19 +1437,20 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
continue;
}
NS_ASSERTION(appUnitsPerDevPixel == AppUnitsPerDevPixel(item),
NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item),
"items in a container layer should all have the same app units per dev pixel");
nsIntRect itemVisibleRect =
item->GetVisibleRect().ScaleToOutsidePixels(
mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel);
nsRect itemContent = item->GetBounds(mBuilder);
ScaleToOutsidePixels(item->GetVisibleRect(), false);
bool snap;
nsRect itemContent = item->GetBounds(mBuilder, &snap);
if (aClip.mHaveClipRect) {
itemContent.IntersectRect(aClip.mClipRect, itemContent);
}
mBounds.UnionRect(mBounds, itemContent);
nsIntRect itemDrawRect = itemContent.ScaleToOutsidePixels(
mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel);
nsIntRect itemDrawRect = ScaleToOutsidePixels(itemContent, snap);
itemVisibleRect.IntersectRect(itemVisibleRect, itemDrawRect);
LayerState layerState = item->GetLayerState(mBuilder, mManager);
nsIFrame* activeScrolledRoot =
@ -1481,8 +1509,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
// It has its own layer. Update that layer's clip and visible rects.
if (aClip.mHaveClipRect) {
ownLayer->IntersectClipRect(
aClip.NonRoundedIntersection().ScaleToNearestPixels(
mParameters.mXScale, mParameters.mYScale, appUnitsPerDevPixel));
ScaleToNearestPixels(aClip.NonRoundedIntersection()));
}
ThebesLayerData* data = GetTopThebesLayerData();
if (data) {
@ -1542,8 +1569,8 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
// The bounds might have changed, but we assume that any difference
// in the bounds will have been invalidated for all Thebes layers
// in the container via regular frame invalidation.
nsRect bounds = aItem->GetBounds(mBuilder);
PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
bool snap;
nsRect bounds = aItem->GetBounds(mBuilder, &snap);
ThebesLayer* t = oldLayer->AsThebesLayer();
if (t) {
@ -1553,7 +1580,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
// so it doesn't matter whether we are using the old scale at last paint
// or a new scale here
InvalidatePostTransformRegion(t,
bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, appUnitsPerDevPixel),
bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
mBuilder->LayerBuilder()->GetLastPaintOffset(t));
}
if (aNewLayer) {
@ -1562,14 +1589,11 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
ThebesDisplayItemLayerUserData* data =
static_cast<ThebesDisplayItemLayerUserData*>(newLayer->GetUserData(&gThebesDisplayItemLayerUserData));
InvalidatePostTransformRegion(newLayer,
bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, appUnitsPerDevPixel),
bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
GetTranslationForThebesLayer(newLayer));
}
}
NS_ASSERTION(appUnitsPerDevPixel ==
mContainerFrame->PresContext()->AppUnitsPerDevPixel(),
"app units per dev pixel should be constant in a container");
mContainerFrame->InvalidateWithFlags(
bounds - mBuilder->ToReferenceFrame(mContainerFrame),
nsIFrame::INVALIDATE_NO_THEBES_LAYERS |
@ -1860,7 +1884,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
containerLayer);
ContainerState state(aBuilder, aManager, aContainerFrame, containerLayer,
scaleParameters);
nscoord appUnitsPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel();
if (aManager == mRetainingManager) {
DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(aContainerFrame);
@ -1880,7 +1903,7 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
invalidThebesContent->MoveBy(offset);
state.SetInvalidThebesContent(invalidThebesContent->
ScaleToOutsidePixels(scaleParameters.mXScale, scaleParameters.mYScale,
appUnitsPerDevPixel));
state.GetAppUnitsPerDevPixel()));
// We have to preserve the current contents of invalidThebesContent
// because there might be multiple container layers for the same
// frame and we need to invalidate the ThebesLayer children of all
@ -1905,15 +1928,13 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
nsRect bounds = state.GetChildrenBounds();
NS_ASSERTION(bounds.IsEqualInterior(aChildren.GetBounds(aBuilder)), "Wrong bounds");
nsIntRect pixBounds =
bounds.ScaleToOutsidePixels(scaleParameters.mXScale, scaleParameters.mYScale,
appUnitsPerDevPixel);
nsIntRect pixBounds = state.ScaleToOutsidePixels(bounds, false);
containerLayer->SetVisibleRegion(pixBounds);
// Make sure that rounding the visible region out didn't add any area
// we won't paint
if (aChildren.IsOpaque() && !aChildren.NeedsTransparentSurface()) {
bounds.ScaleRoundIn(scaleParameters.mXScale, scaleParameters.mYScale);
if (bounds.Contains(pixBounds.ToAppUnits(appUnitsPerDevPixel))) {
if (bounds.Contains(pixBounds.ToAppUnits(state.GetAppUnitsPerDevPixel()))) {
// Clear CONTENT_COMPONENT_ALPHA
flags = Layer::CONTENT_OPAQUE;
}
@ -2046,7 +2067,8 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
#ifdef MOZ_DUMP_PAINTING
static void DebugPaintItem(nsRenderingContext* aDest, nsDisplayItem *aItem, nsDisplayListBuilder* aBuilder)
{
nsRect appUnitBounds = aItem->GetBounds(aBuilder);
bool snap;
nsRect appUnitBounds = aItem->GetBounds(aBuilder, &snap);
gfxRect bounds(appUnitBounds.x, appUnitBounds.y, appUnitBounds.width, appUnitBounds.height);
bounds.ScaleInverse(aDest->AppUnitsPerDevPixel());

View File

@ -163,6 +163,17 @@ public:
bool mInTransformedSubtree;
bool mInActiveTransformedSubtree;
bool mDisableSubpixelAntialiasingInDescendants;
/**
* When this is false, ThebesLayer coordinates are drawn to with an integer
* translation and the scale in mXScale/mYScale.
*/
bool AllowResidualTranslation()
{
// If we're in a transformed subtree, but no ancestor transform is actively
// changing, we'll use the residual translation when drawing into the
// ThebesLayer to ensure that snapping exactly matches the ideal transform.
return mInTransformedSubtree && !mInActiveTransformedSubtree;
}
};
/**
* Build a container layer for a display item that contains a child

View File

@ -88,7 +88,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
mInTransform(false),
mSyncDecodeImages(false),
mIsPaintingToWindow(false),
mSnappingEnabled(mMode != EVENT_DELIVERY),
mHasDisplayPort(false),
mHasFixedItems(false)
{
@ -415,7 +414,8 @@ nsRect
nsDisplayList::GetBounds(nsDisplayListBuilder* aBuilder) const {
nsRect bounds;
for (nsDisplayItem* i = GetBottom(); i != nsnull; i = i->GetAbove()) {
bounds.UnionRect(bounds, i->GetBounds(aBuilder));
bool snap;
bounds.UnionRect(bounds, i->GetBounds(aBuilder, &snap));
}
return bounds;
}
@ -432,7 +432,8 @@ static nsRegion
TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder,
bool* aTransparentBackground)
{
nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, aTransparentBackground);
bool snap;
nsRegion opaque = aItem->GetOpaqueRegion(aBuilder, &snap, aTransparentBackground);
if (aBuilder->IsForPluginGeometry()) {
// Treat all chrome items as opaque, unless their frames are opacity:0.
// Since opacity:0 frames generate an nsDisplayOpacity, that item will
@ -440,7 +441,7 @@ TreatAsOpaque(nsDisplayItem* aItem, nsDisplayListBuilder* aBuilder,
// effectively ignored, as it should be.
nsIFrame* f = aItem->GetUnderlyingFrame();
if (f && f->PresContext()->IsChrome() && f->GetStyleDisplay()->mOpacity != 0.0) {
opaque = aItem->GetBounds(aBuilder);
opaque = aItem->GetBounds(aBuilder, &snap);
}
}
return opaque;
@ -473,6 +474,7 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aListVisibleBounds,
const nsRect& aAllowVisibleRegionExpansion) {
bool snap;
#ifdef DEBUG
nsRegion r;
r.And(*aVisibleRegion, GetBounds(aBuilder));
@ -507,7 +509,7 @@ nsDisplayList::ComputeVisibilityForSublist(nsDisplayListBuilder* aBuilder,
continue;
}
nsRect bounds = item->GetBounds(aBuilder);
nsRect bounds = item->GetBounds(aBuilder, &snap);
nsRegion itemVisible;
if (ForceVisiblityForFixedItem(aBuilder, item)) {
@ -742,7 +744,8 @@ void nsDisplayList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
item = aState->mItemBuffer[i];
aState->mItemBuffer.SetLength(i);
if (aRect.Intersects(item->GetBounds(aBuilder))) {
bool snap;
if (aRect.Intersects(item->GetBounds(aBuilder, &snap))) {
nsAutoTArray<nsIFrame*, 16> outFrames;
item->HitTest(aBuilder, aRect, aState, &outFrames);
@ -895,7 +898,8 @@ void nsDisplayList::Sort(nsDisplayListBuilder* aBuilder,
bool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion) {
nsRect bounds = GetBounds(aBuilder);
bool snap;
nsRect bounds = GetBounds(aBuilder, &snap);
nsRegion itemVisible;
if (ForceVisiblityForFixedItem(aBuilder, this)) {
@ -917,26 +921,11 @@ bool nsDisplayItem::RecomputeVisibility(nsDisplayListBuilder* aBuilder,
return true;
}
// Note that even if the rectangle we draw and snap is smaller than aRect,
// it's OK to call this to get a bounding rect for what we'll draw, because
// snapping a rectangle which is contained in R always gives you a
// rectangle which is contained in the snapped R.
static nsRect
SnapBounds(bool aSnappingEnabled, nsPresContext* aPresContext,
const nsRect& aRect) {
nsRect r = aRect;
if (aSnappingEnabled) {
nscoord appUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
r = r.ToNearestPixels(appUnitsPerDevPixel).ToAppUnits(appUnitsPerDevPixel);
}
return r;
}
nsRect
nsDisplaySolidColor::GetBounds(nsDisplayListBuilder* aBuilder)
nsDisplaySolidColor::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
nsPresContext* presContext = mFrame->PresContext();
return SnapBounds(mSnappingEnabled, presContext, mBounds);
*aSnap = true;
return mBounds;
}
void
@ -968,8 +957,7 @@ RegisterThemeGeometry(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
nsDisplayBackground::nsDisplayBackground(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame),
mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform())
: nsDisplayItem(aBuilder, aFrame)
{
MOZ_COUNT_CTOR(nsDisplayBackground);
const nsStyleDisplay* disp = mFrame->GetStyleDisplay();
@ -1126,7 +1114,8 @@ nsDisplayBackground::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion
nsDisplayBackground::GetInsideClipRegion(nsPresContext* aPresContext,
PRUint8 aClip, const nsRect& aRect)
PRUint8 aClip, const nsRect& aRect,
bool* aSnap)
{
nsRegion result;
if (aRect.IsEmpty())
@ -1153,14 +1142,12 @@ nsDisplayBackground::GetInsideClipRegion(nsPresContext* aPresContext,
return result;
}
nsRect inputRect = SnapBounds(mSnappingEnabled, aPresContext, aRect);
clipRect = SnapBounds(mSnappingEnabled, aPresContext, clipRect);
if (haveRadii) {
result = nsLayoutUtils::RoundedRectIntersectRect(clipRect, radii, inputRect);
*aSnap = false;
result = nsLayoutUtils::RoundedRectIntersectRect(clipRect, radii, aRect);
} else {
nsRect r;
r.IntersectRect(clipRect, inputRect);
r.IntersectRect(clipRect, aRect);
result = r;
}
return result;
@ -1168,11 +1155,11 @@ nsDisplayBackground::GetInsideClipRegion(nsPresContext* aPresContext,
nsRegion
nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap,
bool* aForceTransparentSurface) {
nsRegion result;
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aSnap = false;
*aForceTransparentSurface = false;
// theme background overrides any other background
if (mIsThemed) {
if (aForceTransparentSurface) {
@ -1181,7 +1168,7 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
disp->mAppearance == NS_THEME_WIN_GLASS;
}
if (mThemeTransparency == nsITheme::eOpaque) {
result = GetBounds(aBuilder);
result = GetBounds(aBuilder, aSnap);
}
return result;
}
@ -1193,10 +1180,12 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
const nsStyleBackground* bg = bgSC->GetStyleBackground();
const nsStyleBackground::Layer& bottomLayer = bg->BottomLayer();
*aSnap = true;
nsRect borderBox = nsRect(ToReferenceFrame(), mFrame->GetSize());
if (NS_GET_A(bg->mBackgroundColor) == 255 &&
!nsCSSRendering::IsCanvasFrame(mFrame)) {
result = GetInsideClipRegion(presContext, bottomLayer.mClip, borderBox);
result = GetInsideClipRegion(presContext, bottomLayer.mClip, borderBox, aSnap);
}
// For policies other than EACH_BOX, don't try to optimize here, since
@ -1211,7 +1200,7 @@ nsDisplayBackground::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
if (layer.mImage.IsOpaque()) {
nsRect r = nsCSSRendering::GetBackgroundLayerRect(presContext, mFrame,
borderBox, *bg, layer);
result.Or(result, GetInsideClipRegion(presContext, layer.mClip, r));
result.Or(result, GetInsideClipRegion(presContext, layer.mClip, r, aSnap));
}
}
}
@ -1310,7 +1299,8 @@ nsDisplayBackground::ShouldFixToViewport(nsDisplayListBuilder* aBuilder)
if (nsLayoutUtils::HasNonZeroCorner(mFrame->GetStyleBorder()->mBorderRadius))
return false;
nsRect bounds = GetBounds(aBuilder);
bool snap;
nsRect bounds = GetBounds(aBuilder, &snap);
nsIFrame* rootScrollFrame = presContext->PresShell()->GetRootScrollFrame();
if (!rootScrollFrame)
return false;
@ -1337,7 +1327,7 @@ nsDisplayBackground::Paint(nsDisplayListBuilder* aBuilder,
}
nsRect
nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder) {
nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
nsRect r(nsPoint(0,0), mFrame->GetSize());
nsPresContext* presContext = mFrame->PresContext();
@ -1347,11 +1337,13 @@ nsDisplayBackground::GetBounds(nsDisplayListBuilder* aBuilder) {
mFrame->GetStyleDisplay()->mAppearance, &r);
}
return SnapBounds(mSnappingEnabled, presContext, r + ToReferenceFrame());
*aSnap = true;
return r + ToReferenceFrame();
}
nsRect
nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder) {
nsDisplayOutline::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
@ -1450,11 +1442,12 @@ nsDisplayBorder::Paint(nsDisplayListBuilder* aBuilder,
}
nsRect
nsDisplayBorder::GetBounds(nsDisplayListBuilder* aBuilder)
nsDisplayBorder::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
nsRect borderBounds(ToReferenceFrame(), mFrame->GetSize());
borderBounds.Inflate(mFrame->GetStyleBorder()->GetImageOutset());
return SnapBounds(mSnappingEnabled, mFrame->PresContext(), borderBounds);
*aSnap = true;
return borderBounds;
}
// Given a region, compute a conservative approximation to it as a list
@ -1507,7 +1500,8 @@ nsDisplayBoxShadowOuter::Paint(nsDisplayListBuilder* aBuilder,
}
nsRect
nsDisplayBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder) {
nsDisplayBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
@ -1599,7 +1593,8 @@ nsDisplayWrapList::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
}
nsRect
nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder) {
nsDisplayWrapList::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mList.GetBounds(aBuilder);
}
@ -1614,13 +1609,13 @@ nsDisplayWrapList::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion
nsDisplayWrapList::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap,
bool* aForceTransparentSurface) {
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aForceTransparentSurface = false;
*aSnap = false;
nsRegion result;
if (mList.IsOpaque()) {
result = GetBounds(aBuilder);
result = GetBounds(aBuilder, aSnap);
}
return result;
}
@ -1760,10 +1755,10 @@ nsDisplayOpacity::~nsDisplayOpacity() {
#endif
nsRegion nsDisplayOpacity::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap,
bool* aForceTransparentSurface) {
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aForceTransparentSurface = false;
*aSnap = false;
// We are never opaque, if our opacity was < 1 then we wouldn't have
// been created.
return nsRegion();
@ -1820,7 +1815,8 @@ nsDisplayOpacity::ComputeVisibility(nsDisplayListBuilder* aBuilder,
// our children in the temporary compositing buffer, because if our children
// paint our entire bounds opaquely then we don't need an alpha channel in
// the temporary compositing buffer.
nsRect bounds = GetBounds(aBuilder);
bool snap;
nsRect bounds = GetBounds(aBuilder, &snap);
nsRegion visibleUnderChildren;
visibleUnderChildren.And(*aVisibleRegion, bounds);
nsRect allowExpansion;
@ -2095,23 +2091,20 @@ nsDisplayScrollInfoLayer::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayItem* aItem,
const nsRect& aRect)
: nsDisplayWrapList(aBuilder, aFrame, aItem) {
: nsDisplayWrapList(aBuilder, aFrame, aItem), mClip(aRect) {
MOZ_COUNT_CTOR(nsDisplayClip);
mClip = SnapBounds(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform(),
aBuilder->CurrentPresContext(), aRect);
}
nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame, nsDisplayList* aList,
const nsRect& aRect)
: nsDisplayWrapList(aBuilder, aFrame, aList) {
: nsDisplayWrapList(aBuilder, aFrame, aList), mClip(aRect) {
MOZ_COUNT_CTOR(nsDisplayClip);
mClip = SnapBounds(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform(),
aBuilder->CurrentPresContext(), aRect);
}
nsRect nsDisplayClip::GetBounds(nsDisplayListBuilder* aBuilder) {
nsRect r = nsDisplayWrapList::GetBounds(aBuilder);
nsRect nsDisplayClip::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
nsRect r = nsDisplayWrapList::GetBounds(aBuilder, aSnap);
*aSnap = true;
r.IntersectRect(mClip, r);
return r;
}
@ -2193,11 +2186,11 @@ nsDisplayClipRoundedRect::~nsDisplayClipRoundedRect()
nsRegion
nsDisplayClipRoundedRect::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap,
bool* aForceTransparentSurface)
{
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aSnap = false;
*aForceTransparentSurface = false;
return nsRegion();
}
@ -2267,9 +2260,10 @@ nsDisplayZoom::~nsDisplayZoom() {
}
#endif
nsRect nsDisplayZoom::GetBounds(nsDisplayListBuilder* aBuilder)
nsRect nsDisplayZoom::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
nsRect bounds = nsDisplayWrapList::GetBounds(aBuilder);
nsRect bounds = nsDisplayWrapList::GetBounds(aBuilder, aSnap);
*aSnap = false;
return bounds.ConvertAppUnitsRoundOut(mAPD, mParentAPD);
}
@ -2297,8 +2291,8 @@ void nsDisplayZoom::Paint(nsDisplayListBuilder* aBuilder,
}
bool nsDisplayZoom::ComputeVisibility(nsDisplayListBuilder *aBuilder,
nsRegion *aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
nsRegion *aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
// Convert the passed in visible region to our appunits.
nsRegion visibleRegion =
@ -2800,12 +2794,13 @@ nsDisplayTransform::GetHitDepthAtPoint(const nsPoint& aPoint)
/* The bounding rectangle for the object is the overflow rectangle translated
* by the reference point.
*/
nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder)
nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap)
{
nsRect untransformedBounds =
ShouldPrerenderTransformedContent(aBuilder, mFrame) ?
mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame() :
mStoredList.GetBounds(aBuilder);
mStoredList.GetBounds(aBuilder, aSnap);
*aSnap = false;
float factor = nsPresContext::AppUnitsPerCSSPixel();
return nsLayoutUtils::MatrixTransformRect(untransformedBounds,
GetTransform(factor),
@ -2829,11 +2824,11 @@ nsRect nsDisplayTransform::GetBounds(nsDisplayListBuilder *aBuilder)
* certainly contains the actual (non-axis-aligned) untransformed rect.
*/
nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
bool* aSnap,
bool* aForceTransparentSurface)
{
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aForceTransparentSurface = false;
*aSnap = false;
nsRect untransformedVisible;
float factor = nsPresContext::AppUnitsPerCSSPixel();
if (!UntransformRectMatrix(mVisibleRect, GetTransform(factor), factor, &untransformedVisible)) {
@ -2841,12 +2836,15 @@ nsRegion nsDisplayTransform::GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
}
const gfx3DMatrix& matrix = GetTransform(nsPresContext::AppUnitsPerCSSPixel());
nsRegion result;
gfxMatrix matrix2d;
bool tmpSnap;
bool forceTransparentSurface;
if (matrix.Is2D(&matrix2d) &&
matrix2d.PreservesAxisAlignedRectangles() &&
mStoredList.GetOpaqueRegion(aBuilder).Contains(untransformedVisible)) {
mStoredList.GetOpaqueRegion(aBuilder, &tmpSnap, &forceTransparentSurface).
Contains(untransformedVisible)) {
result = mVisibleRect;
}
return result;
@ -3007,11 +3005,11 @@ nsDisplaySVGEffects::~nsDisplaySVGEffects()
#endif
nsRegion nsDisplaySVGEffects::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap,
bool* aForceTransparentSurface)
{
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aForceTransparentSurface = false;
*aSnap = false;
return nsRegion();
}

View File

@ -306,16 +306,6 @@ public:
void SetHasFixedItems() { mHasFixedItems = true; }
bool GetHasFixedItems() { return mHasFixedItems; }
/**
* Returns true if snapping is enabled for the final drawing context.
* The default is true.
*/
bool IsSnappingEnabled() { return mSnappingEnabled; }
/**
* Set if snapping is enabled for the final drawing context.
*/
void SetSnappingEnabled(bool aSnappingEnabled) { mSnappingEnabled = aSnappingEnabled; }
/**
* @return true if images have been set to decode synchronously.
*/
@ -520,7 +510,6 @@ private:
bool mInTransform;
bool mSyncDecodeImages;
bool mIsPaintingToWindow;
bool mSnappingEnabled;
bool mHasDisplayPort;
bool mHasFixedItems;
};
@ -646,24 +635,33 @@ public:
inline nsIFrame* GetUnderlyingFrame() const { return mFrame; }
/**
* The default bounds is the frame border rect.
* @param aSnap *aSnap is set to true if the returned rect will be
* snapped to nearest device pixel edges during actual drawing.
* It might be set to false and snap anyway, so code computing the set of
* pixels affected by this display item needs to round outwards to pixel
* boundaries when *aSnap is set to false.
* @return a rectangle relative to aBuilder->ReferenceFrame() that
* contains the area drawn by this display item
*/
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = false;
return nsRect(ToReferenceFrame(), GetUnderlyingFrame()->GetSize());
}
/**
* @param aSnap set to true if the edges of the rectangles of the opaque
* region would be snapped to device pixels when drawing
* @return a region of the item that is opaque --- every pixel painted
* with an opaque color. This is useful for determining when one piece
* of content completely obscures another so that we can do occlusion
* culling.
*/
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull)
bool* aSnap,
bool* aForceTransparentSurface)
{
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aSnap = false;
*aForceTransparentSurface = false;
return nsRegion();
}
/**
@ -1332,8 +1330,10 @@ public:
NS_DISPLAY_DECL_NAME(mName, mType)
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder) {
if (mType == nsDisplayItem::TYPE_HEADER_FOOTER)
return GetBounds(aBuilder);
if (mType == nsDisplayItem::TYPE_HEADER_FOOTER) {
bool snap;
return GetBounds(aBuilder, &snap);
}
return nsRect();
}
@ -1441,7 +1441,8 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
// The caret returns a rect in the coordinates of mFrame.
return mCaret->GetCaretRect() + ToReferenceFrame();
}
@ -1457,8 +1458,8 @@ protected:
class nsDisplayBorder : public nsDisplayItem {
public:
nsDisplayBorder(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame) :
nsDisplayItem(aBuilder, aFrame),
mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform()) {
nsDisplayItem(aBuilder, aFrame)
{
MOZ_COUNT_CTOR(nsDisplayBorder);
}
#ifdef NS_BUILD_REFCNT_LOGGING
@ -1467,15 +1468,12 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
NS_DISPLAY_DECL_NAME("Border", TYPE_BORDER)
protected:
bool mSnappingEnabled;
};
/**
@ -1493,8 +1491,8 @@ class nsDisplaySolidColor : public nsDisplayItem {
public:
nsDisplaySolidColor(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
const nsRect& aBounds, nscolor aColor)
: nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor),
mSnappingEnabled(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform()) {
: nsDisplayItem(aBuilder, aFrame), mBounds(aBounds), mColor(aColor)
{
NS_ASSERTION(NS_GET_A(aColor) > 0, "Don't create invisible nsDisplaySolidColors!");
MOZ_COUNT_CTOR(nsDisplaySolidColor);
}
@ -1504,16 +1502,16 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aOutTransparentBackground = nsnull) {
if (aOutTransparentBackground) {
*aOutTransparentBackground = false;
}
bool* aSnap,
bool* aOutTransparentBackground) {
*aSnap = false;
*aOutTransparentBackground = false;
nsRegion result;
if (NS_GET_A(mColor) == 255) {
result = GetBounds(aBuilder);
result = GetBounds(aBuilder, aSnap);
}
return result;
}
@ -1531,7 +1529,6 @@ public:
private:
nsRect mBounds;
nscolor mColor;
bool mSnappingEnabled;
};
/**
@ -1552,21 +1549,21 @@ public:
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull);
bool* aSnap,
bool* aForceTransparentSurface);
virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
NS_DISPLAY_DECL_NAME("Background", TYPE_BACKGROUND)
protected:
nsRegion GetInsideClipRegion(nsPresContext* aPresContext, PRUint8 aClip,
const nsRect& aRect);
const nsRect& aRect, bool* aSnap);
/* Used to cache mFrame->IsThemed() since it isn't a cheap call */
bool mIsThemed;
bool mSnappingEnabled;
nsITheme::Transparency mThemeTransparency;
};
@ -1586,7 +1583,7 @@ public:
#endif
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
@ -1636,7 +1633,7 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
@ -1694,9 +1691,10 @@ public:
virtual ~nsDisplayWrapList();
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull);
bool* aSnap,
bool* aForceTransparentSurface);
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor);
virtual bool IsVaryingRelativeToMovingFrame(nsDisplayListBuilder* aBuilder,
nsIFrame* aFrame);
@ -1781,7 +1779,8 @@ public:
#endif
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull);
bool* aSnap,
bool* aForceTransparentSurface);
virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters);
@ -1946,7 +1945,7 @@ public:
virtual ~nsDisplayClip();
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
@ -1987,7 +1986,8 @@ public:
#endif
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull);
bool* aSnap,
bool* aForceTransparentSurface);
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
@ -2027,7 +2027,7 @@ public:
virtual ~nsDisplayZoom();
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
@ -2058,10 +2058,12 @@ public:
#endif
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull);
bool* aSnap,
bool* aForceTransparentSurface);
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mBounds + aBuilder->ToReferenceFrame(mEffectsFrame);
}
virtual void Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx);
@ -2130,16 +2132,18 @@ public:
{
if (mStoredList.GetComponentAlphaBounds(aBuilder).IsEmpty())
return nsRect();
return GetBounds(aBuilder);
bool snap;
return GetBounds(aBuilder, &snap);
}
nsDisplayWrapList* GetStoredList() { return &mStoredList; }
virtual void HitTest(nsDisplayListBuilder *aBuilder, const nsRect& aRect,
HitTestState *aState, nsTArray<nsIFrame*> *aOutFrames);
virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder *aBuilder, bool* aSnap);
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder *aBuilder,
bool* aForceTransparentSurface = nsnull);
bool* aSnap,
bool* aForceTransparentSurface);
virtual bool IsUniform(nsDisplayListBuilder *aBuilder, nscolor* aColor);
virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager);

View File

@ -170,7 +170,8 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
f->GetFrameName(fName);
}
#endif
nsRect rect = i->GetBounds(aBuilder);
bool snap;
nsRect rect = i->GetBounds(aBuilder, &snap);
switch (i->GetType()) {
case nsDisplayItem::TYPE_CLIP:
case nsDisplayItem::TYPE_CLIP_ROUNDED_RECT: {
@ -191,7 +192,8 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
}
#ifdef DEBUG
if (!list || list->DidComputeVisibility()) {
opaque = i->GetOpaqueRegion(aBuilder);
bool forceTransparentSurface;
opaque = i->GetOpaqueRegion(aBuilder, &snap, &forceTransparentSurface);
}
#endif
if (i->Painted()) {

View File

@ -1607,10 +1607,6 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
if (aFlags & PAINT_IGNORE_SUPPRESSION) {
builder.IgnorePaintSuppression();
}
if (aRenderingContext &&
aRenderingContext->ThebesContext()->GetFlags() & gfxContext::FLAG_DISABLE_SNAPPING) {
builder.SetSnappingEnabled(false);
}
nsRect canvasArea(nsPoint(0, 0), aFrame->GetSize());
#ifdef DEBUG

View File

@ -4603,7 +4603,8 @@ PresShell::ClipListToRange(nsDisplayListBuilder *aBuilder,
nsRange::CompareNodeToRange(content, aRange, &before, &after);
if (NS_SUCCEEDED(rv) && !before && !after) {
itemToInsert = i;
surfaceRect.UnionRect(surfaceRect, i->GetBounds(aBuilder));
bool snap;
surfaceRect.UnionRect(surfaceRect, i->GetBounds(aBuilder, &snap));
}
}
}

View File

@ -106,14 +106,15 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
NS_DISPLAY_DECL_NAME("ButtonBoxShadowOuter", TYPE_BUTTON_BOX_SHADOW_OUTER)
private:
nsButtonFrameRenderer* mBFR;
};
nsRect
nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder) {
nsDisplayButtonBoxShadowOuter::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}

View File

@ -149,7 +149,8 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
// override bounds because the list item focus ring may extend outside
// the nsSelectsAreaFrame
nsListControlFrame* listFrame = GetEnclosingListFrame(GetUnderlyingFrame());

View File

@ -190,7 +190,8 @@ public:
MOZ_COUNT_DTOR(nsDisplayTextOverflowMarker);
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
nsRect shadowRect =
nsLayoutUtils::GetTextShadowRectsUnion(mRect, mFrame);
return mRect.Union(shadowRect);

View File

@ -213,8 +213,9 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder)
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
@ -227,7 +228,8 @@ public:
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
{
return GetBounds(aBuilder);
bool snap;
return GetBounds(aBuilder, &snap);
}
};

View File

@ -253,8 +253,9 @@ public:
MOZ_COUNT_DTOR(nsDisplayCanvasFocus);
}
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder)
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = false;
// This is an overestimate, but that's not a problem.
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
return frame->CanvasArea() + ToReferenceFrame();

View File

@ -162,22 +162,23 @@ public:
}
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
return NS_GET_A(mExtraBackgroundColor) > 0 ||
nsDisplayBackground::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion);
}
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull)
bool* aSnap,
bool* aForceTransparentSurface)
{
if (aForceTransparentSurface) {
if (NS_GET_A(mExtraBackgroundColor) == 255) {
*aForceTransparentSurface = false;
return nsRegion(GetBounds(aBuilder, aSnap));
}
if (NS_GET_A(mExtraBackgroundColor) == 255)
return nsRegion(GetBounds(aBuilder));
return nsDisplayBackground::GetOpaqueRegion(aBuilder);
return nsDisplayBackground::GetOpaqueRegion(aBuilder, aSnap,
aForceTransparentSurface);
}
virtual bool IsUniform(nsDisplayListBuilder* aBuilder, nscolor* aColor)
{
@ -190,15 +191,11 @@ public:
*aColor = mExtraBackgroundColor;
return true;
}
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder)
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
nsCanvasFrame* frame = static_cast<nsCanvasFrame*>(mFrame);
nsRect r = frame->CanvasArea() + ToReferenceFrame();
if (mSnappingEnabled) {
nscoord appUnitsPerDevPixel = frame->PresContext()->AppUnitsPerDevPixel();
r = r.ToNearestPixels(appUnitsPerDevPixel).ToAppUnits(appUnitsPerDevPixel);
}
return r;
*aSnap = true;
return frame->CanvasArea() + ToReferenceFrame();
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)

View File

@ -82,20 +82,21 @@ public:
NS_DISPLAY_DECL_NAME("nsDisplayCanvas", TYPE_CANVAS)
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull) {
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
bool* aSnap,
bool* aForceTransparentSurface) {
*aForceTransparentSurface = false;
*aSnap = false;
nsIFrame* f = GetUnderlyingFrame();
nsHTMLCanvasElement *canvas = CanvasElementFromContent(f->GetContent());
nsRegion result;
if (canvas->GetIsOpaque()) {
result = GetBounds(aBuilder);
result = GetBounds(aBuilder, aSnap);
}
return result;
}
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
nsHTMLCanvasFrame* f = static_cast<nsHTMLCanvasFrame*>(GetUnderlyingFrame());
return f->GetInnerArea() + ToReferenceFrame();
}

View File

@ -917,7 +917,7 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion);
@ -946,8 +946,9 @@ GetDisplayItemBounds(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, nsIFr
}
nsRect
nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder)
nsDisplayPluginReadback::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = false;
return GetDisplayItemBounds(aBuilder, this, mFrame);
}
@ -961,7 +962,8 @@ nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder,
return false;
nsRect expand;
expand.IntersectRect(aAllowVisibleRegionExpansion, GetBounds(aBuilder));
bool snap;
expand.IntersectRect(aAllowVisibleRegionExpansion, GetBounds(aBuilder, &snap));
// *Add* our bounds to the visible region so that stuff underneath us is
// likely to be made visible, so we can use it for a background! This is
// a bit crazy since we normally only subtract from the visible region.
@ -970,8 +972,9 @@ nsDisplayPluginReadback::ComputeVisibility(nsDisplayListBuilder* aBuilder,
}
nsRect
nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder)
nsDisplayPlugin::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = false;
return GetDisplayItemBounds(aBuilder, this, mFrame);
}
@ -980,7 +983,8 @@ nsDisplayPlugin::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx)
{
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder));
bool snap;
f->PaintPlugin(aBuilder, *aCtx, mVisibleRect, GetBounds(aBuilder, &snap));
}
bool
@ -988,18 +992,19 @@ nsDisplayPlugin::ComputeVisibility(nsDisplayListBuilder* aBuilder,
nsRegion* aVisibleRegion,
const nsRect& aAllowVisibleRegionExpansion)
{
mVisibleRegion.And(*aVisibleRegion, GetBounds(aBuilder));
bool snap;
mVisibleRegion.And(*aVisibleRegion, GetBounds(aBuilder, &snap));
return nsDisplayItem::ComputeVisibility(aBuilder, aVisibleRegion,
aAllowVisibleRegionExpansion);
}
nsRegion
nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aSnap,
bool* aForceTransparentSurface)
{
if (aForceTransparentSurface) {
*aForceTransparentSurface = false;
}
*aForceTransparentSurface = false;
*aSnap = false;
nsRegion result;
nsObjectFrame* f = static_cast<nsObjectFrame*>(mFrame);
if (!aBuilder->IsForPluginGeometry()) {
@ -1018,11 +1023,13 @@ nsDisplayPlugin::GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
}
}
}
if (f->IsOpaque() &&
(aBuilder->IsForPluginGeometry() ||
(f->GetPaintedRect(this) + ToReferenceFrame()).Contains(GetBounds(aBuilder)))) {
// We can treat this as opaque
result = GetBounds(aBuilder);
if (f->IsOpaque()) {
nsRect bounds = GetBounds(aBuilder, aSnap);
if (aBuilder->IsForPluginGeometry() ||
(f->GetPaintedRect(this) + ToReferenceFrame()).Contains(bounds)) {
// We can treat this as opaque
result = bounds;
}
}
return result;
}

View File

@ -299,9 +299,10 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
virtual nsRegion GetOpaqueRegion(nsDisplayListBuilder* aBuilder,
bool* aForceTransparentSurface = nsnull);
bool* aSnap,
bool* aForceTransparentSurface);
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx);
virtual bool ComputeVisibility(nsDisplayListBuilder* aBuilder,

View File

@ -4389,7 +4389,8 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}
virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
@ -4404,7 +4405,8 @@ public:
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
{
return GetBounds(aBuilder);
bool snap;
return GetBounds(aBuilder, &snap);
}
virtual void DisableComponentAlpha() { mDisableSubpixelAA = true; }

View File

@ -345,8 +345,9 @@ public:
// away completely (e.g. because of a decoder error). The problem would
// be especially acute if we have off-main-thread rendering.
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder)
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = false;
nsIFrame* f = GetUnderlyingFrame();
return f->GetContentRect() - f->GetPosition() + ToReferenceFrame();
}

View File

@ -198,8 +198,9 @@ public:
, mId(aId)
{}
NS_OVERRIDE nsRect GetBounds(nsDisplayListBuilder* aBuilder)
NS_OVERRIDE nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap)
{
*aSnap = false;
return mRect;
}

View File

@ -1909,7 +1909,8 @@ public:
}
#endif
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder) {
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
nsRect rect;
mChar->GetRect(rect);
nsPoint offset = ToReferenceFrame() + rect.TopLeft();
@ -1930,7 +1931,8 @@ public:
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
{
return GetBounds(aBuilder);
bool snap;
return GetBounds(aBuilder, &snap);
}
private:

View File

@ -7,7 +7,7 @@ HTTP(..) == scroll-rounding.html scroll-rounding-ref.html
HTTP(..) == anonymous-block.html anonymous-block-ref.html
HTTP(..) == false-marker-overlap.html false-marker-overlap-ref.html
HTTP(..) == visibility-hidden.html visibility-hidden-ref.html
fails-if(Android&&layersOpenGL) HTTP(..) == block-padding.html block-padding-ref.html
fails-if(Android) HTTP(..) == block-padding.html block-padding-ref.html
HTTP(..) == quirks-decorations.html quirks-decorations-ref.html
HTTP(..) == quirks-line-height.html quirks-line-height-ref.html
HTTP(..) == standards-decorations.html standards-decorations-ref.html

View File

@ -401,7 +401,7 @@ public:
}
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
NS_DISPLAY_DECL_NAME("TableCellBackground", TYPE_TABLE_CELL_BACKGROUND)
};
@ -415,11 +415,12 @@ void nsDisplayTableCellBackground::Paint(nsDisplayListBuilder* aBuilder,
}
nsRect
nsDisplayTableCellBackground::GetBounds(nsDisplayListBuilder* aBuilder)
nsDisplayTableCellBackground::GetBounds(nsDisplayListBuilder* aBuilder,
bool* aSnap)
{
// revert from nsDisplayTableItem's implementation ... cell backgrounds
// don't overflow the cell
return nsDisplayItem::GetBounds(aBuilder);
return nsDisplayItem::GetBounds(aBuilder, aSnap);
}
static void

View File

@ -1062,7 +1062,8 @@ nsTableFrame::GetChildLists(nsTArray<ChildList>* aLists) const
}
nsRect
nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder) {
nsDisplayTableItem::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}

View File

@ -78,7 +78,7 @@ public:
// the table part frames, so allow this display element to blow out to our
// overflow rect. This is also useful for row frames that have spanning
// cells extending outside them.
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
void UpdateForFrameBackground(nsIFrame* aFrame);

View File

@ -325,7 +325,7 @@ public:
virtual void Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext* aCtx);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder);
virtual nsRect GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap);
NS_DISPLAY_DECL_NAME("XULTextBox", TYPE_XUL_TEXT_BOX)
virtual nsRect GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder);
@ -378,7 +378,8 @@ nsDisplayXULTextBox::PaintTextToContext(nsRenderingContext* aCtx,
}
nsRect
nsDisplayXULTextBox::GetBounds(nsDisplayListBuilder* aBuilder) {
nsDisplayXULTextBox::GetBounds(nsDisplayListBuilder* aBuilder, bool* aSnap) {
*aSnap = false;
return mFrame->GetVisualOverflowRectRelativeToSelf() + ToReferenceFrame();
}

View File

@ -706,3 +706,6 @@ pref("full-screen-api.enabled", true);
pref("direct-texture.force.enabled", false);
pref("direct-texture.force.disabled", false);
pref("remote-debugger.enabled", false);
pref("remote-debugger.port", 6000);

View File

@ -52,6 +52,11 @@ XPCOMUtils.defineLazyGetter(this, "PluralForm", function() {
return PluralForm;
});
XPCOMUtils.defineLazyGetter(this, "DebuggerServer", function() {
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
return DebuggerServer;
});
// Lazily-loaded browser scripts:
[
["SelectHelper", "chrome://browser/content/SelectHelper.js"],
@ -237,6 +242,7 @@ var BrowserApp = {
SearchEngines.init();
ActivityObserver.init();
WebappsUI.init();
RemoteDebugger.init();
// Init LoginManager
Cc["@mozilla.org/login-manager;1"].getService(Ci.nsILoginManager);
@ -417,6 +423,7 @@ var BrowserApp = {
CharacterEncoding.uninit();
SearchEngines.uninit();
WebappsUI.uninit();
RemoteDebugger.uninit();
},
// This function returns false during periods where the browser displayed document is
@ -4618,3 +4625,69 @@ var WebappsUI = {
}
}
}
var RemoteDebugger = {
init: function rd_init() {
Services.prefs.addObserver("remote-debugger.", this, false);
if (this._isEnabled())
this._start();
},
observe: function rd_observe(aSubject, aTopic, aData) {
if (aTopic != "nsPref:changed")
return;
switch (aData) {
case "remote-debugger.enabled":
if (this._isEnabled())
this._start();
else
this._stop();
break;
case "remote-debugger.port":
if (this._isEnabled())
this._restart();
break;
}
},
uninit: function rd_uninit() {
Services.prefs.removeObserver("remote-debugger.", this);
this._stop();
},
_getPort: function _rd_getPort() {
return Services.prefs.getIntPref("remote-debugger.port");
},
_isEnabled: function rd_isEnabled() {
return Services.prefs.getBoolPref("remote-debugger.enabled");
},
_restart: function rd_restart() {
this._stop();
this._start();
},
_start: function rd_start() {
try {
if (!DebuggerServer.initialized) {
DebuggerServer.init();
DebuggerServer.addActors("chrome://browser/content/dbg-browser-actors.js");
}
let port = this._getPort();
DebuggerServer.openListener(port, false);
dump("Remote debugger listening on port " + port);
} catch(e) {
dump("Remote debugger didn't start: " + e);
}
},
_stop: function rd_start() {
DebuggerServer.closeListener();
dump("Remote debugger stopped");
}
}

View File

@ -0,0 +1,414 @@
/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
/**
* Fennec-specific actors.
*/
var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"]
.getService(Ci.nsIWindowMediator);
function createRootActor(aConnection) {
return new BrowserRootActor(aConnection);
}
/**
* Creates the root actor that client-server communications always start with.
* The root actor is responsible for the initial 'hello' packet and for
* responding to a 'listTabs' request that produces the list of currently open
* tabs.
*
* @param aConnection DebuggerServerConnection
* The conection to the client.
*/
function BrowserRootActor(aConnection) {
this.conn = aConnection;
this._tabActors = new WeakMap();
this._tabActorPool = null;
this._actorFactories = null;
this.onTabClosed = this.onTabClosed.bind(this);
windowMediator.addListener(this);
}
BrowserRootActor.prototype = {
/**
* Return a 'hello' packet as specified by the Remote Debugging Protocol.
*/
sayHello: function BRA_sayHello() {
return { from: "root",
applicationType: "browser",
traits: [] };
},
/**
* Disconnects the actor from the browser window.
*/
disconnect: function BRA_disconnect() {
windowMediator.removeListener(this);
// We may have registered event listeners on browser windows to
// watch for tab closes, remove those.
let win = windowMediator.getMostRecentWindow("navigator:browser");
this.unwatchWindow(win);
// Signal our imminent shutdown.
let evt = win.document.createEvent("Event");
evt.initEvent("Debugger:Shutdown", true, false);
win.document.documentElement.dispatchEvent(evt);
},
/**
* Handles the listTabs request. Builds a list of actors
* for the tabs running in the process. The actors will survive
* until at least the next listTabs request.
*/
onListTabs: function BRA_onListTabs() {
// Get actors for all the currently-running tabs (reusing
// existing actors where applicable), and store them in
// an ActorPool.
let actorPool = new ActorPool(this.conn);
let actorList = [];
let win = windowMediator.getMostRecentWindow("navigator:browser");
this.browser = win.BrowserApp.selectedBrowser;
// Watch the window for tab closes so we can invalidate
// actors as needed.
this.watchWindow(win);
let tabs = win.BrowserApp.tabs;
let selected;
for each (let tab in tabs) {
let browser = tab.browser;
if (browser == this.browser) {
selected = actorList.length;
}
let actor = this._tabActors.get(browser);
if (!actor) {
actor = new BrowserTabActor(this.conn, browser);
actor.parentID = this.actorID;
this._tabActors.set(browser, actor);
}
actorPool.addActor(actor);
actorList.push(actor);
}
// Now drop the old actorID -> actor map. Actors that still
// mattered were added to the new map, others will go
// away.
if (this._tabActorPool) {
this.conn.removeActorPool(this._tabActorPool);
}
this._tabActorPool = actorPool;
this.conn.addActorPool(this._tabActorPool);
return { "from": "root",
"selected": selected,
"tabs": [actor.grip()
for each (actor in actorList)] };
},
/**
* Watch a window that was visited during onListTabs for
* tab closures.
*/
watchWindow: function BRA_watchWindow(aWindow) {
let tabContainer = aWindow.document.getElementById("browsers");
tabContainer.addEventListener("TabClose",
this.onTabClosed,
false);
},
/**
* Stop watching a window for tab closes.
*/
unwatchWindow: function BRA_unwatchWindow(aWindow) {
let tabContainer = aWindow.document.getElementById("browsers");
tabContainer.removeEventListener("TabClose", this.onTabClosed);
this.exitTabActor(aWindow);
},
/**
* When a tab is closed, exit its tab actor. The actor
* will be dropped at the next listTabs request.
*/
onTabClosed: function BRA_onTabClosed(aEvent) {
this.exitTabActor(aEvent.target.browser);
},
/**
* Exit the tab actor of the specified tab.
*/
exitTabActor: function BRA_exitTabActor(aWindow) {
let actor = this._tabActors.get(aWindow);
if (actor) {
actor.exit();
}
},
// nsIWindowMediatorListener
onWindowTitleChange: function BRA_onWindowTitleChange(aWindow, aTitle) { },
onOpenWindow: function BRA_onOpenWindow(aWindow) { },
onCloseWindow: function BRA_onCloseWindow(aWindow) {
if (aWindow.BrowserApp) {
this.unwatchWindow(aWindow);
}
}
}
/**
* The request types this actor can handle.
*/
BrowserRootActor.prototype.requestTypes = {
"listTabs": BrowserRootActor.prototype.onListTabs
};
/**
* Creates a tab actor for handling requests to a browser tab, like attaching
* and detaching.
*
* @param aConnection DebuggerServerConnection
* The conection to the client.
* @param aBrowser browser
* The browser instance that contains this tab.
*/
function BrowserTabActor(aConnection, aBrowser)
{
this.conn = aConnection;
this._browser = aBrowser;
this._onWindowCreated = this.onWindowCreated.bind(this);
}
// XXX (bug 710213): BrowserTabActor attach/detach/exit/disconnect is a
// *complete* mess, needs to be rethought asap.
BrowserTabActor.prototype = {
get browser() { return this._browser; },
get exited() { return !this._browser; },
get attached() { return !!this._attached },
_tabPool: null,
get tabActorPool() { return this._tabPool; },
_contextPool: null,
get contextActorPool() { return this._contextPool; },
actorPrefix: "tab",
grip: function BTA_grip() {
dbg_assert(!this.exited,
"grip() shouldn't be called on exited browser actor.");
dbg_assert(this.actorID,
"tab should have an actorID.");
return { actor: this.actorID,
title: this._browser.contentTitle,
url: this._browser.currentURI.spec }
},
/**
* Called when the actor is removed from the connection.
*/
disconnect: function BTA_disconnect() {
this._detach();
},
/**
* Called by the root actor when the underlying tab is closed.
*/
exit: function BTA_exit() {
if (this.exited) {
return;
}
if (this.attached) {
this._detach();
this.conn.send({ from: this.actorID,
type: "tabDetached" });
}
this._browser = null;
},
/**
* Does the actual work of attching to a tab.
*/
_attach: function BTA_attach() {
if (this._attached) {
return;
}
// Create a pool for tab-lifetime actors.
dbg_assert(!this._tabPool, "Shouldn't have a tab pool if we weren't attached.");
this._tabPool = new ActorPool(this.conn);
this.conn.addActorPool(this._tabPool);
// ... and a pool for context-lifetime actors.
this._pushContext();
// Watch for globals being created in this tab.
this._browser.addEventListener("DOMWindowCreated", this._onWindowCreated, true);
this._attached = true;
},
/**
* Creates a thread actor and a pool for context-lifetime actors. It then sets
* up the content window for debugging.
*/
_pushContext: function BTA_pushContext() {
dbg_assert(!this._contextPool, "Can't push multiple contexts");
this._contextPool = new ActorPool(this.conn);
this.conn.addActorPool(this._contextPool);
this.threadActor = new ThreadActor(this);
this._addDebuggees(this._browser.contentWindow.wrappedJSObject);
this._contextPool.addActor(this.threadActor);
},
/**
* Add the provided window and all windows in its frame tree as debuggees.
*/
_addDebuggees: function BTA__addDebuggees(aWindow) {
this.threadActor.addDebuggee(aWindow);
let frames = aWindow.frames;
for (let i = 0; i < frames.length; i++) {
this._addDebuggees(frames[i]);
}
},
/**
* Exits the current thread actor and removes the context-lifetime actor pool.
* The content window is no longer being debugged after this call.
*/
_popContext: function BTA_popContext() {
dbg_assert(!!this._contextPool, "No context to pop.");
this.conn.removeActorPool(this._contextPool);
this._contextPool = null;
this.threadActor.exit();
this.threadActor = null;
},
/**
* Does the actual work of detaching from a tab.
*/
_detach: function BTA_detach() {
if (!this.attached) {
return;
}
this._browser.removeEventListener("DOMWindowCreated", this._onWindowCreated, true);
this._popContext();
// Shut down actors that belong to this tab's pool.
this.conn.removeActorPool(this._tabPool);
this._tabPool = null;
this._attached = false;
},
// Protocol Request Handlers
onAttach: function BTA_onAttach(aRequest) {
if (this.exited) {
return { type: "exited" };
}
this._attach();
return { type: "tabAttached", threadActor: this.threadActor.actorID };
},
onDetach: function BTA_onDetach(aRequest) {
if (!this.attached) {
return { error: "wrongState" };
}
this._detach();
return { type: "detached" };
},
/**
* Prepare to enter a nested event loop by disabling debuggee events.
*/
preNest: function BTA_preNest() {
if (!this._browser) {
// The tab is already closed.
return;
}
let windowUtils = this._browser.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.suppressEventHandling(true);
windowUtils.suspendTimeouts();
},
/**
* Prepare to exit a nested event loop by enabling debuggee events.
*/
postNest: function BTA_postNest(aNestData) {
if (!this._browser) {
// The tab is already closed.
return;
}
let windowUtils = this._browser.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
windowUtils.resumeTimeouts();
windowUtils.suppressEventHandling(false);
},
/**
* Handle location changes, by sending a tabNavigated notification to the
* client.
*/
onWindowCreated: function BTA_onWindowCreated(evt) {
if (evt.target === this._browser.contentDocument) {
if (this._attached) {
this.conn.send({ from: this.actorID, type: "tabNavigated",
url: this._browser.contentDocument.URL });
}
}
}
};
/**
* The request types this actor can handle.
*/
BrowserTabActor.prototype.requestTypes = {
"attach": BrowserTabActor.prototype.onAttach,
"detach": BrowserTabActor.prototype.onDetach
};
/**
* Registers handlers for new request types defined dynamically. This is used
* for example by add-ons to augment the functionality of the tab actor.
*
* @param aName string
* The name of the new request type.
* @param aFunction function
* The handler for this request type.
*/
DebuggerServer.addTabRequest = function DS_addTabRequest(aName, aFunction) {
BrowserTabActor.prototype.requestTypes[aName] = function(aRequest) {
if (!this.attached) {
return { error: "wrongState" };
}
return aFunction(this, aRequest);
}
};

View File

@ -30,6 +30,7 @@ chrome.jar:
* content/downloads.js (content/downloads.js)
content/netError.xhtml (content/netError.xhtml)
content/SelectHelper.js (content/SelectHelper.js)
content/dbg-browser-actors.js (content/dbg-browser-actors.js)
% override chrome://global/content/config.xul chrome://browser/content/config.xhtml
% override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml

View File

@ -199,6 +199,8 @@
@BINPATH@/components/jar.xpt
@BINPATH@/components/jetpack.xpt
@BINPATH@/components/jsdservice.xpt
@BINPATH@/components/jsdebugger.xpt
@BINPATH@/components/jsinspector.xpt
@BINPATH@/components/layout_base.xpt
@BINPATH@/components/layout_forms.xpt
#ifdef NS_PRINTING

View File

@ -2106,7 +2106,7 @@ nsParser::OnDataAvailable(nsIRequest *request, nsISupports* aContext,
nsresult rv = NS_OK;
if (mIsAboutBlank) {
MOZ_NOT_REACHED("Must not get OnDataAvailable for about:blank");
MOZ_ASSERT(false, "Must not get OnDataAvailable for about:blank");
// ... but if an extension tries to feed us data for about:blank in a
// release build, silently ignore the data.
PRUint32 totalRead;

View File

@ -221,7 +221,9 @@ TimerManager.prototype = {
lastUpdateTime = Services.prefs.getIntPref(prefLastUpdate);
}
else {
lastUpdateTime = now;
// Initialize the last update time to 0 so that we check for
// an update the first time the interval expires.
lastUpdateTime = 0;
Services.prefs.setIntPref(prefLastUpdate, lastUpdateTime);
}

View File

@ -95,7 +95,8 @@ nsAppShell::nsAppShell()
mCondLock("nsAppShell.mCondLock"),
mQueueCond(mCondLock, "nsAppShell.mQueueCond"),
mQueuedDrawEvent(nsnull),
mQueuedViewportEvent(nsnull)
mQueuedViewportEvent(nsnull),
mAllowCoalescingNextDraw(false)
{
gAppShell = this;
}
@ -516,6 +517,11 @@ void
nsAppShell::PostEvent(AndroidGeckoEvent *ae)
{
{
// set this to true when inserting events that we can coalesce
// viewport events across. this is effectively maintaining a whitelist
// of events that are unaffected by viewport changes.
bool allowCoalescingNextViewport = false;
MutexAutoLock lock(mQueueLock);
EVLOG("nsAppShell::PostEvent %p %d", ae, ae->Type());
switch (ae->Type()) {
@ -576,7 +582,18 @@ nsAppShell::PostEvent(AndroidGeckoEvent *ae)
delete mQueuedDrawEvent;
}
mQueuedDrawEvent = ae;
if (mAllowCoalescingNextDraw) {
// if we're not allowing coalescing of this draw event, then
// don't set mQueuedDrawEvent to point to this; that way the
// next draw event that comes in won't kill this one.
mAllowCoalescingNextDraw = true;
mQueuedDrawEvent = nsnull;
} else {
mQueuedDrawEvent = ae;
}
allowCoalescingNextViewport = true;
mEventQueue.AppendElement(ae);
break;
@ -588,6 +605,11 @@ nsAppShell::PostEvent(AndroidGeckoEvent *ae)
delete mQueuedViewportEvent;
}
mQueuedViewportEvent = ae;
// temporarily turn off draw-coalescing, so that we process a draw
// event as soon as possible after a viewport change
mAllowCoalescingNextDraw = false;
allowCoalescingNextViewport = true;
mEventQueue.AppendElement(ae);
break;
@ -607,10 +629,20 @@ nsAppShell::PostEvent(AndroidGeckoEvent *ae)
mEventQueue.AppendElement(ae);
break;
case AndroidGeckoEvent::NATIVE_POKE:
allowCoalescingNextViewport = true;
// fall through
default:
mEventQueue.AppendElement(ae);
break;
}
// if the event wasn't on our whitelist then reset mQueuedViewportEvent
// so that we don't coalesce future viewport events into the last viewport
// event we added
if (!allowCoalescingNextViewport)
mQueuedViewportEvent = nsnull;
}
NotifyNativeEvent();
}

View File

@ -102,6 +102,7 @@ protected:
CondVar mQueueCond;
mozilla::AndroidGeckoEvent *mQueuedDrawEvent;
mozilla::AndroidGeckoEvent *mQueuedViewportEvent;
bool mAllowCoalescingNextDraw;
nsTArray<mozilla::AndroidGeckoEvent *> mEventQueue;
nsInterfaceHashtable<nsStringHashKey, nsIObserver> mObserversHash;