Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Aaline blend test #585

Merged
merged 3 commits into from Nov 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
81 changes: 43 additions & 38 deletions src_c/draw.c
Expand Up @@ -31,8 +31,18 @@

#include <math.h>

/* Many C libraries seem to lack the trunc call (added in C99) */
#define trunc(d) ((int)(d))
/*
Many C libraries seem to lack the trunc call (added in C99).

Not sure int() is usable for all cases where trunc is used in this code?
However casting to int gives quite a speedup over the one defined.
Now sure how it compares to the trunc built into the C library.
#define trunc(d) ((int)(d))
*/
#ifndef trunc
#define trunc(d) (((d) >= 0.0) ? (floor(d)) : (ceil(d)))
#endif

#define FRAC(z) ((z)-trunc(z))
#define INVFRAC(z) (1 - FRAC(z))

Expand Down Expand Up @@ -82,7 +92,6 @@ draw_fillpoly(SDL_Surface *dst, int *vx, int *vy, int n, Uint32 color);
else \
return RAISE(PyExc_TypeError, "invalid color argument");


static PyObject *
aaline(PyObject *self, PyObject *arg)
{
Expand All @@ -102,7 +111,6 @@ aaline(PyObject *self, PyObject *arg)
return NULL;
surf = pgSurface_AsSurface(surfobj);


CHECK_LOAD_COLOR(colorobj)

if (!pg_TwoFloatsFromObj(start, &startx, &starty))
Expand Down Expand Up @@ -228,7 +236,6 @@ aalines(PyObject *self, PyObject *arg)
return NULL;
surf = pgSurface_AsSurface(surfobj);


CHECK_LOAD_COLOR(colorobj)

closed = PyObject_IsTrue(closedobj);
Expand Down Expand Up @@ -538,7 +545,7 @@ circle(PyObject *self, PyObject *arg)
* ellipse. We draw another ellipse offset by a pixel, over
* drawing the missed spots in the filled circle caused by which
* pixels are filled.
*/
*/
if (width > 1 && loop > 0)
draw_ellipse(surf, posx + 1, posy, 2 * (radius - loop),
2 * (radius - loop), 0, color);
Expand Down Expand Up @@ -757,7 +764,7 @@ clip_and_draw_line_width(SDL_Surface *surf, SDL_Rect *rect, Uint32 color,
#define SWAP(a, b, tmp) \
tmp = b; \
b = a; \
a = tmp; \
a = tmp;

/*this line clipping based heavily off of code from
http://www.ncsa.uiuc.edu/Vis/Graphics/src/clipCohSuth.c */
Expand Down Expand Up @@ -980,15 +987,15 @@ get_pixel_32(Uint8 *pixels, SDL_PixelFormat *format)
{
switch (format->BytesPerPixel) {
case 4:
return *((Uint32*)pixels);
return *((Uint32 *)pixels);
case 3:
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
return *pixels | *(pixels+1) << 8 | *(pixels+2) << 16;
return *pixels | *(pixels + 1) << 8 | *(pixels + 2) << 16;
#else
return *pixels << 16 | *(pixels+1) << 8 | *(pixels+2);
return *pixels << 16 | *(pixels + 1) << 8 | *(pixels + 2);
#endif
case 2:
return *((Uint16*)pixels);
return *((Uint16 *)pixels);
case 1:
return *pixels;
}
Expand All @@ -1000,18 +1007,18 @@ set_pixel_32(Uint8 *pixels, SDL_PixelFormat *format, Uint32 pixel)
{
switch (format->BytesPerPixel) {
case 4:
*(Uint32*)pixels = pixel;
*(Uint32 *)pixels = pixel;
break;
case 3:
*(Uint16*)pixels = pixel;
*(Uint16 *)pixels = pixel;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
pixels[2] = pixel >> 16;
#else
pixels[0] = pixel;
#endif
break;
case 2:
*(Uint16*)pixels = pixel;
*(Uint16 *)pixels = pixel;
break;
case 1:
*pixels = pixel;
Expand All @@ -1020,30 +1027,31 @@ set_pixel_32(Uint8 *pixels, SDL_PixelFormat *format, Uint32 pixel)
}

static void
draw_pixel_blended_32(Uint8 *pixels, Uint8 *colors, float br, SDL_PixelFormat *format)
draw_pixel_blended_32(Uint8 *pixels, Uint8 *colors, float br,
SDL_PixelFormat *format)
{
Uint8 pixel32[4];
SDL_GetRGBA(get_pixel_32(pixels, format),
format, &pixel32[0], &pixel32[1], &pixel32[2], &pixel32[3]);
*(Uint32*)pixel32 = SDL_MapRGBA(format,
br * colors[0] + (1 - br) * pixel32[0],
br * colors[1] + (1 - br) * pixel32[1],
br * colors[2] + (1 - br) * pixel32[2],
br * colors[3] + (1 - br) * pixel32[3]);
set_pixel_32(pixels, format, *(Uint32*)pixel32);
SDL_GetRGBA(get_pixel_32(pixels, format), format, &pixel32[0], &pixel32[1],
&pixel32[2], &pixel32[3]);
*(Uint32 *)pixel32 =
SDL_MapRGBA(format, br * colors[0] + (1 - br) * pixel32[0],
br * colors[1] + (1 - br) * pixel32[1],
br * colors[2] + (1 - br) * pixel32[2],
br * colors[3] + (1 - br) * pixel32[3]);
set_pixel_32(pixels, format, *(Uint32 *)pixel32);
}

#define DRAWPIX32(pixels, colorptr, br, blend) {\
if (blend) \
draw_pixel_blended_32(pixels, colorptr, br, surf->format); \
else {\
set_pixel_32(pixels, surf->format, \
SDL_MapRGBA(surf->format, \
br * colorptr[0], \
br * colorptr[1], \
br * colorptr[2], \
br * colorptr[3])); \
}}
#define DRAWPIX32(pixels, colorptr, br, blend) \
{ \
if (blend) \
draw_pixel_blended_32(pixels, colorptr, br, surf->format); \
else { \
set_pixel_32( \
pixels, surf->format, \
SDL_MapRGBA(surf->format, br *colorptr[0], br *colorptr[1], \
br *colorptr[2], br *colorptr[3])); \
} \
}

/* Adapted from http://freespace.virgin.net/hugo.elias/graphics/x_wuline.htm */
static void
Expand All @@ -1060,10 +1068,7 @@ drawaaline(SDL_Surface *surf, Uint32 color, float x1, float y1, float x2,

Uint8 *pixel;
Uint8 *pm = (Uint8 *)surf->pixels;
SDL_GetRGBA(color, surf->format,
&colorptr[0],
&colorptr[1],
&colorptr[2],
SDL_GetRGBA(color, surf->format, &colorptr[0], &colorptr[1], &colorptr[2],
&colorptr[3]);
if (!blend)
colorptr[3] = 255;
Expand Down
13 changes: 13 additions & 0 deletions test/draw_test.py
Expand Up @@ -274,6 +274,19 @@ def test_color_validation(self):
with self.assertRaises(TypeError):
draw.polygon(surf, col, points, 0)

def test_aaline_blend(self):
""" blends correctly with the background color.
"""
surface = pygame.Surface((20, 20))
surface.fill(pygame.Color(0, 255, 0))
draw.aaline(surface, pygame.Color(255, 255, 255), (2, 2), (18, 18), 1)
draw.aaline(surface, pygame.Color(255, 255, 255), (2, 18), (18, 2), 1)

# white should be blended with the background green.
self.assertEqual(surface.get_at((10, 10)), (191, 255, 191, 255))

This comment was marked as off-topic.

# should be full green here.
self.assertEqual(surface.get_at((9, 7)), (0, 255, 0, 255))


class AntiAliasedLineMixin:
'''Mixin for tests of Anti Aliasing of Lines.
Expand Down