diff --git a/gfx/src/cairo/nsCairoImage.cpp b/gfx/src/cairo/nsCairoImage.cpp index 6e8d1ba4fa5..d4e55419b49 100644 --- a/gfx/src/cairo/nsCairoImage.cpp +++ b/gfx/src/cairo/nsCairoImage.cpp @@ -197,53 +197,30 @@ nsCairoImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface, cairo_t *dstCairo = cairoContext->GetCairo(); - cairo_pattern_t *prepat = cairo_current_pattern (dstCairo); - fprintf (stderr, " IMAGE: pattern: %p ", prepat); - cairo_save(dstCairo); -#if 0 - { - cairo_matrix_t *mat = cairo_matrix_create(); - cairo_current_matrix (dstCairo, mat); + // just in case this needs setting + cairo_set_target_surface(dstCairo, dstSurf->GetCairoSurface()); - double a,b,c,d,tx,ty; - cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty); - fprintf (stderr, " [cur tx ty: %g %g %d %d] ", tx, ty, (int) tx, (int) ty); - } - - if (aSWidth == 16 && aSHeight == 16 && aDWidth == 16 && aDHeight == 16) - cairo_set_rgb_color (dstCairo, 0.0, 1.0, 0.0); - else - cairo_set_rgb_color (dstCairo, 1.0, 0.0, 0.0); - cairo_rectangle (dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight)); - cairo_fill (dstCairo); + // the coords here are absolute + cairo_identity_matrix(dstCairo); - cairo_pattern_t *postpat = cairo_current_pattern (dstCairo); - fprintf (stderr, " ---> %p ", postpat); + // clip to target + cairo_rectangle(dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight)); + cairo_clip(dstCairo); -#else - cairo_pattern_t *imgpat = cairo_pattern_create_for_surface (mImageSurface); - cairo_matrix_t *mat = cairo_matrix_create(); - cairo_matrix_scale (mat, 1.0/15.0, 1.0/15.0); - cairo_matrix_scale (mat, double(aDWidth)/double(aSWidth), double(aDHeight)/double(aSHeight)); - cairo_matrix_translate (mat, double(aSX), double(aSY)); - cairo_pattern_set_matrix (imgpat, mat); - cairo_set_pattern (dstCairo, imgpat); + // scale up to the size difference + cairo_scale(dstCairo, double(aDWidth)/double(aSWidth), double(aDHeight)/double(aSHeight)); - cairo_new_path (dstCairo); - cairo_rectangle (dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight)); - cairo_fill (dstCairo); + // move to where we need to start the image rectangle, so that + // it gets clipped to the right place + cairo_translate(dstCairo, double(aDX - aSX), double(aDY - aSY)); - cairo_set_pattern (dstCairo, nsnull); - cairo_pattern_destroy (imgpat); - cairo_matrix_destroy(mat); -#endif + // show it + cairo_show_surface (dstCairo, mImageSurface, mWidth, mHeight); cairo_restore(dstCairo); - cairo_pattern_t *endpat = cairo_current_pattern (dstCairo); - fprintf (stderr, " ---> %p\n", endpat); return NS_OK; } @@ -254,7 +231,34 @@ nsCairoImage::DrawTile(nsIRenderingContext &aContext, PRInt32 aPadX, PRInt32 aPadY, const nsRect &aTileRect) { - NS_WARNING("not implemented"); + if (aPadX || aPadY) + fprintf (stderr, "Warning: nsCairoImage::DrawTile given padX(%d)/padY(%d), ignoring\n", aPadX, aPadY); + if (aSXOffset || aSYOffset) + fprintf (stderr, "Warning: nsCairoImage::DrawTile given XOffset(%d)/YOffset(%d), ignoring\n", aSXOffset, aSYOffset); + + nsCairoDrawingSurface *dstSurf = NS_STATIC_CAST(nsCairoDrawingSurface*, aSurface); + nsCairoRenderingContext *cairoContext = NS_STATIC_CAST(nsCairoRenderingContext*, &aContext); + + cairo_t *dstCairo = cairoContext->GetCairo(); + + cairo_save(dstCairo); + + // just in case this needs setting + cairo_set_target_surface(dstCairo, dstSurf->GetCairoSurface()); + + // coords are absolute again + cairo_identity_matrix(dstCairo); + + cairo_pattern_t *pat = cairo_pattern_create_for_surface (mImageSurface); + cairo_pattern_set_extend (pat, CAIRO_EXTEND_REPEAT); + cairo_set_pattern (dstCairo, pat); + cairo_pattern_destroy (pat); + + cairo_rectangle (dstCairo, aTileRect.x, aTileRect.y, aTileRect.width, aTileRect.height); + cairo_fill (dstCairo); + + cairo_restore(dstCairo); + return NS_OK; } @@ -263,25 +267,25 @@ nsCairoImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32 { nsCairoImage *dstCairoImage = NS_STATIC_CAST(nsCairoImage*, aDstImage); - cairo_t *cairo = cairo_create (); + cairo_t *dstCairo = cairo_create (); - cairo_set_target_surface (cairo, dstCairoImage->mImageSurface); + cairo_set_target_surface(dstCairo, dstCairoImage->mImageSurface); - cairo_pattern_t *pat = cairo_pattern_create_for_surface (mImageSurface); - cairo_matrix_t *mat = cairo_matrix_create (); - cairo_matrix_scale (mat, 1.0/15.0, 1.0/15.0); - cairo_matrix_scale (mat, double(aDWidth)/double(mWidth), double(aDHeight)/double(mHeight)); - cairo_pattern_set_matrix (pat, mat); + // clip to target + cairo_rectangle(dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight)); + cairo_clip(dstCairo); - cairo_set_pattern (cairo, pat); + // scale up to the size difference + cairo_scale(dstCairo, double(aDWidth)/double(mWidth), double(aDHeight)/double(mHeight)); - cairo_new_path (cairo); - cairo_rectangle (cairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight)); - cairo_fill (cairo); + // move to where we need to start the image rectangle, so that + // it gets clipped to the right place + cairo_translate(dstCairo, double(aDX), double(aDY)); - cairo_destroy (cairo); - cairo_pattern_destroy (pat); - cairo_matrix_destroy (mat); + // show it + cairo_show_surface (dstCairo, mImageSurface, mWidth, mHeight); + + cairo_destroy (dstCairo); return NS_OK; } @@ -289,7 +293,7 @@ nsCairoImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32 PRInt8 nsCairoImage::GetAlphaDepth() { - return 0; + return 8; } void * diff --git a/gfx/src/cairo/nsCairoRenderingContext.cpp b/gfx/src/cairo/nsCairoRenderingContext.cpp index f82a65e65a0..6eeadb6bb9c 100644 --- a/gfx/src/cairo/nsCairoRenderingContext.cpp +++ b/gfx/src/cairo/nsCairoRenderingContext.cpp @@ -833,6 +833,31 @@ nsCairoRenderingContext::DrawImage(imgIContainer *aImage, const nsRect &aSrcRect, const nsRect &aDestRect) { + // from nsRenderingContextImpl.cpp + + double x,y,w,h; + + nsRect dr = aDestRect; + x = dr.x; y = dr.y; w = dr.width; h = dr.height; + cairo_transform_point(mCairo, &x, &y); + cairo_transform_distance(mCairo, &w, &h); + dr.x = (int) x; dr.y = (int) y; dr.width = (int) w; dr.height = (int) h; + + nsRect sr = aSrcRect; + x = sr.x; y = sr.y; w = sr.width; h = sr.height; + cairo_transform_point(mCairo, &x, &y); + cairo_transform_distance(mCairo, &w, &h); + sr.x = (int) x; sr.y = (int) y; sr.width = (int) w; sr.height = (int) h; + + if (sr.IsEmpty() || dr.IsEmpty()) + return NS_OK; + + /* What the heck? + * sr.x = aSrcRect.x; + * sr.y = aSrcRect.y; + * mTranMatrix->TransformNoXLateCoord(&sr.x, &sr.y); + */ + nsCOMPtr iframe; aImage->GetCurrentFrame(getter_AddRefs(iframe)); if (!iframe) return NS_ERROR_FAILURE; @@ -840,24 +865,30 @@ nsCairoRenderingContext::DrawImage(imgIContainer *aImage, nsCOMPtr img(do_GetInterface(iframe)); if (!img) return NS_ERROR_FAILURE; + nsIDrawingSurface *surface = nsnull; + GetDrawingSurface(&surface); + if (!surface) return NS_ERROR_FAILURE; + // For Bug 87819 // iframe may want image to start at different position, so adjust nsRect iframeRect; iframe->GetRect(iframeRect); - - nsRect sr(aSrcRect); - nsRect dr(aDestRect); - -#if 0 + if (iframeRect.x > 0) { - float xScaleRatio = float(dr.width) / sr.width; + // Adjust for the iframe offset before we do scaling. sr.x -= iframeRect.x; + + nscoord scaled_x = sr.x; + if (dr.width != sr.width) { + PRFloat64 scale_ratio = PRFloat64(dr.width) / PRFloat64(sr.width); + scaled_x = NSToCoordRound(scaled_x * scale_ratio); + } if (sr.x < 0) { - dr.x -= NSToIntRound(sr.x * xScaleRatio); + dr.x -= scaled_x; sr.width += sr.x; - dr.width += NSToIntRound(sr.x * xScaleRatio); + dr.width += scaled_x; if (sr.width <= 0 || dr.width <= 0) - return NS_OK; + return NS_OK; sr.x = 0; } else if (sr.x > iframeRect.width) { return NS_OK; @@ -865,32 +896,28 @@ nsCairoRenderingContext::DrawImage(imgIContainer *aImage, } if (iframeRect.y > 0) { - float yScaleRatio = float(dr.height) / sr.height; - - // adjust for offset + // Adjust for the iframe offset before we do scaling. sr.y -= iframeRect.y; + + nscoord scaled_y = sr.y; + if (dr.height != sr.height) { + PRFloat64 scale_ratio = PRFloat64(dr.height) / PRFloat64(sr.height); + scaled_y = NSToCoordRound(scaled_y * scale_ratio); + } if (sr.y < 0) { - dr.y -= NSToIntRound(sr.y * yScaleRatio); + dr.y -= scaled_y; sr.height += sr.y; - dr.height += NSToIntRound(sr.y * yScaleRatio); + dr.height += scaled_y; if (sr.height <= 0 || dr.height <= 0) - return NS_OK; + return NS_OK; sr.y = 0; } else if (sr.y > iframeRect.height) { return NS_OK; } - } -#endif + } - img->LockImagePixels(PR_FALSE); - - img->Draw(*this, mDrawingSurface, - sr.x, sr.y, sr.width, sr.height, - dr.x, dr.y, dr.width, dr.height); - - img->UnlockImagePixels(PR_FALSE); - - return NS_OK; + return img->Draw(*this, surface, sr.x, sr.y, sr.width, sr.height, + dr.x, dr.y, dr.width, dr.height); } NS_IMETHODIMP @@ -898,6 +925,28 @@ nsCairoRenderingContext::DrawTile(imgIContainer *aImage, nscoord aXOffset, nscoord aYOffset, const nsRect * aTargetRect) { + // from nsRenderingContextImpl.cpp + + nsRect dr(*aTargetRect); + double x = dr.x, y = dr.y, w = dr.width, h = dr.height; + cairo_transform_point(mCairo, &x, &y); + cairo_transform_distance(mCairo, &w, &h); + dr.x = (int) x; dr.y = (int) y; dr.width = (int) w; dr.height = (int) h; + + x = aXOffset; y = aYOffset; + cairo_transform_point(mCairo, &x, &y); + aXOffset = (int) x; aYOffset = (int) y; + + nscoord width, height; + aImage->GetWidth(&width); + aImage->GetHeight(&height); + + if (width == 0 || height == 0) + return PR_FALSE; + + nscoord xOffset = (dr.x - aXOffset) % width; + nscoord yOffset = (dr.y - aYOffset) % height; + nsCOMPtr iframe; aImage->GetCurrentFrame(getter_AddRefs(iframe)); if (!iframe) return NS_ERROR_FAILURE; @@ -905,15 +954,20 @@ nsCairoRenderingContext::DrawTile(imgIContainer *aImage, nsCOMPtr img(do_GetInterface(iframe)); if (!img) return NS_ERROR_FAILURE; - img->LockImagePixels(PR_FALSE); + nsIDrawingSurface *surface = nsnull; + GetDrawingSurface(&surface); + if (!surface) return NS_ERROR_FAILURE; - img->Draw(*this, mDrawingSurface, - aXOffset, aYOffset, aTargetRect->width, aTargetRect->height, - aTargetRect->x, aTargetRect->y, aTargetRect->width, aTargetRect->height); + /* bug 113561 - frame can be smaller than container */ + nsRect iframeRect; + iframe->GetRect(iframeRect); + PRInt32 padx = width - iframeRect.width; + PRInt32 pady = height - iframeRect.height; - img->UnlockImagePixels(PR_FALSE); - - return NS_OK; + return img->DrawTile(*this, surface, + xOffset - iframeRect.x, yOffset - iframeRect.y, + padx, pady, + dr); } // diff --git a/gfx/src/cairo/nsFontMetricsXft.cpp b/gfx/src/cairo/nsFontMetricsXft.cpp index 444571fa5ad..5d05988a898 100644 --- a/gfx/src/cairo/nsFontMetricsXft.cpp +++ b/gfx/src/cairo/nsFontMetricsXft.cpp @@ -1487,7 +1487,7 @@ nsFontMetricsXft::PrepareToDraw(nsCairoRenderingContext *aContext, *aDraw = aSurface->GetXftDraw(); - fprintf (stderr, "+++ PrepareToDraw: %p\n", *aDraw); +// fprintf (stderr, "+++ PrepareToDraw: %p\n", *aDraw); nsCOMPtr lastRegion; nsCOMPtr clipRegion; @@ -2006,9 +2006,9 @@ nsFontXft::DrawStringSpec(FcChar32 *aString, PRUint32 aLen, void *aData) nscoord x = data->x + data->xOffset; nscoord y = data->y; /* Convert to device coordinate. */ - fprintf (stderr, "[%d %d -> ", x, y); +// fprintf (stderr, "[%d %d -> ", x, y); data->context->TransformCoord(&x, &y); - fprintf (stderr, "%d %d] ", x, y); +// fprintf (stderr, "%d %d] ", x, y); /* position in X is the location offset in the string plus whatever offset is required for the spacing