This commit is contained in:
vladimir%pobox.com 2004-08-19 02:07:31 +00:00
Родитель 67a92a6c9c
Коммит 80f80bb59d
3 изменённых файлов: 147 добавлений и 89 удалений

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

@ -197,53 +197,30 @@ nsCairoImage::Draw(nsIRenderingContext &aContext, nsIDrawingSurface *aSurface,
cairo_t *dstCairo = cairoContext->GetCairo(); cairo_t *dstCairo = cairoContext->GetCairo();
cairo_pattern_t *prepat = cairo_current_pattern (dstCairo);
fprintf (stderr, " IMAGE: pattern: %p ", prepat);
cairo_save(dstCairo); cairo_save(dstCairo);
#if 0 // just in case this needs setting
{ cairo_set_target_surface(dstCairo, dstSurf->GetCairoSurface());
cairo_matrix_t *mat = cairo_matrix_create();
cairo_current_matrix (dstCairo, mat);
double a,b,c,d,tx,ty; // the coords here are absolute
cairo_matrix_get_affine (mat, &a, &b, &c, &d, &tx, &ty); cairo_identity_matrix(dstCairo);
fprintf (stderr, " [cur tx ty: %g %g %d %d] ", tx, ty, (int) tx, (int) ty);
}
if (aSWidth == 16 && aSHeight == 16 && aDWidth == 16 && aDHeight == 16) // clip to target
cairo_set_rgb_color (dstCairo, 0.0, 1.0, 0.0); cairo_rectangle(dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight));
else cairo_clip(dstCairo);
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);
cairo_pattern_t *postpat = cairo_current_pattern (dstCairo); // scale up to the size difference
fprintf (stderr, " ---> %p ", postpat); cairo_scale(dstCairo, double(aDWidth)/double(aSWidth), double(aDHeight)/double(aSHeight));
#else // move to where we need to start the image rectangle, so that
cairo_pattern_t *imgpat = cairo_pattern_create_for_surface (mImageSurface); // it gets clipped to the right place
cairo_matrix_t *mat = cairo_matrix_create(); cairo_translate(dstCairo, double(aDX - aSX), double(aDY - aSY));
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);
cairo_new_path (dstCairo); // show it
cairo_rectangle (dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight)); cairo_show_surface (dstCairo, mImageSurface, mWidth, mHeight);
cairo_fill (dstCairo);
cairo_set_pattern (dstCairo, nsnull);
cairo_pattern_destroy (imgpat);
cairo_matrix_destroy(mat);
#endif
cairo_restore(dstCairo); cairo_restore(dstCairo);
cairo_pattern_t *endpat = cairo_current_pattern (dstCairo);
fprintf (stderr, " ---> %p\n", endpat);
return NS_OK; return NS_OK;
} }
@ -254,7 +231,34 @@ nsCairoImage::DrawTile(nsIRenderingContext &aContext,
PRInt32 aPadX, PRInt32 aPadY, PRInt32 aPadX, PRInt32 aPadY,
const nsRect &aTileRect) 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; return NS_OK;
} }
@ -263,25 +267,25 @@ nsCairoImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32
{ {
nsCairoImage *dstCairoImage = NS_STATIC_CAST(nsCairoImage*, aDstImage); 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); // clip to target
cairo_matrix_t *mat = cairo_matrix_create (); cairo_rectangle(dstCairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight));
cairo_matrix_scale (mat, 1.0/15.0, 1.0/15.0); cairo_clip(dstCairo);
cairo_matrix_scale (mat, double(aDWidth)/double(mWidth), double(aDHeight)/double(mHeight));
cairo_pattern_set_matrix (pat, mat);
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); // move to where we need to start the image rectangle, so that
cairo_rectangle (cairo, double(aDX), double(aDY), double(aDWidth), double(aDHeight)); // it gets clipped to the right place
cairo_fill (cairo); cairo_translate(dstCairo, double(aDX), double(aDY));
cairo_destroy (cairo); // show it
cairo_pattern_destroy (pat); cairo_show_surface (dstCairo, mImageSurface, mWidth, mHeight);
cairo_matrix_destroy (mat);
cairo_destroy (dstCairo);
return NS_OK; return NS_OK;
} }
@ -289,7 +293,7 @@ nsCairoImage::DrawToImage(nsIImage* aDstImage, PRInt32 aDX, PRInt32 aDY, PRInt32
PRInt8 PRInt8
nsCairoImage::GetAlphaDepth() nsCairoImage::GetAlphaDepth()
{ {
return 0; return 8;
} }
void * void *

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

@ -833,6 +833,31 @@ nsCairoRenderingContext::DrawImage(imgIContainer *aImage,
const nsRect &aSrcRect, const nsRect &aSrcRect,
const nsRect &aDestRect) 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<gfxIImageFrame> iframe; nsCOMPtr<gfxIImageFrame> iframe;
aImage->GetCurrentFrame(getter_AddRefs(iframe)); aImage->GetCurrentFrame(getter_AddRefs(iframe));
if (!iframe) return NS_ERROR_FAILURE; if (!iframe) return NS_ERROR_FAILURE;
@ -840,24 +865,30 @@ nsCairoRenderingContext::DrawImage(imgIContainer *aImage,
nsCOMPtr<nsIImage> img(do_GetInterface(iframe)); nsCOMPtr<nsIImage> img(do_GetInterface(iframe));
if (!img) return NS_ERROR_FAILURE; if (!img) return NS_ERROR_FAILURE;
nsIDrawingSurface *surface = nsnull;
GetDrawingSurface(&surface);
if (!surface) return NS_ERROR_FAILURE;
// For Bug 87819 // For Bug 87819
// iframe may want image to start at different position, so adjust // iframe may want image to start at different position, so adjust
nsRect iframeRect; nsRect iframeRect;
iframe->GetRect(iframeRect); iframe->GetRect(iframeRect);
nsRect sr(aSrcRect);
nsRect dr(aDestRect);
#if 0
if (iframeRect.x > 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; 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) { if (sr.x < 0) {
dr.x -= NSToIntRound(sr.x * xScaleRatio); dr.x -= scaled_x;
sr.width += sr.x; sr.width += sr.x;
dr.width += NSToIntRound(sr.x * xScaleRatio); dr.width += scaled_x;
if (sr.width <= 0 || dr.width <= 0) if (sr.width <= 0 || dr.width <= 0)
return NS_OK; return NS_OK;
sr.x = 0; sr.x = 0;
} else if (sr.x > iframeRect.width) { } else if (sr.x > iframeRect.width) {
return NS_OK; return NS_OK;
@ -865,32 +896,28 @@ nsCairoRenderingContext::DrawImage(imgIContainer *aImage,
} }
if (iframeRect.y > 0) { if (iframeRect.y > 0) {
float yScaleRatio = float(dr.height) / sr.height; // Adjust for the iframe offset before we do scaling.
// adjust for offset
sr.y -= iframeRect.y; 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) { if (sr.y < 0) {
dr.y -= NSToIntRound(sr.y * yScaleRatio); dr.y -= scaled_y;
sr.height += sr.y; sr.height += sr.y;
dr.height += NSToIntRound(sr.y * yScaleRatio); dr.height += scaled_y;
if (sr.height <= 0 || dr.height <= 0) if (sr.height <= 0 || dr.height <= 0)
return NS_OK; return NS_OK;
sr.y = 0; sr.y = 0;
} else if (sr.y > iframeRect.height) { } else if (sr.y > iframeRect.height) {
return NS_OK; return NS_OK;
} }
} }
#endif
img->LockImagePixels(PR_FALSE); return img->Draw(*this, surface, sr.x, sr.y, sr.width, sr.height,
dr.x, dr.y, dr.width, dr.height);
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;
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -898,6 +925,28 @@ nsCairoRenderingContext::DrawTile(imgIContainer *aImage,
nscoord aXOffset, nscoord aYOffset, nscoord aXOffset, nscoord aYOffset,
const nsRect * aTargetRect) 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<gfxIImageFrame> iframe; nsCOMPtr<gfxIImageFrame> iframe;
aImage->GetCurrentFrame(getter_AddRefs(iframe)); aImage->GetCurrentFrame(getter_AddRefs(iframe));
if (!iframe) return NS_ERROR_FAILURE; if (!iframe) return NS_ERROR_FAILURE;
@ -905,15 +954,20 @@ nsCairoRenderingContext::DrawTile(imgIContainer *aImage,
nsCOMPtr<nsIImage> img(do_GetInterface(iframe)); nsCOMPtr<nsIImage> img(do_GetInterface(iframe));
if (!img) return NS_ERROR_FAILURE; 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, /* bug 113561 - frame can be smaller than container */
aXOffset, aYOffset, aTargetRect->width, aTargetRect->height, nsRect iframeRect;
aTargetRect->x, aTargetRect->y, aTargetRect->width, aTargetRect->height); iframe->GetRect(iframeRect);
PRInt32 padx = width - iframeRect.width;
PRInt32 pady = height - iframeRect.height;
img->UnlockImagePixels(PR_FALSE); return img->DrawTile(*this, surface,
xOffset - iframeRect.x, yOffset - iframeRect.y,
return NS_OK; padx, pady,
dr);
} }
// //

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

@ -1487,7 +1487,7 @@ nsFontMetricsXft::PrepareToDraw(nsCairoRenderingContext *aContext,
*aDraw = aSurface->GetXftDraw(); *aDraw = aSurface->GetXftDraw();
fprintf (stderr, "+++ PrepareToDraw: %p\n", *aDraw); // fprintf (stderr, "+++ PrepareToDraw: %p\n", *aDraw);
nsCOMPtr<nsIRegion> lastRegion; nsCOMPtr<nsIRegion> lastRegion;
nsCOMPtr<nsIRegion> clipRegion; nsCOMPtr<nsIRegion> clipRegion;
@ -2006,9 +2006,9 @@ nsFontXft::DrawStringSpec(FcChar32 *aString, PRUint32 aLen, void *aData)
nscoord x = data->x + data->xOffset; nscoord x = data->x + data->xOffset;
nscoord y = data->y; nscoord y = data->y;
/* Convert to device coordinate. */ /* Convert to device coordinate. */
fprintf (stderr, "[%d %d -> ", x, y); // fprintf (stderr, "[%d %d -> ", x, y);
data->context->TransformCoord(&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 /* position in X is the location offset in the string
plus whatever offset is required for the spacing plus whatever offset is required for the spacing