1
/* Copyright (C) 2001-2006 Artifex Software, Inc.
4
This software is provided AS-IS with no warranty, either express or
7
This software is distributed under license and may not be copied, modified
8
or distributed except as expressly authorized under the terms of that
9
license. Refer to licensing information at http://www.artifex.com/
10
or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134,
11
San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information.
14
/* $Id: gxdda.h 8522 2008-02-12 20:30:17Z leonardo $ */
15
/* Definitions for DDAs */
16
/* Requires gxfixed.h */
18
#ifndef gxdda_INCLUDED
19
# define gxdda_INCLUDED
22
* We use the familiar Bresenham DDA algorithm for several purposes:
23
* - tracking the edges when filling trapezoids;
24
* - tracking the current pixel corner coordinates when rasterizing
25
* skewed or rotated images;
26
* - converting curves to sequences of lines (this is a 3rd-order
27
* DDA, the others are 1st-order);
28
* - perhaps someday for drawing single-pixel lines.
29
* In the case of trapezoids, lines, and curves, we need to use
30
* the DDA to find the integer X values at integer+0.5 values of Y;
31
* in the case of images, we use DDAs to compute the (fixed)
32
* X and Y values at (integer) source pixel corners.
34
* The purpose of the DDA is to compute the exact values Q(i) = floor(i*D/N)
35
* for increasing integers i, 0 <= i <= N. D is considered to be an
36
* integer, although it may actually be a fixed. For the algorithm,
37
* we maintain i*D/N as Q + (N-R)/N where Q and R are integers, 0 < R <= N,
38
* with the following auxiliary values:
40
* dR = D mod N (0 <= dR < N)
42
* Then at each iteration we do:
44
* if ( R > dR ) R -= dR; else ++Q, R += NdR;
45
* These formulas work regardless of the sign of D, and never let R go
48
/* In the following structure definitions, ntype must be an unsigned type. */
49
#define dda_state_struct(sname, dtype, ntype)\
50
struct sname { dtype Q; ntype R; }
51
#define dda_step_struct(sname, dtype, ntype)\
52
struct sname { dtype dQ; ntype dR, NdR; }
54
/* DDA with int Q and uint N */
55
typedef struct gx_dda_int_s {
56
dda_state_struct(ia_, int, uint) state;
57
dda_step_struct(ie_, int, uint) step;
60
/* DDA with fixed Q and (unsigned) integer N */
62
dda_state_struct(_a, fixed, uint) gx_dda_state_fixed;
63
typedef dda_step_struct(_e, fixed, uint) gx_dda_step_fixed;
64
typedef struct gx_dda_fixed_s {
65
gx_dda_state_fixed state;
66
gx_dda_step_fixed step;
69
* Define a pair of DDAs for iterating along an arbitrary line.
71
typedef struct gx_dda_fixed_point_s {
75
* Initialize a DDA. The sign test is needed only because C doesn't
76
* provide reliable definitions of / and % for integers (!!!).
78
#define dda_init_state(dstate, init, N)\
79
(dstate).Q = (init), (dstate).R = (N)
80
#define dda_init_step(dstep, D, N)\
82
(dstep).dQ = 0, (dstep).dR = 0;\
84
{ (dstep).dQ = -(int)((uint)-(D) / (N));\
85
if ( ((dstep).dR = -(D) % (N)) != 0 )\
86
--(dstep).dQ, (dstep).dR = (N) - (dstep).dR;\
89
{ (dstep).dQ = (D) / (N); (dstep).dR = (D) % (N); }\
90
(dstep).NdR = (N) - (dstep).dR
91
#define dda_init(dda, init, D, N)\
92
dda_init_state((dda).state, init, N);\
93
dda_init_step((dda).step, D, N)
95
* Compute the sum of two DDA steps with the same D and N.
96
* Note that since dR + NdR = N, this quantity must be the same in both
97
* fromstep and tostep.
99
#define dda_step_add(tostep, fromstep)\
101
((tostep).dR < (fromstep).NdR ?\
102
((tostep).dR += (fromstep).dR, (tostep).NdR -= (fromstep).dR,\
104
((tostep).dR -= (fromstep).NdR, (tostep).NdR += (fromstep).NdR,\
107
* Return the current value in a DDA.
109
#define dda_state_current(dstate) (dstate).Q
110
#define dda_current(dda) dda_state_current((dda).state)
111
#define dda_current_fixed2int(dda)\
112
fixed2int_var(dda_state_current((dda).state))
114
* Increment a DDA to the next point.
115
* Returns the updated current value.
117
#define dda_state_next(dstate, dstep)\
119
((dstate).R > (dstep).dR ?\
120
((dstate).R -= (dstep).dR, (dstep).dQ) :\
121
((dstate).R += (dstep).NdR, (dstep).dQ + 1))
122
#define dda_next(dda) dda_state_next((dda).state, (dda).step)
124
* Back up a DDA to the previous point.
125
* Returns the updated current value.
127
#define dda_state_previous(dstate, dstep)\
129
((dstate).R <= (dstep).NdR ?\
130
((dstate).R += (dstep).dR, (dstep).dQ) :\
131
((dstate).R -= (dstep).NdR, (dstep).dQ + 1))
132
#define dda_previous(dda) dda_state_previous((dda).state, (dda).step)
134
* Advance a DDA by an arbitrary number of steps.
135
* This implementation is very inefficient; we'll improve it if needed.
137
#define dda_state_advance(dstate, dstep, nsteps)\
140
(dstate).Q += (dstep).dQ * (nsteps);\
142
if ( (dstate).R > (dstep).dR ) (dstate).R -= (dstep).dR;\
143
else (dstate).R += (dstep).NdR, (dstate).Q++;\
145
#define dda_advance(dda, nsteps)\
146
dda_state_advance((dda).state, (dda).step, nsteps)
148
* Translate the position of a DDA by a given amount.
150
#define dda_state_translate(dstate, delta)\
151
((dstate).Q += (delta))
152
#define dda_translate(dda, delta)\
153
dda_state_translate((dda).state, delta)
155
#endif /* gxdda_INCLUDED */