This commit is contained in:
roc+@cs.cmu.edu 2008-03-04 01:36:07 -08:00
Родитель ffb68f7a15
Коммит d5b5fd63c2
10 изменённых файлов: 28 добавлений и 99 удалений

Просмотреть файл

@ -71,10 +71,10 @@ typedef enum {
#define nsImageUpdateFlags_kBitsChanged 0x2
// IID for the nsIImage interface
// 96d9d7ce-e575-4265-8507-35555112a430
// fd31e1f2-bd46-47f1-b8b6-b94ce954f9ce
#define NS_IIMAGE_IID \
{ 0x96d9d7ce, 0xe575, 0x4265, \
{ 0x85, 0x07, 0x35, 0x55, 0x51, 0x12, 0xa4, 0x30 } }
{ 0xfd31e1f2, 0xbd46, 0x47f1, \
{ 0xb8, 0xb6, 0xb9, 0x4c, 0xe9, 0x54, 0xf9, 0xce } }
// Interface to Images
class nsIImage : public nsISupports
@ -189,14 +189,10 @@ public:
/**
* BitBlit the nsIImage to a device, the source and dest can be scaled
* @param aSourceRect source rectangle, in image pixels
* @param aSubimageRect the subimage that we're extracting the contents from.
* It must contain aSourceRect. Pixels outside this rectangle must not
* be sampled.
* @param aDestRect destination rectangle, in device pixels
*/
NS_IMETHOD Draw(nsIRenderingContext &aContext,
const gfxRect &aSourceRect,
const gfxRect &aSubimageRect,
const gfxRect &aDestRect) = 0;
/**

Просмотреть файл

@ -412,7 +412,6 @@ nsThebesImage::UnlockImagePixels(PRBool aMaskPixels)
NS_IMETHODIMP
nsThebesImage::Draw(nsIRenderingContext &aContext,
const gfxRect &aSourceRect,
const gfxRect &aSubimageRect,
const gfxRect &aDestRect)
{
if (NS_UNLIKELY(aDestRect.IsEmpty())) {
@ -453,24 +452,21 @@ nsThebesImage::Draw(nsIRenderingContext &aContext,
gfxFloat yscale = aDestRect.size.height / aSourceRect.size.height;
gfxRect srcRect(aSourceRect);
gfxRect subimageRect(aSubimageRect);
gfxRect destRect(aDestRect);
if (!GetIsImageComplete()) {
gfxRect decoded = gfxRect(mDecoded.x, mDecoded.y,
mDecoded.width, mDecoded.height);
srcRect = srcRect.Intersect(decoded);
subimageRect = subimageRect.Intersect(decoded);
srcRect = srcRect.Intersect(gfxRect(mDecoded.x, mDecoded.y,
mDecoded.width, mDecoded.height));
// This happens when mDecoded.width or height is zero. bug 368427.
if (NS_UNLIKELY(srcRect.size.width == 0 || srcRect.size.height == 0))
return NS_OK;
// This happens when mDecoded.width or height is zero. bug 368427.
if (NS_UNLIKELY(srcRect.size.width == 0 || srcRect.size.height == 0))
return NS_OK;
destRect.pos.x += (srcRect.pos.x - aSourceRect.pos.x)*xscale;
destRect.pos.y += (srcRect.pos.y - aSourceRect.pos.y)*yscale;
destRect.pos.x += (srcRect.pos.x - aSourceRect.pos.x)*xscale;
destRect.pos.y += (srcRect.pos.y - aSourceRect.pos.y)*yscale;
destRect.size.width = srcRect.size.width * xscale;
destRect.size.height = srcRect.size.height * yscale;
destRect.size.width = srcRect.size.width * xscale;
destRect.size.height = srcRect.size.height * yscale;
}
// if either rectangle is empty now (possibly after the image complete check)
@ -481,39 +477,7 @@ nsThebesImage::Draw(nsIRenderingContext &aContext,
if (!AllowedImageSize(destRect.size.width + 1, destRect.size.height + 1))
return NS_ERROR_FAILURE;
// Expand the subimageRect to place its edges on integer coordinates.
// Basically, if we're allowed to sample part of a pixel we can
// sample the whole pixel.
subimageRect.RoundOut();
nsRefPtr<gfxPattern> pat;
PRBool ctxHasNonTranslation = ctx->CurrentMatrix().HasNonTranslation();
if ((xscale == 1.0 && yscale == 1.0 && !ctxHasNonTranslation) ||
subimageRect == gfxRect(0, 0, mWidth, mHeight))
{
// No need to worry about sampling outside the subimage rectangle,
// so no need for a temporary
// XXX should we also check for situations where the source rect
// is well inside the subimage so we can't sample outside?
pat = new gfxPattern(ThebesSurface());
} else {
// Because of the RoundOut above, the subimageRect has
// integer width and height.
gfxIntSize size(PRInt32(subimageRect.Width()),
PRInt32(subimageRect.Height()));
nsRefPtr<gfxASurface> temp =
gfxPlatform::GetPlatform()->CreateOffscreenSurface(size, mFormat);
if (!temp || temp->CairoStatus() != 0)
return NS_ERROR_FAILURE;
gfxContext tempctx(temp);
tempctx.SetSource(ThebesSurface(), -subimageRect.pos);
tempctx.SetOperator(gfxContext::OPERATOR_SOURCE);
tempctx.Paint();
pat = new gfxPattern(temp);
srcRect.MoveBy(-subimageRect.pos);
}
/* See bug 364968 to understand the necessity of this goop; we basically
* have to pre-downscale any image that would fall outside of a scaled 16-bit
@ -536,12 +500,13 @@ nsThebesImage::Draw(nsIRenderingContext &aContext,
gfxContext tempctx(temp);
gfxPattern srcpat(ThebesSurface());
gfxMatrix mat;
mat.Translate(srcRect.pos);
mat.Scale(1.0 / xscale, 1.0 / yscale);
pat->SetMatrix(mat);
srcpat.SetMatrix(mat);
tempctx.SetPattern(pat);
tempctx.SetPattern(&srcpat);
tempctx.SetOperator(gfxContext::OPERATOR_SOURCE);
tempctx.NewPath();
tempctx.Rectangle(gfxRect(0.0, 0.0, dim.width, dim.height));
@ -558,6 +523,10 @@ nsThebesImage::Draw(nsIRenderingContext &aContext,
yscale = 1.0;
}
if (!pat) {
pat = new gfxPattern(ThebesSurface());
}
gfxMatrix mat;
mat.Translate(srcRect.pos);
mat.Scale(1.0/xscale, 1.0/yscale);
@ -578,14 +547,14 @@ nsThebesImage::Draw(nsIRenderingContext &aContext,
// available
//
// This effectively disables smooth upscaling for images.
if (xscale > 1.0 || yscale > 1.0 || ctxHasNonTranslation)
if (xscale > 1.0 || yscale > 1.0)
pat->SetFilter(0);
#endif
#if defined(XP_WIN) || defined(XP_OS2)
// turn on EXTEND_PAD only for win32, and only when scaling;
// it's not implemented correctly on linux in the X server.
if (xscale != 1.0 || yscale != 1.0 || ctxHasNonTranslation)
if (xscale != 1.0 || yscale != 1.0)
pat->SetExtend(gfxPattern::EXTEND_PAD);
#endif

Просмотреть файл

@ -76,7 +76,6 @@ public:
NS_IMETHOD Draw(nsIRenderingContext &aContext,
const gfxRect &aSourceRect,
const gfxRect &aSubimageRect,
const gfxRect &aDestRect);
nsresult ThebesDrawTile(gfxContext *thebesContext,

Просмотреть файл

@ -115,9 +115,7 @@ struct THEBES_API gfxRect {
Outset(sides[0], sides[1], sides[2], sides[3]);
}
// Round the rectangle edges to integer coordinates, such that the rounded
// rectangle has the same set of pixel centers as the original rectangle.
// Edges at offset 0.5 round up.
// Round the rectangle to integer coordinates.
// Suitable for most places where integral device coordinates
// are needed, but note that any translation should be applied first to
// avoid pixel rounding errors.
@ -127,10 +125,6 @@ struct THEBES_API gfxRect {
// If you need similar method which is using NS_round(), you should create
// new |RoundAwayFromZero()| method.
void Round();
// Snap the rectangle edges to integer coordinates, such that the
// resulting rectangle contains the original rectangle.
void RoundOut();
// grabbing specific points
gfxPoint TopLeft() const { return gfxPoint(pos); }

Просмотреть файл

@ -89,21 +89,6 @@ gfxRect::Round()
size.height = y1 - y0;
}
void
gfxRect::RoundOut()
{
gfxFloat x0 = NS_floor(X());
gfxFloat y0 = NS_floor(Y());
gfxFloat x1 = NS_ceil(XMost());
gfxFloat y1 = NS_ceil(YMost());
pos.x = x0;
pos.y = y0;
size.width = x1 - x0;
size.height = y1 - y0;
}
/* Clamp r to CAIRO_COORD_MIN .. CAIRO_COORD_MAX
* these are to be device coordinates.
*/

Просмотреть файл

@ -3916,14 +3916,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
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);
nsLayoutUtils::DrawImage(&aRenderingContext, image, absTileRect, drawRect);
} else {
aRenderingContext.DrawTile(image, absTileRect.x, absTileRect.y, &drawRect);
}

Просмотреть файл

@ -2314,7 +2314,6 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
pxSrc.size.width = gfxFloat(w);
pxSrc.size.height = gfxFloat(h);
}
gfxRect pxSubimage = pxSrc;
nsCOMPtr<nsIDeviceContext> dc;
aRenderingContext->GetDeviceContext(*getter_AddRefs(dc));
@ -2376,9 +2375,7 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
imgFrame->GetRect(pxImgFrameRect);
if (pxImgFrameRect.x > 0) {
gfxFloat fx(pxImgFrameRect.x);
pxSubimage.pos.x -= fx;
pxSrc.pos.x -= fx;
pxSrc.pos.x -= gfxFloat(pxImgFrameRect.x);
gfxFloat scaled_x = pxSrc.pos.x;
if (pxDirty.size.width != pxSrc.size.width) {
@ -2399,9 +2396,7 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
}
if (pxImgFrameRect.y > 0) {
gfxFloat fy(pxImgFrameRect.y);
pxSubimage.pos.y -= fy;
pxSrc.pos.y -= fy;
pxSrc.pos.y -= gfxFloat(pxImgFrameRect.y);
gfxFloat scaled_y = pxSrc.pos.y;
if (pxDirty.size.height != pxSrc.size.height) {
@ -2421,7 +2416,7 @@ nsLayoutUtils::DrawImage(nsIRenderingContext* aRenderingContext,
return NS_OK;
}
return img->Draw(*aRenderingContext, pxSrc, pxSubimage, pxDirty);
return img->Draw(*aRenderingContext, pxSrc, pxDirty);
}
void

Просмотреть файл

@ -715,8 +715,7 @@ public:
* @param aDestRect Where to draw the image (app units).
* @param aDirtyRect Draw only within this region (rounded to the
* nearest pixel); the intersection of
* invalidation and clipping (this is the
* destination clip)
* invalidation and clipping.
* @param aSourceRect If null, draw the entire image so it fits in
* aDestRect. If non-null, the subregion of the
* image that should be drawn (in app units, such

Просмотреть файл

@ -647,7 +647,6 @@ skip-if(MOZ_WIDGET_TOOLKIT!="windows") == 391045.html 391045-ref.html # windows-
== 403129-3.html 403129-3-ref.html
== 403129-4.html 403129-4-ref.html
random == 403134-1.html 403134-1-ref.html # bug 405377
== 403181-1.xml 403181-1-ref.xml
== 403249-1a.html 403249-1-ref.html
== 403249-1b.html 403249-1-ref.html
== 403249-2a.html 403249-2-ref.html

Просмотреть файл

@ -566,7 +566,7 @@ nsBaseDragService::DrawDragForImage(nsPresContext* aPresContext,
gfxRect inRect = gfxRect(srcRect.x, srcRect.y, srcRect.width, srcRect.height);
gfxRect outRect = gfxRect(destRect.x, destRect.y, destRect.width, destRect.height);
return img->Draw(*rc, inRect, inRect, outRect);
return img->Draw(*rc, inRect, outRect);
}
void