929564dafcc38dc50145c7cee69b6615c82cb033
[platform/upstream/gst-plugins-good.git] / gst / goom / drawmethods.c
1 #include "drawmethods.h"
2
3 #define DRAWMETHOD_PLUS(_out,_backbuf,_col) \
4 {\
5       int tra=0,i=0;\
6       unsigned char *bra = (unsigned char*)&(_backbuf);\
7       unsigned char *dra = (unsigned char*)&(_out);\
8       unsigned char *cra = (unsigned char*)&(_col);\
9       for (;i<4;i++) {\
10                                 tra = *cra;\
11                                 tra += *bra;\
12                                 if (tra>255) tra=255;\
13                                 *dra = tra;\
14                                 ++dra;++cra;++bra;\
15                         }\
16 }
17
18 #define DRAWMETHOD DRAWMETHOD_PLUS(*p,*p,col)
19
20 void
21 draw_line (Pixel * data, int x1, int y1, int x2, int y2, int col, int screenx,
22     int screeny)
23 {
24   int x, y, dx, dy, yy, xx;
25   Pixel *p;
26
27   if ((y1 < 0) || (y2 < 0) || (x1 < 0) || (x2 < 0) || (y1 >= screeny)
28       || (y2 >= screeny) || (x1 >= screenx) || (x2 >= screenx))
29     return;
30
31   /* clip to top edge 
32      if ((y1 < 0) && (y2 < 0))
33      return;
34
35      if (y1 < 0) {
36      x1 += (y1 * (x1 - x2)) / (y2 - y1);
37      y1 = 0;
38      }
39      if (y2 < 0) {
40      x2 += (y2 * (x1 - x2)) / (y2 - y1);
41      y2 = 0;
42      }
43
44      clip to bottom edge 
45      if ((y1 >= screeny) && (y2 >= screeny))
46      return;
47      if (y1 >= screeny) {
48      x1 -= ((screeny - y1) * (x1 - x2)) / (y2 - y1);
49      y1 = screeny - 1;
50      }
51      if (y2 >= screeny) {
52      x2 -= ((screeny - y2) * (x1 - x2)) / (y2 - y1);
53      y2 = screeny - 1;
54      }
55      clip to left edge 
56      if ((x1 < 0) && (x2 < 0))
57      return;
58      if (x1 < 0) {
59      y1 += (x1 * (y1 - y2)) / (x2 - x1);
60      x1 = 0;
61      }
62      if (x2 < 0) {
63      y2 += (x2 * (y1 - y2)) / (x2 - x1);
64      x2 = 0;
65      }
66      clip to right edge 
67      if ((x1 >= screenx) && (x2 >= screenx))
68      return;
69      if (x1 >= screenx) {
70      y1 -= ((screenx - x1) * (y1 - y2)) / (x2 - x1);
71      x1 = screenx - 1;
72      }
73      if (x2 >= screenx) {
74      y2 -= ((screenx - x2) * (y1 - y2)) / (x2 - x1);
75      x2 = screenx - 1;
76      }
77    */
78
79   dx = x2 - x1;
80   dy = y2 - y1;
81   if (x1 > x2) {
82     int tmp;
83
84     tmp = x1;
85     x1 = x2;
86     x2 = tmp;
87     tmp = y1;
88     y1 = y2;
89     y2 = tmp;
90     dx = x2 - x1;
91     dy = y2 - y1;
92   }
93
94   /* vertical line */
95   if (dx == 0) {
96     if (y1 < y2) {
97       p = &(data[(screenx * y1) + x1]);
98       for (y = y1; y <= y2; y++) {
99         DRAWMETHOD;
100         p += screenx;
101       }
102     } else {
103       p = &(data[(screenx * y2) + x1]);
104       for (y = y2; y <= y1; y++) {
105         DRAWMETHOD;
106         p += screenx;
107       }
108     }
109     return;
110   }
111   /* horizontal line */
112   if (dy == 0) {
113     if (x1 < x2) {
114       p = &(data[(screenx * y1) + x1]);
115       for (x = x1; x <= x2; x++) {
116         DRAWMETHOD;
117         p++;
118       }
119       return;
120     } else {
121       p = &(data[(screenx * y1) + x2]);
122       for (x = x2; x <= x1; x++) {
123         DRAWMETHOD;
124         p++;
125       }
126       return;
127     }
128   }
129   /* 1    */
130   /* \   */
131   /* \  */
132   /* 2 */
133   if (y2 > y1) {
134     /* steep */
135     if (dy > dx) {
136       dx = ((dx << 16) / dy);
137       x = x1 << 16;
138       for (y = y1; y <= y2; y++) {
139         xx = x >> 16;
140         p = &(data[(screenx * y) + xx]);
141         DRAWMETHOD;
142         if (xx < (screenx - 1)) {
143           p++;
144           /* DRAWMETHOD; */
145         }
146         x += dx;
147       }
148       return;
149     }
150     /* shallow */
151     else {
152       dy = ((dy << 16) / dx);
153       y = y1 << 16;
154       for (x = x1; x <= x2; x++) {
155         yy = y >> 16;
156         p = &(data[(screenx * yy) + x]);
157         DRAWMETHOD;
158         if (yy < (screeny - 1)) {
159           p += screeny;
160           /* DRAWMETHOD; */
161         }
162         y += dy;
163       }
164     }
165   }
166   /* 2 */
167   /* /  */
168   /* /   */
169   /* 1    */
170   else {
171     /* steep */
172     if (-dy > dx) {
173       dx = ((dx << 16) / -dy);
174       x = (x1 + 1) << 16;
175       for (y = y1; y >= y2; y--) {
176         xx = x >> 16;
177         p = &(data[(screenx * y) + xx]);
178         DRAWMETHOD;
179         if (xx < (screenx - 1)) {
180           p--;
181           /* DRAWMETHOD; */
182         }
183         x += dx;
184       }
185       return;
186     }
187     /* shallow */
188     else {
189       dy = ((dy << 16) / dx);
190       y = y1 << 16;
191       for (x = x1; x <= x2; x++) {
192         yy = y >> 16;
193         p = &(data[(screenx * yy) + x]);
194         DRAWMETHOD;
195         if (yy < (screeny - 1)) {
196           p += screeny;
197           /* DRAWMETHOD; */
198         }
199         y += dy;
200       }
201       return;
202     }
203   }
204 }