source: trunk/third/libart_lgpl/art_render_mask.c @ 18256

Revision 18256, 4.1 KB checked in by ghudson, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18255, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * art_render_mask.c: Alpha mask source for modular rendering.
3 *
4 * Libart_LGPL - library of basic graphic primitives
5 * Copyright (C) 2000 Raph Levien
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Library General Public License for more details.
16 *
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library; if not, write to the
19 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 * Boston, MA 02111-1307, USA.
21 *
22 * Authors: Raph Levien <raph@acm.org>
23 */
24
25#include "config.h"
26#include "art_render_mask.h"
27
28#include <string.h>
29
30
31typedef struct _ArtMaskSourceMask ArtMaskSourceMask;
32
33struct _ArtMaskSourceMask {
34  ArtMaskSource super;
35  ArtRender *render;
36  art_boolean first;
37  int x0;
38  int y0;
39  int x1;
40  int y1;
41  const art_u8 *mask_buf;
42  int rowstride;
43};
44
45static void
46art_render_mask_done (ArtRenderCallback *self, ArtRender *render)
47{
48  art_free (self);
49}
50
51static int
52art_render_mask_can_drive (ArtMaskSource *self, ArtRender *render)
53{
54  return 0;
55}
56
57static void
58art_render_mask_render (ArtRenderCallback *self, ArtRender *render,
59                        art_u8 *dest, int y)
60{
61  ArtMaskSourceMask *z = (ArtMaskSourceMask *)self;
62  int x0 = render->x0, x1 = render->x1;
63  int z_x0 = z->x0, z_x1 = z->x1;
64  int width = x1 - x0;
65  int z_width = z_x1 - z_x0;
66  art_u8 *alpha_buf = render->alpha_buf;
67
68  if (y < z->y0 || y >= z->y1 || z_width <= 0)
69    memset (alpha_buf, 0, width);
70  else
71    {
72      const art_u8 *src_line = z->mask_buf + (y - z->y0) * z->rowstride;
73      art_u8 *dst_line = alpha_buf + z_x0 - x0;
74
75      if (z_x0 > x0)
76        memset (alpha_buf, 0, z_x0 - x0);
77     
78      if (z->first)
79        memcpy (dst_line, src_line, z_width);
80      else
81        {
82          int x;
83         
84          for (x = 0; x < z_width; x++)
85            {
86              int v;
87              v = src_line[x];
88              if (v)
89                {
90                  v = v * dst_line[x] + 0x80;
91                  v = (v + (v >> 8)) >> 8;
92                  dst_line[x] = v;
93                }
94              else
95                {
96                  dst_line[x] = 0;
97                }
98            }
99        }
100     
101      if (z_x1 < x1)
102        memset (alpha_buf + z_x1 - x0, 0, x1 - z_x1);
103    }
104}
105
106static void
107art_render_mask_prepare (ArtMaskSource *self, ArtRender *render,
108                         art_boolean first)
109{
110  ArtMaskSourceMask *z = (ArtMaskSourceMask *)self;
111  self->super.render = art_render_mask_render;
112  z->first = first;
113}
114
115/**
116 * art_render_mask: Use an alpha buffer as a render mask source.
117 * @render: Render object.
118 * @x0: Left coordinate of mask rect.
119 * @y0: Top coordinate of mask rect.
120 * @x1: Right coordinate of mask rect.
121 * @y1: Bottom coordinate of mask rect.
122 * @mask_buf: Buffer containing 8bpp alpha mask data.
123 * @rowstride: Rowstride of @mask_buf.
124 *
125 * Adds @mask_buf to the render object as a mask. Note: @mask_buf must
126 * remain allocated until art_render_invoke() is called on @render.
127 **/
128void
129art_render_mask (ArtRender *render,
130                 int x0, int y0, int x1, int y1,
131                 const art_u8 *mask_buf, int rowstride)
132{
133  ArtMaskSourceMask *mask_source;
134
135  if (x0 < render->x0)
136    {
137      mask_buf += render->x0 - x0;
138      x0 = render->x0;
139    }
140  if (x1 > render->x1)
141    x1 = render->x1;
142
143  if (y0 < render->y0)
144    {
145      mask_buf += (render->y0 - y0) * rowstride;
146      y0 = render->y0;
147    }
148  if (y1 > render->y1)
149    y1 = render->y1;
150
151  mask_source = art_new (ArtMaskSourceMask, 1);
152
153  mask_source->super.super.render = NULL;
154  mask_source->super.super.done = art_render_mask_done;
155  mask_source->super.can_drive = art_render_mask_can_drive;
156  mask_source->super.invoke_driver = NULL;
157  mask_source->super.prepare = art_render_mask_prepare;
158  mask_source->render = render;
159  mask_source->x0 = x0;
160  mask_source->y0 = y0;
161  mask_source->x1 = x1;
162  mask_source->y1 = y1;
163  mask_source->mask_buf = mask_buf;
164  mask_source->rowstride = rowstride;
165
166  art_render_add_mask_source (render, &mask_source->super);
167
168}
Note: See TracBrowser for help on using the repository browser.