From 7f0b18c94cf84750b097fe96aa3c8ac9e1b406e3 Mon Sep 17 00:00:00 2001 From: Soren Sandmann Pedersen Date: Fri, 4 May 2007 22:07:19 -0400 Subject: [PATCH] Add code to initialize images, based on picture.c from the X server --- pixman/Makefile.am | 9 ++- pixman/pixman-image.c | 199 +++++++++++++++++++++++++++++++++++++++++++----- pixman/pixman-private.h | 157 ++++++++++++++++++++++++++++++++++++++ pixman/pixman.h | 24 ++++++ 4 files changed, 369 insertions(+), 20 deletions(-) create mode 100644 pixman/pixman-private.h diff --git a/pixman/Makefile.am b/pixman/Makefile.am index e53d3af..ef378d5 100644 --- a/pixman/Makefile.am +++ b/pixman/Makefile.am @@ -2,9 +2,12 @@ lib_LTLIBRARIES = libpixman.la libpixman_la_LIBADD = @DEP_LIBS@ -libpixman_la_SOURCES = \ - pixman.h \ - pixman-region.c +libpixman_la_SOURCES = \ + pixman.h \ + pixman-region.c \ + pixman-private.h \ + pixman-image.c +# pixman-compose.c libpixmanincludedir = $(includedir)/libcomp libpixmaninclude_HEADERS = pixman.h diff --git a/pixman/pixman-image.c b/pixman/pixman-image.c index 9439199..dca04cd 100644 --- a/pixman/pixman-image.c +++ b/pixman/pixman-image.c @@ -21,34 +21,27 @@ * Author: Soren Sandmann, Red Hat, Inc. */ -#include "pixman.h" - -typedef struct image image_t; +#include -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 @@ -58,6 +51,178 @@ pixman_set_clip_region (pixman_image_t *image, } +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, diff --git a/pixman/pixman-private.h b/pixman/pixman-private.h new file mode 100644 index 0000000..695342c --- /dev/null +++ b/pixman/pixman-private.h @@ -0,0 +1,157 @@ +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 + diff --git a/pixman/pixman.h b/pixman/pixman.h index 233e531..09f3625 100644 --- a/pixman/pixman.h +++ b/pixman/pixman.h @@ -45,6 +45,7 @@ SOFTWARE. ******************************************************************/ /* * Copyright © 1998 Keith Packard + * Copyright 2007 Red Hat, Inc. * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that @@ -92,6 +93,10 @@ typedef unsigned __int64 uint64_t; #endif typedef int pixman_bool_t; +typedef uint32_t pixman_fixed_t; +typedef struct pixman_color pixman_color_t; +typedef struct pixman_point_fixed pixman_point_fixed_t; +typedef struct pixman_line_fixed pixman_line_fixed_t; #ifndef FALSE #define FALSE 0 @@ -101,6 +106,25 @@ typedef int pixman_bool_t; #define TRUE 1 #endif +struct pixman_color +{ + uint16_t red; + uint16_t green; + uint16_t blue; + uint16_t alpha; +}; + +struct pixman_point_fixed +{ + pixman_fixed_t x; + pixman_fixed_t y; +}; + +struct pixman_line_fixed +{ + pixman_point_fixed_t p1, p2; +}; + /* * Regions */ -- 2.7.4