1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * art_rgba_svp.c: A slightly modified version of art_rgb_svp to render into rgba buffer
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public License
7 * as published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * Raph Levien <raph@acm.org>
21 * Lauris Kaplinski <lauris@ariman.ee>
23 * Copyright (C) 1998 Raph Levien
27 #define SP_ART_RGBA_SVP_C
29 /* Render a sorted vector path into an RGBA buffer. */
31 #include <libart_lgpl/art_misc.h>
32 #include <libart_lgpl/art_svp.h>
33 #include <libart_lgpl/art_svp_render_aa.h>
34 #include <libart_lgpl/art_rgb.h>
36 #include "art_rgba_svp.h"
38 static void art_rgba_fill_run (art_u8 * linebuf, art_u8 r, art_u8 g, art_u8 b, int n);
39 static void art_rgba_run_alpha (art_u8 * linebuf, art_u8 r, art_u8 g, art_u8 b, int alpha, int n);
41 typedef struct _ArtRgbaSVPAlphaData ArtRgbaSVPAlphaData;
43 struct _ArtRgbaSVPAlphaData {
45 art_u8 r, g, b, alpha;
52 art_rgba_svp_alpha_callback (void *callback_data, int y,
53 int start, ArtSVPRenderAAStep *steps, int n_steps)
55 ArtRgbaSVPAlphaData *data = callback_data;
58 art_u32 running_sum = start;
72 alphatab = data->alphatab;
79 alpha = (running_sum >> 16) & 0xff;
81 art_rgba_run_alpha (linebuf,
82 r, g, b, alphatab[alpha],
86 /* render the steps into tmpbuf */
87 for (k = 0; k < n_steps - 1; k++)
89 running_sum += steps[k].delta;
91 run_x1 = steps[k + 1].x;
94 alpha = (running_sum >> 16) & 0xff;
96 art_rgba_run_alpha (linebuf + (run_x0 - x0) * 4,
97 r, g, b, alphatab[alpha],
101 running_sum += steps[k].delta;
104 alpha = (running_sum >> 16) & 0xff;
106 art_rgba_run_alpha (linebuf + (run_x1 - x0) * 4,
107 r, g, b, alphatab[alpha],
113 alpha = (running_sum >> 16) & 0xff;
115 art_rgba_run_alpha (linebuf,
116 r, g, b, alphatab[alpha],
120 data->buf += data->rowstride;
124 art_rgba_svp_alpha_opaque_callback (void *callback_data, int y,
126 ArtSVPRenderAAStep *steps, int n_steps)
128 ArtRgbaSVPAlphaData *data = callback_data;
131 art_u32 running_sum = start;
145 alphatab = data->alphatab;
152 alpha = running_sum >> 16;
156 art_rgba_fill_run (linebuf,
160 art_rgba_run_alpha (linebuf,
161 r, g, b, alphatab[alpha],
166 /* render the steps into tmpbuf */
167 for (k = 0; k < n_steps - 1; k++)
169 running_sum += steps[k].delta;
171 run_x1 = steps[k + 1].x;
174 alpha = running_sum >> 16;
178 art_rgba_fill_run (linebuf + (run_x0 - x0) * 4,
182 art_rgba_run_alpha (linebuf + (run_x0 - x0) * 4,
183 r, g, b, alphatab[alpha],
188 running_sum += steps[k].delta;
191 alpha = running_sum >> 16;
195 art_rgba_fill_run (linebuf + (run_x1 - x0) * 4,
199 art_rgba_run_alpha (linebuf + (run_x1 - x0) * 4,
200 r, g, b, alphatab[alpha],
207 alpha = running_sum >> 16;
211 art_rgba_fill_run (linebuf,
215 art_rgba_run_alpha (linebuf,
216 r, g, b, alphatab[alpha],
221 data->buf += data->rowstride;
225 * gnome_print_art_rgba_svp_alpha: Alpha-composite sorted vector path over RGBA buffer.
226 * @svp: The source sorted vector path.
227 * @x0: Left coordinate of destination rectangle.
228 * @y0: Top coordinate of destination rectangle.
229 * @x1: Right coordinate of destination rectangle.
230 * @y1: Bottom coordinate of destination rectangle.
231 * @rgba: Color in 0xRRGGBBAA format.
232 * @buf: Destination RGB buffer.
233 * @rowstride: Rowstride of @buf buffer.
234 * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
236 * Renders the shape specified with @svp over the @buf RGB buffer.
237 * @x1 - @x0 specifies the width, and @y1 - @y0 specifies the height,
238 * of the rectangle rendered. The new pixels are stored starting at
239 * the first byte of @buf. Thus, the @x0 and @y0 parameters specify
240 * an offset within @svp, and may be tweaked as a way of doing
241 * integer-pixel translations without fiddling with @svp itself.
243 * The @rgba argument specifies the color for the rendering. Pixels of
244 * entirely 0 winding number are left untouched. Pixels of entirely
245 * 1 winding number have the color @rgba composited over them (ie,
246 * are replaced by the red, green, blue components of @rgba if the alpha
247 * component is 0xff). Pixels of intermediate coverage are interpolated
248 * according to the rule in @alphagamma, or default to linear if
249 * @alphagamma is NULL.
252 gnome_print_art_rgba_svp_alpha (const ArtSVP *svp,
253 int x0, int y0, int x1, int y1,
255 art_u8 *buf, int rowstride,
256 ArtAlphaGamma *alphagamma)
258 ArtRgbaSVPAlphaData data;
264 g = (rgba >> 16) & 0xff;
265 b = (rgba >> 8) & 0xff;
274 da = (alpha * 66051 + 0x80) >> 8; /* 66051 equals 2 ^ 32 / (255 * 255) */
276 for (i = 0; i < 256; i++)
278 data.alphatab[i] = a >> 16;
283 data.rowstride = rowstride;
287 art_svp_render_aa (svp, x0, y0, x1, y1, art_rgba_svp_alpha_opaque_callback,
290 art_svp_render_aa (svp, x0, y0, x1, y1, art_rgba_svp_alpha_callback, &data);
294 art_rgba_fill_run (art_u8 * buf, art_u8 r, art_u8 g, art_u8 b, int n)
298 for (i = 0; i < n; i++) {
309 art_rgba_run_alpha (art_u8 * buf, art_u8 r, art_u8 g, art_u8 b, int alpha, int n)
315 for (i = 0; i < n; i++) {
321 cr = (br * ba + 0x80) >> 8;
322 cg = (bg * ba + 0x80) >> 8;
323 cb = (bb * ba + 0x80) >> 8;
325 * buf++ = cr + (((r - cr) * alpha + 0x80) >> 8);
326 * buf++ = cg + (((g - cg) * alpha + 0x80) >> 8);
327 * buf++ = cb + (((b - cb) * alpha + 0x80) >> 8);
328 * buf++ = ba + (((255 - ba) * alpha + 0x80) >> 8);