Skip to content

Commit 32d5e2e

Browse files
committed
De-triplicate Bresenham walkers; use hline when possible
1 parent 78abe13 commit 32d5e2e

1 file changed

Lines changed: 69 additions & 204 deletions

File tree

src/libImaging/Draw.c

Lines changed: 69 additions & 204 deletions
Original file line numberDiff line numberDiff line change
@@ -205,221 +205,86 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink, Imaging mask) {
205205
}
206206
}
207207

208-
static inline void
209-
line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
210-
int i, n, e;
211-
int dx, dy;
212-
int xs, ys;
213-
214-
/* normalize coordinates */
215-
dx = x1 - x0;
216-
if (dx < 0) {
217-
dx = -dx, xs = -1;
218-
} else {
219-
xs = 1;
220-
}
221-
dy = y1 - y0;
222-
if (dy < 0) {
223-
dy = -dy, ys = -1;
224-
} else {
225-
ys = 1;
208+
#define GEN_LINE(point, hline) \
209+
{ \
210+
int i, n, e, dx, dy, xs, ys; \
211+
/* normalize coordinates */ \
212+
dy = y1 - y0; \
213+
if (dy < 0) { \
214+
dy = -dy, ys = -1; \
215+
} else { \
216+
ys = 1; \
217+
} \
218+
if (dy == 0) { /* horizontal, exclude endpoint */ \
219+
if (x1 > x0) { \
220+
hline(im, x0, y0, x1 - 1, ink, NULL); \
221+
} else if (x0 > x1) { \
222+
hline(im, x1 + 1, y0, x0, ink, NULL); \
223+
} \
224+
return; \
225+
} \
226+
dx = x1 - x0; \
227+
if (dx < 0) { \
228+
dx = -dx, xs = -1; \
229+
} else { \
230+
xs = 1; \
231+
} \
232+
\
233+
n = (dx > dy) ? dx : dy; \
234+
\
235+
if (dx == 0) { /* vertical */ \
236+
for (i = 0; i < dy; i++) { \
237+
point(im, x0, y0, ink); \
238+
y0 += ys; \
239+
} \
240+
} else if (dx > dy) { /* bresenham, horizontal slope */ \
241+
n = dx; \
242+
dy += dy; \
243+
e = dy - dx; \
244+
dx += dx; \
245+
\
246+
for (i = 0; i < n; i++) { \
247+
point(im, x0, y0, ink); \
248+
if (e >= 0) { \
249+
y0 += ys; \
250+
e -= dx; \
251+
} \
252+
e += dy; \
253+
x0 += xs; \
254+
} \
255+
} else { /* bresenham, vertical slope */ \
256+
n = dy; \
257+
dx += dx; \
258+
e = dx - dy; \
259+
dy += dy; \
260+
\
261+
for (i = 0; i < n; i++) { \
262+
point(im, x0, y0, ink); \
263+
if (e >= 0) { \
264+
x0 += xs; \
265+
e -= dy; \
266+
} \
267+
e += dx; \
268+
y0 += ys; \
269+
} \
270+
} \
226271
}
227272

228-
n = (dx > dy) ? dx : dy;
229-
230-
if (dx == 0) {
231-
/* vertical */
232-
for (i = 0; i < dy; i++) {
233-
point8(im, x0, y0, ink);
234-
y0 += ys;
235-
}
236-
237-
} else if (dy == 0) {
238-
/* horizontal */
239-
for (i = 0; i < dx; i++) {
240-
point8(im, x0, y0, ink);
241-
x0 += xs;
242-
}
243-
244-
} else if (dx > dy) {
245-
/* bresenham, horizontal slope */
246-
n = dx;
247-
dy += dy;
248-
e = dy - dx;
249-
dx += dx;
250-
251-
for (i = 0; i < n; i++) {
252-
point8(im, x0, y0, ink);
253-
if (e >= 0) {
254-
y0 += ys;
255-
e -= dx;
256-
}
257-
e += dy;
258-
x0 += xs;
259-
}
260-
261-
} else {
262-
/* bresenham, vertical slope */
263-
n = dy;
264-
dx += dx;
265-
e = dx - dy;
266-
dy += dy;
267-
268-
for (i = 0; i < n; i++) {
269-
point8(im, x0, y0, ink);
270-
if (e >= 0) {
271-
x0 += xs;
272-
e -= dy;
273-
}
274-
e += dx;
275-
y0 += ys;
276-
}
277-
}
273+
static inline void
274+
line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
275+
GEN_LINE(point8, hline8);
278276
}
279277

280278
static inline void
281279
line32(Imaging im, int x0, int y0, int x1, int y1, int ink) {
282-
int i, n, e;
283-
int dx, dy;
284-
int xs, ys;
285-
286-
/* normalize coordinates */
287-
dx = x1 - x0;
288-
if (dx < 0) {
289-
dx = -dx, xs = -1;
290-
} else {
291-
xs = 1;
292-
}
293-
dy = y1 - y0;
294-
if (dy < 0) {
295-
dy = -dy, ys = -1;
296-
} else {
297-
ys = 1;
298-
}
299-
300-
n = (dx > dy) ? dx : dy;
301-
302-
if (dx == 0) {
303-
/* vertical */
304-
for (i = 0; i < dy; i++) {
305-
point32(im, x0, y0, ink);
306-
y0 += ys;
307-
}
308-
309-
} else if (dy == 0) {
310-
/* horizontal */
311-
for (i = 0; i < dx; i++) {
312-
point32(im, x0, y0, ink);
313-
x0 += xs;
314-
}
315-
316-
} else if (dx > dy) {
317-
/* bresenham, horizontal slope */
318-
n = dx;
319-
dy += dy;
320-
e = dy - dx;
321-
dx += dx;
322-
323-
for (i = 0; i < n; i++) {
324-
point32(im, x0, y0, ink);
325-
if (e >= 0) {
326-
y0 += ys;
327-
e -= dx;
328-
}
329-
e += dy;
330-
x0 += xs;
331-
}
332-
333-
} else {
334-
/* bresenham, vertical slope */
335-
n = dy;
336-
dx += dx;
337-
e = dx - dy;
338-
dy += dy;
339-
340-
for (i = 0; i < n; i++) {
341-
point32(im, x0, y0, ink);
342-
if (e >= 0) {
343-
x0 += xs;
344-
e -= dy;
345-
}
346-
e += dx;
347-
y0 += ys;
348-
}
349-
}
280+
GEN_LINE(point32, hline32);
350281
}
351282

352283
static inline void
353284
line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) {
354-
int i, n, e;
355-
int dx, dy;
356-
int xs, ys;
357-
358-
/* normalize coordinates */
359-
dx = x1 - x0;
360-
if (dx < 0) {
361-
dx = -dx, xs = -1;
362-
} else {
363-
xs = 1;
364-
}
365-
dy = y1 - y0;
366-
if (dy < 0) {
367-
dy = -dy, ys = -1;
368-
} else {
369-
ys = 1;
370-
}
371-
372-
n = (dx > dy) ? dx : dy;
373-
374-
if (dx == 0) {
375-
/* vertical */
376-
for (i = 0; i < dy; i++) {
377-
point32rgba(im, x0, y0, ink);
378-
y0 += ys;
379-
}
380-
381-
} else if (dy == 0) {
382-
/* horizontal */
383-
for (i = 0; i < dx; i++) {
384-
point32rgba(im, x0, y0, ink);
385-
x0 += xs;
386-
}
387-
388-
} else if (dx > dy) {
389-
/* bresenham, horizontal slope */
390-
n = dx;
391-
dy += dy;
392-
e = dy - dx;
393-
dx += dx;
394-
395-
for (i = 0; i < n; i++) {
396-
point32rgba(im, x0, y0, ink);
397-
if (e >= 0) {
398-
y0 += ys;
399-
e -= dx;
400-
}
401-
e += dy;
402-
x0 += xs;
403-
}
404-
405-
} else {
406-
/* bresenham, vertical slope */
407-
n = dy;
408-
dx += dx;
409-
e = dx - dy;
410-
dy += dy;
411-
412-
for (i = 0; i < n; i++) {
413-
point32rgba(im, x0, y0, ink);
414-
if (e >= 0) {
415-
x0 += xs;
416-
e -= dy;
417-
}
418-
e += dx;
419-
y0 += ys;
420-
}
421-
}
285+
GEN_LINE(point32rgba, hline32rgba);
422286
}
287+
#undef GEN_LINE
423288

424289
static int
425290
x_cmp(const void *x0, const void *x1) {

0 commit comments

Comments
 (0)