Move SourcePictClassify into pixman-image.c
authorSøren Sandmann Pedersen <sandmann@redhat.com>
Wed, 29 Apr 2009 23:55:19 +0000 (19:55 -0400)
committerSøren Sandmann Pedersen <sandmann@redhat.com>
Mon, 4 May 2009 22:55:04 +0000 (18:55 -0400)
In preparation for making pixman_image_t more of a real object, move
SourcePictClassify into pixman-image.c and expose it through a
function pointer. Later, this function will be split into smaller
functions depending on the exact type of the image.

pixman/pixman-compose.c
pixman/pixman-image.c
pixman/pixman-private.h

index 315206d..eb31617 100644 (file)
 #define PIXMAN_COMPOSITE_RECT_GENERAL pixman_composite_rect_general_no_accessors
 #endif
 
-static unsigned int
-SourcePictureClassify (source_image_t *pict,
-                      int             x,
-                      int             y,
-                      int             width,
-                      int             height)
-{
-    if (pict->common.type == SOLID)
-    {
-       pict->class = SOURCE_IMAGE_CLASS_HORIZONTAL;
-    }
-    else if (pict->common.type == LINEAR)
-    {
-       linear_gradient_t *linear = (linear_gradient_t *)pict;
-       pixman_vector_t   v;
-       pixman_fixed_32_32_t l;
-       pixman_fixed_48_16_t dx, dy, a, b, off;
-       pixman_fixed_48_16_t factors[4];
-       int          i;
-
-       dx = linear->p2.x - linear->p1.x;
-       dy = linear->p2.y - linear->p1.y;
-       l = dx * dx + dy * dy;
-       if (l)
-       {
-           a = (dx << 32) / l;
-           b = (dy << 32) / l;
-       }
-       else
-       {
-           a = b = 0;
-       }
-
-       off = (-a * linear->p1.x
-              -b * linear->p1.y) >> 16;
-
-       for (i = 0; i < 3; i++)
-       {
-           v.vector[0] = pixman_int_to_fixed ((i % 2) * (width  - 1) + x);
-           v.vector[1] = pixman_int_to_fixed ((i / 2) * (height - 1) + y);
-           v.vector[2] = pixman_fixed_1;
-
-           if (pict->common.transform)
-           {
-               if (!pixman_transform_point_3d (pict->common.transform, &v))
-                   return SOURCE_IMAGE_CLASS_UNKNOWN;
-           }
-
-           factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
-       }
-
-       if (factors[2] == factors[0])
-           pict->class = SOURCE_IMAGE_CLASS_HORIZONTAL;
-       else if (factors[1] == factors[0])
-           pict->class = SOURCE_IMAGE_CLASS_VERTICAL;
-    }
-
-    return pict->class;
-}
-
 static void fbFetchSolid(bits_image_t * pict, int x, int y, int width, uint32_t *buffer, uint32_t *mask, uint32_t maskBits)
 {
     uint32_t color;
@@ -252,9 +192,9 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbComposeData *data,
     else if (IS_SOURCE_IMAGE (data->src))
     {
        fetchSrc = get_fetch_source_pict(wide);
-       srcClass = SourcePictureClassify ((source_image_t *)data->src,
-                                         data->xSrc, data->ySrc,
-                                         data->width, data->height);
+       srcClass = _pixman_image_classify (data->src,
+                                          data->xSrc, data->ySrc,
+                                          data->width, data->height);
     }
     else
     {
@@ -291,9 +231,9 @@ PIXMAN_COMPOSITE_RECT_GENERAL (const FbComposeData *data,
        if (IS_SOURCE_IMAGE (data->mask))
        {
            fetchMask = (scanFetchProc)pixmanFetchSourcePict;
-           maskClass = SourcePictureClassify ((source_image_t *)data->mask,
-                                              data->xMask, data->yMask,
-                                              data->width, data->height);
+           maskClass = _pixman_image_classify (data->mask,
+                                               data->xMask, data->yMask,
+                                               data->width, data->height);
        }
        else
        {
index bd52f25..ec2e58e 100644 (file)
 
 #define Alpha(x) ((x) >> 24)
 
+static source_pict_class_t
+SourcePictureClassify (pixman_image_t *image,
+                      int             x,
+                      int             y,
+                      int             width,
+                      int             height)
+{
+    source_image_t *pict = &image->source;
+    
+    if (pict->class != SOURCE_IMAGE_CLASS_UNKNOWN)
+       return pict->class;
+
+    pict->class = SOURCE_IMAGE_CLASS_NEITHER;
+    
+    if (pict->common.type == SOLID)
+    {
+       pict->class = SOURCE_IMAGE_CLASS_HORIZONTAL;
+    }
+    else if (pict->common.type == LINEAR)
+    {
+       linear_gradient_t *linear = (linear_gradient_t *)pict;
+       pixman_vector_t   v;
+       pixman_fixed_32_32_t l;
+       pixman_fixed_48_16_t dx, dy, a, b, off;
+       pixman_fixed_48_16_t factors[4];
+       int          i;
+
+       dx = linear->p2.x - linear->p1.x;
+       dy = linear->p2.y - linear->p1.y;
+       l = dx * dx + dy * dy;
+       if (l)
+       {
+           a = (dx << 32) / l;
+           b = (dy << 32) / l;
+       }
+       else
+       {
+           a = b = 0;
+       }
+
+       off = (-a * linear->p1.x
+              -b * linear->p1.y) >> 16;
+
+       for (i = 0; i < 3; i++)
+       {
+           v.vector[0] = pixman_int_to_fixed ((i % 2) * (width  - 1) + x);
+           v.vector[1] = pixman_int_to_fixed ((i / 2) * (height - 1) + y);
+           v.vector[2] = pixman_fixed_1;
+
+           if (pict->common.transform)
+           {
+               if (!pixman_transform_point_3d (pict->common.transform, &v))
+                   return SOURCE_IMAGE_CLASS_UNKNOWN;
+           }
+
+           factors[i] = ((a * v.vector[0] + b * v.vector[1]) >> 16) + off;
+       }
+
+       if (factors[2] == factors[0])
+           pict->class = SOURCE_IMAGE_CLASS_HORIZONTAL;
+       else if (factors[1] == factors[0])
+           pict->class = SOURCE_IMAGE_CLASS_VERTICAL;
+    }
+
+    return pict->class;
+}
+
 static void
 init_source_image (source_image_t *image)
 {
     image->class = SOURCE_IMAGE_CLASS_UNKNOWN;
+    image->common.classify = SourcePictureClassify;
 }
 
 static pixman_bool_t
@@ -100,6 +168,19 @@ allocate_image (void)
     return image;
 }
 
+source_pict_class_t
+_pixman_image_classify (pixman_image_t *image,
+                       int             x,
+                       int             y,
+                       int             width,
+                       int             height)
+{
+    if (image->common.classify)
+       return image->common.classify (image, x, y, width, height);
+    else
+       return SOURCE_IMAGE_CLASS_NEITHER;
+}
+
 /* Ref Counting */
 PIXMAN_EXPORT pixman_image_t *
 pixman_image_ref (pixman_image_t *image)
index debd723..c2b7e44 100644 (file)
@@ -280,9 +280,22 @@ typedef enum
 {
     SOURCE_IMAGE_CLASS_UNKNOWN,
     SOURCE_IMAGE_CLASS_HORIZONTAL,
-    SOURCE_IMAGE_CLASS_VERTICAL
+    SOURCE_IMAGE_CLASS_VERTICAL,
+    SOURCE_IMAGE_CLASS_NEITHER
 } source_pict_class_t;
 
+typedef source_pict_class_t (* classify_func_t) (pixman_image_t *image,
+                                                int             x,
+                                                int             y,
+                                                int             width,
+                                                int             height);
+
+source_pict_class_t _pixman_image_classify (pixman_image_t *image,
+                                           int             x,
+                                           int             y,
+                                           int             width,
+                                           int             height);
+
 struct point
 {
     int16_t x, y;
@@ -306,6 +319,7 @@ struct image_common
     pixman_bool_t              component_alpha;
     pixman_read_memory_func_t  read_func;
     pixman_write_memory_func_t write_func;
+    classify_func_t            classify;
 };
 
 struct source_image
@@ -380,6 +394,7 @@ union pixman_image
     image_type_t               type;
     image_common_t             common;
     bits_image_t               bits;
+    source_image_t             source;
     gradient_t                 gradient;
     linear_gradient_t          linear;
     conical_gradient_t         conical;