fermium/surface.rs
1//! Module for SDL's in-memory bitmap type.
2
3use crate::{
4 blendmode::*, c_char, c_int, c_void, pixels::*, rect::*, rwops::*, stdinc::*,
5};
6
7// makes rustdoc link properly!
8#[allow(unused)]
9use crate::error::*;
10
11/// Surface uses preallocated memory
12pub const SDL_PREALLOC: u32 = 0x00000001;
13/// Surface is RLE encoded
14pub const SDL_RLEACCEL: u32 = 0x00000002;
15/// Surface is referenced internally
16pub const SDL_DONTFREE: u32 = 0x00000004;
17/// Surface uses aligned memory
18pub const SDL_SIMD_ALIGNED: u32 = 0x00000008;
19
20/// Checks if an [`SDL_Surface`] must be locked before the pixels are accessed
21/// directly.
22#[inline]
23#[must_use]
24pub unsafe fn SDL_MUSTLOCK(s: *const SDL_Surface) -> bool {
25 ((*s).flags & SDL_RLEACCEL) != 0
26}
27
28/// A newtype'd `c_void`.
29#[allow(unused)]
30#[repr(transparent)]
31pub struct SDL_BlitMap(c_void);
32
33/// Represents a bitmap image in CPU memory.
34///
35/// Generally, you should not touch these fields yourself.
36#[derive(Debug)]
37#[repr(C)]
38#[allow(missing_docs)]
39pub struct SDL_Surface {
40 /// Read-only
41 pub flags: Uint32,
42 /// Read-only
43 pub format: *mut SDL_PixelFormat,
44 /// Read-only
45 pub w: c_int,
46 /// Read-only
47 pub h: c_int,
48 /// Read-only
49 pub pitch: c_int,
50 /// Read-write
51 pub pixels: *mut c_void,
52 /// Application data associated with the surface, Read-write
53 pub userdata: *mut c_void,
54 /// information needed for surfaces requiring locks, Read-only
55 pub locked: c_int,
56 /// list of BlitMap that hold a reference to this surface, Private
57 pub list_blitmap: *mut c_void,
58 /// clipping information, Read-only
59 pub clip_rect: SDL_Rect,
60 /// info for fast blit mapping to other surfaces, Private
61 pub map: *mut SDL_BlitMap,
62 /// Reference count -- used when freeing surface, Read-mostly
63 pub refcount: c_int,
64}
65
66/// The formula used for converting between YUV and RGB.
67#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
68#[repr(transparent)]
69pub struct SDL_YUV_CONVERSION_MODE(pub u32);
70/// Full range JPEG
71pub const SDL_YUV_CONVERSION_JPEG: SDL_YUV_CONVERSION_MODE =
72 SDL_YUV_CONVERSION_MODE(0);
73/// BT.601 (the default)
74pub const SDL_YUV_CONVERSION_BT601: SDL_YUV_CONVERSION_MODE =
75 SDL_YUV_CONVERSION_MODE(1);
76/// BT.709
77pub const SDL_YUV_CONVERSION_BT709: SDL_YUV_CONVERSION_MODE =
78 SDL_YUV_CONVERSION_MODE(2);
79/// BT.601 for SD content, BT.709 for HD content
80pub const SDL_YUV_CONVERSION_AUTOMATIC: SDL_YUV_CONVERSION_MODE =
81 SDL_YUV_CONVERSION_MODE(3);
82
83/// Given a file path to a BMP file, load and parse it into an [`SDL_Surface`]
84/// as one step.
85///
86/// **Return:** As [`SDL_LoadBMP_RW`]: the new surface, or NULL if there was an
87/// error.
88#[inline]
89pub unsafe fn SDL_LoadBMP(file: *const c_char) -> *mut SDL_Surface {
90 SDL_LoadBMP_RW(SDL_RWFromFile(file, b"rb\0".as_ptr().cast()), 1)
91}
92
93/// Save an [`SDL_Surface`] to the file path specified.
94///
95/// **Return:** As [`SDL_SaveBMP_RW`]: 0 if successful or -1 if there was an
96/// error.
97#[inline]
98pub unsafe fn SDL_SaveBMP(
99 surface: *mut SDL_Surface, file: *const c_char,
100) -> c_int {
101 SDL_SaveBMP_RW(surface, SDL_RWFromFile(file, b"wb\0".as_ptr().cast()), 1)
102}
103
104extern "C" {
105 /// Allocate a new RGB surface.
106 ///
107 /// If the depth is 4 or 8 bits, an empty palette is allocated for the
108 /// surface. If the depth is greater than 8 bits, the pixel format is set
109 /// using the flags `[RGB]mask`.
110 ///
111 /// If the function runs out of memory, it will return NULL.
112 ///
113 /// * `flags`: The `flags` are obsolete and should be set to 0.
114 /// * `width`: The width in pixels of the surface to create.
115 /// * `height`: The height in pixels of the surface to create.
116 /// * `depth`: The depth in bits of the surface to create.
117 /// * `Rmask`: The red mask of the surface to create.
118 /// * `Gmask`: The green mask of the surface to create.
119 /// * `Bmask`: The blue mask of the surface to create.
120 /// * `Amask`: The alpha mask of the surface to create.
121 ///
122 /// **Return:** A new [`SDL_Surface`], or NULL on error (call
123 /// [`SDL_GetErrorMsg`] for more info).
124 ///
125 /// **Note:** This actually uses [`SDL_MasksToPixelFormatEnum`] to determine a
126 /// pixel format enum value, and then calls
127 /// [`SDL_CreateRGBSurfaceWithFormat`]. If you already know the pixel format
128 /// enum value, then you can use that function directly.
129 pub fn SDL_CreateRGBSurface(
130 flags: Uint32, width: c_int, height: c_int, depth: c_int, Rmask: Uint32,
131 Gmask: Uint32, Bmask: Uint32, Amask: Uint32,
132 ) -> *mut SDL_Surface;
133
134 /// Similar to [`SDL_CreateRGBSurface`], but using a pixel format enum value.
135 pub fn SDL_CreateRGBSurfaceWithFormat(
136 flags: Uint32, width: c_int, height: c_int, depth: c_int, format: Uint32,
137 ) -> *mut SDL_Surface;
138
139 /// Makes a surface from a pre-allocated buffer.
140 ///
141 /// The surface depends on the pixels allocation for its lifetime, but has the
142 /// `PRE_ALLOC` flag so it won't free the pixels on its own. In other words,
143 /// this works like a borrow rather than like an ownership transfer.
144 pub fn SDL_CreateRGBSurfaceFrom(
145 pixels: *mut c_void, width: c_int, height: c_int, depth: c_int,
146 pitch: c_int, Rmask: Uint32, Gmask: Uint32, Bmask: Uint32, Amask: Uint32,
147 ) -> *mut SDL_Surface;
148
149 /// Makes a surface from a pre-allocated buffer in a specified format.
150 ///
151 /// This is like a combination of [`SDL_CreateRGBSurfaceWithFormat`] and
152 /// [`SDL_CreateRGBSurfaceFrom`].
153 pub fn SDL_CreateRGBSurfaceWithFormatFrom(
154 pixels: *mut c_void, width: c_int, height: c_int, depth: c_int,
155 pitch: c_int, format: Uint32,
156 ) -> *mut SDL_Surface;
157
158 /// Frees the surface.
159 ///
160 /// This doesn't necessarily free any memory. Surfaces use ref counting for
161 /// some things, and this will only actually free the memory if the ref count
162 /// goes to 0. Also, they can be formed using borrowed memory, and in that
163 /// case freeing the surface will not free the borrowed pixel memory itself.
164 pub fn SDL_FreeSurface(surface: *mut SDL_Surface);
165
166 /// Set the palette used by a surface.
167 ///
168 /// A single palette can be shared with many surfaces.
169 ///
170 /// **Return:** 0, or -1 if the surface format doesn't use a palette.
171 pub fn SDL_SetSurfacePalette(
172 surface: *mut SDL_Surface, palette: *mut SDL_Palette,
173 ) -> c_int;
174
175 /// Sets up a surface for directly accessing the pixels.
176 ///
177 /// Between calls to [`SDL_LockSurface`] / [`SDL_UnlockSurface`], you can
178 /// write to and read from `surface->pixels`, using the pixel format stored
179 /// in `surface->format`. Once you are done accessing the surface, you
180 /// should use [`SDL_UnlockSurface`] to release it.
181 ///
182 /// Not all surfaces require locking. If
183 /// [`SDL_MUSTLOCK(surface)`](SDL_MUSTLOCK) evaluates to 0, then you can
184 /// read and write to the surface at any time, and the pixel format of the
185 /// surface will not change.
186 ///
187 /// No operating system or library calls should be made between lock/unlock
188 /// pairs, as critical system locks may be held during this time.
189 ///
190 /// [`SDL_LockSurface`] returns 0, or -1 if the surface couldn't be locked.
191 pub fn SDL_LockSurface(surface: *mut SDL_Surface) -> c_int;
192
193 /// See [`SDL_LockSurface`]
194 pub fn SDL_UnlockSurface(surface: *mut SDL_Surface);
195
196 /// Load a surface from a seekable SDL data stream (memory or file).
197 ///
198 /// If `freesrc` is non-zero, the stream will be closed after being read.
199 ///
200 /// The new surface should be freed with [`SDL_FreeSurface`].
201 ///
202 /// **Return:** the new surface, or NULL if there was an error.
203 pub fn SDL_LoadBMP_RW(
204 src: *mut SDL_RWops, freesrc: c_int,
205 ) -> *mut SDL_Surface;
206
207 /// Save a surface to a seekable SDL data stream (memory or file).
208 ///
209 /// Surfaces with a 24-bit, 32-bit and paletted 8-bit format get saved in the
210 /// BMP directly. Other RGB formats with 8-bit or higher get converted to a
211 /// 24-bit surface or, if they have an alpha mask or a colorkey, to a 32-bit
212 /// surface before they are saved. YUV and paletted 1-bit and 4-bit formats
213 /// are not supported.
214 ///
215 /// If `freedst` is non-zero, the stream will be closed after being written.
216 ///
217 /// **Return:** 0 if successful or -1 if there was an error.
218 pub fn SDL_SaveBMP_RW(
219 surface: *mut SDL_Surface, dst: *mut SDL_RWops, freedst: c_int,
220 ) -> c_int;
221
222 /// Sets the RLE acceleration hint for a surface.
223 ///
224 /// If RLE is enabled, colorkey and alpha blending blits are much faster,
225 /// but the surface must be locked before directly accessing the pixels.
226 ///
227 /// **Return:** 0 on success, or -1 if the surface is not valid
228 pub fn SDL_SetSurfaceRLE(surface: *mut SDL_Surface, flag: c_int) -> c_int;
229
230 /// Returns whether the surface is RLE enabled
231 ///
232 /// **Returns:** `SDL_TRUE` if the surface is RLE enabled, or `SDL_FALSE` if
233 /// the surface is `NULL` or not RLE enabled
234 pub fn SDL_HasSurfaceRLE(surface: *mut SDL_Surface) -> SDL_bool;
235
236 /// Sets the color key (transparent pixel) in a blit-able surface.
237 ///
238 /// You can pass [`SDL_RLEACCEL`] to enable RLE accelerated blits.
239 ///
240 /// * `surface`: The surface to update
241 /// * `flag`: Non-zero to enable colorkey and 0 to disable colorkey
242 /// * `key`: The transparent pixel in the native surface format
243 ///
244 /// **Return:** 0 on success, or -1 if the surface is not valid
245 pub fn SDL_SetColorKey(
246 surface: *mut SDL_Surface, flag: c_int, key: Uint32,
247 ) -> c_int;
248
249 /// Returns whether the surface has a color key
250 ///
251 /// **Return:** `SDL_TRUE` if the surface has a color key, or `SDL_FALSE` if
252 /// the surface is NULL or has no color key
253 pub fn SDL_HasColorKey(surface: *mut SDL_Surface) -> SDL_bool;
254
255 /// Gets the color key (transparent pixel) in a blit-able surface.
256 ///
257 /// * `surface`: The surface to update
258 /// * `key`: A pointer filled in with the transparent pixel in the native
259 /// surface format
260 ///
261 /// **Return:** 0 on success, or -1 if the surface is not valid or colorkey is
262 /// not enabled.
263 pub fn SDL_GetColorKey(surface: *mut SDL_Surface, key: *mut Uint32) -> c_int;
264
265 /// Set an additional color value used in blit operations.
266 ///
267 /// * `surface`: The surface to update.
268 /// * `r`: The red color value multiplied into blit operations.
269 /// * `g`: The green color value multiplied into blit operations.
270 /// * `b`: The blue color value multiplied into blit operations.
271 ///
272 /// **Return:** 0 on success, or -1 if the surface is not valid.
273 pub fn SDL_SetSurfaceColorMod(
274 surface: *mut SDL_Surface, r: Uint8, g: Uint8, b: Uint8,
275 ) -> c_int;
276
277 /// Get the additional color value used in blit operations.
278 ///
279 /// * `surface`: The surface to query.
280 /// * `r`: A pointer filled in with the current red color value.
281 /// * `g`: A pointer filled in with the current green color value.
282 /// * `b`: A pointer filled in with the current blue color value.
283 ///
284 /// **Return:** 0 on success, or -1 if the surface is not valid.
285 pub fn SDL_GetSurfaceColorMod(
286 surface: *mut SDL_Surface, r: *mut Uint8, g: *mut Uint8, b: *mut Uint8,
287 ) -> c_int;
288
289 /// Get the additional alpha value used in blit operations.
290 ///
291 /// * `surface`: The surface to query.
292 /// * `alpha`: A pointer filled in with the current alpha value.
293 ///
294 /// **Return:** 0 on success, or -1 if the surface is not valid.
295 pub fn SDL_SetSurfaceAlphaMod(
296 surface: *mut SDL_Surface, alpha: Uint8,
297 ) -> c_int;
298
299 /// Set the blend mode used for blit operations.
300 ///
301 /// * `surface`: The surface to update.
302 /// * `blendMode`: [`SDL_BlendMode`] to use for blit blending.
303 ///
304 /// **Return:** 0 on success, or -1 if the parameters are not valid.
305 pub fn SDL_SetSurfaceBlendMode(
306 surface: *mut SDL_Surface, blendMode: SDL_BlendMode,
307 ) -> c_int;
308
309 /// Get the blend mode used for blit operations.
310 ///
311 /// * `surface`: The surface to query.
312 /// * `blendMode`: A pointer filled in with the current blend mode.
313 ///
314 /// **Return:** 0 on success, or -1 if the surface is not valid.
315 pub fn SDL_GetSurfaceBlendMode(
316 surface: *mut SDL_Surface, blendMode: *mut SDL_BlendMode,
317 ) -> c_int;
318
319 /// Sets the clipping rectangle for the destination surface in a blit.
320 ///
321 /// If the clip rectangle is NULL, clipping will be disabled.
322 ///
323 /// If the clip rectangle doesn't intersect the surface, the function will
324 /// return `SDL_FALSE` and blits will be completely clipped. Otherwise the
325 /// function returns `SDL_TRUE` and blits to the surface will be clipped to
326 /// the intersection of the surface area and the clipping rectangle.
327 ///
328 /// Note that blits are automatically clipped to the edges of the source
329 /// and destination surfaces.
330 pub fn SDL_SetClipRect(
331 surface: *mut SDL_Surface, rect: *const SDL_Rect,
332 ) -> SDL_bool;
333
334 /// Gets the clipping rectangle for the destination surface in a blit.
335 ///
336 /// `rect` must be a pointer to a valid rectangle which will be filled
337 /// with the correct values.
338 pub fn SDL_GetClipRect(surface: *mut SDL_Surface, rect: *mut SDL_Rect);
339
340 /// Creates a new surface identical to the existing surface
341 pub fn SDL_DuplicateSurface(surface: *mut SDL_Surface) -> *mut SDL_Surface;
342
343 /// Creates a new surface of the specified format, and then copies and maps
344 /// the given surface to it so the blit of the converted surface will be as
345 /// fast as possible. If this function fails, it returns NULL.
346 ///
347 /// The `flags` parameter is passed to [`SDL_CreateRGBSurface`] and has those
348 /// semantics. You can also pass [`SDL_RLEACCEL`] in the flags parameter and
349 /// SDL will try to RLE accelerate colorkey and alpha blits in the resulting
350 /// surface.
351 pub fn SDL_ConvertSurface(
352 src: *mut SDL_Surface, fmt: *const SDL_PixelFormat, flags: Uint32,
353 ) -> *mut SDL_Surface;
354
355 /// See [`SDL_ConvertSurface`]
356 pub fn SDL_ConvertSurfaceFormat(
357 src: *mut SDL_Surface, pixel_format: Uint32, flags: Uint32,
358 ) -> *mut SDL_Surface;
359
360 /// Copy a block of pixels of one format to another format
361 ///
362 /// **Return:** 0 on success, or -1 if there was an error
363 pub fn SDL_ConvertPixels(
364 width: c_int, height: c_int, src_format: Uint32, src: *const c_void,
365 src_pitch: c_int, dst_format: Uint32, dst: *mut c_void, dst_pitch: c_int,
366 ) -> c_int;
367
368 /// Performs a fast fill of the given rectangle with `color`.
369 ///
370 /// If `rect` is NULL, the whole surface will be filled with `color`.
371 ///
372 /// The color should be a pixel of the format used by the surface, and
373 /// can be generated by the SDL_MapRGB() function.
374 ///
375 /// **Return:** 0 on success, or -1 on error.
376 pub fn SDL_FillRect(
377 dst: *mut SDL_Surface, rect: *const SDL_Rect, color: Uint32,
378 ) -> c_int;
379
380 /// See [`SDL_FillRect`]
381 pub fn SDL_FillRects(
382 dst: *mut SDL_Surface, rects: *const SDL_Rect, count: c_int, color: Uint32,
383 ) -> c_int;
384
385 /// Performs a fast blit from the source surface to the destination surface.
386 ///
387 /// This assumes that the source and destination rectangles are
388 /// the same size. If either `srcrect` or `dstrect` are NULL, the entire
389 /// surface (`src` or `dst`) is copied. The final blit rectangles are saved
390 /// in `srcrect` and `dstrect` after all clipping is performed.
391 ///
392 /// **Return:** If the blit is successful, it returns 0, otherwise it returns
393 /// -1.
394 ///
395 /// The blit function should **not** be called on a locked surface.
396 ///
397 /// The blit semantics for surfaces with and without blending and colorkey
398 /// are defined as follows:
399 /// ```txt
400 /// RGBA->RGB:
401 /// Source surface blend mode set to SDL_BLENDMODE_BLEND:
402 /// alpha-blend (using the source alpha-channel and per-surface alpha)
403 /// SDL_SRCCOLORKEY ignored.
404 /// Source surface blend mode set to SDL_BLENDMODE_NONE:
405 /// copy RGB.
406 /// if SDL_SRCCOLORKEY set, only copy the pixels matching the
407 /// RGB values of the source color key, ignoring alpha in the
408 /// comparison.
409 /// RGB->RGBA:
410 /// Source surface blend mode set to SDL_BLENDMODE_BLEND:
411 /// alpha-blend (using the source per-surface alpha)
412 /// Source surface blend mode set to SDL_BLENDMODE_NONE:
413 /// copy RGB, set destination alpha to source per-surface alpha value.
414 /// both:
415 /// if SDL_SRCCOLORKEY set, only copy the pixels matching the
416 /// source color key.
417 /// RGBA->RGBA:
418 /// Source surface blend mode set to SDL_BLENDMODE_BLEND:
419 /// alpha-blend (using the source alpha-channel and per-surface alpha)
420 /// SDL_SRCCOLORKEY ignored.
421 /// Source surface blend mode set to SDL_BLENDMODE_NONE:
422 /// copy all of RGBA to the destination.
423 /// if SDL_SRCCOLORKEY set, only copy the pixels matching the
424 /// RGB values of the source color key, ignoring alpha in the
425 /// comparison.
426 /// RGB->RGB:
427 /// Source surface blend mode set to SDL_BLENDMODE_BLEND:
428 /// alpha-blend (using the source per-surface alpha)
429 /// Source surface blend mode set to SDL_BLENDMODE_NONE:
430 /// copy RGB.
431 /// both:
432 /// if SDL_SRCCOLORKEY set, only copy the pixels matching the
433 /// source color key.
434 /// ```
435 ///
436 /// You should call [`SDL_BlitSurface`] unless you know exactly how SDL
437 /// blitting works internally and how to use the other blit functions.
438 #[link_name = "SDL_UpperBlit"]
439 pub fn SDL_BlitSurface(
440 src: *mut SDL_Surface, srcrect: *const SDL_Rect, dst: *mut SDL_Surface,
441 dstrect: *mut SDL_Rect,
442 ) -> c_int;
443
444 /// This is the public scaled blit function, SDL_BlitScaled(), and it performs
445 /// rectangle validation and clipping before passing it to
446 /// SDL_LowerBlitScaled()
447 #[link_name = "SDL_UpperBlitScaled"]
448 pub fn SDL_BlitScaled(
449 src: *mut SDL_Surface, srcrect: *const SDL_Rect, dst: *mut SDL_Surface,
450 dstrect: *mut SDL_Rect,
451 ) -> c_int;
452
453 /// Set the YUV conversion mode
454 pub fn SDL_SetYUVConversionMode(mode: SDL_YUV_CONVERSION_MODE);
455
456 /// Get the YUV conversion mode
457 pub fn SDL_GetYUVConversionMode() -> SDL_YUV_CONVERSION_MODE;
458
459 /// Get the YUV conversion mode.
460 ///
461 /// Returns the correct mode for the resolution when the current conversion
462 /// mode is `SDL_YUV_CONVERSION_AUTOMATIC`
463 pub fn SDL_GetYUVConversionModeForResolution(
464 width: c_int, height: c_int,
465 ) -> SDL_YUV_CONVERSION_MODE;
466
467 /// Perform bilinear scaling between two surfaces of the same format, 32BPP.
468 pub fn SDL_SoftStretchLinear(
469 src: *mut SDL_Surface, srcrect: *const SDL_Rect, dst: *mut SDL_Surface,
470 dstrect: *const SDL_Rect,
471 ) -> c_int;
472}