gfx/cairo/libpixman/src/pixman-conical-gradient.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /*
michael@0 2 * Copyright © 2000 SuSE, Inc.
michael@0 3 * Copyright © 2007 Red Hat, Inc.
michael@0 4 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
michael@0 5 * 2005 Lars Knoll & Zack Rusin, Trolltech
michael@0 6 *
michael@0 7 * Permission to use, copy, modify, distribute, and sell this software and its
michael@0 8 * documentation for any purpose is hereby granted without fee, provided that
michael@0 9 * the above copyright notice appear in all copies and that both that
michael@0 10 * copyright notice and this permission notice appear in supporting
michael@0 11 * documentation, and that the name of Keith Packard not be used in
michael@0 12 * advertising or publicity pertaining to distribution of the software without
michael@0 13 * specific, written prior permission. Keith Packard makes no
michael@0 14 * representations about the suitability of this software for any purpose. It
michael@0 15 * is provided "as is" without express or implied warranty.
michael@0 16 *
michael@0 17 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
michael@0 18 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
michael@0 19 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
michael@0 20 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
michael@0 21 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
michael@0 22 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
michael@0 23 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
michael@0 24 * SOFTWARE.
michael@0 25 */
michael@0 26
michael@0 27 #ifdef HAVE_CONFIG_H
michael@0 28 #include <config.h>
michael@0 29 #endif
michael@0 30
michael@0 31 #include <stdlib.h>
michael@0 32 #include <math.h>
michael@0 33 #include "pixman-private.h"
michael@0 34
michael@0 35 static force_inline double
michael@0 36 coordinates_to_parameter (double x, double y, double angle)
michael@0 37 {
michael@0 38 double t;
michael@0 39
michael@0 40 t = atan2 (y, x) + angle;
michael@0 41
michael@0 42 while (t < 0)
michael@0 43 t += 2 * M_PI;
michael@0 44
michael@0 45 while (t >= 2 * M_PI)
michael@0 46 t -= 2 * M_PI;
michael@0 47
michael@0 48 return 1 - t * (1 / (2 * M_PI)); /* Scale t to [0, 1] and
michael@0 49 * make rotation CCW
michael@0 50 */
michael@0 51 }
michael@0 52
michael@0 53 static uint32_t *
michael@0 54 conical_get_scanline_narrow (pixman_iter_t *iter, const uint32_t *mask)
michael@0 55 {
michael@0 56 pixman_image_t *image = iter->image;
michael@0 57 int x = iter->x;
michael@0 58 int y = iter->y;
michael@0 59 int width = iter->width;
michael@0 60 uint32_t *buffer = iter->buffer;
michael@0 61
michael@0 62 gradient_t *gradient = (gradient_t *)image;
michael@0 63 conical_gradient_t *conical = (conical_gradient_t *)image;
michael@0 64 uint32_t *end = buffer + width;
michael@0 65 pixman_gradient_walker_t walker;
michael@0 66 pixman_bool_t affine = TRUE;
michael@0 67 double cx = 1.;
michael@0 68 double cy = 0.;
michael@0 69 double cz = 0.;
michael@0 70 double rx = x + 0.5;
michael@0 71 double ry = y + 0.5;
michael@0 72 double rz = 1.;
michael@0 73
michael@0 74 _pixman_gradient_walker_init (&walker, gradient, image->common.repeat);
michael@0 75
michael@0 76 if (image->common.transform)
michael@0 77 {
michael@0 78 pixman_vector_t v;
michael@0 79
michael@0 80 /* reference point is the center of the pixel */
michael@0 81 v.vector[0] = pixman_int_to_fixed (x) + pixman_fixed_1 / 2;
michael@0 82 v.vector[1] = pixman_int_to_fixed (y) + pixman_fixed_1 / 2;
michael@0 83 v.vector[2] = pixman_fixed_1;
michael@0 84
michael@0 85 if (!pixman_transform_point_3d (image->common.transform, &v))
michael@0 86 return iter->buffer;
michael@0 87
michael@0 88 cx = image->common.transform->matrix[0][0] / 65536.;
michael@0 89 cy = image->common.transform->matrix[1][0] / 65536.;
michael@0 90 cz = image->common.transform->matrix[2][0] / 65536.;
michael@0 91
michael@0 92 rx = v.vector[0] / 65536.;
michael@0 93 ry = v.vector[1] / 65536.;
michael@0 94 rz = v.vector[2] / 65536.;
michael@0 95
michael@0 96 affine =
michael@0 97 image->common.transform->matrix[2][0] == 0 &&
michael@0 98 v.vector[2] == pixman_fixed_1;
michael@0 99 }
michael@0 100
michael@0 101 if (affine)
michael@0 102 {
michael@0 103 rx -= conical->center.x / 65536.;
michael@0 104 ry -= conical->center.y / 65536.;
michael@0 105
michael@0 106 while (buffer < end)
michael@0 107 {
michael@0 108 if (!mask || *mask++)
michael@0 109 {
michael@0 110 double t = coordinates_to_parameter (rx, ry, conical->angle);
michael@0 111
michael@0 112 *buffer = _pixman_gradient_walker_pixel (
michael@0 113 &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
michael@0 114 }
michael@0 115
michael@0 116 ++buffer;
michael@0 117
michael@0 118 rx += cx;
michael@0 119 ry += cy;
michael@0 120 }
michael@0 121 }
michael@0 122 else
michael@0 123 {
michael@0 124 while (buffer < end)
michael@0 125 {
michael@0 126 double x, y;
michael@0 127
michael@0 128 if (!mask || *mask++)
michael@0 129 {
michael@0 130 double t;
michael@0 131
michael@0 132 if (rz != 0)
michael@0 133 {
michael@0 134 x = rx / rz;
michael@0 135 y = ry / rz;
michael@0 136 }
michael@0 137 else
michael@0 138 {
michael@0 139 x = y = 0.;
michael@0 140 }
michael@0 141
michael@0 142 x -= conical->center.x / 65536.;
michael@0 143 y -= conical->center.y / 65536.;
michael@0 144
michael@0 145 t = coordinates_to_parameter (x, y, conical->angle);
michael@0 146
michael@0 147 *buffer = _pixman_gradient_walker_pixel (
michael@0 148 &walker, (pixman_fixed_48_16_t)pixman_double_to_fixed (t));
michael@0 149 }
michael@0 150
michael@0 151 ++buffer;
michael@0 152
michael@0 153 rx += cx;
michael@0 154 ry += cy;
michael@0 155 rz += cz;
michael@0 156 }
michael@0 157 }
michael@0 158
michael@0 159 iter->y++;
michael@0 160 return iter->buffer;
michael@0 161 }
michael@0 162
michael@0 163 static uint32_t *
michael@0 164 conical_get_scanline_wide (pixman_iter_t *iter, const uint32_t *mask)
michael@0 165 {
michael@0 166 uint32_t *buffer = conical_get_scanline_narrow (iter, NULL);
michael@0 167
michael@0 168 pixman_expand_to_float (
michael@0 169 (argb_t *)buffer, buffer, PIXMAN_a8r8g8b8, iter->width);
michael@0 170
michael@0 171 return buffer;
michael@0 172 }
michael@0 173
michael@0 174 void
michael@0 175 _pixman_conical_gradient_iter_init (pixman_image_t *image, pixman_iter_t *iter)
michael@0 176 {
michael@0 177 if (iter->iter_flags & ITER_NARROW)
michael@0 178 iter->get_scanline = conical_get_scanline_narrow;
michael@0 179 else
michael@0 180 iter->get_scanline = conical_get_scanline_wide;
michael@0 181 }
michael@0 182
michael@0 183 PIXMAN_EXPORT pixman_image_t *
michael@0 184 pixman_image_create_conical_gradient (const pixman_point_fixed_t * center,
michael@0 185 pixman_fixed_t angle,
michael@0 186 const pixman_gradient_stop_t *stops,
michael@0 187 int n_stops)
michael@0 188 {
michael@0 189 pixman_image_t *image = _pixman_image_allocate ();
michael@0 190 conical_gradient_t *conical;
michael@0 191
michael@0 192 if (!image)
michael@0 193 return NULL;
michael@0 194
michael@0 195 conical = &image->conical;
michael@0 196
michael@0 197 if (!_pixman_init_gradient (&conical->common, stops, n_stops))
michael@0 198 {
michael@0 199 free (image);
michael@0 200 return NULL;
michael@0 201 }
michael@0 202
michael@0 203 angle = MOD (angle, pixman_int_to_fixed (360));
michael@0 204
michael@0 205 image->type = CONICAL;
michael@0 206
michael@0 207 conical->center = *center;
michael@0 208 conical->angle = (pixman_fixed_to_double (angle) / 180.0) * M_PI;
michael@0 209
michael@0 210 return image;
michael@0 211 }
michael@0 212

mercurial