... |
... |
@@ -142,6 +142,233 @@ |
142
|
142
|
return code;
|
143
|
143
|
}
|
144
|
144
|
|
|
145
|
+#elif defined( _WIN32 )
|
|
146
|
+
|
|
147
|
+#define WIN32_LEAN_AND_MEAN
|
|
148
|
+#include<windows.h>
|
|
149
|
+
|
|
150
|
+#pragma comment (lib,"Gdiplus.lib")
|
|
151
|
+
|
|
152
|
+ /* Barebone definitions and opaque types to avoid GDI+ (C++) headers */
|
|
153
|
+
|
|
154
|
+#define WINGDIPAPI WINAPI
|
|
155
|
+#define GDIPCONST const
|
|
156
|
+
|
|
157
|
+ typedef enum Status {
|
|
158
|
+ Ok,
|
|
159
|
+ GenericError,
|
|
160
|
+ InvalidParameter,
|
|
161
|
+ OutOfMemory,
|
|
162
|
+ ObjectBusy,
|
|
163
|
+ InsufficientBuffer,
|
|
164
|
+ NotImplemented,
|
|
165
|
+ Win32Error,
|
|
166
|
+ WrongState,
|
|
167
|
+ Aborted,
|
|
168
|
+ FileNotFound,
|
|
169
|
+ ValueOverflow,
|
|
170
|
+ AccessDenied,
|
|
171
|
+ UnknownImageFormat,
|
|
172
|
+ FontFamilyNotFound,
|
|
173
|
+ FontStyleNotFound,
|
|
174
|
+ NotTrueTypeFont,
|
|
175
|
+ UnsupportedGdiplusVersion,
|
|
176
|
+ GdiplusNotInitialized,
|
|
177
|
+ PropertyNotFound,
|
|
178
|
+ PropertyNotSupported,
|
|
179
|
+ ProfileNotFound
|
|
180
|
+ } GpStatus;
|
|
181
|
+
|
|
182
|
+ typedef VOID (WINGDIPAPI *DebugEventProc)(VOID); /* unused, NULL */
|
|
183
|
+
|
|
184
|
+ typedef struct GdiplusStartupInput {
|
|
185
|
+ UINT32 GdiplusVersion;
|
|
186
|
+ DebugEventProc DebugEventCallback;
|
|
187
|
+ BOOL SuppressBackgroundThread;
|
|
188
|
+ BOOL SuppressExternalCodecs;
|
|
189
|
+ } GdiplusStartupInput;
|
|
190
|
+
|
|
191
|
+ typedef VOID GdiplusStartupOutput; /* unused, NULL */
|
|
192
|
+
|
|
193
|
+ GpStatus WINAPI GdiplusStartup(
|
|
194
|
+ ULONG_PTR *token,
|
|
195
|
+ GDIPCONST GdiplusStartupInput *input,
|
|
196
|
+ GdiplusStartupOutput *output
|
|
197
|
+ );
|
|
198
|
+
|
|
199
|
+ VOID WINAPI GdiplusShutdown( ULONG_PTR token);
|
|
200
|
+
|
|
201
|
+ typedef enum PixelFormat {
|
|
202
|
+ PixelFormatUndefined = 0x00000000,
|
|
203
|
+ PixelFormat1bppIndexed = 0x00030101,
|
|
204
|
+ PixelFormat4bppIndexed = 0x00030402,
|
|
205
|
+ PixelFormat8bppIndexed = 0x00030803,
|
|
206
|
+ PixelFormat16bppGrayScale = 0x00101004,
|
|
207
|
+ PixelFormat16bppRGB555 = 0x00021005,
|
|
208
|
+ PixelFormat16bppRGB565 = 0x00021006,
|
|
209
|
+ PixelFormat16bppARGB1555 = 0x00061007,
|
|
210
|
+ PixelFormat24bppRGB = 0x00021808,
|
|
211
|
+ PixelFormat32bppRGB = 0x00022009,
|
|
212
|
+ PixelFormat32bppARGB = 0x0026200A,
|
|
213
|
+ PixelFormat32bppPARGB = 0x000E200B,
|
|
214
|
+ PixelFormat48bppRGB = 0x0010300C,
|
|
215
|
+ PixelFormat64bppARGB = 0x0034400D,
|
|
216
|
+ PixelFormat64bppPARGB = 0x001A400E
|
|
217
|
+ } PixelFormat;
|
|
218
|
+
|
|
219
|
+ typedef VOID GpBitmap; /* opaque */
|
|
220
|
+
|
|
221
|
+ GpStatus WINGDIPAPI GdipCreateBitmapFromScan0(
|
|
222
|
+ INT width,
|
|
223
|
+ INT height,
|
|
224
|
+ INT stride,
|
|
225
|
+ PixelFormat format,
|
|
226
|
+ BYTE* scan0,
|
|
227
|
+ GpBitmap** bitmap
|
|
228
|
+ );
|
|
229
|
+
|
|
230
|
+ typedef VOID GpImage; /* opaque */
|
|
231
|
+
|
|
232
|
+ typedef DWORD ARGB;
|
|
233
|
+
|
|
234
|
+ enum PaletteFlags {
|
|
235
|
+ PaletteFlagsHasAlpha = 1,
|
|
236
|
+ PaletteFlagsGrayScale = 2,
|
|
237
|
+ PaletteFlagsHalftone = 4
|
|
238
|
+ };
|
|
239
|
+
|
|
240
|
+ typedef struct ColorPalette {
|
|
241
|
+ UINT Flags;
|
|
242
|
+ UINT Count;
|
|
243
|
+ ARGB Entries[256];
|
|
244
|
+ } ColorPalette;
|
|
245
|
+
|
|
246
|
+ GpStatus WINGDIPAPI GdipSetImagePalette(
|
|
247
|
+ GpImage *image,
|
|
248
|
+ GDIPCONST ColorPalette *palette
|
|
249
|
+ );
|
|
250
|
+
|
|
251
|
+ typedef ULONG PROPID;
|
|
252
|
+
|
|
253
|
+#define PropertyTagTypeASCII 2
|
|
254
|
+#define PropertyTagTypeRational 5
|
|
255
|
+#define PropertyTagSoftwareUsed 0x0131
|
|
256
|
+#define PropertyTagGamma 0x0301
|
|
257
|
+
|
|
258
|
+ typedef struct PropertyItem {
|
|
259
|
+ PROPID id;
|
|
260
|
+ ULONG length;
|
|
261
|
+ WORD type;
|
|
262
|
+ VOID *value;
|
|
263
|
+ } PropertyItem;
|
|
264
|
+
|
|
265
|
+ GpStatus WINGDIPAPI GdipSetPropertyItem(
|
|
266
|
+ GpImage *image,
|
|
267
|
+ GDIPCONST PropertyItem* item
|
|
268
|
+ );
|
|
269
|
+
|
|
270
|
+ typedef GUID CLSID;
|
|
271
|
+
|
|
272
|
+ typedef VOID EncoderParameters;
|
|
273
|
+
|
|
274
|
+ GpStatus WINGDIPAPI GdipSaveImageToFile(
|
|
275
|
+ GpImage *image,
|
|
276
|
+ GDIPCONST WCHAR* filename,
|
|
277
|
+ GDIPCONST CLSID* clsidEncoder,
|
|
278
|
+ GDIPCONST EncoderParameters* encoderParams
|
|
279
|
+ );
|
|
280
|
+
|
|
281
|
+ GpStatus WINGDIPAPI GdipFree(void* ptr);
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+ int
|
|
285
|
+ FTDemo_Display_Print( FTDemo_Display* display,
|
|
286
|
+ const char* filename,
|
|
287
|
+ FT_String* ver_str )
|
|
288
|
+ {
|
|
289
|
+ grBitmap* bit = display->bitmap;
|
|
290
|
+
|
|
291
|
+ WCHAR wfilename[20];
|
|
292
|
+ PixelFormat format;
|
|
293
|
+ ColorPalette palette;
|
|
294
|
+ GpStatus ret = Ok;
|
|
295
|
+
|
|
296
|
+ GdiplusStartupInput gdiplusStartupInput = { 1, NULL, FALSE, FALSE };
|
|
297
|
+ ULONG_PTR gdiplusToken = 0;
|
|
298
|
+ GpBitmap* bitmap = NULL;
|
|
299
|
+ GDIPCONST CLSID GpPngEncoder = { 0x557cf406, 0x1a04, 0x11d3,
|
|
300
|
+ { 0x9a,0x73,0x00,0x00,0xf8,0x1e,0xf3,0x2e } };
|
|
301
|
+
|
|
302
|
+ ULONG gg[2] = { display->gamma * 0x10000, 0x10000 };
|
|
303
|
+ PropertyItem gamma = { PropertyTagGamma, 2 * sizeof(ULONG),
|
|
304
|
+ PropertyTagTypeRational, gg };
|
|
305
|
+ PropertyItem software = { PropertyTagSoftwareUsed, strlen(ver_str) + 1,
|
|
306
|
+ PropertyTagTypeASCII, ver_str };
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+ /* Set format */
|
|
310
|
+ switch ( bit->mode )
|
|
311
|
+ {
|
|
312
|
+ case gr_pixel_mode_gray:
|
|
313
|
+ {
|
|
314
|
+ ARGB color;
|
|
315
|
+ ARGB* entry = palette.Entries;
|
|
316
|
+
|
|
317
|
+ palette.Flags = PaletteFlagsGrayScale;
|
|
318
|
+ palette.Count = 256;
|
|
319
|
+
|
|
320
|
+ format = PixelFormat8bppIndexed;
|
|
321
|
+ for ( color = 0xFF000000; color >= 0xFF000000 ; color += 0x00010101 )
|
|
322
|
+ *entry++ = color;
|
|
323
|
+ }
|
|
324
|
+ break;
|
|
325
|
+ case gr_pixel_mode_rgb555:
|
|
326
|
+ format = PixelFormat16bppRGB555;
|
|
327
|
+ break;
|
|
328
|
+ case gr_pixel_mode_rgb565:
|
|
329
|
+ format = PixelFormat16bppRGB565;
|
|
330
|
+ break;
|
|
331
|
+ case gr_pixel_mode_rgb24: /* XXX: wrong endianness */
|
|
332
|
+ format = PixelFormat24bppRGB;
|
|
333
|
+ break;
|
|
334
|
+ case gr_pixel_mode_rgb32:
|
|
335
|
+ format = PixelFormat32bppRGB;
|
|
336
|
+ break;
|
|
337
|
+ default:
|
|
338
|
+ fprintf( stderr, "Unsupported color type.\n" );
|
|
339
|
+ ret = UnknownImageFormat;
|
|
340
|
+ goto Exit;
|
|
341
|
+ }
|
|
342
|
+
|
|
343
|
+ if ( mbstowcs( wfilename, filename, 20 ) != strlen(filename) )
|
|
344
|
+ ret = InsufficientBuffer;
|
|
345
|
+
|
|
346
|
+ if ( !ret )
|
|
347
|
+ ret = GdiplusStartup( &gdiplusToken, &gdiplusStartupInput, NULL );
|
|
348
|
+
|
|
349
|
+ if ( !ret )
|
|
350
|
+ ret = GdipCreateBitmapFromScan0( bit->width, bit->rows, bit->pitch,
|
|
351
|
+ format, bit->buffer, &bitmap);
|
|
352
|
+
|
|
353
|
+ if ( !ret && format == PixelFormat8bppIndexed )
|
|
354
|
+ ret = GdipSetImagePalette( bitmap, &palette );
|
|
355
|
+
|
|
356
|
+ if ( !ret )
|
|
357
|
+ ret = GdipSetPropertyItem( bitmap, &gamma );
|
|
358
|
+
|
|
359
|
+ if ( !ret )
|
|
360
|
+ ret = GdipSetPropertyItem( bitmap, &software );
|
|
361
|
+
|
|
362
|
+ if ( !ret )
|
|
363
|
+ ret = GdipSaveImageToFile( bitmap, wfilename, &GpPngEncoder, NULL );
|
|
364
|
+
|
|
365
|
+ GdipFree( bitmap );
|
|
366
|
+ GdiplusShutdown( gdiplusToken );
|
|
367
|
+
|
|
368
|
+ Exit:
|
|
369
|
+ return ret;
|
|
370
|
+ }
|
|
371
|
+
|
145
|
372
|
#else
|
146
|
373
|
|
147
|
374
|
int
|