* Author: Soren Sandmann, Red Hat, Inc.
*/
-#include "pixman.h"
-
-typedef struct image image_t;
+#include <stdlib.h>
-struct image
-{
- pixman_format_code_t format;
- int width;
- int height;
- uint8_t * bits;
- int rowstride; /* in bytes */
-};
+#include "pixman.h"
+#include "pixman-private.h"
void
pixman_image_init_bits (pixman_image_t *image,
pixman_format_code_t format,
int width,
- int height
+ int height,
uint8_t *bits,
int rowstride)
{
image_t *img = (image_t *)image;
- img->format = format;
- img->width = width;
- img->height = height;
- img->bits = bits;
- img->rowstride = rowstride;
+ img->type = BITS;
+ img->bits.format = format;
+ img->bits.width = width;
+ img->bits.height = height;
+ img->bits.bits = bits;
+ img->bits.rowstride = rowstride;
}
void
}
+enum
+{
+ PIXMAN_BAD_VALUE,
+ PIXMAN_BAD_ALLOC
+};
+
+static void
+init_source_image (source_image_t *image)
+{
+ image->class = SOURCE_IMAGE_CLASS_UNKNOWN;
+}
+
+static void
+init_gradient (gradient_t *gradient,
+ int stop_count,
+ pixman_fixed_t *stop_points,
+ pixman_color_t *stop_colors,
+ int *error)
+{
+ int i;
+ pixman_fixed_t dpos;
+
+ if (stop_count <= 0)
+ {
+ *error = PIXMAN_BAD_VALUE;
+ return;
+ }
+
+ init_source_image (&gradient->common);
+
+ dpos = -1;
+ for (i = 0; i < stop_count; ++i)
+ {
+ if (stop_points[i] < dpos || stop_points[i] > (1<<16))
+ {
+ *error = PIXMAN_BAD_VALUE;
+ return;
+ }
+ dpos = stop_points[i];
+ }
+
+ gradient->stops = malloc (stop_count * sizeof (gradient_stop_t));
+ if (!gradient->stops)
+ {
+ *error = PIXMAN_BAD_ALLOC;
+ return;
+ }
+
+ gradient->n_stops = stop_count;
+
+ for (i = 0; i < stop_count; ++i)
+ {
+ gradient->stops[i].x = stop_points[i];
+ gradient->stops[i].color = stop_colors[i];
+ }
+
+ gradient->stop_range = 0xffff;
+ gradient->color_table = NULL;
+ gradient->color_table_size = 0;
+}
+
+static uint32_t
+color_to_uint32 (const pixman_color_t *color)
+{
+ return
+ (color->alpha >> 8 << 24) |
+ (color->red >> 8 << 16) |
+ (color->green & 0xff00) |
+ (color->blue >> 8);
+}
+
+void
+pixman_image_init_solid_fill (pixman_image_t *image,
+ pixman_color_t *color,
+ int *error)
+{
+ image_t *priv = (image_t *)image;
+ priv->type = SOLID;
+ priv->solid.color = color_to_uint32 (color);
+}
+
+void
+pixman_image_init_linear_gradient (pixman_image_t *image,
+ pixman_point_fixed_t *p1,
+ pixman_point_fixed_t *p2,
+ int n_stops,
+ pixman_fixed_t *stops,
+ pixman_color_t *colors,
+ int *error)
+{
+ image_t *priv = (image_t *)image;
+ linear_gradient_t *linear = &priv->linear;
+
+ if (n_stops < 2)
+ {
+ *error = PIXMAN_BAD_VALUE;
+ return;
+ }
+
+ init_gradient (&linear->common, n_stops, stops, colors, error);
+
+ linear->p1 = *p1;
+ linear->p2 = *p2;
+
+ priv->type = LINEAR;
+}
+
+
+void
+pixman_image_init_radial_gradient (pixman_image_t *image,
+ pixman_point_fixed_t *inner,
+ pixman_point_fixed_t *outer,
+ pixman_fixed_t inner_radius,
+ pixman_fixed_t outer_radius,
+ int n_stops,
+ pixman_fixed_t *stops,
+ pixman_color_t *colors,
+ int *error)
+{
+ image_t *priv = (image_t *)image;
+ radial_gradient_t *radial = &priv->radial;
+
+ if (n_stops < 2)
+ {
+ *error = PIXMAN_BAD_VALUE;
+ return;
+ }
+
+ init_gradient (&radial->common, n_stops, stops, colors, error);
+
+ priv->type = RADIAL;
+
+ radial->c1.x = inner->x;
+ radial->c1.y = inner->y;
+ radial->c1.radius = inner_radius;
+ radial->c2.x = outer->x;
+ radial->c2.y = outer->y;
+ radial->c2.radius = outer_radius;
+ radial->cdx = (radial->c2.x - radial->c1.x) / 65536.;
+ radial->cdy = (radial->c2.y - radial->c1.y) / 65536.;
+ radial->dr = (radial->c2.radius - radial->c1.radius) / 65536.;
+ radial->A = ( radial->cdx * radial->cdx
+ + radial->cdy * radial->cdy
+ - radial->dr * radial->dr);
+}
+
+void
+pixman_image_init_conical_gradient (pixman_image_t *image,
+ pixman_point_fixed_t *center,
+ pixman_fixed_t angle,
+ int n_stops,
+ pixman_fixed_t *stops,
+ pixman_color_t *colors,
+ int *error)
+{
+ image_t *priv = (image_t *)image;
+ conical_gradient_t *conical = &priv->conical;
+
+ if (n_stops < 2)
+ {
+ *error = PIXMAN_BAD_VALUE;
+ return;
+ }
+
+ init_gradient (&conical->common, n_stops, stops, colors, error);
+
+ priv->type = CONICAL;
+ conical->center = *center;
+ conical->angle = angle;
+}
+
+#define SCANLINE_BUFFER_LENGTH 1024
void
pixman_composite (pixman_image_t *src_img,
--- /dev/null
+typedef union image image_t;
+typedef struct source_image source_image_t;
+typedef struct solid_fill solid_fill_t;
+typedef struct gradient gradient_t;
+typedef struct linear_gradient linear_gradient_t;
+typedef struct horizontal_gradient horizontal_gradient_t;
+typedef struct vertical_gradient vertical_gradient_t;
+typedef struct conical_gradient conical_gradient_t;
+typedef struct radial_gradient radial_gradient_t;
+typedef struct bits_image bits_image_t;
+typedef struct gradient_stop gradient_stop_t;
+typedef struct circle circle_t;
+
+typedef enum
+{
+ BITS,
+ LINEAR,
+ CONICAL,
+ RADIAL,
+ SOLID
+} image_type_t;
+
+struct gradient_stop
+{
+ pixman_fixed_t x;
+ pixman_color_t color;
+};
+
+typedef enum
+{
+ SOURCE_IMAGE_CLASS_UNKNOWN,
+ SOURCE_IMAGE_CLASS_HORIZONTAL,
+ SOURCE_IMAGE_CLASS_VERTICAL
+} source_pict_class_t;
+
+struct source_image
+{
+ image_type_t type;
+ unsigned int class; /* FIXME: should be an enum */
+};
+
+struct solid_fill
+{
+ source_image_t common;
+ uint32_t color; /* FIXME: shouldn't this be a pixman_color_t? */
+};
+
+struct gradient
+{
+ source_image_t common;
+ int n_stops;
+ gradient_stop_t * stops;
+ int stop_range;
+ uint32_t * color_table;
+ int color_table_size;
+};
+
+struct linear_gradient
+{
+ gradient_t common;
+ pixman_point_fixed_t p1;
+ pixman_point_fixed_t p2;
+};
+
+struct circle
+{
+ pixman_fixed_t x;
+ pixman_fixed_t y;
+ pixman_fixed_t radius;
+};
+
+struct radial_gradient
+{
+ gradient_t common;
+
+ circle_t c1;
+ circle_t c2;
+ double cdx;
+ double cdy;
+ double dr;
+ double A;
+};
+
+struct conical_gradient
+{
+ gradient_t common;
+ pixman_point_fixed_t center;
+ pixman_fixed_t angle;
+};
+
+struct bits_image
+{
+ image_type_t type;
+ pixman_format_code_t format;
+ int width;
+ int height;
+ uint8_t * bits;
+ int rowstride; /* in bytes */
+};
+
+union image
+{
+ image_type_t type;
+ bits_image_t bits;
+ linear_gradient_t linear;
+ conical_gradient_t conical;
+ radial_gradient_t radial;
+ solid_fill_t solid;
+};
+
+
+
+
+#if 0
+typedef struct _Picture {
+ DrawablePtr pDrawable;
+ PictFormatPtr pFormat;
+ PictFormatShort format; /* PICT_FORMAT */
+ int refcnt;
+ CARD32 id;
+ PicturePtr pNext; /* chain on same drawable */
+
+ unsigned int repeat : 1;
+ unsigned int graphicsExposures : 1;
+ unsigned int subWindowMode : 1;
+ unsigned int polyEdge : 1;
+ unsigned int polyMode : 1;
+ unsigned int freeCompClip : 1;
+ unsigned int clientClipType : 2;
+ unsigned int componentAlpha : 1;
+ unsigned int repeatType : 2;
+ unsigned int unused : 21;
+
+ PicturePtr alphaMap;
+ DDXPointRec alphaOrigin;
+
+ DDXPointRec clipOrigin;
+ pointer clientClip;
+
+ Atom dither;
+
+ unsigned long stateChanges;
+ unsigned long serialNumber;
+
+ RegionPtr pCompositeClip;
+
+ DevUnion *devPrivates;
+
+ PictTransform *transform;
+
+ int filter;
+ xFixed *filter_params;
+ int filter_nparams;
+ SourcePictPtr pSourcePict;
+} PictureRec;
+#endif
+