gfx/cairo/libpixman/src/pixman-gradient-walker.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 *
michael@0 3 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc.
michael@0 4 * 2005 Lars Knoll & Zack Rusin, Trolltech
michael@0 5 *
michael@0 6 * Permission to use, copy, modify, distribute, and sell this software and its
michael@0 7 * documentation for any purpose is hereby granted without fee, provided that
michael@0 8 * the above copyright notice appear in all copies and that both that
michael@0 9 * copyright notice and this permission notice appear in supporting
michael@0 10 * documentation, and that the name of Keith Packard not be used in
michael@0 11 * advertising or publicity pertaining to distribution of the software without
michael@0 12 * specific, written prior permission. Keith Packard makes no
michael@0 13 * representations about the suitability of this software for any purpose. It
michael@0 14 * is provided "as is" without express or implied warranty.
michael@0 15 *
michael@0 16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
michael@0 17 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
michael@0 18 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
michael@0 19 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
michael@0 20 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
michael@0 21 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
michael@0 22 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
michael@0 23 * SOFTWARE.
michael@0 24 */
michael@0 25
michael@0 26 #ifdef HAVE_CONFIG_H
michael@0 27 #include <config.h>
michael@0 28 #endif
michael@0 29 #include "pixman-private.h"
michael@0 30
michael@0 31 void
michael@0 32 _pixman_gradient_walker_init (pixman_gradient_walker_t *walker,
michael@0 33 gradient_t * gradient,
michael@0 34 pixman_repeat_t repeat)
michael@0 35 {
michael@0 36 walker->num_stops = gradient->n_stops;
michael@0 37 walker->stops = gradient->stops;
michael@0 38 walker->left_x = 0;
michael@0 39 walker->right_x = 0x10000;
michael@0 40 walker->stepper = 0;
michael@0 41 walker->left_ag = 0;
michael@0 42 walker->left_rb = 0;
michael@0 43 walker->right_ag = 0;
michael@0 44 walker->right_rb = 0;
michael@0 45 walker->repeat = repeat;
michael@0 46
michael@0 47 walker->need_reset = TRUE;
michael@0 48 }
michael@0 49
michael@0 50 static void
michael@0 51 gradient_walker_reset (pixman_gradient_walker_t *walker,
michael@0 52 pixman_fixed_48_16_t pos)
michael@0 53 {
michael@0 54 int32_t x, left_x, right_x;
michael@0 55 pixman_color_t *left_c, *right_c;
michael@0 56 int n, count = walker->num_stops;
michael@0 57 pixman_gradient_stop_t *stops = walker->stops;
michael@0 58
michael@0 59 if (walker->repeat == PIXMAN_REPEAT_NORMAL)
michael@0 60 {
michael@0 61 x = (int32_t)pos & 0xffff;
michael@0 62 }
michael@0 63 else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
michael@0 64 {
michael@0 65 x = (int32_t)pos & 0xffff;
michael@0 66 if ((int32_t)pos & 0x10000)
michael@0 67 x = 0x10000 - x;
michael@0 68 }
michael@0 69 else
michael@0 70 {
michael@0 71 x = pos;
michael@0 72 }
michael@0 73
michael@0 74 for (n = 0; n < count; n++)
michael@0 75 {
michael@0 76 if (x < stops[n].x)
michael@0 77 break;
michael@0 78 }
michael@0 79
michael@0 80 left_x = stops[n - 1].x;
michael@0 81 left_c = &stops[n - 1].color;
michael@0 82
michael@0 83 right_x = stops[n].x;
michael@0 84 right_c = &stops[n].color;
michael@0 85
michael@0 86 if (walker->repeat == PIXMAN_REPEAT_NORMAL)
michael@0 87 {
michael@0 88 left_x += (pos - x);
michael@0 89 right_x += (pos - x);
michael@0 90 }
michael@0 91 else if (walker->repeat == PIXMAN_REPEAT_REFLECT)
michael@0 92 {
michael@0 93 if ((int32_t)pos & 0x10000)
michael@0 94 {
michael@0 95 pixman_color_t *tmp_c;
michael@0 96 int32_t tmp_x;
michael@0 97
michael@0 98 tmp_x = 0x10000 - right_x;
michael@0 99 right_x = 0x10000 - left_x;
michael@0 100 left_x = tmp_x;
michael@0 101
michael@0 102 tmp_c = right_c;
michael@0 103 right_c = left_c;
michael@0 104 left_c = tmp_c;
michael@0 105
michael@0 106 x = 0x10000 - x;
michael@0 107 }
michael@0 108 left_x += (pos - x);
michael@0 109 right_x += (pos - x);
michael@0 110 }
michael@0 111 else if (walker->repeat == PIXMAN_REPEAT_NONE)
michael@0 112 {
michael@0 113 if (n == 0)
michael@0 114 right_c = left_c;
michael@0 115 else if (n == count)
michael@0 116 left_c = right_c;
michael@0 117 }
michael@0 118
michael@0 119 walker->left_x = left_x;
michael@0 120 walker->right_x = right_x;
michael@0 121 walker->left_ag = ((left_c->alpha >> 8) << 16) | (left_c->green >> 8);
michael@0 122 walker->left_rb = ((left_c->red & 0xff00) << 8) | (left_c->blue >> 8);
michael@0 123 walker->right_ag = ((right_c->alpha >> 8) << 16) | (right_c->green >> 8);
michael@0 124 walker->right_rb = ((right_c->red & 0xff00) << 8) | (right_c->blue >> 8);
michael@0 125
michael@0 126 if (walker->left_x == walker->right_x ||
michael@0 127 (walker->left_ag == walker->right_ag &&
michael@0 128 walker->left_rb == walker->right_rb))
michael@0 129 {
michael@0 130 walker->stepper = 0;
michael@0 131 }
michael@0 132 else
michael@0 133 {
michael@0 134 int32_t width = right_x - left_x;
michael@0 135 walker->stepper = ((1 << 24) + width / 2) / width;
michael@0 136 }
michael@0 137
michael@0 138 walker->need_reset = FALSE;
michael@0 139 }
michael@0 140
michael@0 141 uint32_t
michael@0 142 _pixman_gradient_walker_pixel (pixman_gradient_walker_t *walker,
michael@0 143 pixman_fixed_48_16_t x)
michael@0 144 {
michael@0 145 int dist, idist;
michael@0 146 uint32_t t1, t2, a, color;
michael@0 147
michael@0 148 if (walker->need_reset || x < walker->left_x || x >= walker->right_x)
michael@0 149 gradient_walker_reset (walker, x);
michael@0 150
michael@0 151 dist = ((int)(x - walker->left_x) * walker->stepper) >> 16;
michael@0 152 idist = 256 - dist;
michael@0 153
michael@0 154 /* combined INTERPOLATE and premultiply */
michael@0 155 t1 = walker->left_rb * idist + walker->right_rb * dist;
michael@0 156 t1 = (t1 >> 8) & 0xff00ff;
michael@0 157
michael@0 158 t2 = walker->left_ag * idist + walker->right_ag * dist;
michael@0 159 t2 &= 0xff00ff00;
michael@0 160
michael@0 161 color = t2 & 0xff000000;
michael@0 162 a = t2 >> 24;
michael@0 163
michael@0 164 t1 = t1 * a + 0x800080;
michael@0 165 t1 = (t1 + ((t1 >> 8) & 0xff00ff)) >> 8;
michael@0 166
michael@0 167 t2 = (t2 >> 8) * a + 0x800080;
michael@0 168 t2 = (t2 + ((t2 >> 8) & 0xff00ff));
michael@0 169
michael@0 170 return (color | (t1 & 0xff00ff) | (t2 & 0xff00));
michael@0 171 }
michael@0 172

mercurial