[PATCH] Implement PIXMAN_REPEAT_REFLECT for images

Thomas Jaeger ThJaeger at gmail.com
Tue Jan 20 15:40:46 PST 2009


---
 pixman/pixman-compose.c     |    8 ++++----
 pixman/pixman-pict.c        |    4 +++-
 pixman/pixman-transformed.c |   38 ++++++++++++++++++++++++++++++++++++--
 3 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/pixman/pixman-compose.c b/pixman/pixman-compose.c
index 820545c..315206d 100644
--- a/pixman/pixman-compose.c
+++ b/pixman/pixman-compose.c
@@ -264,7 +264,7 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbComposeData *data,
 	{
 	    fetchSrc = get_fetch_external_alpha(wide);
 	}
-	else if ((bits->common.repeat == PIXMAN_REPEAT_NORMAL || bits->common.repeat == PIXMAN_REPEAT_PAD) &&
+	else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
 		 bits->width == 1 &&
 		 bits->height == 1)
 	{
@@ -272,7 +272,7 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbComposeData *data,
 	    srcClass = SOURCE_IMAGE_CLASS_HORIZONTAL;
 	}
 	else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION
-                && bits->common.repeat != PIXMAN_REPEAT_PAD)
+                && bits->common.repeat != PIXMAN_REPEAT_PAD && bits->common.repeat != PIXMAN_REPEAT_REFLECT)
 	{
 	    fetchSrc = get_fetch(wide);
 	}
@@ -303,14 +303,14 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbComposeData *data,
 	    {
 		fetchMask = get_fetch_external_alpha(wide);
 	    }
-	    else if ((bits->common.repeat == PIXMAN_REPEAT_NORMAL || bits->common.repeat == PIXMAN_REPEAT_PAD) &&
+	    else if ((bits->common.repeat != PIXMAN_REPEAT_NONE) &&
 		     bits->width == 1 && bits->height == 1)
 	    {
 		fetchMask = get_fetch_solid(wide);
 		maskClass = SOURCE_IMAGE_CLASS_HORIZONTAL;
 	    }
 	    else if (!bits->common.transform && bits->common.filter != PIXMAN_FILTER_CONVOLUTION
-                    && bits->common.repeat != PIXMAN_REPEAT_PAD)
+                    && bits->common.repeat != PIXMAN_REPEAT_PAD && bits->common.repeat != PIXMAN_REPEAT_REFLECT)
 		fetchMask = get_fetch(wide);
 	    else
 		fetchMask = get_fetch_transformed(wide);
diff --git a/pixman/pixman-pict.c b/pixman/pixman-pict.c
index 42a0454..a703dda 100644
--- a/pixman/pixman-pict.c
+++ b/pixman/pixman-pict.c
@@ -1966,7 +1966,9 @@ pixman_image_composite (pixman_op_t      op,
         && !maskAlphaMap && !srcAlphaMap && !dstAlphaMap
         && (pSrc->common.filter != PIXMAN_FILTER_CONVOLUTION)
         && (pSrc->common.repeat != PIXMAN_REPEAT_PAD)
-        && (!pMask || (pMask->common.filter != PIXMAN_FILTER_CONVOLUTION && pMask->common.repeat != PIXMAN_REPEAT_PAD))
+        && (pSrc->common.repeat != PIXMAN_REPEAT_REFLECT)
+        && (!pMask || (pMask->common.filter != PIXMAN_FILTER_CONVOLUTION &&
+		pMask->common.repeat != PIXMAN_REPEAT_PAD && pMask->common.repeat != PIXMAN_REPEAT_REFLECT))
 	&& !pSrc->common.read_func && !pSrc->common.write_func
 	&& !(pMask && pMask->common.read_func) && !(pMask && pMask->common.write_func)
 	&& !pDst->common.read_func && !pDst->common.write_func)
diff --git a/pixman/pixman-transformed.c b/pixman/pixman-transformed.c
index 983ff1f..f0e8906 100644
--- a/pixman/pixman-transformed.c
+++ b/pixman/pixman-transformed.c
@@ -129,7 +129,16 @@ fetch_nearest (bits_image_t		*pict,
 	    inside_bounds = TRUE;
 	    break;
 	    
-	case PIXMAN_REPEAT_REFLECT: /* FIXME: this should be implemented for images */
+	case PIXMAN_REPEAT_REFLECT:
+	    x = MOD (x, pict->width * 2);
+	    if (x >= pict->width)
+		x = pict->width * 2 - x - 1;
+	    y = MOD (y, pict->height * 2);
+	    if (y >= pict->height)
+		y = pict->height * 2 - y - 1;
+	    inside_bounds = TRUE;
+	    break;
+
 	case PIXMAN_REPEAT_NONE:
 	    inside_bounds = FALSE;
 	    break;
@@ -202,7 +211,22 @@ fetch_bilinear (bits_image_t		*pict,
 	    inside_bounds = TRUE;
 	    break;
 	    
-	case PIXMAN_REPEAT_REFLECT: /* FIXME: this should be implemented for images */
+	case PIXMAN_REPEAT_REFLECT:
+	    x1 = MOD (x1, pict->width * 2);
+	    if (x1 >= pict->width)
+		x1 = pict->width * 2 - x1 - 1;
+	    x2 = MOD (x2, pict->width * 2);
+	    if (x2 >= pict->width)
+		x2 = pict->width * 2 - x2 - 1;
+	    y1 = MOD (y1, pict->height * 2);
+	    if (y1 >= pict->height)
+		y1 = pict->height * 2 - y1 - 1;
+	    y2 = MOD (y2, pict->height * 2);
+	    if (y2 >= pict->height)
+		y2 = pict->height * 2 - y2 - 1;
+	    inside_bounds = TRUE;
+	    break;
+
 	case PIXMAN_REPEAT_NONE:
 	    inside_bounds = FALSE;
 	    break;
@@ -282,6 +306,11 @@ fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer,
                         case PIXMAN_REPEAT_PAD:
                             ty = CLIP (y, 0, pict->height-1);
                             break;
+			case PIXMAN_REPEAT_REFLECT:
+			    ty = MOD (y, pict->height * 2);
+			    if (ty >= pict->height)
+				ty = pict->height * 2 - ty - 1;
+			    break;
                         default:
                             ty = y;
                     }
@@ -295,6 +324,11 @@ fbFetchTransformed_Convolution(bits_image_t * pict, int width, uint32_t *buffer,
                                 case PIXMAN_REPEAT_PAD:
                                     tx = CLIP (x, 0, pict->width-1);
                                     break;
+				case PIXMAN_REPEAT_REFLECT:
+				    tx = MOD (x, pict->width * 2);
+				    if (tx >= pict->width)
+					tx = pict->width * 2 - tx - 1;
+				    break;
                                 default:
                                     tx = x;
                             }
-- 
1.6.0.6


--------------090107040407060406090608--


More information about the cairo mailing list