| File: | pixman/pixman-trap.c |
| Location: | line 99, column 15 |
| Description: | The right operand of '*' is a garbage value |
| 1 | /* | |||
| 2 | * Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc. | |||
| 3 | * Copyright © 2004 Keith Packard | |||
| 4 | * | |||
| 5 | * Permission to use, copy, modify, distribute, and sell this software and its | |||
| 6 | * documentation for any purpose is hereby granted without fee, provided that | |||
| 7 | * the above copyright notice appear in all copies and that both that | |||
| 8 | * copyright notice and this permission notice appear in supporting | |||
| 9 | * documentation, and that the name of Keith Packard not be used in | |||
| 10 | * advertising or publicity pertaining to distribution of the software without | |||
| 11 | * specific, written prior permission. Keith Packard makes no | |||
| 12 | * representations about the suitability of this software for any purpose. It | |||
| 13 | * is provided "as is" without express or implied warranty. | |||
| 14 | * | |||
| 15 | * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | |||
| 16 | * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | |||
| 17 | * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR | |||
| 18 | * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |||
| 19 | * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | |||
| 20 | * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | |||
| 21 | * PERFORMANCE OF THIS SOFTWARE. | |||
| 22 | */ | |||
| 23 | ||||
| 24 | #ifdef HAVE_CONFIG_H1 | |||
| 25 | #include <config.h> | |||
| 26 | #endif | |||
| 27 | ||||
| 28 | #include <stdio.h> | |||
| 29 | #include <stdlib.h> | |||
| 30 | #include "pixman-private.h" | |||
| 31 | ||||
| 32 | /* | |||
| 33 | * Compute the smallest value greater than or equal to y which is on a | |||
| 34 | * grid row. | |||
| 35 | */ | |||
| 36 | ||||
| 37 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) pixman_fixed_t | |||
| 38 | pixman_sample_ceil_y (pixman_fixed_t y, int n) | |||
| 39 | { | |||
| 40 | pixman_fixed_t f = pixman_fixed_frac (y)((y) & ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))); | |||
| 41 | pixman_fixed_t i = pixman_fixed_floor (y)((y) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))); | |||
| 42 | ||||
| 43 | f = DIV (f - Y_FRAC_FIRST (n) + (STEP_Y_SMALL (n) - pixman_fixed_e), STEP_Y_SMALL (n))((((f - (((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2) + (((((pixman_fixed_t) ((1) << 16))) / ((n ) == 1 ? 1 : (1 << ((n) / 2)) - 1)) - ((pixman_fixed_t) 1))) < 0) == ((((((pixman_fixed_t) ((1) << 16))) / ( (n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) < 0)) ? (f - ( ((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2) + (((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : ( 1 << ((n) / 2)) - 1)) - ((pixman_fixed_t) 1))) / (((((pixman_fixed_t ) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2) ) - 1))) : ((f - (((((pixman_fixed_t) ((1) << 16))) - ( ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t ) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2) ) - 1))) / 2) + (((((pixman_fixed_t) ((1) << 16))) / (( n) == 1 ? 1 : (1 << ((n) / 2)) - 1)) - ((pixman_fixed_t ) 1))) - (((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) + 1 - (((((((pixman_fixed_t ) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2) ) - 1))) < 0) << 1)) / (((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)))) * STEP_Y_SMALL (n)((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)) + | |||
| 44 | Y_FRAC_FIRST (n)(((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : ( 1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2); | |||
| 45 | ||||
| 46 | if (f > Y_FRAC_LAST (n)((((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : ( 1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2) + (((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t ) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2) ) - 1)))) | |||
| 47 | { | |||
| 48 | if (pixman_fixed_to_int (i)((int) ((i) >> 16)) == 0x7fff) | |||
| 49 | { | |||
| 50 | f = 0xffff; /* saturate */ | |||
| 51 | } | |||
| 52 | else | |||
| 53 | { | |||
| 54 | f = Y_FRAC_FIRST (n)(((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : ( 1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2); | |||
| 55 | i += pixman_fixed_1(((pixman_fixed_t) ((1) << 16))); | |||
| 56 | } | |||
| 57 | } | |||
| 58 | return (i | f); | |||
| 59 | } | |||
| 60 | ||||
| 61 | /* | |||
| 62 | * Compute the largest value strictly less than y which is on a | |||
| 63 | * grid row. | |||
| 64 | */ | |||
| 65 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) pixman_fixed_t | |||
| 66 | pixman_sample_floor_y (pixman_fixed_t y, | |||
| 67 | int n) | |||
| 68 | { | |||
| 69 | pixman_fixed_t f = pixman_fixed_frac (y)((y) & ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))); | |||
| 70 | pixman_fixed_t i = pixman_fixed_floor (y)((y) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))); | |||
| 71 | ||||
| 72 | f = DIV (f - pixman_fixed_e - Y_FRAC_FIRST (n), STEP_Y_SMALL (n))((((f - ((pixman_fixed_t) 1) - (((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ( (((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2)) < 0) == ((((((pixman_fixed_t) ((1 ) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1 ))) < 0)) ? (f - ((pixman_fixed_t) 1) - (((((pixman_fixed_t ) ((1) << 16))) - (((n) == 1 ? 1 : (1 << ((n) / 2 )) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2)) / (((((pixman_fixed_t ) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2) ) - 1))) : ((f - ((pixman_fixed_t) 1) - (((((pixman_fixed_t) ( (1) << 16))) - (((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2)) - (((((pixman_fixed_t ) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2) ) - 1))) + 1 - (((((((pixman_fixed_t) ((1) << 16))) / ( (n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) < 0) << 1)) / (((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)))) * STEP_Y_SMALL (n)((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)) + | |||
| 73 | Y_FRAC_FIRST (n)(((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : ( 1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2); | |||
| 74 | ||||
| 75 | if (f < Y_FRAC_FIRST (n)(((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : ( 1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2)) | |||
| 76 | { | |||
| 77 | if (pixman_fixed_to_int (i)((int) ((i) >> 16)) == 0x8000) | |||
| 78 | { | |||
| 79 | f = 0; /* saturate */ | |||
| 80 | } | |||
| 81 | else | |||
| 82 | { | |||
| 83 | f = Y_FRAC_LAST (n)((((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : ( 1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))) / 2) + (((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t ) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2) ) - 1))); | |||
| 84 | i -= pixman_fixed_1(((pixman_fixed_t) ((1) << 16))); | |||
| 85 | } | |||
| 86 | } | |||
| 87 | return (i | f); | |||
| 88 | } | |||
| 89 | ||||
| 90 | /* | |||
| 91 | * Step an edge by any amount (including negative values) | |||
| 92 | */ | |||
| 93 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 94 | pixman_edge_step (pixman_edge_t *e, | |||
| 95 | int n) | |||
| 96 | { | |||
| 97 | pixman_fixed_48_16_t ne; | |||
| 98 | ||||
| 99 | e->x += n * e->stepx; | |||
| ||||
| 100 | ||||
| 101 | ne = e->e + n * (pixman_fixed_48_16_t) e->dx; | |||
| 102 | ||||
| 103 | if (n >= 0) | |||
| 104 | { | |||
| 105 | if (ne > 0) | |||
| 106 | { | |||
| 107 | int nx = (ne + e->dy - 1) / e->dy; | |||
| 108 | e->e = ne - nx * (pixman_fixed_48_16_t) e->dy; | |||
| 109 | e->x += nx * e->signdx; | |||
| 110 | } | |||
| 111 | } | |||
| 112 | else | |||
| 113 | { | |||
| 114 | if (ne <= -e->dy) | |||
| 115 | { | |||
| 116 | int nx = (-ne) / e->dy; | |||
| 117 | e->e = ne + nx * (pixman_fixed_48_16_t) e->dy; | |||
| 118 | e->x -= nx * e->signdx; | |||
| 119 | } | |||
| 120 | } | |||
| 121 | } | |||
| 122 | ||||
| 123 | /* | |||
| 124 | * A private routine to initialize the multi-step | |||
| 125 | * elements of an edge structure | |||
| 126 | */ | |||
| 127 | static void | |||
| 128 | _pixman_edge_multi_init (pixman_edge_t * e, | |||
| 129 | int n, | |||
| 130 | pixman_fixed_t *stepx_p, | |||
| 131 | pixman_fixed_t *dx_p) | |||
| 132 | { | |||
| 133 | pixman_fixed_t stepx; | |||
| 134 | pixman_fixed_48_16_t ne; | |||
| 135 | ||||
| 136 | ne = n * (pixman_fixed_48_16_t) e->dx; | |||
| 137 | stepx = n * e->stepx; | |||
| 138 | ||||
| 139 | if (ne > 0) | |||
| 140 | { | |||
| 141 | int nx = ne / e->dy; | |||
| 142 | ne -= nx * (pixman_fixed_48_16_t)e->dy; | |||
| 143 | stepx += nx * e->signdx; | |||
| 144 | } | |||
| 145 | ||||
| 146 | *dx_p = ne; | |||
| 147 | *stepx_p = stepx; | |||
| 148 | } | |||
| 149 | ||||
| 150 | /* | |||
| 151 | * Initialize one edge structure given the line endpoints and a | |||
| 152 | * starting y value | |||
| 153 | */ | |||
| 154 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 155 | pixman_edge_init (pixman_edge_t *e, | |||
| 156 | int n, | |||
| 157 | pixman_fixed_t y_start, | |||
| 158 | pixman_fixed_t x_top, | |||
| 159 | pixman_fixed_t y_top, | |||
| 160 | pixman_fixed_t x_bot, | |||
| 161 | pixman_fixed_t y_bot) | |||
| 162 | { | |||
| 163 | pixman_fixed_t dx, dy; | |||
| 164 | ||||
| 165 | e->x = x_top; | |||
| 166 | e->e = 0; | |||
| 167 | dx = x_bot - x_top; | |||
| 168 | dy = y_bot - y_top; | |||
| 169 | e->dy = dy; | |||
| 170 | e->dx = 0; | |||
| 171 | ||||
| 172 | if (dy) | |||
| 173 | { | |||
| 174 | if (dx >= 0) | |||
| 175 | { | |||
| 176 | e->signdx = 1; | |||
| 177 | e->stepx = dx / dy; | |||
| 178 | e->dx = dx % dy; | |||
| 179 | e->e = -dy; | |||
| 180 | } | |||
| 181 | else | |||
| 182 | { | |||
| 183 | e->signdx = -1; | |||
| 184 | e->stepx = -(-dx / dy); | |||
| 185 | e->dx = -dx % dy; | |||
| 186 | e->e = 0; | |||
| 187 | } | |||
| 188 | ||||
| 189 | _pixman_edge_multi_init (e, STEP_Y_SMALL (n)((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1)), | |||
| 190 | &e->stepx_small, &e->dx_small); | |||
| 191 | ||||
| 192 | _pixman_edge_multi_init (e, STEP_Y_BIG (n)((((pixman_fixed_t) ((1) << 16))) - (((n) == 1 ? 1 : (1 << ((n) / 2)) - 1) - 1) * ((((pixman_fixed_t) ((1) << 16))) / ((n) == 1 ? 1 : (1 << ((n) / 2)) - 1))), | |||
| 193 | &e->stepx_big, &e->dx_big); | |||
| 194 | } | |||
| 195 | pixman_edge_step (e, y_start - y_top); | |||
| 196 | } | |||
| 197 | ||||
| 198 | /* | |||
| 199 | * Initialize one edge structure given a line, starting y value | |||
| 200 | * and a pixel offset for the line | |||
| 201 | */ | |||
| 202 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 203 | pixman_line_fixed_edge_init (pixman_edge_t * e, | |||
| 204 | int n, | |||
| 205 | pixman_fixed_t y, | |||
| 206 | const pixman_line_fixed_t *line, | |||
| 207 | int x_off, | |||
| 208 | int y_off) | |||
| 209 | { | |||
| 210 | pixman_fixed_t x_off_fixed = pixman_int_to_fixed (x_off)((pixman_fixed_t) ((x_off) << 16)); | |||
| 211 | pixman_fixed_t y_off_fixed = pixman_int_to_fixed (y_off)((pixman_fixed_t) ((y_off) << 16)); | |||
| 212 | const pixman_point_fixed_t *top, *bot; | |||
| 213 | ||||
| 214 | if (line->p1.y <= line->p2.y) | |||
| 215 | { | |||
| 216 | top = &line->p1; | |||
| 217 | bot = &line->p2; | |||
| 218 | } | |||
| 219 | else | |||
| 220 | { | |||
| 221 | top = &line->p2; | |||
| 222 | bot = &line->p1; | |||
| 223 | } | |||
| 224 | ||||
| 225 | pixman_edge_init (e, n, y, | |||
| 226 | top->x + x_off_fixed, | |||
| 227 | top->y + y_off_fixed, | |||
| 228 | bot->x + x_off_fixed, | |||
| 229 | bot->y + y_off_fixed); | |||
| 230 | } | |||
| 231 | ||||
| 232 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 233 | pixman_add_traps (pixman_image_t * image, | |||
| 234 | int16_t x_off, | |||
| 235 | int16_t y_off, | |||
| 236 | int ntrap, | |||
| 237 | const pixman_trap_t *traps) | |||
| 238 | { | |||
| 239 | int bpp; | |||
| 240 | int height; | |||
| 241 | ||||
| 242 | pixman_fixed_t x_off_fixed; | |||
| 243 | pixman_fixed_t y_off_fixed; | |||
| 244 | pixman_edge_t l, r; | |||
| 245 | pixman_fixed_t t, b; | |||
| 246 | ||||
| 247 | _pixman_image_validate (image); | |||
| 248 | ||||
| 249 | height = image->bits.height; | |||
| 250 | bpp = PIXMAN_FORMAT_BPP (image->bits.format)(((image->bits.format) >> 24) ); | |||
| 251 | ||||
| 252 | x_off_fixed = pixman_int_to_fixed (x_off)((pixman_fixed_t) ((x_off) << 16)); | |||
| 253 | y_off_fixed = pixman_int_to_fixed (y_off)((pixman_fixed_t) ((y_off) << 16)); | |||
| 254 | ||||
| 255 | while (ntrap--) | |||
| ||||
| 256 | { | |||
| 257 | t = traps->top.y + y_off_fixed; | |||
| 258 | if (t < 0) | |||
| 259 | t = 0; | |||
| 260 | t = pixman_sample_ceil_y (t, bpp); | |||
| 261 | ||||
| 262 | b = traps->bot.y + y_off_fixed; | |||
| 263 | if (pixman_fixed_to_int (b)((int) ((b) >> 16)) >= height) | |||
| 264 | b = pixman_int_to_fixed (height)((pixman_fixed_t) ((height) << 16)) - 1; | |||
| 265 | b = pixman_sample_floor_y (b, bpp); | |||
| 266 | ||||
| 267 | if (b >= t) | |||
| 268 | { | |||
| 269 | /* initialize edge walkers */ | |||
| 270 | pixman_edge_init (&l, bpp, t, | |||
| 271 | traps->top.l + x_off_fixed, | |||
| 272 | traps->top.y + y_off_fixed, | |||
| 273 | traps->bot.l + x_off_fixed, | |||
| 274 | traps->bot.y + y_off_fixed); | |||
| 275 | ||||
| 276 | pixman_edge_init (&r, bpp, t, | |||
| 277 | traps->top.r + x_off_fixed, | |||
| 278 | traps->top.y + y_off_fixed, | |||
| 279 | traps->bot.r + x_off_fixed, | |||
| 280 | traps->bot.y + y_off_fixed); | |||
| 281 | ||||
| 282 | pixman_rasterize_edges (image, &l, &r, t, b); | |||
| 283 | } | |||
| 284 | ||||
| 285 | traps++; | |||
| 286 | } | |||
| 287 | } | |||
| 288 | ||||
| 289 | #if 0 | |||
| 290 | static void | |||
| 291 | dump_image (pixman_image_t *image, | |||
| 292 | const char * title) | |||
| 293 | { | |||
| 294 | int i, j; | |||
| 295 | ||||
| 296 | if (!image->type == BITS) | |||
| 297 | printf ("%s is not a regular image\n", title); | |||
| 298 | ||||
| 299 | if (!image->bits.format == PIXMAN_a8) | |||
| 300 | printf ("%s is not an alpha mask\n", title); | |||
| 301 | ||||
| 302 | printf ("\n\n\n%s: \n", title); | |||
| 303 | ||||
| 304 | for (i = 0; i < image->bits.height; ++i) | |||
| 305 | { | |||
| 306 | uint8_t *line = | |||
| 307 | (uint8_t *)&(image->bits.bits[i * image->bits.rowstride]); | |||
| 308 | ||||
| 309 | for (j = 0; j < image->bits.width; ++j) | |||
| 310 | printf ("%c", line[j] ? '#' : ' '); | |||
| 311 | ||||
| 312 | printf ("\n"); | |||
| 313 | } | |||
| 314 | } | |||
| 315 | #endif | |||
| 316 | ||||
| 317 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 318 | pixman_add_trapezoids (pixman_image_t * image, | |||
| 319 | int16_t x_off, | |||
| 320 | int y_off, | |||
| 321 | int ntraps, | |||
| 322 | const pixman_trapezoid_t *traps) | |||
| 323 | { | |||
| 324 | int i; | |||
| 325 | ||||
| 326 | #if 0 | |||
| 327 | dump_image (image, "before"); | |||
| 328 | #endif | |||
| 329 | ||||
| 330 | for (i = 0; i < ntraps; ++i) | |||
| 331 | { | |||
| 332 | const pixman_trapezoid_t *trap = &(traps[i]); | |||
| 333 | ||||
| 334 | if (!pixman_trapezoid_valid (trap)((trap)->left.p1.y != (trap)->left.p2.y && (trap )->right.p1.y != (trap)->right.p2.y && ((trap)-> bottom > (trap)->top))) | |||
| 335 | continue; | |||
| 336 | ||||
| 337 | pixman_rasterize_trapezoid (image, trap, x_off, y_off); | |||
| 338 | } | |||
| 339 | ||||
| 340 | #if 0 | |||
| 341 | dump_image (image, "after"); | |||
| 342 | #endif | |||
| 343 | } | |||
| 344 | ||||
| 345 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 346 | pixman_rasterize_trapezoid (pixman_image_t * image, | |||
| 347 | const pixman_trapezoid_t *trap, | |||
| 348 | int x_off, | |||
| 349 | int y_off) | |||
| 350 | { | |||
| 351 | int bpp; | |||
| 352 | int height; | |||
| 353 | ||||
| 354 | pixman_fixed_t y_off_fixed; | |||
| 355 | pixman_edge_t l, r; | |||
| 356 | pixman_fixed_t t, b; | |||
| 357 | ||||
| 358 | return_if_fail (image->type == BITS)do { if (__builtin_expect ((!(image->type == BITS)), 0)) { _pixman_log_error (((const char*) (__PRETTY_FUNCTION__)), "The expression " "image->type == BITS" " was false"); return; } } while (0 ); | |||
| 359 | ||||
| 360 | _pixman_image_validate (image); | |||
| 361 | ||||
| 362 | if (!pixman_trapezoid_valid (trap)((trap)->left.p1.y != (trap)->left.p2.y && (trap )->right.p1.y != (trap)->right.p2.y && ((trap)-> bottom > (trap)->top))) | |||
| 363 | return; | |||
| 364 | ||||
| 365 | height = image->bits.height; | |||
| 366 | bpp = PIXMAN_FORMAT_BPP (image->bits.format)(((image->bits.format) >> 24) ); | |||
| 367 | ||||
| 368 | y_off_fixed = pixman_int_to_fixed (y_off)((pixman_fixed_t) ((y_off) << 16)); | |||
| 369 | ||||
| 370 | t = trap->top + y_off_fixed; | |||
| 371 | if (t < 0) | |||
| 372 | t = 0; | |||
| 373 | t = pixman_sample_ceil_y (t, bpp); | |||
| 374 | ||||
| 375 | b = trap->bottom + y_off_fixed; | |||
| 376 | if (pixman_fixed_to_int (b)((int) ((b) >> 16)) >= height) | |||
| 377 | b = pixman_int_to_fixed (height)((pixman_fixed_t) ((height) << 16)) - 1; | |||
| 378 | b = pixman_sample_floor_y (b, bpp); | |||
| 379 | ||||
| 380 | if (b >= t) | |||
| 381 | { | |||
| 382 | /* initialize edge walkers */ | |||
| 383 | pixman_line_fixed_edge_init (&l, bpp, t, &trap->left, x_off, y_off); | |||
| 384 | pixman_line_fixed_edge_init (&r, bpp, t, &trap->right, x_off, y_off); | |||
| 385 | ||||
| 386 | pixman_rasterize_edges (image, &l, &r, t, b); | |||
| 387 | } | |||
| 388 | } | |||
| 389 | ||||
| 390 | static const pixman_bool_t zero_src_has_no_effect[PIXMAN_N_OPERATORS] = | |||
| 391 | { | |||
| 392 | FALSE0, /* Clear 0 0 */ | |||
| 393 | FALSE0, /* Src 1 0 */ | |||
| 394 | TRUE1, /* Dst 0 1 */ | |||
| 395 | TRUE1, /* Over 1 1-Aa */ | |||
| 396 | TRUE1, /* OverReverse 1-Ab 1 */ | |||
| 397 | FALSE0, /* In Ab 0 */ | |||
| 398 | FALSE0, /* InReverse 0 Aa */ | |||
| 399 | FALSE0, /* Out 1-Ab 0 */ | |||
| 400 | TRUE1, /* OutReverse 0 1-Aa */ | |||
| 401 | TRUE1, /* Atop Ab 1-Aa */ | |||
| 402 | FALSE0, /* AtopReverse 1-Ab Aa */ | |||
| 403 | TRUE1, /* Xor 1-Ab 1-Aa */ | |||
| 404 | TRUE1, /* Add 1 1 */ | |||
| 405 | }; | |||
| 406 | ||||
| 407 | static pixman_bool_t | |||
| 408 | get_trap_extents (pixman_op_t op, pixman_image_t *dest, | |||
| 409 | const pixman_trapezoid_t *traps, int n_traps, | |||
| 410 | pixman_box32_t *box) | |||
| 411 | { | |||
| 412 | int i; | |||
| 413 | ||||
| 414 | /* When the operator is such that a zero source has an | |||
| 415 | * effect on the underlying image, we have to | |||
| 416 | * composite across the entire destination | |||
| 417 | */ | |||
| 418 | if (!zero_src_has_no_effect [op]) | |||
| 419 | { | |||
| 420 | box->x1 = 0; | |||
| 421 | box->y1 = 0; | |||
| 422 | box->x2 = dest->bits.width; | |||
| 423 | box->y2 = dest->bits.height; | |||
| 424 | return TRUE1; | |||
| 425 | } | |||
| 426 | ||||
| 427 | box->x1 = INT32_MAX2147483647; | |||
| 428 | box->y1 = INT32_MAX2147483647; | |||
| 429 | box->x2 = INT32_MIN(-2147483647 -1); | |||
| 430 | box->y2 = INT32_MIN(-2147483647 -1); | |||
| 431 | ||||
| 432 | for (i = 0; i < n_traps; ++i) | |||
| 433 | { | |||
| 434 | const pixman_trapezoid_t *trap = &(traps[i]); | |||
| 435 | int y1, y2; | |||
| 436 | ||||
| 437 | if (!pixman_trapezoid_valid (trap)((trap)->left.p1.y != (trap)->left.p2.y && (trap )->right.p1.y != (trap)->right.p2.y && ((trap)-> bottom > (trap)->top))) | |||
| 438 | continue; | |||
| 439 | ||||
| 440 | y1 = pixman_fixed_to_int (trap->top)((int) ((trap->top) >> 16)); | |||
| 441 | if (y1 < box->y1) | |||
| 442 | box->y1 = y1; | |||
| 443 | ||||
| 444 | y2 = pixman_fixed_to_int (pixman_fixed_ceil (trap->bottom))((int) (((((trap->bottom) + ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t) (( 1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)); | |||
| 445 | if (y2 > box->y2) | |||
| 446 | box->y2 = y2; | |||
| 447 | ||||
| 448 | #define EXTEND_MIN(x)if (((int) (((x)) >> 16)) < box->x1) box->x1 = ((int) (((x)) >> 16)); \ | |||
| 449 | if (pixman_fixed_to_int ((x))((int) (((x)) >> 16)) < box->x1) \ | |||
| 450 | box->x1 = pixman_fixed_to_int ((x))((int) (((x)) >> 16)); | |||
| 451 | #define EXTEND_MAX(x)if (((int) ((((((x)) + ((((pixman_fixed_t) ((1) << 16)) ) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2 ) box->x2 = ((int) ((((((x)) + ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t) (( 1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)); \ | |||
| 452 | if (pixman_fixed_to_int (pixman_fixed_ceil ((x)))((int) ((((((x)) + ((((pixman_fixed_t) ((1) << 16))) - ( (pixman_fixed_t) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2) \ | |||
| 453 | box->x2 = pixman_fixed_to_int (pixman_fixed_ceil ((x)))((int) ((((((x)) + ((((pixman_fixed_t) ((1) << 16))) - ( (pixman_fixed_t) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)); | |||
| 454 | ||||
| 455 | #define EXTEND(x)if (((int) (((x)) >> 16)) < box->x1) box->x1 = ((int) (((x)) >> 16));; if (((int) ((((((x)) + ((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2) box->x2 = ((int) ((((((x)) + ((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) ;; \ | |||
| 456 | EXTEND_MIN(x)if (((int) (((x)) >> 16)) < box->x1) box->x1 = ((int) (((x)) >> 16));; \ | |||
| 457 | EXTEND_MAX(x)if (((int) ((((((x)) + ((((pixman_fixed_t) ((1) << 16)) ) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2 ) box->x2 = ((int) ((((((x)) + ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t) (( 1) << 16))) - ((pixman_fixed_t) 1)))) >> 16));; | |||
| 458 | ||||
| 459 | EXTEND(trap->left.p1.x)if (((int) (((trap->left.p1.x)) >> 16)) < box-> x1) box->x1 = ((int) (((trap->left.p1.x)) >> 16)) ;; if (((int) ((((((trap->left.p1.x)) + ((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2) box->x2 = ((int) ((((((trap->left.p1. x)) + ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1)))) >> 16));;; | |||
| 460 | EXTEND(trap->left.p2.x)if (((int) (((trap->left.p2.x)) >> 16)) < box-> x1) box->x1 = ((int) (((trap->left.p2.x)) >> 16)) ;; if (((int) ((((((trap->left.p2.x)) + ((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2) box->x2 = ((int) ((((((trap->left.p2. x)) + ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1)))) >> 16));;; | |||
| 461 | EXTEND(trap->right.p1.x)if (((int) (((trap->right.p1.x)) >> 16)) < box-> x1) box->x1 = ((int) (((trap->right.p1.x)) >> 16) );; if (((int) ((((((trap->right.p1.x)) + ((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2) box->x2 = ((int) ((((((trap->right.p1 .x)) + ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1)))) >> 16));;; | |||
| 462 | EXTEND(trap->right.p2.x)if (((int) (((trap->right.p2.x)) >> 16)) < box-> x1) box->x1 = ((int) (((trap->right.p2.x)) >> 16) );; if (((int) ((((((trap->right.p2.x)) + ((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1))) & ~((((pixman_fixed_t ) ((1) << 16))) - ((pixman_fixed_t) 1)))) >> 16)) > box->x2) box->x2 = ((int) ((((((trap->right.p2 .x)) + ((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1))) & ~((((pixman_fixed_t) ((1) << 16))) - ((pixman_fixed_t ) 1)))) >> 16));;; | |||
| 463 | } | |||
| 464 | ||||
| 465 | if (box->x1 >= box->x2 || box->y1 >= box->y2) | |||
| 466 | return FALSE0; | |||
| 467 | ||||
| 468 | return TRUE1; | |||
| 469 | } | |||
| 470 | ||||
| 471 | /* | |||
| 472 | * pixman_composite_trapezoids() | |||
| 473 | * | |||
| 474 | * All the trapezoids are conceptually rendered to an infinitely big image. | |||
| 475 | * The (0, 0) coordinates of this image are then aligned with the (x, y) | |||
| 476 | * coordinates of the source image, and then both images are aligned with | |||
| 477 | * the (x, y) coordinates of the destination. Then these three images are | |||
| 478 | * composited across the entire destination. | |||
| 479 | */ | |||
| 480 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 481 | pixman_composite_trapezoids (pixman_op_t op, | |||
| 482 | pixman_image_t * src, | |||
| 483 | pixman_image_t * dst, | |||
| 484 | pixman_format_code_t mask_format, | |||
| 485 | int x_src, | |||
| 486 | int y_src, | |||
| 487 | int x_dst, | |||
| 488 | int y_dst, | |||
| 489 | int n_traps, | |||
| 490 | const pixman_trapezoid_t * traps) | |||
| 491 | { | |||
| 492 | int i; | |||
| 493 | ||||
| 494 | return_if_fail (PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A)do { if (__builtin_expect ((!((((mask_format) >> 16) & 0xff) == 1)), 0)) { _pixman_log_error (((const char*) (__PRETTY_FUNCTION__ )), "The expression " "PIXMAN_FORMAT_TYPE (mask_format) == PIXMAN_TYPE_A" " was false"); return; } } while (0); | |||
| 495 | ||||
| 496 | if (n_traps <= 0) | |||
| 497 | return; | |||
| 498 | ||||
| 499 | _pixman_image_validate (src); | |||
| 500 | _pixman_image_validate (dst); | |||
| 501 | ||||
| 502 | if (op == PIXMAN_OP_ADD && | |||
| 503 | (src->common.flags & FAST_PATH_IS_OPAQUE(1 << 13)) && | |||
| 504 | (mask_format == dst->common.extended_format_code) && | |||
| 505 | !(dst->common.have_clip_region)) | |||
| 506 | { | |||
| 507 | for (i = 0; i < n_traps; ++i) | |||
| 508 | { | |||
| 509 | const pixman_trapezoid_t *trap = &(traps[i]); | |||
| 510 | ||||
| 511 | if (!pixman_trapezoid_valid (trap)((trap)->left.p1.y != (trap)->left.p2.y && (trap )->right.p1.y != (trap)->right.p2.y && ((trap)-> bottom > (trap)->top))) | |||
| 512 | continue; | |||
| 513 | ||||
| 514 | pixman_rasterize_trapezoid (dst, trap, x_dst, y_dst); | |||
| 515 | } | |||
| 516 | } | |||
| 517 | else | |||
| 518 | { | |||
| 519 | pixman_image_t *tmp; | |||
| 520 | pixman_box32_t box; | |||
| 521 | int i; | |||
| 522 | ||||
| 523 | if (!get_trap_extents (op, dst, traps, n_traps, &box)) | |||
| 524 | return; | |||
| 525 | ||||
| 526 | if (!(tmp = pixman_image_create_bits ( | |||
| 527 | mask_format, box.x2 - box.x1, box.y2 - box.y1, NULL((void*)0), -1))) | |||
| 528 | return; | |||
| 529 | ||||
| 530 | for (i = 0; i < n_traps; ++i) | |||
| 531 | { | |||
| 532 | const pixman_trapezoid_t *trap = &(traps[i]); | |||
| 533 | ||||
| 534 | if (!pixman_trapezoid_valid (trap)((trap)->left.p1.y != (trap)->left.p2.y && (trap )->right.p1.y != (trap)->right.p2.y && ((trap)-> bottom > (trap)->top))) | |||
| 535 | continue; | |||
| 536 | ||||
| 537 | pixman_rasterize_trapezoid (tmp, trap, - box.x1, - box.y1); | |||
| 538 | } | |||
| 539 | ||||
| 540 | pixman_image_composite (op, src, tmp, dst, | |||
| 541 | x_src + box.x1, y_src + box.y1, | |||
| 542 | 0, 0, | |||
| 543 | x_dst + box.x1, y_dst + box.y1, | |||
| 544 | box.x2 - box.x1, box.y2 - box.y1); | |||
| 545 | ||||
| 546 | pixman_image_unref (tmp); | |||
| 547 | } | |||
| 548 | } | |||
| 549 | ||||
| 550 | static int | |||
| 551 | greater_y (const pixman_point_fixed_t *a, const pixman_point_fixed_t *b) | |||
| 552 | { | |||
| 553 | if (a->y == b->y) | |||
| 554 | return a->x > b->x; | |||
| 555 | return a->y > b->y; | |||
| 556 | } | |||
| 557 | ||||
| 558 | /* | |||
| 559 | * Note that the definition of this function is a bit odd because | |||
| 560 | * of the X coordinate space (y increasing downwards). | |||
| 561 | */ | |||
| 562 | static int | |||
| 563 | clockwise (const pixman_point_fixed_t *ref, | |||
| 564 | const pixman_point_fixed_t *a, | |||
| 565 | const pixman_point_fixed_t *b) | |||
| 566 | { | |||
| 567 | pixman_point_fixed_t ad, bd; | |||
| 568 | ||||
| 569 | ad.x = a->x - ref->x; | |||
| 570 | ad.y = a->y - ref->y; | |||
| 571 | bd.x = b->x - ref->x; | |||
| 572 | bd.y = b->y - ref->y; | |||
| 573 | ||||
| 574 | return ((pixman_fixed_32_32_t) bd.y * ad.x - | |||
| 575 | (pixman_fixed_32_32_t) ad.y * bd.x) < 0; | |||
| 576 | } | |||
| 577 | ||||
| 578 | static void | |||
| 579 | triangle_to_trapezoids (const pixman_triangle_t *tri, pixman_trapezoid_t *traps) | |||
| 580 | { | |||
| 581 | const pixman_point_fixed_t *top, *left, *right, *tmp; | |||
| 582 | ||||
| 583 | top = &tri->p1; | |||
| 584 | left = &tri->p2; | |||
| 585 | right = &tri->p3; | |||
| 586 | ||||
| 587 | if (greater_y (top, left)) | |||
| 588 | { | |||
| 589 | tmp = left; | |||
| 590 | left = top; | |||
| 591 | top = tmp; | |||
| 592 | } | |||
| 593 | ||||
| 594 | if (greater_y (top, right)) | |||
| 595 | { | |||
| 596 | tmp = right; | |||
| 597 | right = top; | |||
| 598 | top = tmp; | |||
| 599 | } | |||
| 600 | ||||
| 601 | if (clockwise (top, right, left)) | |||
| 602 | { | |||
| 603 | tmp = right; | |||
| 604 | right = left; | |||
| 605 | left = tmp; | |||
| 606 | } | |||
| 607 | ||||
| 608 | /* | |||
| 609 | * Two cases: | |||
| 610 | * | |||
| 611 | * + + | |||
| 612 | * / \ / \ | |||
| 613 | * / \ / \ | |||
| 614 | * / + + \ | |||
| 615 | * / -- -- \ | |||
| 616 | * / -- -- \ | |||
| 617 | * / --- --- \ | |||
| 618 | * +-- --+ | |||
| 619 | */ | |||
| 620 | ||||
| 621 | traps->top = top->y; | |||
| 622 | traps->left.p1 = *top; | |||
| 623 | traps->left.p2 = *left; | |||
| 624 | traps->right.p1 = *top; | |||
| 625 | traps->right.p2 = *right; | |||
| 626 | ||||
| 627 | if (right->y < left->y) | |||
| 628 | traps->bottom = right->y; | |||
| 629 | else | |||
| 630 | traps->bottom = left->y; | |||
| 631 | ||||
| 632 | traps++; | |||
| 633 | ||||
| 634 | *traps = *(traps - 1); | |||
| 635 | ||||
| 636 | if (right->y < left->y) | |||
| 637 | { | |||
| 638 | traps->top = right->y; | |||
| 639 | traps->bottom = left->y; | |||
| 640 | traps->right.p1 = *right; | |||
| 641 | traps->right.p2 = *left; | |||
| 642 | } | |||
| 643 | else | |||
| 644 | { | |||
| 645 | traps->top = left->y; | |||
| 646 | traps->bottom = right->y; | |||
| 647 | traps->left.p1 = *left; | |||
| 648 | traps->left.p2 = *right; | |||
| 649 | } | |||
| 650 | } | |||
| 651 | ||||
| 652 | static pixman_trapezoid_t * | |||
| 653 | convert_triangles (int n_tris, const pixman_triangle_t *tris) | |||
| 654 | { | |||
| 655 | pixman_trapezoid_t *traps; | |||
| 656 | int i; | |||
| 657 | ||||
| 658 | if (n_tris <= 0) | |||
| 659 | return NULL((void*)0); | |||
| 660 | ||||
| 661 | traps = pixman_malloc_ab (n_tris, 2 * sizeof (pixman_trapezoid_t)); | |||
| 662 | if (!traps) | |||
| 663 | return NULL((void*)0); | |||
| 664 | ||||
| 665 | for (i = 0; i < n_tris; ++i) | |||
| 666 | triangle_to_trapezoids (&(tris[i]), traps + 2 * i); | |||
| 667 | ||||
| 668 | return traps; | |||
| 669 | } | |||
| 670 | ||||
| 671 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 672 | pixman_composite_triangles (pixman_op_t op, | |||
| 673 | pixman_image_t * src, | |||
| 674 | pixman_image_t * dst, | |||
| 675 | pixman_format_code_t mask_format, | |||
| 676 | int x_src, | |||
| 677 | int y_src, | |||
| 678 | int x_dst, | |||
| 679 | int y_dst, | |||
| 680 | int n_tris, | |||
| 681 | const pixman_triangle_t * tris) | |||
| 682 | { | |||
| 683 | pixman_trapezoid_t *traps; | |||
| 684 | ||||
| 685 | if ((traps = convert_triangles (n_tris, tris))) | |||
| 686 | { | |||
| 687 | pixman_composite_trapezoids (op, src, dst, mask_format, | |||
| 688 | x_src, y_src, x_dst, y_dst, | |||
| 689 | n_tris * 2, traps); | |||
| 690 | ||||
| 691 | free (traps); | |||
| 692 | } | |||
| 693 | } | |||
| 694 | ||||
| 695 | PIXMAN_EXPORT__attribute__ ((visibility("default"))) void | |||
| 696 | pixman_add_triangles (pixman_image_t *image, | |||
| 697 | int32_t x_off, | |||
| 698 | int32_t y_off, | |||
| 699 | int n_tris, | |||
| 700 | const pixman_triangle_t *tris) | |||
| 701 | { | |||
| 702 | pixman_trapezoid_t *traps; | |||
| 703 | ||||
| 704 | if ((traps = convert_triangles (n_tris, tris))) | |||
| 705 | { | |||
| 706 | pixman_add_trapezoids (image, x_off, y_off, | |||
| 707 | n_tris * 2, traps); | |||
| 708 | ||||
| 709 | free (traps); | |||
| 710 | } | |||
| 711 | } |