// Computes the area in which aRect1 and aRect2 overlap and fills 'this' with // the result. Returns FALSE if the rectangles don't intersect. PRBool nsRect::IntersectRect(const nsRect &aRect1, const nsRect &aRect2) { nscoord xmost1 = aRect1.XMost(); nscoord ymost1 = aRect1.YMost(); nscoord xmost2 = aRect2.XMost(); nscoord ymost2 = aRect2.YMost(); nscoord temp; x = PR_MAX(aRect1.x, aRect2.x); y = PR_MAX(aRect1.y, aRect2.y); // Compute the destination width temp = PR_MIN(xmost1, xmost2); if (temp <= x) { width = 0; } else { width = temp - x; } // Compute the destination height temp = PR_MIN(ymost1, ymost2); if (temp <= y) { height = 0; } else { height = temp - y; } return !IsEmpty(); }
static Maybe<nsRect> EdgeInclusiveIntersection(const nsRect& aRect, const nsRect& aOtherRect) { nscoord left = std::max(aRect.x, aOtherRect.x); nscoord top = std::max(aRect.y, aOtherRect.y); nscoord right = std::min(aRect.XMost(), aOtherRect.XMost()); nscoord bottom = std::min(aRect.YMost(), aOtherRect.YMost()); if (left > right || top > bottom) { return Nothing(); } return Some(nsRect(left, top, right - left, bottom - top)); }
void nsRect::UnionRectIncludeEmpty(const nsRect &aRect1, const nsRect &aRect2) { nscoord xmost1 = aRect1.XMost(); nscoord xmost2 = aRect2.XMost(); nscoord ymost1 = aRect1.YMost(); nscoord ymost2 = aRect2.YMost(); // Compute the origin x = PR_MIN(aRect1.x, aRect2.x); y = PR_MIN(aRect1.y, aRect2.y); // Compute the size width = PR_MAX(xmost1, xmost2) - x; height = PR_MAX(ymost1, ymost2) - y; }
static float ComputeDistanceFromRect(const nsPoint& aPoint, const nsRect& aRect) { nscoord dx = std::max(0, std::max(aRect.x - aPoint.x, aPoint.x - aRect.XMost())); nscoord dy = std::max(0, std::max(aRect.y - aPoint.y, aPoint.y - aRect.YMost())); return float(NS_hypot(dx, dy)); }
// Find difference between rects as an nsMargin nsMargin nsRect::operator-(const nsRect& aRect) const { nsMargin margin; margin.left = aRect.x - x; margin.right = XMost() - aRect.XMost(); margin.top = aRect.y - y; margin.bottom = YMost() - aRect.YMost(); return margin; }
void DOMRect::SetLayoutRect(const nsRect& aLayoutRect) { double scale = 65536.0; // Round to the nearest 1/scale units. We choose scale so it can be represented // exactly by machine floating point. double scaleInv = 1/scale; double t2pScaled = scale/nsPresContext::AppUnitsPerCSSPixel(); double x = RoundFloat(aLayoutRect.x*t2pScaled)*scaleInv; double y = RoundFloat(aLayoutRect.y*t2pScaled)*scaleInv; SetRect(x, y, RoundFloat(aLayoutRect.XMost()*t2pScaled)*scaleInv - x, RoundFloat(aLayoutRect.YMost()*t2pScaled)*scaleInv - y); }
void nsViewManager::InvalidateRectDifference(nsView *aView, const nsRect& aRect, const nsRect& aCutOut) { NS_ASSERTION(aView->GetViewManager() == this, "InvalidateRectDifference called on view we don't own"); if (aRect.y < aCutOut.y) { InvalidateHorizontalBandDifference(aView, aRect, aCutOut, aRect.y, aCutOut.y, false); } if (aCutOut.y < aCutOut.YMost()) { InvalidateHorizontalBandDifference(aView, aRect, aCutOut, aCutOut.y, aCutOut.YMost(), true); } if (aCutOut.YMost() < aRect.YMost()) { InvalidateHorizontalBandDifference(aView, aRect, aCutOut, aCutOut.YMost(), aRect.YMost(), false); } }
// Intersection. Returns TRUE if the receiver overlaps aRect and // FALSE otherwise PRBool nsRect::Intersects(const nsRect &aRect) const { return (PRBool) ((x < aRect.XMost()) && (y < aRect.YMost()) && (aRect.x < XMost()) && (aRect.y < YMost())); }
//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; }
// Draw a header or footer string // @param aRenderingContext - rendering context to draw into // @param aHeaderFooter - indicates whether it is a header or footer // @param aJust - indicates where the string is located within the header/footer // @param aStr - the string to be drawn // @param aRect - the rect of the page // @param aHeight - the height of the font // @param aAscent - the ascent of the font // @param aWidth - available width for the string void nsPageFrame::DrawHeaderFooter(nsIRenderingContext& aRenderingContext, nsHeaderFooterEnum aHeaderFooter, PRInt32 aJust, const nsString& aStr, const nsRect& aRect, nscoord aAscent, nscoord aHeight, nscoord aWidth) { nscoord contentWidth = aWidth - (mPD->mEdgePaperMargin.left + mPD->mEdgePaperMargin.right); if ((aHeaderFooter == eHeader && aHeight < mPD->mReflowMargin.top) || (aHeaderFooter == eFooter && aHeight < mPD->mReflowMargin.bottom)) { nsAutoString str; ProcessSpecialCodes(aStr, str); PRInt32 indx; PRInt32 textWidth = 0; const PRUnichar* text = str.get(); PRInt32 len = (PRInt32)str.Length(); if (len == 0) { return; // bail is empty string } // find how much text fits, the "position" is the size of the available area if (nsLayoutUtils::BinarySearchForPosition(&aRenderingContext, text, 0, 0, 0, len, PRInt32(contentWidth), indx, textWidth)) { if (indx < len-1 ) { // we can't fit in all the text if (indx > 3) { // But we can fit in at least 4 chars. Show all but 3 of them, then // an ellipsis. // XXXbz for non-plane0 text, this may be cutting things in the // middle of a codepoint! Also, we have no guarantees that the three // dots will fit in the space the three chars we removed took up with // these font metrics! str.Truncate(indx-3); str.AppendLiteral("..."); } else { // We can only fit 3 or fewer chars. Just show nothing str.Truncate(); } } } else { return; // bail if couldn't find the correct length } if (HasRTLChars(str)) { PresContext()->SetBidiEnabled(); } // cacl the x and y positions of the text nscoord x = GetXPosition(aRenderingContext, aRect, aJust, str); nscoord y; if (aHeaderFooter == eHeader) { y = aRect.y + mPD->mExtraMargin.top + mPD->mEdgePaperMargin.top; } else { y = aRect.YMost() - aHeight - mPD->mExtraMargin.bottom - mPD->mEdgePaperMargin.bottom; } // set up new clip and draw the text aRenderingContext.PushState(); aRenderingContext.SetColor(NS_RGB(0,0,0)); aRenderingContext.SetClipRect(aRect, nsClipCombine_kIntersect); nsLayoutUtils::DrawString(this, &aRenderingContext, str.get(), str.Length(), nsPoint(x, y + aAscent)); aRenderingContext.PopState(); } }