Class: SDL2::Surface

Inherits:
Object
  • Object
show all
Defined in:
ext/sdl2_ext/video.c,
ext/sdl2_ext/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)


2905
2906
2907
2908
2909
2910
2911
2912
# File 'ext/sdl2_ext/video.c', line 2905

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

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

Perform a fast scaling 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)


2930
2931
2932
2933
2934
2935
2936
2937
# File 'ext/sdl2_ext/video.c', line 2930

static VALUE Surface_s_blit_scaled(VALUE self, VALUE src, VALUE srcrect, VALUE dst, VALUE dstrect)
{
    HANDLE_ERROR(SDL_BlitScaled(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



2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
# File 'ext/sdl2_ext/video.c', line 2527

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:



4033
4034
4035
4036
4037
4038
4039
4040
4041
# File 'ext/sdl2_ext/video.c', line 4033

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.



2495
2496
2497
2498
2499
2500
2501
2502
2503
# File 'ext/sdl2_ext/video.c', line 2495

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:



2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
# File 'ext/sdl2_ext/video.c', line 2959

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

Instance Method Details

#bits_per_pixelInteger

Get bits per pixel of the surface.

Returns:

  • (Integer)


2708
2709
2710
2711
# File 'ext/sdl2_ext/video.c', line 2708

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:



2590
2591
2592
2593
2594
2595
# File 'ext/sdl2_ext/video.c', line 2590

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:



2605
2606
2607
2608
2609
# File 'ext/sdl2_ext/video.c', line 2605

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

#blit_to(dst, x, y) ⇒ self

Perform a fast blit to *dst* surface.

Parameters:

  • dst (SDL2::Surface)

    the destination surface

  • x (Integer)
  • y (Integer)

    Blits this surface onto the given destination surface at the given coordinates.

Returns:

  • (self)


2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
# File 'ext/sdl2_ext/video.c', line 2854

static VALUE Surface_blit_to(VALUE self, VALUE dst, VALUE x, VALUE y)
{
    SDL_Surface *surface = Get_SDL_Surface(self);
    SDL_Rect rect;

    rect.x = FIX2INT(x);
    rect.y = FIX2INT(y);
    rect.w = surface->w;
    rect.h = surface->h;

    HANDLE_ERROR(SDL_BlitSurface(surface,
                                 NULL,
                                 Get_SDL_Surface(dst),
                                 &rect));
    return self;
}

#bytes_per_pixelInteger

Get bytes per pixel of the surface.

Returns:

  • (Integer)


2718
2719
2720
2721
# File 'ext/sdl2_ext/video.c', line 2718

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:



2813
2814
2815
2816
2817
2818
2819
2820
# File 'ext/sdl2_ext/video.c', line 2813

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:



2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
# File 'ext/sdl2_ext/video.c', line 2794

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:



2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
# File 'ext/sdl2_ext/video.c', line 2572

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)

#fill_rect(rect, color) ⇒ nil

Draw a filled rectangle using the given color.

Parameters:

  • rect (SDL2::Rect)

    the drawing rectangle

  • color (Integer)

Returns:

  • (nil)


2881
2882
2883
2884
2885
2886
2887
# File 'ext/sdl2_ext/video.c', line 2881

static VALUE Surface_fill_rect(VALUE self, VALUE rect, VALUE rgba)
{
    /* Remove alpha channel */
    Uint32 color = NUM2UINT(rgba) >> 8;
    HANDLE_ERROR(SDL_FillRect(Get_SDL_Surface(self), Get_SDL_Rect_or_NULL(rect), color));
    return Qnil;
}

#hInteger

Get the height of the surface.

Returns:

  • (Integer)


2837
2838
2839
2840
# File 'ext/sdl2_ext/video.c', line 2837

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

#locknil

Lock the surface.

Returns:

  • (nil)

See Also:



2630
2631
2632
2633
2634
# File 'ext/sdl2_ext/video.c', line 2630

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:



2617
2618
2619
2620
# File 'ext/sdl2_ext/video.c', line 2617

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)


2698
2699
2700
2701
# File 'ext/sdl2_ext/video.c', line 2698

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:



2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
# File 'ext/sdl2_ext/video.c', line 2660

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.



2733
2734
2735
2736
2737
2738
2739
2740
2741
# File 'ext/sdl2_ext/video.c', line 2733

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)


2686
2687
2688
2689
2690
2691
# File 'ext/sdl2_ext/video.c', line 2686

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:



2643
2644
2645
2646
2647
# File 'ext/sdl2_ext/video.c', line 2643

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:



2775
2776
2777
2778
2779
# File 'ext/sdl2_ext/video.c', line 2775

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)


2827
2828
2829
2830
# File 'ext/sdl2_ext/video.c', line 2827

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