/* static */ void nsSVGIntegrationUtils::DrawPaintServer(nsRenderingContext* aRenderingContext, nsIFrame* aTarget, nsIFrame* aPaintServer, gfxPattern::GraphicsFilter aFilter, const nsRect& aDest, const nsRect& aFill, const nsPoint& aAnchor, const nsRect& aDirty, const nsSize& aPaintServerSize) { if (aDest.IsEmpty() || aFill.IsEmpty()) return; PRInt32 appUnitsPerDevPixel = aTarget->PresContext()->AppUnitsPerDevPixel(); nsRect destSize = aDest - aDest.TopLeft(); nsIntSize roundedOut = destSize.ToOutsidePixels(appUnitsPerDevPixel).Size(); gfxIntSize imageSize(roundedOut.width, roundedOut.height); nsRefPtr<gfxDrawable> drawable = DrawableFromPaintServer(aPaintServer, aTarget, aPaintServerSize, imageSize); if (drawable) { nsLayoutUtils::DrawPixelSnapped(aRenderingContext, drawable, aFilter, aDest, aFill, aAnchor, aDirty); } }
// Computes the smallest rectangle that contains both aRect1 and aRect2 and // fills 'this' with the result. Returns FALSE if both aRect1 and aRect2 are // empty and TRUE otherwise PRBool nsRect::UnionRect(const nsRect &aRect1, const nsRect &aRect2) { PRBool result = PR_TRUE; // Is aRect1 empty? if (aRect1.IsEmpty()) { if (aRect2.IsEmpty()) { // Both rectangles are empty which is an error Empty(); result = PR_FALSE; } else { // aRect1 is empty so set the result to aRect2 *this = aRect2; } } else if (aRect2.IsEmpty()) { // aRect2 is empty so set the result to aRect1 *this = aRect1; } else { UnionRectIncludeEmpty(aRect1, aRect2); } return result; }
void nsSVGForeignObjectFrame::InvalidateDirtyRect(const nsRect& aRect, PRUint32 aFlags, bool aDuringReflowSVG) { if (aRect.IsEmpty()) return; // Don't invalidate areas outside our bounds: nsRect rect = aRect.Intersect(nsRect(nsPoint(0,0), mRect.Size())); if (rect.IsEmpty()) return; nsSVGUtils::InvalidateBounds(this, aDuringReflowSVG, &rect, aFlags); }
bool DisplayItemClip::MayIntersect(const nsRect& aRect) const { if (!mHaveClipRect) { return !aRect.IsEmpty(); } nsRect r = aRect.Intersect(mClipRect); if (r.IsEmpty()) { return false; } for (uint32_t i = 0; i < mRoundedClipRects.Length(); ++i) { const RoundedRect& rr = mRoundedClipRects[i]; if (!nsLayoutUtils::RoundedRectIntersectsRect(rr.mRect, rr.mRadii, r)) { return false; } } return true; }
void nsSVGForeignObjectFrame::InvalidateDirtyRect(nsSVGOuterSVGFrame* aOuter, const nsRect& aRect, PRUint32 aFlags) { if (aRect.IsEmpty()) return; // Don't invalidate areas outside our bounds: nsRect rect = aRect.Intersect(mRect); if (rect.IsEmpty()) return; // The areas dirtied by children are in app units, relative to this frame. // We need to convert the rect from app units in our userspace to app units // relative to our nsSVGOuterSVGFrame's content rect. gfxRect r(aRect.x, aRect.y, aRect.width, aRect.height); r.Scale(1.0 / nsPresContext::AppUnitsPerCSSPixel()); rect = ToCanvasBounds(r, GetCanvasTM(), PresContext()); rect = nsSVGUtils::FindFilterInvalidation(this, rect); aOuter->InvalidateWithFlags(rect, aFlags); }
nsRect nsFilterInstance::GetPostFilterDirtyArea(nsIFrame *aFilteredFrame, const nsRect& aPreFilterDirtyRect) { if (aPreFilterDirtyRect.IsEmpty()) { return nsRect(); } nsFilterInstance instance(aFilteredFrame, nullptr, nullptr, &aPreFilterDirtyRect); if (!instance.IsInitialized()) { return nsRect(); } // We've passed in the source's dirty area so the instance knows about it. // Now we can ask the instance to compute the area of the filter output // that's dirty. nsRect dirtyRect; nsresult rv = instance.ComputePostFilterDirtyRect(&dirtyRect); if (NS_SUCCEEDED(rv)) { return dirtyRect; } return nsRect(); }
//Also Returns true if aRect is Empty PRBool nsRect::Contains(const nsRect &aRect) const { return aRect.IsEmpty() || ((PRBool) ((aRect.x >= x) && (aRect.y >= y) && (aRect.XMost() <= XMost()) && (aRect.YMost() <= YMost()))); }
nsRect nsRegion::GetLargestRectangle (const nsRect& aContainingRect) const { nsRect bestRect; if (GetNumRects() <= 1) { bestRect = GetBounds(); return bestRect; } AxisPartition xaxis, yaxis; // Step 1: Calculate the grid lines nsRegionRectIterator iter(*this); const nsRect *currentRect; while ((currentRect = iter.Next())) { xaxis.InsertCoord(currentRect->x); xaxis.InsertCoord(currentRect->XMost()); yaxis.InsertCoord(currentRect->y); yaxis.InsertCoord(currentRect->YMost()); } if (!aContainingRect.IsEmpty()) { xaxis.InsertCoord(aContainingRect.x); xaxis.InsertCoord(aContainingRect.XMost()); yaxis.InsertCoord(aContainingRect.y); yaxis.InsertCoord(aContainingRect.YMost()); } // Step 2: Fill out the grid with the areas // Note: due to the ordering of rectangles in the region, it is not always // possible to combine steps 2 and 3 so we don't try to be clever. int32_t matrixHeight = yaxis.GetNumStops() - 1; int32_t matrixWidth = xaxis.GetNumStops() - 1; int32_t matrixSize = matrixHeight * matrixWidth; nsTArray<SizePair> areas(matrixSize); areas.SetLength(matrixSize); iter.Reset(); while ((currentRect = iter.Next())) { int32_t xstart = xaxis.IndexOf(currentRect->x); int32_t xend = xaxis.IndexOf(currentRect->XMost()); int32_t y = yaxis.IndexOf(currentRect->y); int32_t yend = yaxis.IndexOf(currentRect->YMost()); for (; y < yend; y++) { nscoord height = yaxis.StopSize(y); for (int32_t x = xstart; x < xend; x++) { nscoord width = xaxis.StopSize(x); int64_t size = width*int64_t(height); if (currentRect->Intersects(aContainingRect)) { areas[y*matrixWidth+x].mSizeContainingRect = size; } areas[y*matrixWidth+x].mSize = size; } } } // Step 3: Find the maximum submatrix sum that does not contain a rectangle { // First get the prefix sum array int32_t m = matrixHeight + 1; int32_t n = matrixWidth + 1; nsTArray<SizePair> pareas(m*n); pareas.SetLength(m*n); for (int32_t y = 1; y < m; y++) { for (int32_t x = 1; x < n; x++) { SizePair area = areas[(y-1)*matrixWidth+x-1]; if (!area.mSize) { area = SizePair::VeryLargeNegative(); } area = area + pareas[ y*n+x-1] + pareas[(y-1)*n+x ] - pareas[(y-1)*n+x-1]; pareas[y*n+x] = area; } } // No longer need the grid areas.SetLength(0); SizePair bestArea; struct { int32_t left, top, right, bottom; } bestRectIndices = { 0, 0, 0, 0 }; for (int32_t m1 = 0; m1 < m; m1++) { for (int32_t m2 = m1+1; m2 < m; m2++) { nsTArray<SizePair> B; B.SetLength(n); for (int32_t i = 0; i < n; i++) { B[i] = pareas[m2*n+i] - pareas[m1*n+i]; } int32_t minIdx, maxIdx; SizePair area = MaxSum1D(B, n, &minIdx, &maxIdx); if (area > bestArea) { bestRectIndices.left = minIdx; bestRectIndices.top = m1; bestRectIndices.right = maxIdx; bestRectIndices.bottom = m2; bestArea = area; } } } bestRect.MoveTo(xaxis.StopAt(bestRectIndices.left), yaxis.StopAt(bestRectIndices.top)); bestRect.SizeTo(xaxis.StopAt(bestRectIndices.right) - bestRect.x, yaxis.StopAt(bestRectIndices.bottom) - bestRect.y); } return bestRect; }