backends: Add support for timers to backends.
[gfxprim/pasky.git] / libs / gfx / GP_LineAA.gen.c.t
blobc5796d5ee2a1bcc81c3891843e94809d9362401f
1 %% extends "base.c.t"
3 {% block descr %}Anti Aliased Line{% endblock %}
5 %% block body
7 #include "core/GP_Context.h"
8 #include "core/GP_MixPixels.h"
9 #include "core/GP_FixedPoint.h"
10 #include "core/GP_GammaCorrection.h"
12 #include "gfx/GP_HLineAA.h"
13 #include "gfx/GP_VLineAA.h"
15 #define FP_TO_PERC(a) (GP_FP_ROUND_TO_INT((a) * 255))
17 static inline void line_aa_x(GP_Context *context,
18                              GP_Coord x0, GP_Coord y0,
19                              GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
21         GP_Coord xend, yend, xgap, xpx0, ypx0, xpx1, ypx1;
22         uint8_t perc;
23         
24         int64_t dx = x1 - x0;
25         int64_t dy = y1 - y0;
26         
27         if (x1 < x0) {
28                 GP_SWAP(x0, x1);
29                 GP_SWAP(y0, y1);
30         }
32         xend = GP_FP_ROUND(x1);
33         yend = y1 + GP_FP_DIV(GP_FP_MUL(dy, xend - x1), dx);
34         xgap = GP_FP_FRAC(x1 + GP_FP_1_2);
35         xpx1 = GP_FP_TO_INT(xend);
36         ypx1 = GP_FP_TO_INT(yend);
38         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_RFRAC(yend), xgap));
39         GP_MixPixel_Raw_Clipped(context, xpx1, ypx1, pixel, perc);
40         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_FRAC(yend), xgap));
41         GP_MixPixel_Raw_Clipped(context, xpx1, ypx1+1, pixel, perc);
43         xend = GP_FP_ROUND(x0);
44         yend = y0 + GP_FP_DIV(GP_FP_MUL(dy, xend - x0), dx);
45         xgap = GP_FP_RFRAC(x0 + GP_FP_1_2);
46         xpx0 = GP_FP_TO_INT(xend);
47         ypx0 = GP_FP_TO_INT(yend);
49         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_RFRAC(yend), xgap));
50         GP_MixPixel_Raw_Clipped(context, xpx0, ypx0, pixel, perc);
51         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_FRAC(yend), xgap));
52         GP_MixPixel_Raw_Clipped(context, xpx0, ypx0+1, pixel, perc);
54         GP_Coord x;
55         GP_Coord intery;
57         for (x = xpx0 + 1; x < xpx1; x++) {
58                 intery = yend + GP_FP_DIV((x - xpx0) * dy, dx);
59                 
60                 perc = FP_TO_PERC(GP_FP_RFRAC(intery));
61                 GP_MixPixel_Raw_Clipped(context, x, GP_FP_TO_INT(intery), pixel, perc);
62                 perc = FP_TO_PERC(GP_FP_FRAC(intery));
63                 GP_MixPixel_Raw_Clipped(context, x, GP_FP_TO_INT(intery)+1, pixel, perc);
64         }
67 static inline void line_aa_y(GP_Context *context,
68                              GP_Coord x0, GP_Coord y0,
69                              GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
71         GP_Coord xend, yend, ygap, xpx0, ypx0, xpx1, ypx1;
72         uint8_t perc;
73         
74         int64_t dx = x1 - x0;
75         int64_t dy = y1 - y0;
76         
77         if (y1 < y0) {
78                 GP_SWAP(x0, x1);
79                 GP_SWAP(y0, y1);
80         }
82         yend = GP_FP_ROUND(y1);
83         xend = x1 + GP_FP_DIV(GP_FP_MUL(dx, yend - y1), dy);
84         ygap = GP_FP_FRAC(y1 + GP_FP_1_2);
85         ypx1 = GP_FP_TO_INT(yend);
86         xpx1 = GP_FP_TO_INT(xend);
88         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_RFRAC(xend), ygap));
89         GP_MixPixel_Raw_Clipped(context, xpx1, ypx1, pixel, perc);
90         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_FRAC(xend), ygap));
91         GP_MixPixel_Raw_Clipped(context, xpx1, ypx1+1, pixel, perc);
93         yend = GP_FP_ROUND(y0);
94         xend = x0 + GP_FP_DIV(GP_FP_MUL(dx, yend - y0), dy);
95         ygap = GP_FP_RFRAC(y0 + GP_FP_1_2);
96         ypx0 = GP_FP_TO_INT(yend);
97         xpx0 = GP_FP_TO_INT(xend);
99         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_RFRAC(xend), ygap));
100         GP_MixPixel_Raw_Clipped(context, xpx0, ypx0, pixel, perc);
101         perc = FP_TO_PERC(GP_FP_MUL(GP_FP_FRAC(xend), ygap));
102         GP_MixPixel_Raw_Clipped(context, xpx0, ypx0+1, pixel, perc);
104         GP_Coord y;
105         GP_Coord intery;
107         for (y = ypx0 + 1; y < ypx1; y++) {
108                 intery = xend + GP_FP_DIV((y - ypx0) * dx, dy);
109                 
110                 perc = FP_TO_PERC(GP_FP_RFRAC(intery));
111                 GP_MixPixel_Raw_Clipped(context, GP_FP_TO_INT(intery), y, pixel, perc);
112                 perc = FP_TO_PERC(GP_FP_FRAC(intery));
113                 GP_MixPixel_Raw_Clipped(context, GP_FP_TO_INT(intery)+1, y, pixel, perc);
114         }
117 void GP_LineAA_Raw(GP_Context *context, GP_Coord x0, GP_Coord y0,
118                    GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
120         int64_t dx = x1 - x0;
121         int64_t dy = y1 - y0;
123         if (dy == 0) {
124                 GP_HLineAA_Raw(context, x0, x1, y0, pixel);
125                 return;
126         }
128         if (dx == 0) {
129                 GP_VLineAA_Raw(context, x0, y0, y1, pixel);
130                 return;
131         }
133         if (GP_ABS(dx) < GP_ABS(dy))
134                 line_aa_y(context, x0, y0, x1, y1, pixel);
135         else
136                 line_aa_x(context, x0, y0, x1, y1, pixel);
139 %% endblock body