1 /* Libart_LGPL - library of basic graphic primitives
2 * Copyright (C) 1998 Raph Levien
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 /* Render a sorted vector path into an RGB buffer. */
23 #include "art_rgb_svp.h"
26 #include "art_svp_render_aa.h"
29 typedef struct _ArtRgbSVPData ArtRgbSVPData;
30 typedef struct _ArtRgbSVPAlphaData ArtRgbSVPAlphaData;
32 struct _ArtRgbSVPData {
39 struct _ArtRgbSVPAlphaData {
41 art_u8 r, g, b, alpha;
48 art_rgb_svp_callback (void *callback_data, int y,
49 int start, ArtSVPRenderAAStep *steps, int n_steps)
51 ArtRgbSVPData *data = (ArtRgbSVPData *)callback_data;
54 art_u32 running_sum = start;
68 rgb = data->rgbtab[(running_sum >> 16) & 0xff];
69 art_rgb_fill_run (linebuf,
70 rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
74 for (k = 0; k < n_steps - 1; k++)
76 running_sum += steps[k].delta;
78 run_x1 = steps[k + 1].x;
81 rgb = data->rgbtab[(running_sum >> 16) & 0xff];
82 art_rgb_fill_run (linebuf + (run_x0 - x0) * 3,
83 rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
87 running_sum += steps[k].delta;
90 rgb = data->rgbtab[(running_sum >> 16) & 0xff];
91 art_rgb_fill_run (linebuf + (run_x1 - x0) * 3,
92 rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
98 rgb = data->rgbtab[(running_sum >> 16) & 0xff];
99 art_rgb_fill_run (linebuf,
100 rgb >> 16, (rgb >> 8) & 0xff, rgb & 0xff,
104 data->buf += data->rowstride;
107 /* Render the vector path into the RGB buffer. */
110 * art_rgb_svp_aa: Render sorted vector path into RGB buffer.
111 * @svp: The source sorted vector path.
112 * @x0: Left coordinate of destination rectangle.
113 * @y0: Top coordinate of destination rectangle.
114 * @x1: Right coordinate of destination rectangle.
115 * @y1: Bottom coordinate of destination rectangle.
116 * @fg_color: Foreground color in 0xRRGGBB format.
117 * @bg_color: Background color in 0xRRGGBB format.
118 * @buf: Destination RGB buffer.
119 * @rowstride: Rowstride of @buf buffer.
120 * @alphagamma: #ArtAlphaGamma for gamma-correcting the rendering.
122 * Renders the shape specified with @svp into the @buf RGB buffer.
123 * @x1 - @x0 specifies the width, and @y1 - @y0 specifies the height,
124 * of the rectangle rendered. The new pixels are stored starting at
125 * the first byte of @buf. Thus, the @x0 and @y0 parameters specify
126 * an offset within @svp, and may be tweaked as a way of doing
127 * integer-pixel translations without fiddling with @svp itself.
129 * The @fg_color and @bg_color arguments specify the opaque colors to
130 * be used for rendering. For pixels of entirely 0 winding-number,
131 * @bg_color is used. For pixels of entirely 1 winding number,
132 * @fg_color is used. In between, the color is interpolated based on
133 * the fraction of the pixel with a winding number of 1. If
134 * @alphagamma is NULL, then linear interpolation (in pixel counts) is
135 * the default. Otherwise, the interpolation is as specified by
139 art_rgb_svp_aa (const ArtSVP *svp,
140 int x0, int y0, int x1, int y1,
141 art_u32 fg_color, art_u32 bg_color,
142 art_u8 *buf, int rowstride,
143 ArtAlphaGamma *alphagamma)
147 int r_fg, g_fg, b_fg;
148 int r_bg, g_bg, b_bg;
153 if (alphagamma == NULL)
155 r_fg = fg_color >> 16;
156 g_fg = (fg_color >> 8) & 0xff;
157 b_fg = fg_color & 0xff;
159 r_bg = bg_color >> 16;
160 g_bg = (bg_color >> 8) & 0xff;
161 b_bg = bg_color & 0xff;
163 r = (r_bg << 16) + 0x8000;
164 g = (g_bg << 16) + 0x8000;
165 b = (b_bg << 16) + 0x8000;
166 dr = ((r_fg - r_bg) << 16) / 255;
167 dg = ((g_fg - g_bg) << 16) / 255;
168 db = ((b_fg - b_bg) << 16) / 255;
170 for (i = 0; i < 256; i++)
172 data.rgbtab[i] = (r & 0xff0000) | ((g & 0xff0000) >> 8) | (b >> 16);
183 table = alphagamma->table;
185 r_fg = table[fg_color >> 16];
186 g_fg = table[(fg_color >> 8) & 0xff];
187 b_fg = table[fg_color & 0xff];
189 r_bg = table[bg_color >> 16];
190 g_bg = table[(bg_color >> 8) & 0xff];
191 b_bg = table[bg_color & 0xff];
193 r = (r_bg << 16) + 0x8000;
194 g = (g_bg << 16) + 0x8000;
195 b = (b_bg << 16) + 0x8000;
196 dr = ((r_fg - r_bg) << 16) / 255;
197 dg = ((g_fg - g_bg) << 16) / 255;
198 db = ((b_fg - b_bg) << 16) / 255;
200 invtab = alphagamma->invtable;
201 for (i = 0; i < 256; i++)
203 data.rgbtab[i] = (invtab[r >> 16] << 16) |
204 (invtab[g >> 16] << 8) |
212 data.rowstride = rowstride;
215 art_svp_render_aa (svp, x0, y0, x1, y1, art_rgb_svp_callback, &data);
219 art_rgb_svp_alpha_callback (void *callback_data, int y,
220 int start, ArtSVPRenderAAStep *steps, int n_steps)
222 ArtRgbSVPAlphaData *data = (ArtRgbSVPAlphaData *)callback_data;
225 art_u32 running_sum = start;
239 alphatab = data->alphatab;
246 alpha = (running_sum >> 16) & 0xff;
248 art_rgb_run_alpha (linebuf,
249 r, g, b, alphatab[alpha],
253 for (k = 0; k < n_steps - 1; k++)
255 running_sum += steps[k].delta;
257 run_x1 = steps[k + 1].x;
260 alpha = (running_sum >> 16) & 0xff;
262 art_rgb_run_alpha (linebuf + (run_x0 - x0) * 3,
263 r, g, b, alphatab[alpha],
267 running_sum += steps[k].delta;
270 alpha = (running_sum >> 16) & 0xff;
272 art_rgb_run_alpha (linebuf + (run_x1 - x0) * 3,
273 r, g, b, alphatab[alpha],
279 alpha = (running_sum >> 16) & 0xff;
281 art_rgb_run_alpha (linebuf,
282 r, g, b, alphatab[alpha],
286 data->buf += data->rowstride;
290 art_rgb_svp_alpha_opaque_callback (void *callback_data, int y,
292 ArtSVPRenderAAStep *steps, int n_steps)
294 ArtRgbSVPAlphaData *data = (ArtRgbSVPAlphaData *)callback_data;
297 art_u32 running_sum = start;
311 alphatab = data->alphatab;
318 alpha = running_sum >> 16;
322 art_rgb_fill_run (linebuf,
326 art_rgb_run_alpha (linebuf,
327 r, g, b, alphatab[alpha],
332 for (k = 0; k < n_steps - 1; k++)
334 running_sum += steps[k].delta;
336 run_x1 = steps[k + 1].x;
339 alpha = running_sum >> 16;
343 art_rgb_fill_run (linebuf + (run_x0 - x0) * 3,
347 art_rgb_run_alpha (linebuf + (run_x0 - x0) * 3,
348 r, g, b, alphatab[alpha],
353 running_sum += steps[k].delta;
356 alpha = running_sum >> 16;
360 art_rgb_fill_run (linebuf + (run_x1 - x0) * 3,
364 art_rgb_run_alpha (linebuf + (run_x1 - x0) * 3,
365 r, g, b, alphatab[alpha],
372 alpha = running_sum >> 16;
376 art_rgb_fill_run (linebuf,
380 art_rgb_run_alpha (linebuf,
381 r, g, b, alphatab[alpha],
386 data->buf += data->rowstride;
390 * art_rgb_svp_alpha: Alpha-composite sorted vector path over RGB buffer.
391 * @svp: The source sorted vector path.
392 * @x0: Left coordinate of destination rectangle.
393 * @y0: Top coordinate of destination rectangle.
394 * @x1: Right coordinate of destination rectangle.
395 * @y1: Bottom coordinate of destination rectangle.
396 * @rgba: Color in 0xRRGGBBAA format.
397 * @buf: Destination RGB buffer.
398 * @rowstride: Rowstride of @buf buffer.
399 * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
401 * Renders the shape specified with @svp over the @buf RGB buffer.
402 * @x1 - @x0 specifies the width, and @y1 - @y0 specifies the height,
403 * of the rectangle rendered. The new pixels are stored starting at
404 * the first byte of @buf. Thus, the @x0 and @y0 parameters specify
405 * an offset within @svp, and may be tweaked as a way of doing
406 * integer-pixel translations without fiddling with @svp itself.
408 * The @rgba argument specifies the color for the rendering. Pixels of
409 * entirely 0 winding number are left untouched. Pixels of entirely
410 * 1 winding number have the color @rgba composited over them (ie,
411 * are replaced by the red, green, blue components of @rgba if the alpha
412 * component is 0xff). Pixels of intermediate coverage are interpolated
413 * according to the rule in @alphagamma, or default to linear if
414 * @alphagamma is NULL.
417 art_rgb_svp_alpha (const ArtSVP *svp,
418 int x0, int y0, int x1, int y1,
420 art_u8 *buf, int rowstride,
421 ArtAlphaGamma *alphagamma)
423 ArtRgbSVPAlphaData data;
429 g = (rgba >> 16) & 0xff;
430 b = (rgba >> 8) & 0xff;
439 da = (alpha * 66051 + 0x80) >> 8; /* 66051 equals 2 ^ 32 / (255 * 255) */
441 for (i = 0; i < 256; i++)
443 data.alphatab[i] = a >> 16;
448 data.rowstride = rowstride;
452 art_svp_render_aa (svp, x0, y0, x1, y1, art_rgb_svp_alpha_opaque_callback,
455 art_svp_render_aa (svp, x0, y0, x1, y1, art_rgb_svp_alpha_callback, &data);