--- a/gfx/public/nsIRenderingContext.h
+++ b/gfx/public/nsIRenderingContext.h
@@ -593,24 +593,21 @@ public:
virtual void SetTextRunRTL(PRBool aIsRTL) = 0;
/*
* Tiles an image over an area
* @param aImage Image to tile
* @param aXImageStart x location where the origin (0,0) of the image starts
* @param aYImageStart y location where the origin (0,0) of the image starts
* @param aTargetRect area to draw to
- * @param aSubimageRect the subimage (in tile space) which we expect to
- * sample from; may be null to indicate that the whole image is
- * OK to sample from
*/
NS_IMETHOD DrawTile(imgIContainer *aImage,
nscoord aXImageStart, nscoord aYImageStart,
- const nsRect * aTargetRect,
- const nsIntRect * aSubimageRect) = 0;
+ const nsRect * aTargetRect) = 0;
+
/**
* Get cluster details for a chunk of text.
*
* This will fill in the aClusterStarts array with information about
* what characters are the start of clusters for display. The
* information is just a bitfield that is set to 1 if the character
* is the start of a cluster. aClusterStarts must already be
--- a/gfx/public/nsRect.h
+++ b/gfx/public/nsRect.h
@@ -172,20 +172,16 @@ struct NS_GFX nsRect {
y = NSToCoordRound(y * aScale);
width = NSToCoordRound(width * aScale);
height = NSToCoordRound(height * aScale);
return *this;}
// 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);
- // Scale by the inverse of aScale, converting coordinates to integers so that the result
- // is the smallest integer-coordinate rectangle containing the unrounded result.
- // More accurate than ScaleRoundOut(1.0/aScale).
- nsRect& ScaleRoundOutInverse(float aScale);
// Scale by aScale, converting coordinates to integers so that the result
// is the larges integer-coordinate rectangle contained in the unrounded result
nsRect& ScaleRoundIn(float aScale);
// Scale by the inverse of aScale, converting coordinates to integers so that
// the result contains the same pixel centers as the unrounded result
nsRect& ScaleRoundPreservingCentersInverse(float aScale);
// Helpers for accessing the vertices
--- a/gfx/src/nsRect.cpp
+++ b/gfx/src/nsRect.cpp
@@ -180,27 +180,16 @@ nsRect& nsRect::ScaleRoundOut(float aSca
nscoord bottom = NSToCoordCeil(float(YMost()) * aScale);
x = NSToCoordFloor(float(x) * aScale);
y = NSToCoordFloor(float(y) * aScale);
width = (right - x);
height = (bottom - y);
return *this;
}
-nsRect& nsRect::ScaleRoundOutInverse(float aScale)
-{
- nscoord right = NSToCoordCeil(float(XMost()) / aScale);
- nscoord bottom = NSToCoordCeil(float(YMost()) / aScale);
- x = NSToCoordFloor(float(x) / aScale);
- y = NSToCoordFloor(float(y) / aScale);
- width = (right - x);
- height = (bottom - y);
- return *this;
-}
-
// scale the rect but round to largest contained rect
nsRect& nsRect::ScaleRoundIn(float aScale)
{
nscoord right = NSToCoordFloor(float(XMost()) * aScale);
nscoord bottom = NSToCoordFloor(float(YMost()) * aScale);
x = NSToCoordCeil(float(x) * aScale);
y = NSToCoordCeil(float(y) * aScale);
width = (right - x);
--- a/gfx/src/thebes/nsThebesImage.cpp
+++ b/gfx/src/thebes/nsThebesImage.cpp
@@ -615,34 +615,32 @@ nsThebesImage::Draw(nsIRenderingContext
return NS_OK;
}
nsresult
nsThebesImage::ThebesDrawTile(gfxContext *thebesContext,
nsIDeviceContext* dx,
const gfxPoint& offset,
const gfxRect& targetRect,
- const nsIntRect& aSubimageRect,
const PRInt32 xPadding,
const PRInt32 yPadding)
{
NS_ASSERTION(xPadding >= 0 && yPadding >= 0, "negative padding");
if (targetRect.size.width <= 0.0 || targetRect.size.height <= 0.0)
return NS_OK;
// don't do anything if we have a transparent pixel source
if (mSinglePixel && mSinglePixelColor.a == 0.0)
return NS_OK;
PRBool doSnap = !(thebesContext->CurrentMatrix().HasNonTranslation());
PRBool hasPadding = ((xPadding != 0) || (yPadding != 0));
- gfxImageSurface::gfxImageFormat format = mFormat;
-
- gfxPoint tmpOffset = offset;
+
+ nsRefPtr<gfxASurface> tmpSurfaceGrip;
if (mSinglePixel && !hasPadding) {
thebesContext->SetColor(mSinglePixelColor);
} else {
nsRefPtr<gfxASurface> surface;
PRInt32 width, height;
if (hasPadding) {
@@ -650,136 +648,49 @@ nsThebesImage::ThebesDrawTile(gfxContext
* and render the image into it first. Then we'll tile that surface. */
width = mWidth + xPadding;
height = mHeight + yPadding;
// Reject over-wide or over-tall images.
if (!AllowedImageSize(width, height))
return NS_ERROR_FAILURE;
- format = gfxASurface::ImageFormatARGB32;
- surface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(
- gfxIntSize(width, height), format);
+ surface = new gfxImageSurface(gfxIntSize(width, height),
+ gfxASurface::ImageFormatARGB32);
if (!surface || surface->CairoStatus()) {
return NS_ERROR_OUT_OF_MEMORY;
}
+ tmpSurfaceGrip = surface;
+
gfxContext tmpContext(surface);
if (mSinglePixel) {
tmpContext.SetColor(mSinglePixelColor);
} else {
tmpContext.SetSource(ThebesSurface());
}
tmpContext.SetOperator(gfxContext::OPERATOR_SOURCE);
tmpContext.Rectangle(gfxRect(0, 0, mWidth, mHeight));
tmpContext.Fill();
} else {
width = mWidth;
height = mHeight;
surface = ThebesSurface();
}
-
+
+ gfxMatrix patMat;
+ gfxPoint p0;
+
+ p0.x = - floor(offset.x + 0.5);
+ p0.y = - floor(offset.y + 0.5);
// Scale factor to account for CSS pixels; note that the offset (and
// therefore p0) is in device pixels, while the width and height are in
// CSS pixels.
gfxFloat scale = gfxFloat(dx->AppUnitsPerDevPixel()) /
gfxFloat(nsIDeviceContext::AppUnitsPerCSSPixel());
-
- if ((aSubimageRect.width < width || aSubimageRect.height < height) &&
- (thebesContext->CurrentMatrix().HasNonTranslation() || scale != 1.0)) {
- // Some of the source image should not be drawn, and we're going
- // to be doing more than just translation, so we might accidentally
- // sample the non-drawn pixels. Avoid that by creating a
- // temporary image representing the portion that will be drawn,
- // with built-in padding since we can't use EXTEND_PAD and
- // EXTEND_REPEAT at the same time for different axes.
- PRInt32 padX = aSubimageRect.width < width ? 1 : 0;
- PRInt32 padY = aSubimageRect.height < height ? 1 : 0;
- PRInt32 tileWidth = PR_MIN(aSubimageRect.width, width);
- PRInt32 tileHeight = PR_MIN(aSubimageRect.height, height);
-
- // This tmpSurface will contain a snapshot of the repeated
- // tile image at (aSubimageRect.x, aSubimageRect.y,
- // tileWidth, tileHeight), with padX padding added to the left
- // and right sides and padY padding added to the top and bottom
- // sides.
- nsRefPtr<gfxASurface> tmpSurface;
- tmpSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(
- gfxIntSize(tileWidth + 2*padX, tileHeight + 2*padY), format);
- if (!tmpSurface || tmpSurface->CairoStatus()) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- gfxContext tmpContext(tmpSurface);
- tmpContext.SetOperator(gfxContext::OPERATOR_SOURCE);
- gfxPattern pat(surface);
- pat.SetExtend(gfxPattern::EXTEND_REPEAT);
-
- // Copy the needed portion of the source image to the temporary
- // surface. We also copy over horizontal and/or vertical padding
- // strips one pixel wide, plus the corner pixels if necessary.
- // So in the most general case the temporary surface ends up
- // looking like
- // P P P ... P P P
- // P X X ... X X P
- // P X X ... X X P
- // ...............
- // P X X ... X X P
- // P X X ... X X P
- // P P P ... P P P
- // Where each P pixel has the color of its nearest source X
- // pixel. We implement this as a loop over all nine possible
- // areas, [padding, body, padding] x [padding, body, padding].
- // Note that we will not need padding on both axes unless
- // we are painting just a single tile, in which case this
- // will hardly ever get called since nsCSSRendering converts
- // the single-tile case to nsLayoutUtils::DrawImage. But this
- // could be called on other paths (XUL trees?) and it's simpler
- // and clearer to do it the general way.
- PRInt32 destY = 0;
- for (PRInt32 y = -1; y <= 1; ++y) {
- PRInt32 stripHeight = y == 0 ? tileHeight : padY;
- if (stripHeight == 0)
- continue;
- PRInt32 srcY = y == 1 ? aSubimageRect.YMost() - padY : aSubimageRect.y;
-
- PRInt32 destX = 0;
- for (PRInt32 x = -1; x <= 1; ++x) {
- PRInt32 stripWidth = x == 0 ? tileWidth : padX;
- if (stripWidth == 0)
- continue;
- PRInt32 srcX = x == 1 ? aSubimageRect.XMost() - padX : aSubimageRect.x;
-
- gfxMatrix patMat;
- patMat.Translate(gfxPoint(srcX - destX, srcY - destY));
- pat.SetMatrix(patMat);
- tmpContext.SetPattern(&pat);
- tmpContext.Rectangle(gfxRect(destX, destY, stripWidth, stripHeight));
- tmpContext.Fill();
- tmpContext.NewPath();
-
- destX += stripWidth;
- }
- destY += stripHeight;
- }
-
- // tmpOffset was the top-left of the old tile image. Make it
- // the top-left of the new tile image. Note that tmpOffset is
- // in destination coordinate space so we have to scale our
- // CSS pixels.
- tmpOffset += gfxPoint(aSubimageRect.x - padX, aSubimageRect.y - padY)/scale;
-
- surface = tmpSurface;
- }
-
- gfxMatrix patMat;
- gfxPoint p0;
-
- p0.x = - floor(tmpOffset.x + 0.5);
- p0.y = - floor(tmpOffset.y + 0.5);
patMat.Scale(scale, scale);
patMat.Translate(p0);
gfxPattern pat(surface);
pat.SetExtend(gfxPattern::EXTEND_REPEAT);
pat.SetMatrix(patMat);
#ifndef XP_MACOSX
@@ -789,17 +700,17 @@ nsThebesImage::ThebesDrawTile(gfxContext
pat.SetFilter(0);
}
#endif
thebesContext->SetPattern(&pat);
}
gfxContext::GraphicsOperator op = thebesContext->CurrentOperator();
- if (op == gfxContext::OPERATOR_OVER && format == gfxASurface::ImageFormatRGB24)
+ if (op == gfxContext::OPERATOR_OVER && mFormat == gfxASurface::ImageFormatRGB24)
thebesContext->SetOperator(gfxContext::OPERATOR_SOURCE);
thebesContext->NewPath();
thebesContext->Rectangle(targetRect, doSnap);
thebesContext->Fill();
thebesContext->SetOperator(op);
thebesContext->SetColor(gfxRGBA(0,0,0,0));
--- a/gfx/src/thebes/nsThebesImage.h
+++ b/gfx/src/thebes/nsThebesImage.h
@@ -79,17 +79,16 @@ public:
const gfxRect &aSourceRect,
const gfxRect &aSubimageRect,
const gfxRect &aDestRect);
nsresult ThebesDrawTile(gfxContext *thebesContext,
nsIDeviceContext* dx,
const gfxPoint& aOffset,
const gfxRect& aTileRect,
- const nsIntRect& aSubimageRect,
const PRInt32 aXPadding,
const PRInt32 aYPadding);
virtual PRInt8 GetAlphaDepth();
virtual void* GetBitInfo();
NS_IMETHOD LockImagePixels(PRBool aMaskPixels);
NS_IMETHOD UnlockImagePixels(PRBool aMaskPixels);
--- a/gfx/src/thebes/nsThebesRenderingContext.cpp
+++ b/gfx/src/thebes/nsThebesRenderingContext.cpp
@@ -773,18 +773,17 @@ nsThebesRenderingContext::PopFilter()
return NS_OK;
}
NS_IMETHODIMP
nsThebesRenderingContext::DrawTile(imgIContainer *aImage,
nscoord twXOffset, nscoord twYOffset,
- const nsRect *twTargetRect,
- const nsIntRect *subimageRect)
+ const nsRect *twTargetRect)
{
PR_LOG(gThebesGFXLog, PR_LOG_DEBUG, ("## %p nsTRC::DrawTile %p %f %f [%f,%f,%f,%f]\n",
this, aImage, FROM_TWIPS(twXOffset), FROM_TWIPS(twYOffset),
FROM_TWIPS(twTargetRect->x), FROM_TWIPS(twTargetRect->y),
FROM_TWIPS(twTargetRect->width), FROM_TWIPS(twTargetRect->height)));
nscoord containerWidth, containerHeight;
aImage->GetWidth(&containerWidth);
@@ -809,44 +808,28 @@ nsThebesRenderingContext::DrawTile(imgIC
* so we need to make sure that there is the right amount of padding
* in between each tile of the nsIImage. This problem goes away
* when we change the way the GIF decoder works to have it store
* full frames that are ready to be composited.
*/
PRInt32 xPadding = 0;
PRInt32 yPadding = 0;
- nsIntRect tmpSubimageRect;
- if (subimageRect) {
- tmpSubimageRect = *subimageRect;
- } else {
- tmpSubimageRect = nsIntRect(0, 0, containerWidth, containerHeight);
- }
-
if (imgFrameRect.width != containerWidth ||
imgFrameRect.height != containerHeight)
{
xPadding = containerWidth - imgFrameRect.width;
yPadding = containerHeight - imgFrameRect.height;
- // XXXroc shouldn't we be adding to 'phase' here? it's tbe origin
- // at which the image origin should be drawn, and ThebesDrawTile
- // just draws the origin of its "frame" there, so we should be
- // adding imgFrameRect.x/y. so that the imgFrame draws in the
- // right place.
phase.x -= imgFrameRect.x;
phase.y -= imgFrameRect.y;
-
- tmpSubimageRect.x -= imgFrameRect.x;
- tmpSubimageRect.y -= imgFrameRect.y;
}
return thebesImage->ThebesDrawTile (mThebes, mDeviceContext, phase,
GFX_RECT_FROM_TWIPS_RECT(*twTargetRect),
- tmpSubimageRect,
xPadding, yPadding);
}
//
// text junk
//
NS_IMETHODIMP
nsThebesRenderingContext::SetRightToLeftText(PRBool aIsRTL)
--- a/gfx/src/thebes/nsThebesRenderingContext.h
+++ b/gfx/src/thebes/nsThebesRenderingContext.h
@@ -180,17 +180,17 @@ public:
virtual void* GetNativeGraphicData(GraphicDataType aType);
NS_IMETHOD PushTranslation(PushedTranslation* aState);
NS_IMETHOD PopTranslation(PushedTranslation* aState);
NS_IMETHOD SetTranslation(nscoord aX, nscoord aY);
NS_IMETHOD DrawTile(imgIContainer *aImage, nscoord aXOffset, nscoord aYOffset,
- const nsRect * aTargetRect, const nsIntRect * aSubimageRect);
+ const nsRect * aTargetRect);
NS_IMETHOD SetRightToLeftText(PRBool aIsRTL);
NS_IMETHOD GetRightToLeftText(PRBool* aIsRTL);
virtual void SetTextRunRTL(PRBool aIsRTL);
NS_IMETHOD GetClusterInfo(const PRUnichar *aText,
PRUint32 aLength,
PRUint8 *aClusterStarts);
virtual PRInt32 GetPosition(const PRUnichar *aText,
--- a/gfx/thebes/public/gfxPoint.h
+++ b/gfx/thebes/public/gfxPoint.h
@@ -115,21 +115,16 @@ struct THEBES_API gfxPoint {
void MoveTo(gfxFloat aX, gfxFloat aY) { x = aX; y = aY; }
int operator==(const gfxPoint& p) const {
return ((x == p.x) && (y == p.y));
}
int operator!=(const gfxPoint& p) const {
return ((x != p.x) || (y != p.y));
}
- const gfxPoint& operator+=(const gfxPoint& p) {
- x += p.x;
- y += p.y;
- return *this;
- }
gfxPoint operator+(const gfxPoint& p) const {
return gfxPoint(x + p.x, y + p.y);
}
gfxPoint operator+(const gfxSize& s) const {
return gfxPoint(x + s.width, y + s.height);
}
gfxPoint operator-(const gfxPoint& p) const {
return gfxPoint(x - p.x, y - p.y);
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -3899,33 +3899,29 @@ nsCSSRendering::PaintBackgroundWithSC(ns
NS_ASSERTION(drawRect.x >= absTileRect.x && drawRect.y >= absTileRect.y,
"Bogus intersection");
NS_ASSERTION(drawRect.x < absTileRect.x + tileWidth,
"Bogus x coord for draw rect");
NS_ASSERTION(drawRect.y < absTileRect.y + tileHeight,
"Bogus y coord for draw rect");
// Figure out whether we can get away with not tiling at all.
nsRect sourceRect = drawRect - absTileRect.TopLeft();
- // Compute the subimage rectangle that we expect to be sampled.
- // This is the tile rectangle, clipped to the bgClipArea, and then
- // passed in relative to the image top-left.
- nsRect destRect; // The rectangle we would draw ignoring dirty-rect
- destRect.IntersectRect(absTileRect, bgClipArea);
- nsRect subimageRect = destRect - aBorderArea.TopLeft() - tileRect.TopLeft();
if (sourceRect.XMost() <= tileWidth && sourceRect.YMost() <= tileHeight) {
// The entire drawRect is contained inside a single tile; just
// draw the corresponding part of the image once.
+ // Pass in the subimage rectangle that we expect to be sampled.
+ // This is the tile rectangle, clipped to the bgClipArea, and then
+ // passed in relative to the image top-left.
+ nsRect destRect; // The rectangle we would draw ignoring dirty-rect
+ destRect.IntersectRect(absTileRect, bgClipArea);
+ nsRect subimageRect = destRect - aBorderArea.TopLeft() - tileRect.TopLeft();
nsLayoutUtils::DrawImage(&aRenderingContext, image,
destRect, drawRect, &subimageRect);
} else {
- // Note that the subimage is in tile space so it may cover
- // multiple tiles of the image.
- subimageRect.ScaleRoundOutInverse(nsIDeviceContext::AppUnitsPerCSSPixel());
- aRenderingContext.DrawTile(image, absTileRect.x, absTileRect.y,
- &drawRect, &subimageRect);
+ aRenderingContext.DrawTile(image, absTileRect.x, absTileRect.y, &drawRect);
}
}
ctx->Restore();
}
void
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -768,17 +768,16 @@ fails == 413027-3.html 413027-3-ref.html
== 420069-1.html 420069-1-ref.html
== 420069-2.html 420069-2-ref.html
== 420351-1.html 420351-1-ref.html
== 421069.html 421069-ref.html
== 421069.html 421069-ref2.html
== 421069-ref.html 421069-ref2.html
== 421234-1.html 421234-1-ref.html
== 421419-1.html 421419-1-ref.html
-== 421885-1.xml 421885-1-ref.xml
== 421955-1.html 421955-1-ref.html
== 422394-1.html 422394-1-ref.html
== 423130-1.html 423130-1-ref.html
== 423385-1.html 423385-1-ref.html
== 423599-1.html 423599-1-ref.html
== 423676-1.html 423676-1-ref.html
== 424074-1.xul 424074-1-ref.xul
!= 424074-1.xul 424074-1-ref2.xul
--- a/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
+++ b/layout/xul/base/src/tree/src/nsTreeBodyFrame.cpp
@@ -3652,29 +3652,29 @@ nsTreeBodyFrame::PaintProgressMeter(PRIn
else if (intValue > 100)
intValue = 100;
meterRect.width = NSToCoordRound((float)intValue / 100 * meterRect.width);
PRBool useImageRegion = PR_TRUE;
nsCOMPtr<imgIContainer> image;
GetImage(aRowIndex, aColumn, PR_TRUE, meterContext, useImageRegion, getter_AddRefs(image));
if (image)
- aRenderingContext.DrawTile(image, 0, 0, &meterRect, nsnull);
+ aRenderingContext.DrawTile(image, 0, 0, &meterRect);
else
aRenderingContext.FillRect(meterRect);
}
else if (state == nsITreeView::PROGRESS_UNDETERMINED) {
// Adjust the rect for its border and padding.
AdjustForBorderPadding(meterContext, meterRect);
PRBool useImageRegion = PR_TRUE;
nsCOMPtr<imgIContainer> image;
GetImage(aRowIndex, aColumn, PR_TRUE, meterContext, useImageRegion, getter_AddRefs(image));
if (image)
- aRenderingContext.DrawTile(image, 0, 0, &meterRect, nsnull);
+ aRenderingContext.DrawTile(image, 0, 0, &meterRect);
}
}
void
nsTreeBodyFrame::PaintDropFeedback(const nsRect& aDropFeedbackRect,
nsPresContext* aPresContext,
nsIRenderingContext& aRenderingContext,