w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

pixman-edge.c
Go to the documentation of this file.
1 /*
2  * Copyright © 2004 Keith Packard
3  *
4  * Permission to use, copy, modify, distribute, and sell this software and its
5  * documentation for any purpose is hereby granted without fee, provided that
6  * the above copyright notice appear in all copies and that both that
7  * copyright notice and this permission notice appear in supporting
8  * documentation, and that the name of Keith Packard not be used in
9  * advertising or publicity pertaining to distribution of the software without
10  * specific, written prior permission. Keith Packard makes no
11  * representations about the suitability of this software for any purpose. It
12  * is provided "as is" without express or implied warranty.
13  *
14  * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16  * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20  * PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include <string.h>
28 
29 #include "pixman-private.h"
30 #include "pixman-accessor.h"
31 
32 /*
33  * Step across a small sample grid gap
34  */
35 #define RENDER_EDGE_STEP_SMALL(edge) \
36  { \
37  edge->x += edge->stepx_small; \
38  edge->e += edge->dx_small; \
39  if (edge->e > 0) \
40  { \
41  edge->e -= edge->dy; \
42  edge->x += edge->signdx; \
43  } \
44  }
45 
46 /*
47  * Step across a large sample grid gap
48  */
49 #define RENDER_EDGE_STEP_BIG(edge) \
50  { \
51  edge->x += edge->stepx_big; \
52  edge->e += edge->dx_big; \
53  if (edge->e > 0) \
54  { \
55  edge->e -= edge->dy; \
56  edge->x += edge->signdx; \
57  } \
58  }
59 
60 #ifdef PIXMAN_FB_ACCESSORS
61 #define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_accessors
62 #else
63 #define PIXMAN_RASTERIZE_EDGES pixman_rasterize_edges_no_accessors
64 #endif
65 
66 /*
67  * 4 bit alpha
68  */
69 
70 #define N_BITS 4
71 #define RASTERIZE_EDGES rasterize_edges_4
72 
73 #ifndef WORDS_BIGENDIAN
74 #define SHIFT_4(o) ((o) << 2)
75 #else
76 #define SHIFT_4(o) ((1 - (o)) << 2)
77 #endif
78 
79 #define GET_4(x, o) (((x) >> SHIFT_4 (o)) & 0xf)
80 #define PUT_4(x, o, v) \
81  (((x) & ~(0xf << SHIFT_4 (o))) | (((v) & 0xf) << SHIFT_4 (o)))
82 
83 #define DEFINE_ALPHA(line, x) \
84  uint8_t *__ap = (uint8_t *) line + ((x) >> 1); \
85  int __ao = (x) & 1
86 
87 #define STEP_ALPHA ((__ap += __ao), (__ao ^= 1))
88 
89 #define ADD_ALPHA(a) \
90  { \
91  uint8_t __o = READ (image, __ap); \
92  uint8_t __a = (a) + GET_4 (__o, __ao); \
93  WRITE (image, __ap, PUT_4 (__o, __ao, __a | (0 - ((__a) >> 4)))); \
94  }
95 
96 #include "pixman-edge-imp.h"
97 
98 #undef ADD_ALPHA
99 #undef STEP_ALPHA
100 #undef DEFINE_ALPHA
101 #undef RASTERIZE_EDGES
102 #undef N_BITS
103 
104 
105 /*
106  * 1 bit alpha
107  */
108 
109 #define N_BITS 1
110 #define RASTERIZE_EDGES rasterize_edges_1
111 
112 #include "pixman-edge-imp.h"
113 
114 #undef RASTERIZE_EDGES
115 #undef N_BITS
116 
117 /*
118  * 8 bit alpha
119  */
120 
121 static force_inline uint8_t
122 clip255 (int x)
123 {
124  if (x > 255)
125  return 255;
126 
127  return x;
128 }
129 
130 #define ADD_SATURATE_8(buf, val, length) \
131  do \
132  { \
133  int i__ = (length); \
134  uint8_t *buf__ = (buf); \
135  int val__ = (val); \
136  \
137  while (i__--) \
138  { \
139  WRITE (image, (buf__), clip255 (READ (image, (buf__)) + (val__))); \
140  (buf__)++; \
141  } \
142  } while (0)
143 
144 /*
145  * We want to detect the case where we add the same value to a long
146  * span of pixels. The triangles on the end are filled in while we
147  * count how many sub-pixel scanlines contribute to the middle section.
148  *
149  * +--------------------------+
150  * fill_height =| \ /
151  * +------------------+
152  * |================|
153  * fill_start fill_end
154  */
155 static void
157  pixman_edge_t * l,
158  pixman_edge_t * r,
161 {
162  pixman_fixed_t y = t;
163  uint32_t *line;
164  int fill_start = -1, fill_end = -1;
165  int fill_size = 0;
166  uint32_t *buf = (image)->bits.bits;
167  int stride = (image)->bits.rowstride;
168  int width = (image)->bits.width;
169 
171 
172  for (;;)
173  {
174  uint8_t *ap = (uint8_t *) line;
175  pixman_fixed_t lx, rx;
176  int lxi, rxi;
177 
178  /* clip X */
179  lx = l->x;
180  if (lx < 0)
181  lx = 0;
182 
183  rx = r->x;
184 
185  if (pixman_fixed_to_int (rx) >= width)
186  {
187  /* Use the last pixel of the scanline, covered 100%.
188  * We can't use the first pixel following the scanline,
189  * because accessing it could result in a buffer overrun.
190  */
191  rx = pixman_int_to_fixed (width) - 1;
192  }
193 
194  /* Skip empty (or backwards) sections */
195  if (rx > lx)
196  {
197  int lxs, rxs;
198 
199  /* Find pixel bounds for span. */
200  lxi = pixman_fixed_to_int (lx);
201  rxi = pixman_fixed_to_int (rx);
202 
203  /* Sample coverage for edge pixels */
204  lxs = RENDER_SAMPLES_X (lx, 8);
205  rxs = RENDER_SAMPLES_X (rx, 8);
206 
207  /* Add coverage across row */
208  if (lxi == rxi)
209  {
210  WRITE (image, ap + lxi,
211  clip255 (READ (image, ap + lxi) + rxs - lxs));
212  }
213  else
214  {
215  WRITE (image, ap + lxi,
216  clip255 (READ (image, ap + lxi) + N_X_FRAC (8) - lxs));
217 
218  /* Move forward so that lxi/rxi is the pixel span */
219  lxi++;
220 
221  /* Don't bother trying to optimize the fill unless
222  * the span is longer than 4 pixels. */
223  if (rxi - lxi > 4)
224  {
225  if (fill_start < 0)
226  {
227  fill_start = lxi;
228  fill_end = rxi;
229  fill_size++;
230  }
231  else
232  {
233  if (lxi >= fill_end || rxi < fill_start)
234  {
235  /* We're beyond what we saved, just fill it */
236  ADD_SATURATE_8 (ap + fill_start,
237  fill_size * N_X_FRAC (8),
238  fill_end - fill_start);
239  fill_start = lxi;
240  fill_end = rxi;
241  fill_size = 1;
242  }
243  else
244  {
245  /* Update fill_start */
246  if (lxi > fill_start)
247  {
248  ADD_SATURATE_8 (ap + fill_start,
249  fill_size * N_X_FRAC (8),
250  lxi - fill_start);
251  fill_start = lxi;
252  }
253  else if (lxi < fill_start)
254  {
255  ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8),
256  fill_start - lxi);
257  }
258 
259  /* Update fill_end */
260  if (rxi < fill_end)
261  {
262  ADD_SATURATE_8 (ap + rxi,
263  fill_size * N_X_FRAC (8),
264  fill_end - rxi);
265  fill_end = rxi;
266  }
267  else if (fill_end < rxi)
268  {
269  ADD_SATURATE_8 (ap + fill_end,
270  N_X_FRAC (8),
271  rxi - fill_end);
272  }
273  fill_size++;
274  }
275  }
276  }
277  else
278  {
279  ADD_SATURATE_8 (ap + lxi, N_X_FRAC (8), rxi - lxi);
280  }
281 
282  WRITE (image, ap + rxi, clip255 (READ (image, ap + rxi) + rxs));
283  }
284  }
285 
286  if (y == b)
287  {
288  /* We're done, make sure we clean up any remaining fill. */
289  if (fill_start != fill_end)
290  {
291  if (fill_size == N_Y_FRAC (8))
292  {
293  MEMSET_WRAPPED (image, ap + fill_start,
294  0xff, fill_end - fill_start);
295  }
296  else
297  {
298  ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
299  fill_end - fill_start);
300  }
301  }
302  break;
303  }
304 
305  if (pixman_fixed_frac (y) != Y_FRAC_LAST (8))
306  {
309  y += STEP_Y_SMALL (8);
310  }
311  else
312  {
315  y += STEP_Y_BIG (8);
316  if (fill_start != fill_end)
317  {
318  if (fill_size == N_Y_FRAC (8))
319  {
320  MEMSET_WRAPPED (image, ap + fill_start,
321  0xff, fill_end - fill_start);
322  }
323  else
324  {
325  ADD_SATURATE_8 (ap + fill_start, fill_size * N_X_FRAC (8),
326  fill_end - fill_start);
327  }
328 
329  fill_start = fill_end = -1;
330  fill_size = 0;
331  }
332 
333  line += stride;
334  }
335  }
336 }
337 
338 #ifndef PIXMAN_FB_ACCESSORS
339 static
340 #endif
341 void
343  pixman_edge_t * l,
344  pixman_edge_t * r,
347 {
348  switch (PIXMAN_FORMAT_BPP (image->bits.format))
349  {
350  case 1:
351  rasterize_edges_1 (image, l, r, t, b);
352  break;
353 
354  case 4:
355  rasterize_edges_4 (image, l, r, t, b);
356  break;
357 
358  case 8:
359  rasterize_edges_8 (image, l, r, t, b);
360  break;
361 
362  default:
363  break;
364  }
365 }
366 
367 #ifndef PIXMAN_FB_ACCESSORS
368 
369 PIXMAN_EXPORT void
371  pixman_edge_t * l,
372  pixman_edge_t * r,
375 {
376  return_if_fail (image->type == BITS);
378 
379  if (image->bits.read_func || image->bits.write_func)
381  else
382  pixman_rasterize_edges_no_accessors (image, l, r, t, b);
383 }
384 
385 #endif
void WRITE(T &t, UInt32 v)
Definition: Compiler.cpp:292
#define width(a)
Definition: aptex-macros.h:198
static struct brw_reg stride(struct brw_reg reg, uint32_t vstride, uint32_t width, uint32_t hstride)
#define b
Definition: jpegint.h:372
#define ap
#define t
Definition: afcover.h:96
unsigned char * image
Definition: in_pcx.cpp:323
kerning y
Definition: ttdriver.c:212
unsigned int uint32_t
Definition: stdint.h:80
unsigned char uint8_t
Definition: stdint.h:78
#define buf
#define READ
Definition: config.h:50
float x
Definition: cordic.py:15
#define MEMSET_WRAPPED(img, dst, val, size)
#define PIXMAN_EXPORT
#define force_inline
#define ADD_SATURATE_8(buf, val, length)
Definition: pixman-edge.c:130
#define RENDER_EDGE_STEP_BIG(edge)
Definition: pixman-edge.c:49
static uint8_t clip255(int x)
Definition: pixman-edge.c:122
static void rasterize_edges_8(pixman_image_t *image, pixman_edge_t *l, pixman_edge_t *r, pixman_fixed_t t, pixman_fixed_t b)
Definition: pixman-edge.c:156
#define RENDER_EDGE_STEP_SMALL(edge)
Definition: pixman-edge.c:35
void pixman_rasterize_edges_accessors(pixman_image_t *image, pixman_edge_t *l, pixman_edge_t *r, pixman_fixed_t t, pixman_fixed_t b)
Definition: pixman-edge.c:342
#define PIXMAN_RASTERIZE_EDGES
Definition: pixman-edge.c:61
#define STEP_Y_BIG(n)
#define return_if_fail(expr)
@ BITS
#define STEP_Y_SMALL(n)
#define N_Y_FRAC(n)
#define Y_FRAC_LAST(n)
#define N_X_FRAC(n)
#define RENDER_SAMPLES_X(x, n)
#define PIXMAN_FORMAT_BPP(f)
Definition: pixman.h:837
#define pixman_int_to_fixed(i)
Definition: pixman.h:130
pixman_fixed_16_16_t pixman_fixed_t
Definition: pixman.h:123
#define PIXMAN_FORMAT_TYPE(f)
Definition: pixman.h:839
#define PIXMAN_TYPE_A
Definition: pixman.h:852
#define pixman_fixed_to_int(f)
Definition: pixman.h:129
void pixman_rasterize_edges(pixman_image_t *image, pixman_edge_t *l, pixman_edge_t *r, pixman_fixed_t t, pixman_fixed_t b)
#define pixman_fixed_frac(f)
Definition: pixman.h:133
int r
Definition: ppmqvga.c:68
char line[1024]
Definition: process_score.c:29
Definition: namelist.c:170
struct brw_reg::@486::@487 bits
Definition: sd.h:76
Definition: bdf.c:133
Definition: dvips.h:235