3 * Line drawing algorithm.
5 * Copyright (C) 2009-2012 Jiri "BlueBear" Dluhos
6 * <jiri.bluebear.dluhos@gmail.com>
7 * Copyright (C) 2009-2014 Cyril Hrubis <metan@ucw.cz>
10 #include "core/GP_Common.h"
11 #include "core/GP_GetPutPixel.h"
12 #include "core/GP_FnPerBpp.h"
14 #include "gfx/GP_VLine.h"
15 #include "gfx/GP_HLine.h"
16 #include "gfx/GP_Line.h"
17 #include "gfx/GP_LineClip.h"
20 * The classical Bresenham line drawing algorithm.
21 * Please see http://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm
22 * for a nice and understandable description.
25 @ for ps in pixelsizes:
26 void GP_Line_Raw_{{ ps.suffix }}(GP_Pixmap *pixmap, int x0, int y0,
27 int x1, int y1, GP_Pixel pixval)
29 if (!GP_LineClip(&x0, &y0, &x1, &y1, pixmap->w - 1, pixmap->h - 1))
32 GP_ASSERT(x0 >= 0 && x0 <= (int) pixmap->w-1);
33 GP_ASSERT(x1 >= 0 && x1 <= (int) pixmap->w-1);
34 GP_ASSERT(y0 >= 0 && y0 <= (int) pixmap->h-1);
35 GP_ASSERT(y1 >= 0 && y1 <= (int) pixmap->h-1);
37 /* special cases: vertical line, horizontal line, single point */
40 GP_PutPixel_Raw_Clipped_{{ ps.suffix }}(pixmap,
44 GP_VLine_Raw(pixmap, x0, y0, y1, pixval);
48 GP_HLine_Raw(pixmap, x0, x1, y0, pixval);
53 * Which axis is longer? Swap the coordinates if necessary so
54 * that the X axis is always the longer one and Y is shorter.
56 int steep = abs(y1 - y0) / abs(x1 - x0);
66 /* iterate over the longer axis, calculate values on the shorter */
68 int deltay = abs(y1 - y0);
71 * start with error of 0.5 (multiplied by deltax for integer-only math),
72 * this reflects the fact that ideally, the coordinate should be
73 * in the middle of the pixel
75 int error = deltax / 2;
78 int ystep = (y0 < y1) ? 1 : -1;
79 for (x = x0; x <= x1; x++) {
82 GP_PutPixel_Raw_{{ ps.suffix }}(pixmap, y, x,
85 GP_PutPixel_Raw_{{ ps.suffix }}(pixmap, x, y,
90 y += ystep; /* next step on the shorter axis */
98 void GP_Line_Raw(GP_Pixmap *pixmap, GP_Coord x0, GP_Coord y0,
99 GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
101 GP_CHECK_PIXMAP(pixmap);
103 GP_FN_PER_BPP_PIXMAP(GP_Line_Raw, pixmap, pixmap, x0, y0, x1, y1,
107 void GP_Line(GP_Pixmap *pixmap, GP_Coord x0, GP_Coord y0,
108 GP_Coord x1, GP_Coord y1, GP_Pixel pixel)
110 GP_CHECK_PIXMAP(pixmap);
112 GP_TRANSFORM_POINT(pixmap, x0, y0);
113 GP_TRANSFORM_POINT(pixmap, x1, y1);
115 GP_Line_Raw(pixmap, x0, y0, x1, y1, pixel);