mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 563878. Part 7. Change frame, point, rect, region APIs. r=mats sr=roc
This commit is contained in:
parent
5bf17b6fc0
commit
460def762d
@ -438,6 +438,11 @@ inline PRInt32 NSAppUnitsToIntPixels(nscoord aAppUnits, float aAppUnitsPerPixel)
|
||||
return NSToIntRound(float(aAppUnits) / aAppUnitsPerPixel);
|
||||
}
|
||||
|
||||
inline float NSCoordScale(nscoord aCoord, PRInt32 aFromAPP, PRInt32 aToAPP)
|
||||
{
|
||||
return (NSCoordToFloat(aCoord) * aToAPP) / aFromAPP;
|
||||
}
|
||||
|
||||
/// handy constants
|
||||
#define TWIPS_PER_POINT_INT 20
|
||||
#define TWIPS_PER_POINT_FLOAT 20.0f
|
||||
|
@ -83,6 +83,9 @@ struct nsPoint {
|
||||
}
|
||||
|
||||
inline nsIntPoint ToNearestPixels(nscoord aAppUnitsPerPixel) const;
|
||||
|
||||
// Converts this point from aFromAPP, an appunits per pixel ratio, to aToAPP.
|
||||
inline nsPoint ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
};
|
||||
|
||||
struct nsIntPoint {
|
||||
@ -128,4 +131,15 @@ nsPoint::ToNearestPixels(nscoord aAppUnitsPerPixel) const {
|
||||
NSToIntRound(NSAppUnitsToFloatPixels(y, float(aAppUnitsPerPixel))));
|
||||
}
|
||||
|
||||
inline nsPoint
|
||||
nsPoint::ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const {
|
||||
if (aFromAPP != aToAPP) {
|
||||
nsPoint point;
|
||||
point.x = NSToCoordRound(NSCoordScale(x, aFromAPP, aToAPP));
|
||||
point.y = NSToCoordRound(NSCoordScale(y, aFromAPP, aToAPP));
|
||||
return point;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif /* NSPOINT_H */
|
||||
|
@ -178,10 +178,17 @@ struct NS_GFX nsRect {
|
||||
nsRect operator+(const nsMargin& aMargin) const { return nsRect(*this) += aMargin; }
|
||||
nsRect operator-(const nsMargin& aMargin) const { return nsRect(*this) -= aMargin; }
|
||||
|
||||
// Scale by aScale, converting coordinates to integers so that the result
|
||||
// is the smallest integer-coordinate rectangle containing the unrounded result
|
||||
// Scale by aScale, converting coordinates to integers so that the result is
|
||||
// the smallest integer-coordinate rectangle containing the unrounded result.
|
||||
nsRect& ScaleRoundOut(float aScale);
|
||||
|
||||
// Converts this rect from aFromAPP, an appunits per pixel ratio, to aToAPP.
|
||||
// In the RoundOut version we make the rect the smallest rect containing the
|
||||
// unrounded result. In the RoundIn version we make the rect the largest rect
|
||||
// contained in the unrounded result.
|
||||
inline nsRect ConvertAppUnitsRoundOut(PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
inline nsRect ConvertAppUnitsRoundIn(PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
|
||||
// Helpers for accessing the vertices
|
||||
nsPoint TopLeft() const { return nsPoint(x, y); }
|
||||
nsPoint TopRight() const { return nsPoint(XMost(), y); }
|
||||
@ -333,6 +340,43 @@ struct NS_GFX nsIntRect {
|
||||
/*
|
||||
* App Unit/Pixel conversions
|
||||
*/
|
||||
|
||||
inline nsRect
|
||||
nsRect::ConvertAppUnitsRoundOut(PRInt32 aFromAPP, PRInt32 aToAPP) const
|
||||
{
|
||||
if (aFromAPP == aToAPP) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsRect rect;
|
||||
nscoord right = NSToCoordCeil(NSCoordScale(XMost(), aFromAPP, aToAPP));
|
||||
nscoord bottom = NSToCoordCeil(NSCoordScale(YMost(), aFromAPP, aToAPP));
|
||||
rect.x = NSToCoordFloor(NSCoordScale(x, aFromAPP, aToAPP));
|
||||
rect.y = NSToCoordFloor(NSCoordScale(y, aFromAPP, aToAPP));
|
||||
rect.width = (right - rect.x);
|
||||
rect.height = (bottom - rect.y);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
inline nsRect
|
||||
nsRect::ConvertAppUnitsRoundIn(PRInt32 aFromAPP, PRInt32 aToAPP) const
|
||||
{
|
||||
if (aFromAPP == aToAPP) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
nsRect rect;
|
||||
nscoord right = NSToCoordFloor(NSCoordScale(XMost(), aFromAPP, aToAPP));
|
||||
nscoord bottom = NSToCoordFloor(NSCoordScale(YMost(), aFromAPP, aToAPP));
|
||||
rect.x = NSToCoordCeil(NSCoordScale(x, aFromAPP, aToAPP));
|
||||
rect.y = NSToCoordCeil(NSCoordScale(y, aFromAPP, aToAPP));
|
||||
rect.width = (right - rect.x);
|
||||
rect.height = (bottom - rect.y);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
// scale the rect but round to preserve centers
|
||||
inline nsIntRect
|
||||
nsRect::ToNearestPixels(nscoord aAppUnitsPerPixel) const
|
||||
|
@ -1289,6 +1289,44 @@ void nsRegion::MoveBy (nsPoint aPt)
|
||||
}
|
||||
}
|
||||
|
||||
nsRegion nsRegion::ConvertAppUnitsRoundOut (PRInt32 aFromAPP, PRInt32 aToAPP) const
|
||||
{
|
||||
if (aFromAPP == aToAPP) {
|
||||
return *this;
|
||||
}
|
||||
// Do it in a simplistic and slow way to avoid any weird behaviour with
|
||||
// rounding causing rects to overlap. Should be fast enough for what we need.
|
||||
nsRegion region;
|
||||
nsRegionRectIterator iter(*this);
|
||||
for (;;) {
|
||||
const nsRect* r = iter.Next();
|
||||
if (!r)
|
||||
break;
|
||||
nsRect rect = r->ConvertAppUnitsRoundOut(aFromAPP, aToAPP);
|
||||
region.Or(region, rect);
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
nsRegion nsRegion::ConvertAppUnitsRoundIn (PRInt32 aFromAPP, PRInt32 aToAPP) const
|
||||
{
|
||||
if (aFromAPP == aToAPP) {
|
||||
return *this;
|
||||
}
|
||||
// Do it in a simplistic and slow way to avoid any weird behaviour with
|
||||
// rounding causing rects to overlap. Should be fast enough for what we need.
|
||||
nsRegion region;
|
||||
nsRegionRectIterator iter(*this);
|
||||
for (;;) {
|
||||
const nsRect* r = iter.Next();
|
||||
if (!r)
|
||||
break;
|
||||
nsRect rect = r->ConvertAppUnitsRoundIn(aFromAPP, aToAPP);
|
||||
region.Or(region, rect);
|
||||
}
|
||||
return region;
|
||||
}
|
||||
|
||||
nsIntRegion nsRegion::ToOutsidePixels (nscoord aAppUnitsPerPixel) const
|
||||
{
|
||||
nsIntRegion result;
|
||||
|
@ -178,6 +178,11 @@ public:
|
||||
PRBool IsEqual (const nsRegion& aRegion) const;
|
||||
PRUint32 GetNumRects () const { return mRectCount; }
|
||||
const nsRect& GetBounds () const { return mBoundRect; }
|
||||
// Converts this region from aFromAPP, an appunits per pixel ratio, to
|
||||
// aToAPP. This applies nsRect::ConvertAppUnitsRoundOut/In to each rect of
|
||||
// the region.
|
||||
nsRegion ConvertAppUnitsRoundOut (PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
nsRegion ConvertAppUnitsRoundIn (PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
nsIntRegion ToOutsidePixels (nscoord aAppUnitsPerPixel) const;
|
||||
nsRect GetLargestRectangle () const;
|
||||
|
||||
|
@ -69,6 +69,9 @@ struct nsSize {
|
||||
nsSize& operator+=(const nsSize& aSize) {width += aSize.width;
|
||||
height += aSize.height;
|
||||
return *this;}
|
||||
|
||||
// Converts this size from aFromAPP, an appunits per pixel ratio, to aToAPP.
|
||||
inline nsSize ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const;
|
||||
};
|
||||
|
||||
struct nsIntSize {
|
||||
@ -90,4 +93,15 @@ struct nsIntSize {
|
||||
void SizeTo(PRInt32 aWidth, PRInt32 aHeight) {width = aWidth; height = aHeight;}
|
||||
};
|
||||
|
||||
inline nsSize
|
||||
nsSize::ConvertAppUnits(PRInt32 aFromAPP, PRInt32 aToAPP) const {
|
||||
if (aFromAPP != aToAPP) {
|
||||
nsSize size;
|
||||
size.width = NSToCoordRound(NSCoordScale(width, aFromAPP, aToAPP));
|
||||
size.height = NSToCoordRound(NSCoordScale(height, aFromAPP, aToAPP));
|
||||
return size;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
#endif /* NSSIZE_H */
|
||||
|
@ -205,11 +205,12 @@ public:
|
||||
/**
|
||||
* @return a point pt such that adding pt to a coordinate relative to aFrame
|
||||
* makes it relative to ReferenceFrame(), i.e., returns
|
||||
* aFrame->GetOffsetTo(ReferenceFrame()). It may be optimized to be faster
|
||||
* than aFrame->GetOffsetTo(ReferenceFrame()) (but currently isn't).
|
||||
* aFrame->GetOffsetToCrossDoc(ReferenceFrame()). The returned point is in
|
||||
* the appunits of aFrame. It may be optimized to be faster than
|
||||
* aFrame->GetOffsetToCrossDoc(ReferenceFrame()) (but currently isn't).
|
||||
*/
|
||||
nsPoint ToReferenceFrame(const nsIFrame* aFrame) {
|
||||
return aFrame->GetOffsetTo(ReferenceFrame());
|
||||
return aFrame->GetOffsetToCrossDoc(ReferenceFrame());
|
||||
}
|
||||
/**
|
||||
* When building the display list, the scrollframe aFrame will be "ignored"
|
||||
|
@ -3539,23 +3539,87 @@ nsPoint nsIFrame::GetOffsetTo(const nsIFrame* aOther) const
|
||||
{
|
||||
NS_PRECONDITION(aOther,
|
||||
"Must have frame for destination coordinate system!");
|
||||
|
||||
//NS_ASSERTION(PresContext() == aOther->PresContext(),
|
||||
// "GetOffsetTo called on frames in different documents");
|
||||
|
||||
//XXX sometime in the near future once we are confident that all GetOffsetTo
|
||||
// callers pass frames that are really in the same doc we can get rid of this
|
||||
// check.
|
||||
if (PresContext() != aOther->PresContext()) {
|
||||
return GetOffsetToCrossDoc(aOther);
|
||||
}
|
||||
|
||||
nsPoint offset(0, 0);
|
||||
const nsIFrame* f;
|
||||
for (f = this; f != aOther && f;
|
||||
f = nsLayoutUtils::GetCrossDocParentFrame(f, &offset)) {
|
||||
for (f = this; f != aOther && f; f = f->GetParent()) {
|
||||
offset += f->GetPosition();
|
||||
}
|
||||
|
||||
if (f != aOther) {
|
||||
// Looks like aOther wasn't an ancestor of |this|. So now we have
|
||||
// the root-document-relative position of |this| in |offset|. Convert back
|
||||
// the root-frame-relative position of |this| in |offset|. Convert back
|
||||
// to the coordinates of aOther
|
||||
nsPoint negativeOffset(0,0);
|
||||
while (aOther) {
|
||||
offset -= aOther->GetPosition();
|
||||
aOther = nsLayoutUtils::GetCrossDocParentFrame(aOther, &negativeOffset);
|
||||
aOther = aOther->GetParent();
|
||||
}
|
||||
offset -= negativeOffset;
|
||||
}
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
nsPoint nsIFrame::GetOffsetToCrossDoc(const nsIFrame* aOther) const
|
||||
{
|
||||
return GetOffsetToCrossDoc(aOther, PresContext()->AppUnitsPerDevPixel());
|
||||
}
|
||||
|
||||
nsPoint
|
||||
nsIFrame::GetOffsetToCrossDoc(const nsIFrame* aOther, const PRInt32 aAPD) const
|
||||
{
|
||||
NS_PRECONDITION(aOther,
|
||||
"Must have frame for destination coordinate system!");
|
||||
NS_ASSERTION(PresContext()->GetRootPresContext() ==
|
||||
aOther->PresContext()->GetRootPresContext(),
|
||||
"trying to get the offset between frames in different document "
|
||||
"hierarchies?");
|
||||
|
||||
const nsIFrame* root = nsnull;
|
||||
// offset will hold the final offset
|
||||
// docOffset holds the currently accumulated offset at the current APD, it
|
||||
// will be converted and added to offset when the current APD changes.
|
||||
nsPoint offset(0, 0), docOffset(0, 0);
|
||||
const nsIFrame* f = this;
|
||||
PRInt32 currAPD = PresContext()->AppUnitsPerDevPixel();
|
||||
while (f && f != aOther) {
|
||||
docOffset += f->GetPosition();
|
||||
nsIFrame* parent = f->GetParent();
|
||||
if (parent) {
|
||||
f = parent;
|
||||
} else {
|
||||
nsPoint newOffset(0, 0);
|
||||
root = f;
|
||||
f = nsLayoutUtils::GetCrossDocParentFrame(f, &newOffset);
|
||||
PRInt32 newAPD = f ? f->PresContext()->AppUnitsPerDevPixel() : 0;
|
||||
if (!f || newAPD != currAPD) {
|
||||
// Convert docOffset to the right APD and add it to offset.
|
||||
offset += docOffset.ConvertAppUnits(currAPD, aAPD);
|
||||
docOffset.x = docOffset.y = 0;
|
||||
}
|
||||
currAPD = newAPD;
|
||||
docOffset += newOffset;
|
||||
}
|
||||
}
|
||||
if (f == aOther) {
|
||||
offset += docOffset.ConvertAppUnits(currAPD, aAPD);
|
||||
} else {
|
||||
// Looks like aOther wasn't an ancestor of |this|. So now we have
|
||||
// the root-document-relative position of |this| in |offset|. Subtract the
|
||||
// root-document-relative position of |aOther| from |offset|.
|
||||
// This call won't try to recurse again because root is an ancestor of
|
||||
// aOther.
|
||||
nsPoint negOffset = aOther->GetOffsetToCrossDoc(root, aAPD);
|
||||
offset -= negOffset;
|
||||
}
|
||||
|
||||
return offset;
|
||||
|
@ -1656,7 +1656,8 @@ public:
|
||||
*
|
||||
* This function is fastest when aOther is an ancestor of |this|.
|
||||
*
|
||||
* This function works across document boundaries.
|
||||
* This function _DOES NOT_ work across document boundaries.
|
||||
* Use this function only when |this| and aOther are in the same document.
|
||||
*
|
||||
* NOTE: this actually returns the offset from aOther to |this|, but
|
||||
* that offset is added to transform _coordinates_ from |this| to
|
||||
@ -1665,6 +1666,28 @@ public:
|
||||
nsPoint GetOffsetTo(const nsIFrame* aOther) const;
|
||||
virtual nsPoint GetOffsetToExternal(const nsIFrame* aOther) const;
|
||||
|
||||
/**
|
||||
* Get the offset between the coordinate systems of |this| and aOther
|
||||
* expressed in appunits per dev pixel of |this|' document. Adding the return
|
||||
* value to a point that is relative to the origin of |this| will make the
|
||||
* point relative to the origin of aOther but in the appunits per dev pixel
|
||||
* ratio of |this|.
|
||||
*
|
||||
* aOther must be non-null.
|
||||
*
|
||||
* This function is fastest when aOther is an ancestor of |this|.
|
||||
*
|
||||
* This function works across document boundaries.
|
||||
*
|
||||
* Because this function may cross document boundaries that have different
|
||||
* app units per dev pixel ratios it needs to be used very carefully.
|
||||
*
|
||||
* NOTE: this actually returns the offset from aOther to |this|, but
|
||||
* that offset is added to transform _coordinates_ from |this| to
|
||||
* aOther.
|
||||
*/
|
||||
nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther) const;
|
||||
|
||||
/**
|
||||
* Get the screen rect of the frame in pixels.
|
||||
* @return the pixel rect of the frame in screen coordinates.
|
||||
@ -2572,6 +2595,7 @@ protected:
|
||||
private:
|
||||
nsRect* GetOverflowAreaProperty(PRBool aCreateIfNecessary = PR_FALSE);
|
||||
void SetOverflowRect(const nsRect& aRect);
|
||||
nsPoint GetOffsetToCrossDoc(const nsIFrame* aOther, const PRInt32 aAPD) const;
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user