aboutsummaryrefslogtreecommitdiff
path: root/src/libs/dutil/WixToolset.DUtil/gdiputil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/dutil/WixToolset.DUtil/gdiputil.cpp')
-rw-r--r--src/libs/dutil/WixToolset.DUtil/gdiputil.cpp227
1 files changed, 227 insertions, 0 deletions
diff --git a/src/libs/dutil/WixToolset.DUtil/gdiputil.cpp b/src/libs/dutil/WixToolset.DUtil/gdiputil.cpp
new file mode 100644
index 00000000..b5a0087c
--- /dev/null
+++ b/src/libs/dutil/WixToolset.DUtil/gdiputil.cpp
@@ -0,0 +1,227 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3#include "precomp.h"
4
5using namespace Gdiplus;
6
7
8// Exit macros
9#define GdipExitOnLastError(x, s, ...) ExitOnLastErrorSource(DUTIL_SOURCE_GDIPUTIL, x, s, __VA_ARGS__)
10#define GdipExitOnLastErrorDebugTrace(x, s, ...) ExitOnLastErrorDebugTraceSource(DUTIL_SOURCE_GDIPUTIL, x, s, __VA_ARGS__)
11#define GdipExitWithLastError(x, s, ...) ExitWithLastErrorSource(DUTIL_SOURCE_GDIPUTIL, x, s, __VA_ARGS__)
12#define GdipExitOnFailure(x, s, ...) ExitOnFailureSource(DUTIL_SOURCE_GDIPUTIL, x, s, __VA_ARGS__)
13#define GdipExitOnRootFailure(x, s, ...) ExitOnRootFailureSource(DUTIL_SOURCE_GDIPUTIL, x, s, __VA_ARGS__)
14#define GdipExitOnFailureDebugTrace(x, s, ...) ExitOnFailureDebugTraceSource(DUTIL_SOURCE_GDIPUTIL, x, s, __VA_ARGS__)
15#define GdipExitOnNull(p, x, e, s, ...) ExitOnNullSource(DUTIL_SOURCE_GDIPUTIL, p, x, e, s, __VA_ARGS__)
16#define GdipExitOnNullWithLastError(p, x, s, ...) ExitOnNullWithLastErrorSource(DUTIL_SOURCE_GDIPUTIL, p, x, s, __VA_ARGS__)
17#define GdipExitOnNullDebugTrace(p, x, e, s, ...) ExitOnNullDebugTraceSource(DUTIL_SOURCE_GDIPUTIL, p, x, e, s, __VA_ARGS__)
18#define GdipExitOnInvalidHandleWithLastError(p, x, s, ...) ExitOnInvalidHandleWithLastErrorSource(DUTIL_SOURCE_GDIPUTIL, p, x, s, __VA_ARGS__)
19#define GdipExitOnWin32Error(e, x, s, ...) ExitOnWin32ErrorSource(DUTIL_SOURCE_GDIPUTIL, e, x, s, __VA_ARGS__)
20#define GdipExitOnGdipFailure(g, x, s, ...) ExitOnGdipFailureSource(DUTIL_SOURCE_GDIPUTIL, g, x, s, __VA_ARGS__)
21
22/********************************************************************
23 GdipInitialize - initializes GDI+.
24
25 Note: pOutput must be non-NULL if pInput->SuppressBackgroundThread
26 is TRUE. See GdiplusStartup() for more information.
27********************************************************************/
28extern "C" HRESULT DAPI GdipInitialize(
29 __in const Gdiplus::GdiplusStartupInput* pInput,
30 __out ULONG_PTR* pToken,
31 __out_opt Gdiplus::GdiplusStartupOutput *pOutput
32 )
33{
34 AssertSz(!pInput->SuppressBackgroundThread || pOutput, "pOutput required if background thread suppressed.");
35
36 HRESULT hr = S_OK;
37 Status status = Ok;
38
39 status = GdiplusStartup(pToken, pInput, pOutput);
40 GdipExitOnGdipFailure(status, hr, "Failed to initialize GDI+.");
41
42LExit:
43 return hr;
44}
45
46/********************************************************************
47 GdipUninitialize - uninitializes GDI+.
48
49********************************************************************/
50extern "C" void DAPI GdipUninitialize(
51 __in ULONG_PTR token
52 )
53{
54 GdiplusShutdown(token);
55}
56
57/********************************************************************
58 GdipBitmapFromResource - read a GDI+ image out of a resource stream
59
60********************************************************************/
61extern "C" HRESULT DAPI GdipBitmapFromResource(
62 __in_opt HINSTANCE hinst,
63 __in_z LPCSTR szId,
64 __out Bitmap **ppBitmap
65 )
66{
67 HRESULT hr = S_OK;
68 LPVOID pvData = NULL;
69 DWORD cbData = 0;
70 HGLOBAL hGlobal = NULL;;
71 LPVOID pv = NULL;
72 IStream *pStream = NULL;
73 Bitmap *pBitmap = NULL;
74 Status gs = Ok;
75
76 hr = ResReadData(hinst, szId, &pvData, &cbData);
77 GdipExitOnFailure(hr, "Failed to load GDI+ bitmap from resource.");
78
79 // Have to copy the fixed resource data into moveable (heap) memory
80 // since that's what GDI+ expects.
81 hGlobal = ::GlobalAlloc(GMEM_MOVEABLE, cbData);
82 GdipExitOnNullWithLastError(hGlobal, hr, "Failed to allocate global memory.");
83
84 pv = ::GlobalLock(hGlobal);
85 GdipExitOnNullWithLastError(pv, hr, "Failed to lock global memory.");
86
87 memcpy(pv, pvData, cbData);
88
89 ::GlobalUnlock(pv); // no point taking any more memory than we have already
90 pv = NULL;
91
92 hr = ::CreateStreamOnHGlobal(hGlobal, TRUE, &pStream);
93 GdipExitOnFailure(hr, "Failed to allocate stream from global memory.");
94
95 hGlobal = NULL; // we gave the global memory to the stream object so it will close it
96
97 pBitmap = Bitmap::FromStream(pStream);
98 GdipExitOnNull(pBitmap, hr, E_OUTOFMEMORY, "Failed to allocate bitmap from stream.");
99
100 gs = pBitmap->GetLastStatus();
101 GdipExitOnGdipFailure(gs, hr, "Failed to load bitmap from stream.");
102
103 *ppBitmap = pBitmap;
104 pBitmap = NULL;
105
106LExit:
107 if (pBitmap)
108 {
109 delete pBitmap;
110 }
111
112 ReleaseObject(pStream);
113
114 if (pv)
115 {
116 ::GlobalUnlock(pv);
117 }
118
119 if (hGlobal)
120 {
121 ::GlobalFree(hGlobal);
122 }
123
124 return hr;
125}
126
127
128/********************************************************************
129 GdipBitmapFromFile - read a GDI+ image from a file.
130
131********************************************************************/
132extern "C" HRESULT DAPI GdipBitmapFromFile(
133 __in_z LPCWSTR wzFileName,
134 __out Bitmap **ppBitmap
135 )
136{
137 HRESULT hr = S_OK;
138 Bitmap *pBitmap = NULL;
139 Status gs = Ok;
140
141 GdipExitOnNull(ppBitmap, hr, E_INVALIDARG, "Invalid null wzFileName");
142
143 pBitmap = Bitmap::FromFile(wzFileName);
144 GdipExitOnNull(pBitmap, hr, E_OUTOFMEMORY, "Failed to allocate bitmap from file.");
145
146 gs = pBitmap->GetLastStatus();
147 GdipExitOnGdipFailure(gs, hr, "Failed to load bitmap from file: %ls", wzFileName);
148
149 *ppBitmap = pBitmap;
150 pBitmap = NULL;
151
152LExit:
153 if (pBitmap)
154 {
155 delete pBitmap;
156 }
157
158 return hr;
159}
160
161
162HRESULT DAPI GdipHresultFromStatus(
163 __in Gdiplus::Status gs
164 )
165{
166 switch (gs)
167 {
168 case Ok:
169 return S_OK;
170
171 case GenericError:
172 return E_FAIL;
173
174 case InvalidParameter:
175 return E_INVALIDARG;
176
177 case OutOfMemory:
178 return E_OUTOFMEMORY;
179
180 case ObjectBusy:
181 return HRESULT_FROM_WIN32(ERROR_BUSY);
182
183 case InsufficientBuffer:
184 return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
185
186 case NotImplemented:
187 return E_NOTIMPL;
188
189 case Win32Error:
190 return E_FAIL;
191
192 case WrongState:
193 return E_FAIL;
194
195 case Aborted:
196 return E_ABORT;
197
198 case FileNotFound:
199 return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
200
201 case ValueOverflow:
202 return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);
203
204 case AccessDenied:
205 return E_ACCESSDENIED;
206
207 case UnknownImageFormat:
208 return HRESULT_FROM_WIN32(ERROR_BAD_FORMAT);
209
210 case FontFamilyNotFound: __fallthrough;
211 case FontStyleNotFound: __fallthrough;
212 case NotTrueTypeFont:
213 return E_UNEXPECTED;
214
215 case UnsupportedGdiplusVersion:
216 return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
217
218 case GdiplusNotInitialized:
219 return E_UNEXPECTED;
220
221 case PropertyNotFound: __fallthrough;
222 case PropertyNotSupported:
223 return E_FAIL;
224 }
225
226 return E_UNEXPECTED;
227}