Class: SDL2::Surface

Inherits:
Object
  • Object
show all
Defined in:
video.c,
video.c

Overview

This class represents bitmap images (collection of pixels).

Normally in SDL2, this class is not used for drawing a image on a window. Texture is used for the purpose.

Mainly this class is for compatibility with SDL1, but the class is useful for simple pixel manipulation. For example, TTF can create only surfaces, not textures. You can convert a surface to texture with Renderer#create_texture_from.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.blit(src, srcrect, dst, dstrect) ⇒ nil

Perform a fast blit from src surface to dst surface.

Parameters:

  • src (SDL2::Surface)

    the source surface

  • srcrect (SDL2::Rect, nil)

    the region in the source surface, if nil is given, the whole source is used

  • dst (SDL2::Surface)

    the destination surface

  • dstrect (SDL2::Rect, nil)

    the region in the destination surface if nil is given, the source image is copied to (0, 0) on the destination surface. dstrect is changed by this method to store the actually copied region (since the surface has clipping functionality, actually copied region may be different from given dstrect).

Returns:

  • (nil)


2386
2387
2388
2389
2390
2391
2392
2393
# File 'video.c', line 2386

static VALUE Surface_s_blit(VALUE self, VALUE src, VALUE srcrect, VALUE dst, VALUE dstrect)
{
    HANDLE_ERROR(SDL_BlitSurface(Get_SDL_Surface(src),
                                 Get_SDL_Rect_or_NULL(srcrect),
                                 Get_SDL_Surface(dst),
                                 Get_SDL_Rect_or_NULL(dstrect)));
    return Qnil;
}

.from_string(string, width, heigth, depth, pitch = nil, rmask = nil, gmask = nil, bmask = nil, amask = nil) ⇒ SDL2::Surface

Create a RGB surface from pixel data as String object.

If rmask, gmask, bmask are omitted, the default masks are used. If amask is omitted, alpha mask is considered to be zero.

Parameters:

  • string (String)

    the pixel data

  • width (Integer)

    the width of the creating surface

  • height (Integer)

    the height of the creating surface

  • depth (Integer)

    the color depth (in bits) of the creating surface

  • pitch (Integer) (defaults to: nil)

    the number of bytes of one scanline if this argument is omitted, width*depth/8 is used.

  • rmask (Integer) (defaults to: nil)

    the red mask of a pixel

  • gmask (Integer) (defaults to: nil)

    the green mask of a pixel

  • bmask (Integer) (defaults to: nil)

    the blue mask of a pixel

  • amask (Integer) (defaults to: nil)

    the alpha mask of a pixel

Returns:

Raises:

  • (SDL2::Error)

    raised when an error occurs in C SDL library



2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
# File 'video.c', line 2054

static VALUE Surface_s_from_string(int argc, VALUE* argv, VALUE self)
{
    VALUE string, width, height, depth, pitch, Rmask, Gmask, Bmask, Amask;
    int w, h, d, p, r, g, b, a;
    SDL_Surface* surface;
    void* pixels;
    Surface* s;

    rb_scan_args(argc, argv, "45", &string, &width, &height, &depth,
                 &pitch, &Rmask, &Gmask, &Bmask, &Amask);
    StringValue(string);
    w = NUM2INT(width);
    h = NUM2INT(height);
    d = NUM2INT(depth);
    p = (pitch == Qnil) ? d*w/8 : NUM2INT(pitch);
    r = (Rmask == Qnil) ? 0 : NUM2UINT(Rmask);
    g = (Gmask == Qnil) ? 0 : NUM2UINT(Gmask);
    b = (Bmask == Qnil) ? 0 : NUM2UINT(Bmask);
    a = (Amask == Qnil) ? 0 : NUM2UINT(Amask);

    if (RSTRING_LEN(string) < p*h)
        rb_raise(rb_eArgError, "String too short");
    if (p < d*w/8 )
        rb_raise(rb_eArgError, "pitch too small");

    pixels = ruby_xmalloc(RSTRING_LEN(string));
    memcpy(pixels, RSTRING_PTR(string), RSTRING_LEN(string));
    surface = SDL_CreateRGBSurfaceFrom(pixels, w, h, d, p, r, g, b, a);
    if (!surface)
        SDL_ERROR();

    RB_GC_GUARD(string);

    s = ALLOC(Surface);
    s->surface = surface;
    s->need_to_free_pixels = 1;
    return Data_Wrap_Struct(cSurface, 0, Surface_free, s);
}

.load(file) ⇒ SDL2::Surface

Load file and create a new SDL2::Surface.

This method uses SDL_image. SDL_image supports following formats: BMP, CUR, GIF, ICO, JPG, LBP, PCX, PNG, PNM, TGA, TIF, XCF, XPM, and XV.

Parameters:

  • file (String)

    the image file name to load a surface from

Returns:

Raises:

  • (SDL2::Error)

    raised when you fail to load (for example, you have a wrong file name, or the file is broken)

See Also:



3465
3466
3467
3468
3469
3470
3471
3472
3473
# File 'video.c', line 3465

static VALUE Surface_s_load(VALUE self, VALUE fname)
{
    SDL_Surface* surface = IMG_Load(StringValueCStr(fname));
    if (!surface) {
        SDL_SetError("%s", IMG_GetError());
        SDL_ERROR();
    }
    return Surface_new(surface);
}

.load_bmp(path) ⇒ SDL2::Surface

Load a surface from bmp file.

Parameters:

  • path (String)

    bmp file path

Returns:

Raises:

  • (SDL2::Error)

    raised when an error occurs. For example, if there is no file or the file file format is not Windows BMP.



2002
2003
2004
2005
2006
2007
2008
2009
2010
# File 'video.c', line 2002

static VALUE Surface_s_load_bmp(VALUE self, VALUE fname)
{
    SDL_Surface* surface = SDL_LoadBMP(StringValueCStr(fname));

    if (surface == NULL)
        HANDLE_ERROR(-1);

    return Surface_new(surface);
}

.new(width, height, depth) ⇒ SDL2::Surface .new(width, height, depth, amask) ⇒ SDL2::Surface .new(width, heigth, depth, rmask, gmask, bmask, amask) ⇒ SDL2::Surface

Create an empty RGB surface.

If rmask, gmask, bmask are omitted, the default masks are used. If amask is omitted, alpha mask is considered to be zero.

Parameters:

  • width (Integer)

    the width of the new surface

  • height (Integer)

    the height of the new surface

  • depth (Integer)

    the bit depth of the new surface

  • rmask (Integer)

    the red mask of a pixel

  • gmask (Integer)

    the green mask of a pixel

  • bmask (Integer)

    the blue mask of a pixel

  • amask (Integer)

    the alpha mask of a pixel

Returns:



2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
# File 'video.c', line 2415

static VALUE Surface_s_new(int argc, VALUE* argv, VALUE self)
{
    VALUE width, height, depth;
    Uint32 Rmask, Gmask, Bmask, Amask;
    SDL_Surface * surface;

    if  (argc == 3) {
        rb_scan_args(argc, argv, "30", &width, &height, &depth);
        Rmask = Gmask = Bmask = Amask = 0;
    } else if (argc == 7) {
        VALUE rm, gm, bm, am;
        rb_scan_args(argc, argv, "70", &width, &height, &depth, &rm, &gm, &bm, &am);
        Rmask = NUM2UINT(rm); Gmask = NUM2UINT(gm);
        Bmask = NUM2UINT(bm); Amask = NUM2UINT(am);
    } else {
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 4 or 7)", argc);
    }

    surface = SDL_CreateRGBSurface(0, NUM2INT(width), NUM2INT(height), NUM2INT(depth),
                                   Rmask, Gmask, Bmask, Amask);
    if (!surface)
        SDL_ERROR();

    return Surface_new(surface);
}

.save_bmp(src, path) ⇒ Integer

Save a surface to bmp file.

Parameters:

  • src (SDL2::Surface)

    surface source

  • path (String)

    bmp file path

Returns:

  • (Integer)

Raises:



2022
2023
2024
2025
2026
2027
2028
2029
2030
# File 'video.c', line 2022

static VALUE Surface_s_save_bmp(VALUE self, VALUE src, VALUE fname)
{
    SDL_Surface* surface = Get_SDL_Surface(src);

    if (surface == NULL)
        HANDLE_ERROR(-1);

    return INT2NUM(SDL_SaveBMP(surface, StringValueCStr(fname)));
}

Instance Method Details

#bits_per_pixelInteger

Get bits per pixel of the surface.

Returns:

  • (Integer)


2235
2236
2237
2238
# File 'video.c', line 2235

static VALUE Surface_bits_per_pixel(VALUE self)
{
    return UCHAR2NUM(Get_SDL_Surface(self)->format->BitsPerPixel);
}

#blend_modeInteger

Get the blending mode of the surface used for blit operations.

Returns:

  • (Integer)

See Also:



2117
2118
2119
2120
2121
2122
# File 'video.c', line 2117

static VALUE Surface_blend_mode(VALUE self)
{
    SDL_BlendMode mode;
    HANDLE_ERROR(SDL_GetSurfaceBlendMode(Get_SDL_Surface(self), &mode));
    return INT2FIX(mode);
}

#blend_mode=(mode) ⇒ mode

Set the blending mode of the surface used for blit operations.

Parameters:

  • mode (Integer)

    the blending mode

Returns:

  • (mode)

See Also:



2132
2133
2134
2135
2136
# File 'video.c', line 2132

static VALUE Surface_set_blend_mode(VALUE self, VALUE mode)
{
    HANDLE_ERROR(SDL_SetSurfaceBlendMode(Get_SDL_Surface(self), NUM2INT(mode)));
    return mode;
}

#bytes_per_pixelInteger

Get bytes per pixel of the surface.

Returns:

  • (Integer)


2245
2246
2247
2248
# File 'video.c', line 2245

static VALUE Surface_bytes_per_pixel(VALUE self)
{
    return UCHAR2NUM(Get_SDL_Surface(self)->format->BytesPerPixel);
}

#color_keyInteger

Get the color key of the surface

Returns:

  • (Integer)

    the color key, as pixel value (see #pixel)

See Also:



2340
2341
2342
2343
2344
2345
2346
2347
# File 'video.c', line 2340

static VALUE Surface_color_key(VALUE self)
{
    Uint32 key;
    if (SDL_GetColorKey(Get_SDL_Surface(self), &key) < 0)
        return Qnil;
    else
        return UINT2NUM(key);
}

#color_key=(key) ⇒ key

Set the color key of the surface

Parameters:

  • key (Integer, Array<Integer>)

    the color key, pixel value (see #pixel) or pixel color (array of three or four integer elements).

Returns:

  • (key)

See Also:



2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
# File 'video.c', line 2321

static VALUE Surface_set_color_key(VALUE self, VALUE key)
{
    SDL_Surface* surface = Get_SDL_Surface(self);
    if (key == Qnil)
        return Surface_unset_color_key(self);

    HANDLE_ERROR(SDL_SetColorKey(surface, SDL_TRUE, pixel_value(key, surface->format)));

    return key;
}

#destroynil

Destroy the surface and deallocate the memory for pixels.

Returns:

  • (nil)

See Also:



2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
# File 'video.c', line 2099

static VALUE Surface_destroy(VALUE self)
{
    Surface* s = Get_Surface(self);
    if (s->need_to_free_pixels)
        free(s->surface->pixels);
    s->need_to_free_pixels = 0;
    if (s->surface)
        SDL_FreeSurface(s->surface);
    s->surface = NULL;
    return Qnil;
}

#destroy?Boolean

Return true if the surface is destroyed.

Returns:

  • (Boolean)

#hInteger

Get the height of the surface.

Returns:

  • (Integer)


2364
2365
2366
2367
# File 'video.c', line 2364

static VALUE Surface_h(VALUE self)
{
    return INT2NUM(Get_SDL_Surface(self)->h);
}

#locknil

Lock the surface.

Returns:

  • (nil)

See Also:



2157
2158
2159
2160
2161
# File 'video.c', line 2157

static VALUE Surface_lock(VALUE self)
{
    HANDLE_ERROR(SDL_LockSurface(Get_SDL_Surface(self)));
    return Qnil;
}

#must_lock?Boolean

Return true if the surface need to lock when you get access to the pixel data of the surface.

Returns:

  • (Boolean)

See Also:



2144
2145
2146
2147
# File 'video.c', line 2144

static VALUE Surface_must_lock_p(VALUE self)
{
    return INT2BOOL(SDL_MUSTLOCK(Get_SDL_Surface(self)));
}

#pitchInteger

Get the pitch (bytes per horizontal line) of the surface.

Returns:

  • (Integer)


2225
2226
2227
2228
# File 'video.c', line 2225

static VALUE Surface_pitch(VALUE self)
{
    return UINT2NUM(Get_SDL_Surface(self)->pitch);
}

#pixel(x, y) ⇒ Integer

Get a pixel data at (x, y)

Parameters:

  • x (Integer)

    the x coordinate

  • y (Integer)

    the y coordinate

Returns:

  • (Integer)

    pixel data

See Also:



2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
# File 'video.c', line 2187

static VALUE Surface_pixel(VALUE self, VALUE x_coord, VALUE y_coord)
{
    int x = NUM2INT(x_coord);
    int y = NUM2INT(y_coord);
    SDL_Surface* surface = Get_SDL_Surface(self);
    int offset;
    Uint32 pixel = 0;
    int i;

    if (x < 0 || x >= surface->w || y < 0 || y >= surface->h)
        rb_raise(rb_eArgError, "(%d, %d) out of range for %dx%d",
                 x, y, surface->w, surface->h);
    offset = surface->pitch * y + surface->format->BytesPerPixel * x;
    for (i=0; i<surface->format->BytesPerPixel; ++i) {
        pixel += *((Uint8*)surface->pixels + offset + i) << (8*i);
    }

    return UINT2NUM(SDL_SwapLE32(pixel));
}

#pixel_color(x, y) ⇒ [Integer, Integer, Integer, Integer]

Get the pixel color (r,g,b and a) at (x, y) of the surface.

Parameters:

  • x (Integer)

    the x coordinate

  • y (Integer)

    the y coordinate

Returns:

  • ([Integer, Integer, Integer, Integer])

    the red, green, blue, and alpha component of the specified pixel.



2260
2261
2262
2263
2264
2265
2266
2267
2268
# File 'video.c', line 2260

static VALUE Surface_pixel_color(VALUE self, VALUE x, VALUE y)
{
    Uint32 pixel = NUM2UINT(Surface_pixel(self, x, y));
    SDL_Surface* surface = Get_SDL_Surface(self);
    Uint8 r, g, b, a;
    SDL_GetRGBA(pixel, surface->format, &r, &g, &b, &a);

    return rb_ary_new3(4, UCHAR2NUM(r), UCHAR2NUM(g), UCHAR2NUM(b), UCHAR2NUM(a));
}

#pixelsString

Get all pixel data of the surface as a string.

Returns:

  • (String)


2213
2214
2215
2216
2217
2218
# File 'video.c', line 2213

static VALUE Surface_pixels(VALUE self)
{
    SDL_Surface* surface = Get_SDL_Surface(self);
    int size = surface->h * surface->pitch;
    return rb_str_new(surface->pixels, size);
}

#unlocknil

Unlock the surface.

Returns:

  • (nil)

See Also:



2170
2171
2172
2173
2174
# File 'video.c', line 2170

static VALUE Surface_unlock(VALUE self)
{
    SDL_UnlockSurface(Get_SDL_Surface(self));
    return Qnil;
}

#color_key=(key) ⇒ key

Set the color key of the surface

Parameters:

  • key (Integer, Array<Integer>)

    the color key, pixel value (see #pixel) or pixel color (array of three or four integer elements).

Returns:

  • (key)

See Also:



2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
# File 'video.c', line 2321

static VALUE Surface_set_color_key(VALUE self, VALUE key)
{
    SDL_Surface* surface = Get_SDL_Surface(self);
    if (key == Qnil)
        return Surface_unset_color_key(self);

    HANDLE_ERROR(SDL_SetColorKey(surface, SDL_TRUE, pixel_value(key, surface->format)));

    return key;
}

#wInteger

Get the width of the surface.

Returns:

  • (Integer)


2354
2355
2356
2357
# File 'video.c', line 2354

static VALUE Surface_w(VALUE self)
{
    return INT2NUM(Get_SDL_Surface(self)->w);
}