gfx: Implement GP_FillCircleSeg()
[gfxprim.git] / libs / gfx / GP_FillCircle.gen.c.t
blob41942a318077b67a059c06a556a5ac1b669b75f0
1 @ include source.t
2 /*
3  * A filled circle drawing algorithm.
4  *
5  * Copyright (C) 2009-2012 Jiri "BlueBear" Dluhos
6  *                         <jiri.bluebear.dluhos@gmail.com>
7  * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
8  */
10 #include "core/GP_GetPutPixel.h"
11 #include "core/GP_Transform.h"
12 #include "core/GP_FnPerBpp.h"
13 #include "gfx/GP_HLine.h"
14 #include "gfx/GP_Circle.h"
15 #include "gfx/GP_CircleSeg.h"
18  * A filled circle drawing algorithm.
19  *
20  * A filled circle is drawn in the same way as an unfilled one,
21  * in a top-down, line per line manner, except that we don't need to draw
22  * four points in each X step. Instead, we just iterate X
23  * until we accumulate enough Y changes to reach the next line,
24  * and then draw the full line. The top and bottom half are mirrored.
25  */
26 @ for ps in pixelsizes:
28 static void GP_FillCircle_Raw_{{ ps.suffix }}(GP_Pixmap *pixmap,
29         GP_Coord xcenter, GP_Coord ycenter, GP_Size r, GP_Pixel pixel)
31         /* for r == 0, circle degenerates to a point */
32         if (r == 0) {
33                 GP_PutPixel_Raw_{{ ps.suffix }}(pixmap, xcenter, ycenter, pixel);
34                 return;
35         }
37         int x, y, error;
38         for (x = 0, error = -r, y = r; y >= 0; y--) {
39                 while (error < 0) {
40                         error += 2*x + 1;
41                         x++;
42                 }
43                 error += -2*y + 1;
44                 GP_HLine_Raw_{{ ps.suffix }}(pixmap, xcenter-x+1, xcenter+x-1, ycenter-y, pixel);
45                 GP_HLine_Raw_{{ ps.suffix }}(pixmap, xcenter-x+1, xcenter+x-1, ycenter+y, pixel);
46         }
49 static void GP_FillCircleSeg_Raw_{{ ps.suffix }}(GP_Pixmap *pixmap,
50         GP_Coord xcenter, GP_Coord ycenter, GP_Size r, uint8_t seg_flag, GP_Pixel pixel)
52         /* for r == 0, circle degenerates to a point */
53         if (r == 0) {
54                 GP_PutPixel_Raw_{{ ps.suffix }}(pixmap, xcenter, ycenter, pixel);
55                 return;
56         }
58         int x, y, error;
59         for (x = 0, error = -r, y = r; y >= 0; y--) {
60                 while (error < 0) {
61                         error += 2*x + 1;
62                         x++;
63                 }
64                 error += -2*y + 1;
66                 if (seg_flag & GP_CIRCLE_SEG1)
67                         GP_HLine_Raw_{{ ps.suffix }}(pixmap, xcenter, xcenter+x-1, ycenter-y, pixel);
69                 if (seg_flag & GP_CIRCLE_SEG2)
70                         GP_HLine_Raw_{{ ps.suffix }}(pixmap, xcenter-x+1, xcenter, ycenter-y, pixel);
72                 if (seg_flag & GP_CIRCLE_SEG3)
73                         GP_HLine_Raw_{{ ps.suffix }}(pixmap, xcenter-x+1, xcenter, ycenter+y, pixel);
75                 if (seg_flag & GP_CIRCLE_SEG4)
76                         GP_HLine_Raw_{{ ps.suffix }}(pixmap, xcenter, xcenter+x-1, ycenter+y, pixel);
77         }
80 @ end
82 void GP_FillCircle_Raw(GP_Pixmap *pixmap, GP_Coord xcenter, GP_Coord ycenter,
83                        GP_Size r, GP_Pixel pixel)
85         GP_CHECK_PIXMAP(pixmap);
87         GP_FN_PER_BPP_PIXMAP(GP_FillCircle_Raw, pixmap, pixmap,
88                               xcenter, ycenter, r, pixel);
91 void GP_FillCircleSeg_Raw(GP_Pixmap *pixmap, GP_Coord xcenter, GP_Coord ycenter,
92                           GP_Size r, uint8_t seg_flag, GP_Pixel pixel)
94         GP_CHECK_PIXMAP(pixmap);
96         GP_FN_PER_BPP_PIXMAP(GP_FillCircleSeg_Raw, pixmap, pixmap,
97                               xcenter, ycenter, r, seg_flag, pixel);
100 void GP_FillCircle(GP_Pixmap *pixmap, GP_Coord xcenter, GP_Coord ycenter,
101                    GP_Size r, GP_Pixel pixel)
103         GP_CHECK_PIXMAP(pixmap);
105         GP_TRANSFORM_POINT(pixmap, xcenter, ycenter);
107         GP_FillCircle_Raw(pixmap, xcenter, ycenter, r, pixel);