latest SDK
This commit is contained in:
233
libPPUI/gdiplus_helpers.h
Normal file
233
libPPUI/gdiplus_helpers.h
Normal file
@@ -0,0 +1,233 @@
|
||||
#pragma once
|
||||
#include <GdiPlus.h>
|
||||
|
||||
#include "win32_op.h"
|
||||
#include "win32_utility.h"
|
||||
|
||||
class GdiplusErrorHandler {
|
||||
public:
|
||||
void operator<<(Gdiplus::Status p_code) {
|
||||
if (p_code != Gdiplus::Ok) {
|
||||
throw pfc::exception(PFC_string_formatter() << "Gdiplus error (" << (unsigned) p_code << ")");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class GdiplusScope {
|
||||
public:
|
||||
GdiplusScope() {
|
||||
Gdiplus::GdiplusStartupInput input;
|
||||
Gdiplus::GdiplusStartupOutput output;
|
||||
GdiplusErrorHandler() << Gdiplus::GdiplusStartup(&m_token,&input,&output);
|
||||
}
|
||||
~GdiplusScope() {
|
||||
Gdiplus::GdiplusShutdown(m_token);
|
||||
}
|
||||
static void Once() {
|
||||
static bool done = _Once();
|
||||
}
|
||||
private:
|
||||
static bool _Once() {
|
||||
ULONG_PTR token = 0;
|
||||
Gdiplus::GdiplusStartupInput input;
|
||||
Gdiplus::GdiplusStartupOutput output;
|
||||
GdiplusErrorHandler() << Gdiplus::GdiplusStartup(&token, &input, &output);
|
||||
return true;
|
||||
}
|
||||
GdiplusScope( const GdiplusScope & ) = delete;
|
||||
void operator=( const GdiplusScope & ) = delete;
|
||||
|
||||
ULONG_PTR m_token = 0;
|
||||
};
|
||||
|
||||
static HBITMAP GdiplusLoadBitmap(UINT id, const TCHAR * resType, CSize size) {
|
||||
using namespace Gdiplus;
|
||||
try {
|
||||
auto stream = WinLoadResourceAsStream(GetThisModuleHandle(), MAKEINTRESOURCE(id), resType );
|
||||
|
||||
GdiplusErrorHandler EH;
|
||||
pfc::ptrholder_t<Image> source = new Image(stream);
|
||||
|
||||
EH << source->GetLastStatus();
|
||||
pfc::ptrholder_t<Bitmap> resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB);
|
||||
EH << resized->GetLastStatus();
|
||||
|
||||
{
|
||||
pfc::ptrholder_t<Graphics> target = new Graphics(resized.get_ptr());
|
||||
EH << target->GetLastStatus();
|
||||
EH << target->SetInterpolationMode(InterpolationModeHighQuality);
|
||||
EH << target->Clear(Color(0,0,0,0));
|
||||
EH << target->DrawImage(source.get_ptr(), 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;
|
||||
}
|
||||
}
|
||||
|
||||
static Gdiplus::Image * GdiplusImageFromMem(const void * ptr, size_t bytes) {
|
||||
using namespace Gdiplus;
|
||||
GdiplusErrorHandler EH;
|
||||
pfc::ptrholder_t<Image> source;
|
||||
|
||||
{
|
||||
pfc::com_ptr_t<IStream> stream;
|
||||
stream.attach( SHCreateMemStream((const BYTE*)ptr, pfc::downcast_guarded<UINT>(bytes)) );
|
||||
if (stream.is_empty()) throw std::bad_alloc();
|
||||
source = new Image(stream.get_ptr());
|
||||
}
|
||||
|
||||
EH << source->GetLastStatus();
|
||||
return source.detach();
|
||||
}
|
||||
|
||||
static Gdiplus::Bitmap * GdiplusResizeImage( Gdiplus::Image * source, CSize size ) {
|
||||
using namespace Gdiplus;
|
||||
GdiplusErrorHandler EH;
|
||||
pfc::ptrholder_t<Bitmap> resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB);
|
||||
EH << resized->GetLastStatus();
|
||||
pfc::ptrholder_t<Graphics> target = new Graphics(resized.get_ptr());
|
||||
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.detach();
|
||||
}
|
||||
|
||||
static HICON GdiplusLoadIconFromMem( const void * ptr, size_t bytes, CSize size ) {
|
||||
using namespace Gdiplus;
|
||||
try {
|
||||
|
||||
GdiplusErrorHandler EH;
|
||||
pfc::ptrholder_t<Image> source = GdiplusImageFromMem(ptr, bytes);
|
||||
pfc::ptrholder_t<Bitmap> resized = GdiplusResizeImage( source.get_ptr(), size );
|
||||
HICON icon = NULL;
|
||||
EH << resized->GetHICON(&icon);
|
||||
return icon;
|
||||
} catch (...) {
|
||||
PFC_ASSERT(!"Should not get here");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static HICON GdiplusLoadIcon(UINT id, const TCHAR * resType, CSize size) {
|
||||
using namespace Gdiplus;
|
||||
try {
|
||||
auto stream = WinLoadResourceAsStream(GetThisModuleHandle(), MAKEINTRESOURCE(id), resType);
|
||||
|
||||
GdiplusErrorHandler EH;
|
||||
pfc::ptrholder_t<Image> source = new Image(stream);
|
||||
|
||||
EH << source->GetLastStatus();
|
||||
pfc::ptrholder_t<Bitmap> resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB);
|
||||
EH << resized->GetLastStatus();
|
||||
|
||||
{
|
||||
pfc::ptrholder_t<Graphics> target = new Graphics(resized.get_ptr());
|
||||
EH << target->GetLastStatus();
|
||||
EH << target->SetInterpolationMode(InterpolationModeHighQuality);
|
||||
EH << target->Clear(Color(0,0,0,0));
|
||||
EH << target->DrawImage(source.get_ptr(), Rect(0,0,size.cx,size.cy));
|
||||
}
|
||||
|
||||
HICON icon = NULL;
|
||||
EH << resized->GetHICON(&icon);
|
||||
return icon;
|
||||
} catch(...) {
|
||||
PFC_ASSERT( !"Should not get here");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
static HICON GdiplusLoadPNGIcon(UINT id, CSize size) {return GdiplusLoadIcon(id, _T("PNG"), size);}
|
||||
|
||||
static HICON LoadPNGIcon(UINT id, CSize size) {
|
||||
GdiplusScope scope;
|
||||
return GdiplusLoadPNGIcon(id, size);
|
||||
}
|
||||
|
||||
static void GdiplusLoadButtonPNG(CIcon & icon, HWND btn_, UINT image) {
|
||||
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;
|
||||
icon = GdiplusLoadPNGIcon(image, CSize(v,v));
|
||||
}
|
||||
btn.SetIcon(icon);
|
||||
}
|
||||
|
||||
static Gdiplus::Bitmap * GdiplusLoadResource(UINT id, const TCHAR * resType) {
|
||||
using namespace Gdiplus;
|
||||
GdiplusErrorHandler EH;
|
||||
|
||||
auto stream = WinLoadResourceAsStream(GetThisModuleHandle(), MAKEINTRESOURCE(id), resType);
|
||||
pfc::ptrholder_t<Bitmap> img = new Bitmap(stream);
|
||||
EH << img->GetLastStatus();
|
||||
return img.detach();
|
||||
}
|
||||
|
||||
static Gdiplus::Bitmap * GdiplusLoadResourceAsSize(UINT id, const TCHAR * resType, CSize size) {
|
||||
using namespace Gdiplus;
|
||||
GdiplusErrorHandler EH;
|
||||
pfc::ptrholder_t<Bitmap> source = GdiplusLoadResource(id, resType);
|
||||
|
||||
pfc::ptrholder_t<Bitmap> resized = new Bitmap(size.cx, size.cy, PixelFormat32bppARGB);
|
||||
EH << resized->GetLastStatus();
|
||||
{
|
||||
pfc::ptrholder_t<Graphics> target = new Graphics(resized.get_ptr());
|
||||
EH << target->GetLastStatus();
|
||||
EH << target->SetInterpolationMode(InterpolationModeHighQuality);
|
||||
EH << target->DrawImage(source.get_ptr(), Rect(0, 0, size.cx, size.cy));
|
||||
}
|
||||
return resized.detach();
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
static 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] = 255 - v;
|
||||
px += 4;
|
||||
}
|
||||
scan += data.Stride;
|
||||
}
|
||||
|
||||
EH << bmp->UnlockBits(&data);
|
||||
}
|
||||
#pragma comment(lib, "gdiplus.lib")
|
||||
Reference in New Issue
Block a user