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)


2457
2458
2459
2460
2461
2462
2463
2464
# File 'video.c', line 2457

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, height, 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



2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
# File 'video.c', line 2124

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;
    VALUE obj;

    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);

    obj = TypedData_Make_Struct(cSurface, Surface, &Surface_data_type, s);
    s->surface = surface;
    s->need_to_free_pixels = 1;
    return obj;
}

.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:



3587
3588
3589
3590
3591
3592
3593
3594
3595
# File 'video.c', line 3587

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.



2072
2073
2074
2075
2076
2077
2078
2079
2080
# File 'video.c', line 2072

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:



2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
# File 'video.c', line 2486

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:



2092
2093
2094
2095
2096
2097
2098
2099
2100
# File 'video.c', line 2092

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)


2306
2307
2308
2309
# File 'video.c', line 2306

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:



2188
2189
2190
2191
2192
2193
# File 'video.c', line 2188

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) ⇒ void

This method returns an undefined value.

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

Parameters:

  • mode (Integer)

    the blending mode

See Also:



2203
2204
2205
2206
2207
# File 'video.c', line 2203

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)


2316
2317
2318
2319
# File 'video.c', line 2316

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:



2411
2412
2413
2414
2415
2416
2417
2418
# File 'video.c', line 2411

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) ⇒ Integer+

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:

  • (Integer, Array<Integer>)

    value

See Also:



2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
# File 'video.c', line 2392

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:



2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
# File 'video.c', line 2170

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)


2435
2436
2437
2438
# File 'video.c', line 2435

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

#locknil

Lock the surface.

Returns:

  • (nil)

See Also:



2228
2229
2230
2231
2232
# File 'video.c', line 2228

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:



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

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)


2296
2297
2298
2299
# File 'video.c', line 2296

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:



2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
# File 'video.c', line 2258

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) ⇒ Array(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:

  • (Array(Integer, Integer, Integer, Integer))

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



2331
2332
2333
2334
2335
2336
2337
2338
2339
# File 'video.c', line 2331

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)


2284
2285
2286
2287
2288
2289
# File 'video.c', line 2284

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:



2241
2242
2243
2244
2245
# File 'video.c', line 2241

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

#unset_color_keynil

Unset the color key of the surface.

Returns:

  • (nil)

See Also:



2373
2374
2375
2376
2377
# File 'video.c', line 2373

static VALUE Surface_unset_color_key(VALUE self)
{
    HANDLE_ERROR(SDL_SetColorKey(Get_SDL_Surface(self), SDL_FALSE, 0));
    return Qnil;
}

#wInteger

Get the width of the surface.

Returns:

  • (Integer)


2425
2426
2427
2428
# File 'video.c', line 2425

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