Exemplo n.º 1
0
def tostring(surface, format, flipped=False):
    """ tostring(Surface, format, flipped=False) -> string
    transfer image to string buffer
    """
    surf = surface._c_surface
    if surf.flags & sdl.SDL_OPENGL:
        raise NotImplementedError()

    if format == "P":
        if surf.format.BytesPerPixel != 1:
            raise ValueError("Can only create \"P\" format data with "
                             "8bit Surfaces")
        with locked(surf):
            string = ffi.buffer(ffi.cast('char*', surf.pixels))[:]
    else:
        _tostring = globals().get('_tostring_%s' % format, None)
        if _tostring is None:
            raise ValueError("Unrecognized type of format")
        with locked(surf):
            string = _tostring(surf, flipped)
    return string
Exemplo n.º 2
0
def tostring(surface, format, flipped=False):
    """ tostring(Surface, format, flipped=False) -> string
    transfer image to string buffer
    """
    surf = surface._c_surface
    if surf.flags & sdl.SDL_OPENGL:
        raise NotImplementedError()

    if format == "P":
        if surf.format.BytesPerPixel != 1:
            raise ValueError("Can only create \"P\" format data with "
                             "8bit Surfaces")
        with locked(surf):
            string = ffi.buffer(ffi.cast('char*', surf.pixels))[:]
    else:
        _tostring = globals().get('_tostring_%s' % format, None)
        if _tostring is None:
            raise ValueError("Unrecognized type of format")
        with locked(surf):
            string = _tostring(surf, flipped)
    return string
Exemplo n.º 3
0
def _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
    if radius_x == 0 and radius_y == 0:
        with locked(surface._c_surface):
            surface._set_at(c_x, c_y, c_color)
        return True
    elif radius_x == 0:
        # vertical line
        _drawvertline(surface, c_color, c_y - radius_y, c_y + radius_y, c_x)
        return True
    elif radius_y == 0:
        _drawhorizline(surface, c_color, c_x - radius_x, c_x + radius_x, c_y)
        return True
    return False
Exemplo n.º 4
0
def polygon(surface, color, points, width=0):
    _check_surface(surface)

    if width != 0:
        return lines(surface, color, 1, points, width)

    c_color = create_color(color, surface._format)
    points = _check_and_filter_points(points, 3)

    with locked(surface._c_surface):
        _draw_fillpoly(surface, points, c_color)

    return _make_drawn_rect(points, surface)
Exemplo n.º 5
0
def _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
    if radius_x == 0 and radius_y == 0:
        with locked(surface._c_surface):
            surface._set_at(c_x, c_y, c_color)
        return True
    elif radius_x == 0:
        # vertical line
        _drawvertline(surface, c_color, c_y - radius_y, c_y + radius_y, c_x)
        return True
    elif radius_y == 0:
        _drawhorizline(surface, c_color, c_x - radius_x, c_x + radius_x, c_y)
        return True
    return False
Exemplo n.º 6
0
def polygon(surface, color, points, width=0):
    _check_surface(surface)

    if width != 0:
        return lines(surface, color, 1, points, width)

    c_color = create_color(color, surface._format)
    points = _check_and_filter_points(points, 3)

    with locked(surface._c_surface):
        _draw_fillpoly(surface, points, c_color)

    return _make_drawn_rect(points, surface)
Exemplo n.º 7
0
def _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
    if radius_x == 0 and radius_y == 0:
        clip = surface.get_clip()
        # Throw away points outside the clip area
        if c_x < clip.x or c_x > (clip.x + clip.w):
            return True
        if c_y < clip.y or c_y > (clip.y + clip.h):
            return True
        with locked(surface._c_surface):
            surface._set_at(c_x, c_y, c_color)
        return True
    elif radius_x == 0:
        # vertical line
        _drawvertline(surface, c_color, c_y - radius_y, c_y + radius_y, c_x)
        return True
    elif radius_y == 0:
        _drawhorizline(surface, c_color, c_x - radius_x, c_x + radius_x, c_y)
        return True
    return False
Exemplo n.º 8
0
def _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
    if radius_x == 0 and radius_y == 0:
        clip = surface.get_clip()
        # Throw away points outside the clip area
        if c_x < clip.x or c_x >= (clip.x + clip.w):
            return True
        if c_y < clip.y or c_y >= (clip.y + clip.h):
            return True
        with locked(surface._c_surface):
            surface._set_at(c_x, c_y, c_color)
        return True
    elif radius_x == 0:
        # vertical line
        _drawvertline(surface, c_color, c_y - radius_y, c_y + radius_y, c_x)
        return True
    elif radius_y == 0:
        _drawhorizline(surface, c_color, c_x - radius_x, c_x + radius_x, c_y)
        return True
    return False
Exemplo n.º 9
0
def line(surface, color, start, end, width=1):
    _check_surface(surface)
    c_color = create_color(color, surface._format)

    _check_point(start, "Invalid start position argument")
    _check_point(end, "Invalid end position argument")

    [start] = _check_and_filter_points([start])
    [end] = _check_and_filter_points([end])

    if width < 1:
        return Rect(start, (0, 0))

    with locked(surface._c_surface):
        drawn = _clip_and_draw_line_width(surface, c_color, width, start, end)

    if drawn is None:
        return Rect(start, (0, 0))
    return drawn
Exemplo n.º 10
0
def line(surface, color, start, end, width=1):
    _check_surface(surface)
    c_color = create_color(color, surface._format)

    _check_point(start, "Invalid start position argument")
    _check_point(end, "Invalid end position argument")

    [start] = _check_and_filter_points([start])
    [end] = _check_and_filter_points([end])

    if width < 1:
        return Rect(start, (0, 0))

    with locked(surface._c_surface):
        drawn = _clip_and_draw_line_width(surface, c_color, width, start, end)

    if drawn is None:
        return Rect(start, (0, 0))
    return drawn
Exemplo n.º 11
0
def lines(surface, color, closed, points, width=1):
    _check_surface(surface)
    c_color = create_color(color, surface._format)
    points = _check_and_filter_points(points, 2)
    drawn_points = set()

    with locked(surface._c_surface):
        start_point = points[0]
        for point in points[1:]:
            drawn = _clip_and_draw_line_width(surface, c_color, width,
                                              start_point, point)
            if drawn is not None:
                drawn_points.add(drawn.topleft)
                drawn_points.add(drawn.bottomright)
            start_point = point

        if closed and len(points) > 2:
            _clip_and_draw_line_width(surface, c_color, width, points[0],
                                      points[-1])

    return _make_drawn_rect(drawn_points, surface)
Exemplo n.º 12
0
def lines(surface, color, closed, points, width=1):
    _check_surface(surface)
    c_color = create_color(color, surface._format)
    points = _check_and_filter_points(points, 2)
    drawn_points = set()

    with locked(surface._c_surface):
        start_point = points[0]
        for point in points[1:]:
            drawn = _clip_and_draw_line_width(
                surface, c_color, width, start_point, point)
            if drawn is not None:
                drawn_points.add(drawn.topleft)
                drawn_points.add(drawn.bottomright)
            start_point = point

        if closed and len(points) > 2:
            _clip_and_draw_line_width(
                surface, c_color, width, points[0], points[-1])

    return _make_drawn_rect(drawn_points, surface)
Exemplo n.º 13
0
def _fillellipse(surface, pos, radius_x, radius_y, color):
    """Internal helper function

       draw a filled ellipse on surface."""
    c_surf = surface._c_surface
    c_x, c_y = pos
    c_color = create_color(color, surface._format)
    if _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
        return
    # Draw the filled ellipse
    # We inherit this structure from pygame
    # We draw by drawing horizontal lines between points, while _ellipse
    # is orientated towards creating vertical pairs.
    # There are also some annoying other differences between how
    # the filled ellipse and hollow ellipse are constructed that makes it
    # hard to do both in a single function
    # Why, pygame, why?

    stop_h = stop_i = stop_j = stop_k = -1

    with locked(c_surf):
        i = 1
        h = 0
        if radius_x > radius_y:
            ix = 0
            iy = radius_x * 64
            while i > h:
                h = (ix + 8) // 64
                i = (iy + 8) // 64
                j = (h * radius_y) // radius_x
                k = (i * radius_y) // radius_x

                if stop_k != k and stop_j != k and k < radius_y:
                    _drawhorizline(surface, c_color, c_x - h, c_x + h - 1,
                                   c_y - k - 1)
                    _drawhorizline(surface, c_color, c_x - h, c_x + h - 1,
                                   c_y + k)
                    stop_k = k
                if stop_j != j and stop_k != j and k != j:
                    _drawhorizline(surface, c_color, c_x - i, c_x + i - 1,
                                   c_y - j - 1)
                    _drawhorizline(surface, c_color, c_x - i, c_x + i - 1,
                                   c_y + j)
                    stop_j = j
                ix = ix + _c_div(iy, radius_x)
                iy = iy - _c_div(ix, radius_x)
        else:
            ix = 0
            iy = radius_y * 64
            while i > h:
                h = (ix + 8) // 64
                i = (iy + 8) // 64
                j = (h * radius_x) // radius_y
                k = (i * radius_x) // radius_y

                if stop_i != i and stop_h != i and i < radius_y:
                    _drawhorizline(surface, c_color, c_x - j, c_x + j - 1,
                                   c_y - i - 1)
                    _drawhorizline(surface, c_color, c_x - j, c_x + j - 1,
                                   c_y + i)
                    stop_i = i
                if stop_h != h and stop_i != h and i != h:
                    _drawhorizline(surface, c_color, c_x - k, c_x + k - 1,
                                   c_y - h - 1)
                    _drawhorizline(surface, c_color, c_x - k, c_x + k - 1,
                                   c_y + h)
                    stop_h = h

                ix = ix + _c_div(iy, radius_y)
                iy = iy - _c_div(ix, radius_y)
Exemplo n.º 14
0
def _ellipse(surface, pos, radius_x, radius_y, color):
    """Internal helper function

       draw a ellipse with line thickness 1 on surface."""
    c_surf = surface._c_surface
    c_x, c_y = pos
    c_color = create_color(color, surface._format)
    if _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
        return
    # Draw the ellipse
    # Pygame's ellipse drawing algorithm appears to come from allegro, via sge
    # and SDL_gfxPrimitives. It's known to be non-optimal, but we're aiming
    # for pygame compatibility, so we're doing the same thing, much as
    # it grates me to do so.
    # We assume suitable diligence in terms of the licensing, but allegro's
    # zlib'ish license should mean we're OK anyway.

    stop_h = stop_i = stop_j = stop_k = -1
    bounds = surface.get_bounding_rect()

    with locked(c_surf):
        i = 1
        h = 0
        if radius_x > radius_y:
            ix = 0
            iy = radius_x * 64
            while i > h:
                h = (ix + 16) // 64
                i = (iy + 16) // 64
                j = (h * radius_y) // radius_x
                k = (i * radius_y) // radius_x

                if (stop_k != k
                        and stop_j != k) or (stop_j != j
                                             and stop_k != k) or (k != j):
                    plus_x = c_x + h - 1
                    minus_x = c_x - h
                    if k > 0:
                        plus_y = c_y + k - 1
                        minus_y = c_y - k
                        if h > 0:
                            if bounds.collidepoint(minus_x, plus_y):
                                surface._set_at(minus_x, plus_y, c_color)
                            if bounds.collidepoint(minus_x, minus_y):
                                surface._set_at(minus_x, minus_y, c_color)
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                    stop_k = k
                    plus_x = c_x + i - 1
                    minus_x = c_x - i
                    if j > 0:
                        plus_y = c_y + j - 1
                        minus_y = c_y - j
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                        if bounds.collidepoint(minus_x, plus_y):
                            surface._set_at(minus_x, plus_y, c_color)
                        if bounds.collidepoint(minus_x, minus_y):
                            surface._set_at(minus_x, minus_y, c_color)
                    stop_j = j
                ix = ix + _c_div(iy, radius_x)
                iy = iy - _c_div(ix, radius_x)
        else:
            ix = 0
            iy = radius_y * 64
            while i > h:
                h = (ix + 32) // 64
                i = (iy + 32) // 64
                j = (h * radius_x) // radius_y
                k = (i * radius_x) // radius_y

                if (stop_i != i
                        and stop_h != i) or (stop_i != h
                                             and stop_h != h) or (h != i):
                    plus_x = c_x + j - 1
                    minus_x = c_x - j
                    if i > 0:
                        plus_y = c_y + i - 1
                        minus_y = c_y - i
                        if j > 0:
                            if bounds.collidepoint(minus_x, plus_y):
                                surface._set_at(minus_x, plus_y, c_color)
                            if bounds.collidepoint(minus_x, minus_y):
                                surface._set_at(minus_x, minus_y, c_color)
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                    stop_i = i
                    plus_x = c_x + k - 1
                    minus_x = c_x - k
                    if h > 0:
                        plus_y = c_y + h - 1
                        minus_y = c_y - h
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                        if bounds.collidepoint(minus_x, plus_y):
                            surface._set_at(minus_x, plus_y, c_color)
                        if bounds.collidepoint(minus_x, minus_y):
                            surface._set_at(minus_x, minus_y, c_color)
                    stop_h = h
                ix = ix + _c_div(iy, radius_y)
                iy = iy - _c_div(ix, radius_y)
Exemplo n.º 15
0
        raise IOError("PNGError: %s" % ffi.string(err_msg[0]))
    return result


def fromstring(string, (w, h), format, flipped=False):
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
Exemplo n.º 16
0
        raise IOError("PNGError: %s" % ffi.string(err_msg[0]))
    return result


def fromstring(string, (w, h), format, flipped=False):
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest =  surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
Exemplo n.º 17
0
def fromstring(string, size, format, flipped=False):
    w, h = size
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest =  surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 3 if flipped else y * w * 3
                row = string[src_start:src_start + w * 3]
                for x in range(0, w * 3, 3):
                    # BYTE0, BYTE1 and BYTE2 are determined by byte order
                    pixels[dest + x + BYTE0] = row[x + BYTE0]
                    pixels[dest + x + BYTE1] = row[x + BYTE1]
                    pixels[dest + x + BYTE2] = row[x + BYTE2]

    elif format in ("RGBA", "RGBAX", "ARGB"):
        if len(string) != w * h * 4:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        if format == "ARGB":
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask, amask = (0xff << 8, 0xff << 16,
                                              0xff << 24, 0xff)
            else:
                rmask, gmask, bmask, amask = (0xff << 16, 0xff << 8,
                                              0xff, 0xff << 24)
            surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SRCALPHA, w, h, 32,
                                            rmask, gmask, bmask, amask)
        else:
            alphamult = format == "RGBA"
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask = 0xff, 0xff << 8, 0xff << 16
                amask = 0xff << 24 if alphamult else 0
            else:
                rmask, gmask, bmask = 0xff << 24, 0xff << 16, 0xff << 8
                amask = 0xff if alphamult else 0
            surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SRCALPHA if alphamult
                                            else 0, w, h, 32, rmask, gmask,
                                            bmask, amask)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 4 if flipped else y * w * 4
                pixels[dest:dest + w * 4]  = string[src_start:src_start + w * 4]

    else:
        raise ValueError("Unrecognized type of format")

    return Surface._from_sdl_surface(surf)
Exemplo n.º 18
0
def _ellipse(surface, pos, radius_x, radius_y, color):
    """Internal helper function

       draw a ellipse with line thickness 1 on surface."""
    c_surf = surface._c_surface
    c_x, c_y = pos
    c_color = create_color(color, surface._format)
    if _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
        return
    # Draw the ellipse
    # Pygame's ellipse drawing algorithm appears to come from allegro, via sge
    # and SDL_gfxPrimitives. It's known to be non-optimal, but we're aiming
    # for pygame compatibility, so we're doing the same thing, much as
    # it grates me to do so.
    # We assume suitable diligence in terms of the licensing, but allegro's
    # zlib'ish license should mean we're OK anyway.

    stop_h = stop_i = stop_j = stop_k = -1
    bounds = surface.get_bounding_rect()

    with locked(c_surf):
        i = 1
        h = 0
        if radius_x > radius_y:
            ix = 0
            iy = radius_x * 64
            while i > h:
                h = (ix + 16) // 64
                i = (iy + 16) // 64
                j = (h * radius_y) // radius_x
                k = (i * radius_y) // radius_x

                if (stop_k != k and stop_j != k) or (stop_j != j and stop_k != k) or (k != j):
                    plus_x = c_x + h - 1
                    minus_x = c_x - h
                    if k > 0:
                        plus_y = c_y + k - 1
                        minus_y = c_y - k
                        if h > 0:
                            if bounds.collidepoint(minus_x, plus_y):
                                surface._set_at(minus_x, plus_y, c_color)
                            if bounds.collidepoint(minus_x, minus_y):
                                surface._set_at(minus_x, minus_y, c_color)
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                    stop_k = k
                    plus_x = c_x + i - 1
                    minus_x = c_x - i
                    if j > 0:
                        plus_y = c_y + j - 1
                        minus_y = c_y - j
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                        if bounds.collidepoint(minus_x, plus_y):
                            surface._set_at(minus_x, plus_y, c_color)
                        if bounds.collidepoint(minus_x, minus_y):
                            surface._set_at(minus_x, minus_y, c_color)
                    stop_j = j
                ix = ix + _c_div(iy, radius_x)
                iy = iy - _c_div(ix, radius_x)
        else:
            ix = 0
            iy = radius_y * 64
            while i > h:
                h = (ix + 32) // 64
                i = (iy + 32) // 64
                j = (h * radius_x) // radius_y
                k = (i * radius_x) // radius_y

                if (stop_i != i and stop_h != i) or (stop_i != h and stop_h != h) or (h != i):
                    plus_x = c_x + j - 1
                    minus_x = c_x - j
                    if i > 0:
                        plus_y = c_y + i - 1
                        minus_y = c_y - i
                        if j > 0:
                            if bounds.collidepoint(minus_x, plus_y):
                                surface._set_at(minus_x, plus_y, c_color)
                            if bounds.collidepoint(minus_x, minus_y):
                                surface._set_at(minus_x, minus_y, c_color)
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                    stop_i = i
                    plus_x = c_x + k - 1
                    minus_x = c_x - k
                    if h > 0:
                        plus_y = c_y + h - 1
                        minus_y = c_y - h
                        if bounds.collidepoint(plus_x, plus_y):
                            surface._set_at(plus_x, plus_y, c_color)
                        if bounds.collidepoint(plus_x, minus_y):
                            surface._set_at(plus_x, minus_y, c_color)
                        if bounds.collidepoint(minus_x, plus_y):
                            surface._set_at(minus_x, plus_y, c_color)
                        if bounds.collidepoint(minus_x, minus_y):
                            surface._set_at(minus_x, minus_y, c_color)
                    stop_h = h
                ix = ix + _c_div(iy, radius_y)
                iy = iy - _c_div(ix, radius_y)
Exemplo n.º 19
0
def fromstring(string, size, format, flipped=False):
    w, h = size
    if w < 1 or h < 1:
        raise ValueError("Resolution must be positive values")

    if format == "P":
        if len(string) != w * h:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast('char*', surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w if flipped else y * w
                pixels[dest:dest + w] = string[src_start:src_start + w]

    elif format == "RGB":
        if len(string) != w * h * 3:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        surf = sdl.SDL_CreateRGBSurface(0, w, h, 24, 0xff, 0xff << 16,
                                        0xff << 8, 0)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 3 if flipped else y * w * 3
                row = string[src_start:src_start + w * 3]
                for x in range(0, w * 3, 3):
                    # BYTE0, BYTE1 and BYTE2 are determined by byte order
                    pixels[dest + x + BYTE0] = row[x + BYTE0]
                    pixels[dest + x + BYTE1] = row[x + BYTE1]
                    pixels[dest + x + BYTE2] = row[x + BYTE2]

    elif format in ("RGBA", "RGBAX", "ARGB"):
        if len(string) != w * h * 4:
            raise ValueError("String length does not equal format and "
                             "resolution size")
        if format == "ARGB":
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask, amask = (0xff << 8, 0xff << 16,
                                              0xff << 24, 0xff)
            else:
                rmask, gmask, bmask, amask = (0xff << 16, 0xff << 8, 0xff,
                                              0xff << 24)
            surf = sdl.SDL_CreateRGBSurface(sdl.SDL_SRCALPHA, w, h, 32, rmask,
                                            gmask, bmask, amask)
        else:
            alphamult = format == "RGBA"
            if get_sdl_byteorder() == sdl.SDL_LIL_ENDIAN:
                rmask, gmask, bmask = 0xff, 0xff << 8, 0xff << 16
                amask = 0xff << 24 if alphamult else 0
            else:
                rmask, gmask, bmask = 0xff << 24, 0xff << 16, 0xff << 8
                amask = 0xff if alphamult else 0
            surf = sdl.SDL_CreateRGBSurface(
                sdl.SDL_SRCALPHA if alphamult else 0, w, h, 32, rmask, gmask,
                bmask, amask)
        if not surf:
            raise SDLError.from_sdl_error()
        with locked(surf):
            pixels = ffi.cast("char*", surf.pixels)
            for y in range(h):
                dest = surf.pitch * y
                src_start = (h - 1 - y) * w * 4 if flipped else y * w * 4
                pixels[dest:dest + w * 4] = string[src_start:src_start + w * 4]

    else:
        raise ValueError("Unrecognized type of format")

    return Surface._from_sdl_surface(surf)
Exemplo n.º 20
0
def _fillellipse(surface, pos, radius_x, radius_y, color):
    """Internal helper function

       draw a filled ellipse on surface."""
    c_surf = surface._c_surface
    c_x, c_y = pos
    c_color = create_color(color, surface._format)
    if _check_special_ellipse(surface, c_x, c_y, radius_x, radius_y, c_color):
        return
    # Draw the filled ellipse
    # We inherit this structure from pygame
    # We draw by drawing horizontal lines between points, while _ellipse
    # is orientated towards creating vertical pairs.
    # There are also some annoying other differences between how
    # the filled ellipse and hollow ellipse are constructed that makes it
    # hard to do both in a single function
    # Why, pygame, why?

    stop_h = stop_i = stop_j = stop_k = -1

    with locked(c_surf):
        i = 1
        h = 0
        if radius_x > radius_y:
            ix = 0
            iy = radius_x * 64
            while i > h:
                h = (ix + 8) // 64
                i = (iy + 8) // 64
                j = (h * radius_y) // radius_x
                k = (i * radius_y) // radius_x

                if stop_k != k and stop_j != k and k < radius_y:
                    _drawhorizline(surface, c_color,
                                   c_x - h, c_x + h - 1, c_y - k - 1)
                    _drawhorizline(surface, c_color,
                                   c_x - h, c_x + h - 1, c_y + k)
                    stop_k = k
                if stop_j != j and stop_k != j and k != j:
                    _drawhorizline(surface, c_color,
                                   c_x - i, c_x + i - 1, c_y - j - 1)
                    _drawhorizline(surface, c_color,
                                   c_x - i, c_x + i - 1, c_y + j)
                    stop_j = j
                ix = ix + _c_div(iy, radius_x)
                iy = iy - _c_div(ix, radius_x)
        else:
            ix = 0
            iy = radius_y * 64
            while i > h:
                h = (ix + 8) // 64
                i = (iy + 8) // 64
                j = (h * radius_x) // radius_y
                k = (i * radius_x) // radius_y

                if stop_i != i and stop_h != i and i < radius_y:
                    _drawhorizline(surface, c_color,
                                   c_x - j, c_x + j - 1, c_y - i - 1)
                    _drawhorizline(surface, c_color,
                                   c_x - j, c_x + j - 1, c_y + i)
                    stop_i = i
                if stop_h != h and stop_i != h and i != h:
                    _drawhorizline(surface, c_color,
                                   c_x - k, c_x + k - 1, c_y - h - 1)
                    _drawhorizline(surface, c_color,
                                   c_x - k, c_x + k - 1, c_y + h)
                    stop_h = h

                ix = ix + _c_div(iy, radius_y)
                iy = iy - _c_div(ix, radius_y)