//! The Windows "Graphics Device Interface" (GDI).
//!
//! It mostly lets you do 2D drawing in a Window.
use super::*;
use winapi::um::wingdi::{
GetDeviceCaps, StretchDIBits, BITMAPINFO, BLACKNESS, CAPTUREBLT, DIB_PAL_COLORS,
DIB_RGB_COLORS, DSTINVERT, MERGECOPY, MERGEPAINT, NOMIRRORBITMAP, NOTSRCCOPY,
NOTSRCERASE, PATCOPY, PATINVERT, PATPAINT, SRCAND, SRCCOPY, SRCERASE, SRCINVERT,
SRCPAINT, WHITENESS,
};
/// See [`GetDeviceCaps`](https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-getdevicecaps)
#[inline]
pub unsafe fn get_device_caps(hdc: HDC, index: i32) -> i32 {
GetDeviceCaps(hdc, index)
}
/// Describes the color scheme of some Device Independent Bits.
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DibColors {
/// Paletted colors
Pal = DIB_PAL_COLORS,
/// RGB colors
RGB = DIB_RGB_COLORS,
}
/// Common raster operations, See the parameters of
/// [`BitBlt`](https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-bitblt#parameters)
#[repr(u32)]
#[derive(Debug, Clone, Copy)]
pub enum RasterOp {
/// Fill dest with index 0 in the physical palette (defaults to black)
Blackness = BLACKNESS,
/// Includes windows layered on top of your window in the image
CaptureBlt = CAPTUREBLT,
/// Invert the destination rectangle
DstInvert = DSTINVERT,
/// Merge the source and brush with AND
MergeCopy = MERGECOPY,
/// Merge inverted source with dest using OR
MergePaint = MERGEPAINT,
/// Prevents the bitmap from being mirrored
NoMirrorBitmap = NOMIRRORBITMAP,
/// Copies inverted source to destination
NotSrcCopy = NOTSRCCOPY,
/// Combines source and dest with OR, the inverts
NotSrcErase = NOTSRCERASE,
/// Copies the brush into the dest
PatCopy = PATCOPY,
/// XOR brush with dest
PatInvert = PATINVERT,
/// Combine brush with inverted source with OR, then OR with dest
PatPaint = PATPAINT,
/// Source AND dest
SrcAnd = SRCAND,
/// Copies the source to the destination
SrcCopy = SRCCOPY,
/// Source AND inverted dest
SrcErase = SRCERASE,
/// Source XOR dest
SrcInvert = SRCINVERT,
/// Source OR dest
SrcPaint = SRCPAINT,
/// Fill dest with index 1 of physical palette (default to white)
Whiteness = WHITENESS,
}
impl Default for RasterOp {
fn default() -> Self {
RasterOp::SrcCopy
}
}
/// Use with [`stretch_di_bits`](stretch_di_bits)
#[derive(Debug, Clone, Copy)]
pub struct StretchDIBitsArgs {
/// Destination device context handle
pub hdc: HDC,
/// From upper left origin, logical units
pub dest: PointSizeRect,
/// From upper left origin, logical units
pub src: PointSizeRect,
/// Image data
pub bits: *const c_void,
/// Image format information
pub bitmap_info: *const BITMAPINFO,
/// Describes `bmiColors` in the `bitmap_info`
pub usage: DibColors,
/// How to rasterize the data.
pub raster_op: RasterOp,
}
/// See [`StretchDIBits`](https://docs.microsoft.com/en-us/windows/win32/api/wingdi/nf-wingdi-stretchdibits)
#[inline]
pub unsafe fn stretch_di_bits(args: StretchDIBitsArgs) -> Option<i32> {
let result = StretchDIBits(
args.hdc,
args.dest.x,
args.dest.y,
args.dest.width,
args.dest.height,
args.src.x,
args.src.y,
args.src.width,
args.src.height,
args.bits as *const _,
args.bitmap_info,
args.usage as u32,
args.raster_op as u32,
);
if result >= 0 {
Some(result)
} else {
None
}
}