diff options
Diffstat (limited to 'src/imageDraw.cpp')
-rw-r--r-- | src/imageDraw.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/src/imageDraw.cpp b/src/imageDraw.cpp new file mode 100644 index 0000000..cd40c4a --- /dev/null +++ b/src/imageDraw.cpp @@ -0,0 +1,66 @@ +#include "FLD.hpp" + +FLD::Error +FLD::Image::draw(const DrawImageOpts &opts) const +{ + if (invalid()) + return -1; + + const bool center = opts.f & CENTER; + const bool flip_x = opts.f & FLIP_X; + const bool flip_y = opts.f & FLIP_Y; + + const Uint8 r = fld->drawColor.r * 0xff; + const Uint8 g = fld->drawColor.g * 0xff; + const Uint8 b = fld->drawColor.b * 0xff; + const Uint8 a = fld->drawColor.a * 0xff; + if (SDL_SetTextureColorMod(ptr, r, g, b) < 0) + return fld->sdlError(); + if (SDL_SetTextureAlphaMod(ptr, a) < 0) + return fld->sdlError(); + + auto scale_x = opts.sx; + auto simg_width = (opts.w == INT_MIN) ? width : opts.w; + if (simg_width < 0) { + simg_width *= -1; + scale_x *= -1; + } + if (simg_width + opts.ix > width) + simg_width = width - opts.ix; + + auto scale_y = opts.sy; + auto simg_height = (opts.h == INT_MIN) ? height : opts.h; + if (simg_height < 0) { + simg_height *= -1; + scale_y *= -1; + } + if (simg_height + opts.iy > height) + simg_height = height - opts.iy; + + int flip = 0; + flip |= SDL_FLIP_HORIZONTAL * ((scale_x < 0) ^ flip_x); + flip |= SDL_FLIP_VERTICAL * ((scale_y < 0) ^ flip_y); + + const int w = simg_width * fabs(scale_x); + const int h = simg_height * fabs(scale_y); + const int x = opts.p.x - ((scale_x < 0) ? w : 0); + const int y = opts.p.y - ((scale_y < 0) ? h : 0); + + const SDL_Rect src { + .x = opts.ix, + .y = opts.iy, + .w = simg_width, + .h = simg_height + }; + const SDL_Rect dst { + .x = x - (center ? (int)(simg_width * scale_x / 2) : 0), + .y = y - (center ? (int)(simg_height * scale_y / 2) : 0), + .w = w, + .h = h + }; + + if (SDL_RenderCopyEx(fld->renderer, ptr, &src, &dst, opts.r * 360, + nullptr, static_cast<SDL_RendererFlip>(flip)) < 0) + return fld->sdlError(); + return 0; +} |