Skip to content

Commit c74ec6a

Browse files
committed
De-triplicate Bresenham walkers; use hline when possible
1 parent ea1e317 commit c74ec6a

1 file changed

Lines changed: 69 additions & 205 deletions

File tree

src/libImaging/Draw.c

Lines changed: 69 additions & 205 deletions
Original file line numberDiff line numberDiff line change
@@ -257,226 +257,90 @@ hline32rgba(Imaging im, int x0, int y0, int x1, int ink, Imaging mask) {
257257
}
258258
}
259259

260-
static inline void
261-
line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
262-
int i, n, e;
263-
int dx, dy;
264-
int xs, ys;
265-
266-
/* normalize coordinates */
267-
dx = x1 - x0;
268-
if (dx < 0) {
269-
dx = -dx, xs = -1;
270-
} else {
271-
xs = 1;
272-
}
273-
dy = y1 - y0;
274-
if (dy < 0) {
275-
dy = -dy, ys = -1;
276-
} else {
277-
ys = 1;
260+
#define GEN_LINE(point, hline) \
261+
{ \
262+
int i, n, e, dx, dy, xs, ys; \
263+
/* normalize coordinates */ \
264+
dy = y1 - y0; \
265+
if (dy < 0) { \
266+
dy = -dy, ys = -1; \
267+
} else { \
268+
ys = 1; \
269+
} \
270+
if (dy == 0) { /* horizontal, exclude endpoint */ \
271+
if (x1 > x0) { \
272+
hline(im, x0, y0, x1 - 1, ink, NULL); \
273+
} else if (x0 > x1) { \
274+
hline(im, x1 + 1, y0, x0, ink, NULL); \
275+
} \
276+
return; \
277+
} \
278+
dx = x1 - x0; \
279+
if (dx < 0) { \
280+
dx = -dx, xs = -1; \
281+
} else { \
282+
xs = 1; \
283+
} \
284+
\
285+
n = (dx > dy) ? dx : dy; \
286+
\
287+
if (dx == 0) { /* vertical */ \
288+
for (i = 0; i < dy; i++) { \
289+
point(im, x0, y0, ink); \
290+
y0 += ys; \
291+
} \
292+
} else if (dx > dy) { /* bresenham, horizontal slope */ \
293+
n = dx; \
294+
dy += dy; \
295+
e = dy - dx; \
296+
dx += dx; \
297+
\
298+
for (i = 0; i < n; i++) { \
299+
point(im, x0, y0, ink); \
300+
if (e >= 0) { \
301+
y0 += ys; \
302+
e -= dx; \
303+
} \
304+
e += dy; \
305+
x0 += xs; \
306+
} \
307+
} else { /* bresenham, vertical slope */ \
308+
n = dy; \
309+
dx += dx; \
310+
e = dx - dy; \
311+
dy += dy; \
312+
\
313+
for (i = 0; i < n; i++) { \
314+
point(im, x0, y0, ink); \
315+
if (e >= 0) { \
316+
x0 += xs; \
317+
e -= dy; \
318+
} \
319+
e += dx; \
320+
y0 += ys; \
321+
} \
322+
} \
278323
}
279324

280-
n = (dx > dy) ? dx : dy;
281-
282-
if (dx == 0) {
283-
/* vertical */
284-
for (i = 0; i < dy; i++) {
285-
point8(im, x0, y0, ink);
286-
y0 += ys;
287-
}
288-
289-
} else if (dy == 0) {
290-
/* horizontal */
291-
for (i = 0; i < dx; i++) {
292-
point8(im, x0, y0, ink);
293-
x0 += xs;
294-
}
295-
296-
} else if (dx > dy) {
297-
/* bresenham, horizontal slope */
298-
n = dx;
299-
dy += dy;
300-
e = dy - dx;
301-
dx += dx;
302-
303-
for (i = 0; i < n; i++) {
304-
point8(im, x0, y0, ink);
305-
if (e >= 0) {
306-
y0 += ys;
307-
e -= dx;
308-
}
309-
e += dy;
310-
x0 += xs;
311-
}
312-
313-
} else {
314-
/* bresenham, vertical slope */
315-
n = dy;
316-
dx += dx;
317-
e = dx - dy;
318-
dy += dy;
319-
320-
for (i = 0; i < n; i++) {
321-
point8(im, x0, y0, ink);
322-
if (e >= 0) {
323-
x0 += xs;
324-
e -= dy;
325-
}
326-
e += dx;
327-
y0 += ys;
328-
}
329-
}
325+
static inline void
326+
line8(Imaging im, int x0, int y0, int x1, int y1, int ink) {
327+
GEN_LINE(point8, hline8);
330328
}
331329

332330
static inline void
333331
line32(Imaging im, int x0, int y0, int x1, int y1, int ink) {
334-
int i, n, e;
335-
int dx, dy;
336-
int xs, ys;
337-
338-
/* normalize coordinates */
339-
dx = x1 - x0;
340-
if (dx < 0) {
341-
dx = -dx, xs = -1;
342-
} else {
343-
xs = 1;
344-
}
345-
dy = y1 - y0;
346-
if (dy < 0) {
347-
dy = -dy, ys = -1;
348-
} else {
349-
ys = 1;
350-
}
351-
352-
n = (dx > dy) ? dx : dy;
353-
354-
if (dx == 0) {
355-
/* vertical */
356-
for (i = 0; i < dy; i++) {
357-
point32(im, x0, y0, ink);
358-
y0 += ys;
359-
}
360-
361-
} else if (dy == 0) {
362-
/* horizontal */
363-
for (i = 0; i < dx; i++) {
364-
point32(im, x0, y0, ink);
365-
x0 += xs;
366-
}
367-
368-
} else if (dx > dy) {
369-
/* bresenham, horizontal slope */
370-
n = dx;
371-
dy += dy;
372-
e = dy - dx;
373-
dx += dx;
374-
375-
for (i = 0; i < n; i++) {
376-
point32(im, x0, y0, ink);
377-
if (e >= 0) {
378-
y0 += ys;
379-
e -= dx;
380-
}
381-
e += dy;
382-
x0 += xs;
383-
}
384-
385-
} else {
386-
/* bresenham, vertical slope */
387-
n = dy;
388-
dx += dx;
389-
e = dx - dy;
390-
dy += dy;
391-
392-
for (i = 0; i < n; i++) {
393-
point32(im, x0, y0, ink);
394-
if (e >= 0) {
395-
x0 += xs;
396-
e -= dy;
397-
}
398-
e += dx;
399-
y0 += ys;
400-
}
401-
}
332+
GEN_LINE(point32, hline32);
402333
}
403334

404335
static inline void
405336
line32rgba(Imaging im, int x0, int y0, int x1, int y1, int ink) {
406-
int i, n, e;
407-
int dx, dy;
408-
int xs, ys;
409-
410337
UINT8 a = ((UINT8 *)&ink)[3];
411338
if (a == 0) { // Transparent ink. Nothing to paint.
412339
return;
413340
}
414-
415-
/* normalize coordinates */
416-
dx = x1 - x0;
417-
if (dx < 0) {
418-
dx = -dx, xs = -1;
419-
} else {
420-
xs = 1;
421-
}
422-
dy = y1 - y0;
423-
if (dy < 0) {
424-
dy = -dy, ys = -1;
425-
} else {
426-
ys = 1;
427-
}
428-
429-
n = (dx > dy) ? dx : dy;
430-
431-
if (dx == 0) {
432-
/* vertical */
433-
for (i = 0; i < dy; i++) {
434-
point32rgba(im, x0, y0, ink);
435-
y0 += ys;
436-
}
437-
438-
} else if (dy == 0) {
439-
/* horizontal */
440-
for (i = 0; i < dx; i++) {
441-
point32rgba(im, x0, y0, ink);
442-
x0 += xs;
443-
}
444-
445-
} else if (dx > dy) {
446-
/* bresenham, horizontal slope */
447-
n = dx;
448-
dy += dy;
449-
e = dy - dx;
450-
dx += dx;
451-
452-
for (i = 0; i < n; i++) {
453-
point32rgba(im, x0, y0, ink);
454-
if (e >= 0) {
455-
y0 += ys;
456-
e -= dx;
457-
}
458-
e += dy;
459-
x0 += xs;
460-
}
461-
462-
} else {
463-
/* bresenham, vertical slope */
464-
n = dy;
465-
dx += dx;
466-
e = dx - dy;
467-
dy += dy;
468-
469-
for (i = 0; i < n; i++) {
470-
point32rgba(im, x0, y0, ink);
471-
if (e >= 0) {
472-
x0 += xs;
473-
e -= dy;
474-
}
475-
e += dx;
476-
y0 += ys;
477-
}
478-
}
341+
GEN_LINE(point32rgba, hline32rgba);
479342
}
343+
#undef GEN_LINE
480344

481345
static int
482346
x_cmp(const void *x0, const void *x1) {

0 commit comments

Comments
 (0)