summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-12-02 08:37:20 -0800
committerKeith Packard <keithp@keithp.com>2009-12-11 11:51:45 -0800
commita72c65e9176c51de95db2fdbf4c5d946a4911695 (patch)
tree346647afe949730b6a3eed0f8b1628a058129804
parentbd567061c8b84b268d9bbb01bc4d8981feefb862 (diff)
fb: Adjust transform or composite coordinates for pixman operations
Windows (or even pixmaps, in some cases) may not sit at the origin of the containing pixmap, so any coordinates relative to the drawable must be adjusted. For destinations and untransformed sources, the operation coordinates are adjusted. For transformed sources, the transform matrix is adjusted. Signed-off-by: Keith Packard <keithp@keithp.com> Acked-by: Soeren Sandmann <sandmann@daimi.au.dk>
-rw-r--r--fb/fb.h7
-rw-r--r--fb/fbpict.c71
-rw-r--r--fb/fbtrap.c6
3 files changed, 58 insertions, 26 deletions
diff --git a/fb/fb.h b/fb/fb.h
index ed21f9eb6..02d6c0372 100644
--- a/fb/fb.h
+++ b/fb/fb.h
@@ -2082,8 +2082,11 @@ fbFillRegionSolid (DrawablePtr pDrawable,
FbBits xor);
extern _X_EXPORT pixman_image_t *
-image_from_pict (PicturePtr pict,
- Bool has_clip);
+image_from_pict (PicturePtr pict,
+ Bool has_clip,
+ int *xoff,
+ int *yoff);
+
extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *);
#endif /* _FB_H_ */
diff --git a/fb/fbpict.c b/fb/fbpict.c
index 07a22869d..251754b3f 100644
--- a/fb/fbpict.c
+++ b/fb/fbpict.c
@@ -158,19 +158,24 @@ fbComposite (CARD8 op,
CARD16 height)
{
pixman_image_t *src, *mask, *dest;
+ int src_xoff, src_yoff;
+ int msk_xoff, msk_yoff;
+ int dst_xoff, dst_yoff;
miCompositeSourceValidate (pSrc, xSrc - xDst, ySrc - yDst, width, height);
if (pMask)
miCompositeSourceValidate (pMask, xMask - xDst, yMask - yDst, width, height);
- src = image_from_pict (pSrc, TRUE);
- mask = image_from_pict (pMask, TRUE);
- dest = image_from_pict (pDst, TRUE);
+ src = image_from_pict (pSrc, FALSE, &src_xoff, &src_yoff);
+ mask = image_from_pict (pMask, FALSE, &msk_xoff, &msk_yoff);
+ dest = image_from_pict (pDst, TRUE, &dst_xoff, &dst_yoff);
if (src && dest && !(pMask && !mask))
{
pixman_image_composite (op, src, mask, dest,
- xSrc, ySrc, xMask, yMask, xDst, yDst,
+ xSrc + src_xoff, ySrc + src_yoff,
+ xMask + msk_xoff, yMask + msk_yoff,
+ xDst + dst_xoff, yDst + dst_yoff,
width, height);
}
@@ -270,22 +275,22 @@ create_conical_gradient_image (PictGradient *gradient)
static pixman_image_t *
create_bits_picture (PicturePtr pict,
- Bool has_clip)
+ Bool has_clip,
+ int *xoff,
+ int *yoff)
{
+ PixmapPtr pixmap;
FbBits *bits;
FbStride stride;
- int bpp, xoff, yoff;
+ int bpp;
pixman_image_t *image;
- fbGetDrawable (pict->pDrawable, bits, stride, bpp, xoff, yoff);
-
- bits = (FbBits*)((CARD8*)bits +
- (pict->pDrawable->y + yoff) * stride * sizeof(FbBits) +
- (pict->pDrawable->x + xoff) * (bpp / 8));
+ fbGetDrawablePixmap (pict->pDrawable, pixmap, *xoff, *yoff);
+ fbGetPixmapBitsData(pixmap, bits, stride, bpp);
image = pixman_image_create_bits (
pict->format,
- pict->pDrawable->width, pict->pDrawable->height,
+ pixmap->drawable.width, pixmap->drawable.height,
(uint32_t *)bits, stride * sizeof (FbStride));
@@ -311,30 +316,52 @@ create_bits_picture (PicturePtr pict,
if (pict->clientClipType != CT_NONE)
pixman_image_set_has_client_clip (image, TRUE);
- pixman_region_translate (pict->pCompositeClip, - pict->pDrawable->x, - pict->pDrawable->y);
+ if (*xoff || *yoff)
+ pixman_region_translate (pict->pCompositeClip, *xoff, *yoff);
pixman_image_set_clip_region (image, pict->pCompositeClip);
- pixman_region_translate (pict->pCompositeClip, pict->pDrawable->x, pict->pDrawable->y);
+ if (*xoff || *yoff)
+ pixman_region_translate (pict->pCompositeClip, -*xoff, -*yoff);
}
/* Indexed table */
if (pict->pFormat->index.devPrivate)
pixman_image_set_indexed (image, pict->pFormat->index.devPrivate);
+ /* Add in drawable origin to position within the image */
+ *xoff += pict->pDrawable->x;
+ *yoff += pict->pDrawable->y;
+
return image;
}
static void
-set_image_properties (pixman_image_t *image, PicturePtr pict)
+set_image_properties (pixman_image_t *image, PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
{
pixman_repeat_t repeat;
pixman_filter_t filter;
if (pict->transform)
{
- pixman_image_set_transform (
- image, (pixman_transform_t *)pict->transform);
+ /* For source images, adjust the transform to account
+ * for the drawable offset within the pixman image,
+ * then set the offset to 0 as it will be used
+ * to compute positions within the transformed image.
+ */
+ if (!has_clip) {
+ struct pixman_transform adjusted;
+
+ adjusted = *pict->transform;
+ pixman_transform_translate(&adjusted,
+ NULL,
+ pixman_int_to_fixed(*xoff),
+ pixman_int_to_fixed(*yoff));
+ pixman_image_set_transform (image, &adjusted);
+ *xoff = 0;
+ *yoff = 0;
+ } else
+ pixman_image_set_transform (image, pict->transform);
}
switch (pict->repeatType)
@@ -361,7 +388,8 @@ set_image_properties (pixman_image_t *image, PicturePtr pict)
if (pict->alphaMap)
{
- pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, TRUE);
+ int alpha_xoff, alpha_yoff;
+ pixman_image_t *alpha_map = image_from_pict (pict->alphaMap, FALSE, &alpha_xoff, &alpha_yoff);
pixman_image_set_alpha_map (
image, alpha_map, pict->alphaOrigin.x, pict->alphaOrigin.y);
@@ -394,8 +422,7 @@ set_image_properties (pixman_image_t *image, PicturePtr pict)
}
pixman_image_t *
-image_from_pict (PicturePtr pict,
- Bool has_clip)
+image_from_pict (PicturePtr pict, Bool has_clip, int *xoff, int *yoff)
{
pixman_image_t *image = NULL;
@@ -404,7 +431,7 @@ image_from_pict (PicturePtr pict,
if (pict->pDrawable)
{
- image = create_bits_picture (pict, has_clip);
+ image = create_bits_picture (pict, has_clip, xoff, yoff);
}
else if (pict->pSourcePict)
{
@@ -428,7 +455,7 @@ image_from_pict (PicturePtr pict,
}
if (image)
- set_image_properties (image, pict);
+ set_image_properties (image, pict, has_clip, xoff, yoff);
return image;
}
diff --git a/fb/fbtrap.c b/fb/fbtrap.c
index 830603ae7..515e2e1c1 100644
--- a/fb/fbtrap.c
+++ b/fb/fbtrap.c
@@ -40,7 +40,8 @@ fbAddTraps (PicturePtr pPicture,
int ntrap,
xTrap *traps)
{
- pixman_image_t *image = image_from_pict (pPicture, FALSE);
+ int image_xoff, image_yoff;
+ pixman_image_t *image = image_from_pict (pPicture, FALSE, &image_xoff, &image_yoff);
if (!image)
return;
@@ -56,7 +57,8 @@ fbRasterizeTrapezoid (PicturePtr pPicture,
int x_off,
int y_off)
{
- pixman_image_t *image = image_from_pict (pPicture, FALSE);
+ int mask_xoff, mask_yoff;
+ pixman_image_t *image = image_from_pict (pPicture, FALSE, &mask_xoff, &mask_yoff);
if (!image)
return;