Mercurial > foo_out_sdl
view foosdk/sdk/libPPUI/gdiplus_helpers.cpp @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
line wrap: on
line source
#include "stdafx.h" #include "gdiplus_helpers.h" static bool _Once() { ULONG_PTR token = 0; Gdiplus::GdiplusStartupInput input; Gdiplus::GdiplusStartupOutput output; GdiplusErrorHandler() << Gdiplus::GdiplusStartup(&token, &input, &output); return true; } void GdiplusScope::Once() { static bool done = _Once(); (void)done; // suppress warning } void GdiplusErrorHandler::Handle(Gdiplus::Status p_code) { if (p_code != Gdiplus::Ok) { switch (p_code) { case Gdiplus::InvalidParameter: throw pfc::exception_invalid_params(); default: throw std::runtime_error(pfc::format("Gdiplus error (", (unsigned)p_code, ")")); } } } HBITMAP GdiplusLoadBitmap(UINT id, const TCHAR* resType, CSize size) { using namespace Gdiplus; try { auto stream = WinLoadResourceAsStream(GetThisModuleHandle(), MAKEINTRESOURCE(id), resType); GdiplusErrorHandler EH; Image source ( stream ); EH << source.GetLastStatus(); Bitmap resized (size.cx, size.cy, PixelFormat32bppARGB); EH << resized.GetLastStatus(); { Graphics target(&resized); EH << target.GetLastStatus(); EH << target.SetInterpolationMode(InterpolationModeHighQuality); EH << target.Clear(Color(0, 0, 0, 0)); EH << target.DrawImage(&source, Rect(0, 0, size.cx, size.cy)); } HBITMAP bmp = NULL; EH << resized.GetHBITMAP(Gdiplus::Color::White, &bmp); return bmp; } catch (...) { PFC_ASSERT(!"Should not get here"); return NULL; } } std::unique_ptr<Gdiplus::Image> GdiplusImageFromMem(const void* ptr, size_t bytes) { using namespace Gdiplus; GdiplusErrorHandler EH; CComPtr<IStream> stream; stream.p = SHCreateMemStream((const BYTE*)ptr, pfc::downcast_guarded<UINT>(bytes)); if (!stream) throw std::bad_alloc(); std::unique_ptr<Image> source ( new Image(stream.p) ); EH << source->GetLastStatus(); return source; } std::unique_ptr< Gdiplus::Bitmap > GdiplusResizeImage(Gdiplus::Image* source, CSize size, Gdiplus::PixelFormat pf) { PFC_ASSERT(size.cx > 0 && size.cy > 0); using namespace Gdiplus; GdiplusErrorHandler EH; std::unique_ptr<Bitmap> resized ( new Bitmap(size.cx, size.cy, pf) ); EH << resized->GetLastStatus(); Graphics target (resized.get() ); EH << target.GetLastStatus(); EH << target.SetInterpolationMode(InterpolationModeHighQuality); EH << target.Clear(Color(0, 0, 0, 0)); EH << target.DrawImage(source, Rect(0, 0, size.cx, size.cy)); return resized; } HICON GdiplusLoadIconFromMem(const void* ptr, size_t bytes, CSize size) { using namespace Gdiplus; try { GdiplusErrorHandler EH; auto source = GdiplusImageFromMem(ptr, bytes); auto resized = GdiplusResizeImage(source.get(), size); HICON icon = NULL; EH << resized->GetHICON(&icon); return icon; } catch (...) { PFC_ASSERT(!"Should not get here"); return NULL; } } HICON GdiplusLoadIcon(UINT id, const TCHAR* resType, CSize size) { GdiplusIconArg_t arg = { size }; return GdiplusLoadIconEx(id, resType, arg); } HICON GdiplusLoadIconEx(UINT id, const TCHAR* resType, GdiplusIconArg_t const& arg) { using namespace Gdiplus; try { auto stream = WinLoadResourceAsStream(GetThisModuleHandle(), MAKEINTRESOURCE(id), resType); GdiplusErrorHandler EH; Bitmap resized(arg.size.cx, arg.size.cy, PixelFormat32bppARGB); EH << resized.GetLastStatus(); { Image source(stream); EH << source.GetLastStatus(); Graphics target(&resized); EH << target.GetLastStatus(); EH << target.SetInterpolationMode(InterpolationModeHighQuality); EH << target.Clear(Color(0, 0, 0, 0)); EH << target.DrawImage(&source, Rect(0, 0, arg.size.cx, arg.size.cy)); } if (arg.transform) arg.transform(&resized); HICON icon = NULL; EH << resized.GetHICON(&icon); return icon; } catch (...) { PFC_ASSERT(!"Should not get here"); return NULL; } } HICON GdiplusLoadPNGIcon(UINT id, CSize size) { return GdiplusLoadIcon(id, _T("PNG"), size); } HICON LoadPNGIcon(UINT id, CSize size) { GdiplusScope scope; return GdiplusLoadPNGIcon(id, size); } void GdiplusLoadButtonPNG(CIcon& icon, HWND btn_, UINT image, GdiplusBitmapTransform_t transform) { CButton btn(btn_); if (icon == NULL) { CRect client; WIN32_OP_D(btn.GetClientRect(client)); CSize size = client.Size(); int v = MulDiv(pfc::min_t<int>(size.cx, size.cy), 3, 4); if (v < 8) v = 8; GdiplusIconArg_t arg; arg.size = CSize(v, v); arg.transform = transform; icon = GdiplusLoadIconEx(image, L"PNG", arg); } btn.SetIcon(icon); } std::unique_ptr<Gdiplus::Bitmap> GdiplusLoadResource(UINT id, const TCHAR* resType) { using namespace Gdiplus; GdiplusErrorHandler EH; auto stream = WinLoadResourceAsStream(GetThisModuleHandle(), MAKEINTRESOURCE(id), resType); std::unique_ptr<Bitmap> img ( new Bitmap(stream) ); EH << img->GetLastStatus(); return img; } std::unique_ptr<Gdiplus::Bitmap> GdiplusLoadResourceAsSize(UINT id, const TCHAR* resType, CSize size) { auto source = GdiplusLoadResource(id, resType); return GdiplusResizeImage(source.get(), size); } void GdiplusDimImage(Gdiplus::Bitmap* bmp) { using namespace Gdiplus; GdiplusErrorHandler EH; Gdiplus::Rect r(0, 0, bmp->GetWidth(), bmp->GetHeight()); BitmapData data = {}; EH << bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite, PixelFormat32bppARGB, &data); BYTE* scan = (BYTE*)data.Scan0; for (UINT y = 0; y < data.Height; ++y) { BYTE* px = scan; for (UINT x = 0; x < data.Width; ++x) { //px[0] = _dimPixel(px[0]); //px[1] = _dimPixel(px[1]); //px[2] = _dimPixel(px[2]); px[3] /= 3; px += 4; } scan += data.Stride; } EH << bmp->UnlockBits(&data); } void GdiplusInvertImage(Gdiplus::Bitmap* bmp) { using namespace Gdiplus; GdiplusErrorHandler EH; Gdiplus::Rect r(0, 0, bmp->GetWidth(), bmp->GetHeight()); BitmapData data = {}; EH << bmp->LockBits(&r, ImageLockModeRead | ImageLockModeWrite, PixelFormat32bppARGB, &data); BYTE* scan = (BYTE*)data.Scan0; for (UINT y = 0; y < data.Height; ++y) { BYTE* px = scan; for (UINT x = 0; x < data.Width; ++x) { unsigned v = (unsigned)px[0] + (unsigned)px[1] + (unsigned)px[2]; v /= 3; px[0] = px[1] = px[2] = (BYTE)(255 - v); px += 4; } scan += data.Stride; } EH << bmp->UnlockBits(&data); } #pragma comment(lib, "gdiplus.lib")
