2
* Copyright (C) 2007 Novell, Inc (http://www.novell.com)
4
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software
5
* and associated documentation files (the "Software"), to deal in the Software without restriction,
6
* including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
* and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
8
* subject to the following conditions:
10
* The above copyright notice and this permission notice shall be included in all copies or substantial
11
* portions of the Software.
13
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
15
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
16
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
17
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
* Sebastien Pouliot <sebastien@ximian.com>
25
//#define DEBUG_EMFPLUS_ALL
26
#ifdef DEBUG_EMFPLUS_ALL
28
#define DEBUG_EMFPLUS_2
29
#define DEBUG_EMFPLUS_3
30
#define DEBUG_EMFPLUS_NOTIMPLEMENTED
34
/* http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/Header.html */
36
EmfPlusHeader (MetafilePlayContext *context, WORD flags, BYTE* data, int size)
39
/* if flags == 1, EmfPlusDual (GDI and GDI+), else EmfPlusOnly (GDI+) */
40
printf ("\nEmfPlusHeader flags %X", flags);
41
printf ("\n\tData Size %d", GETDW(DWP1));
42
printf ("\n\tObject Header %X", GETDW(DWP2));
43
printf ("\n\tVersion %d", GETDW(DWP3));
44
printf ("\n\tHorizontal Resolution %d", GETDW(DWP4));
45
printf ("\n\tVertical Resolution %d", GETDW(DWP5));
47
context->metafile->metafile_header.Type = (flags & 1) ? METAFILETYPE_EMFPLUSDUAL : METAFILETYPE_EMFPLUSONLY;
48
/* ObjectHeader, not Version, is returned to be compatible with GDI+ */
49
context->metafile->metafile_header.Version = GETDW(DWP2);
50
/* Horizontal and Vertical Resolution aren't reported correctly by GDI+ (generally 0) */
54
/* http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/EndOfFile.html */
56
EmfPlusEndOfFile (MetafilePlayContext *context, WORD flags, BYTE* data, int size)
59
printf ("EmfPlusRecordTypeEndOfFile flags %X", flags);
64
/* http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/FillRects.html */
66
EmfPlusFillRects (MetafilePlayContext *context, WORD flags, BYTE* data, int size)
69
GpSolidFill *solid = NULL;
70
GpBrush *brush = NULL;
73
printf ("EmfPlusRecordTypeFillRects flags %X", flags, size);
74
printf ("\n\tColor: 0x%X", GETDW(DWP2));
75
printf ("\n\t#rect: %d", GETDW(DWP3));
77
BOOL use_int16 = (flags & 0x4000);
78
BOOL use_color = (flags & 0x8000);
79
DWORD num = GETDW(DWP3);
84
status = GdipCreateSolidFill (GETDW(DWP2), &solid);
87
brush = (GpBrush*)solid;
89
/* TODO - get brush from index */
92
while ((i++ < num) && (status == Ok)) {
95
DWORD xy = GETDW(DWP(n++));
98
DWORD wh = GETDW(DWP(n++));
102
x = (float) GETDW(DWP(n++));
103
y = (float) GETDW(DWP(n++));
104
w = (float) GETDW(DWP(n++));
105
h = (float) GETDW(DWP(n++));
107
#ifdef DEBUG_EMFPLUS_2
108
printf ("\n\t\t%d - x %g, y %g, w %g, h %g", i, x, y, w, h);
110
status = GdipFillRectangle (context->graphics, brush, x, y, w, h);
114
GdipDeleteBrush (brush); /* brush == a GpBrush* typecasted solid, if used */
119
gdip_metafile_play_emfplus_block (MetafilePlayContext *context, BYTE* data, int length)
121
GpStatus status = Ok;
122
BYTE *end = data + length;
127
/* special case to update the header informations (we're not really playing the metafile) */
128
if (!context->graphics) {
129
DWORD record = GETDW(EMF_FUNCTION);
130
WORD func = (WORD)record;
131
if (func == EmfPlusRecordTypeHeader) {
132
WORD flags = (record >> 16);
133
DWORD size = GETDW(EMF_RECORDSIZE);
134
return EmfPlusHeader (context, flags, data, size);
136
/* no header, continue */
140
/* reality check - each record is, at minimum, 8 bytes long (when size == 0) */
141
while (data < end - EMF_MIN_RECORD_SIZE) {
142
DWORD record = GETDW(EMF_FUNCTION);
143
WORD func = (WORD)record;
144
WORD flags = (record >> 16);
145
DWORD size = GETDW(EMF_RECORDSIZE);
146
int params = (size - EMF_MIN_RECORD_SIZE) / sizeof (DWORD);
148
printf ("\n\tEMF+[#%d] size %d ", i++, size);
151
case EmfPlusRecordTypeHeader:
152
status = EmfPlusHeader (context, flags, data, size);
154
case EmfPlusRecordTypeEndOfFile:
155
return EmfPlusEndOfFile (context, flags, data, size);
156
case EmfPlusRecordTypeFillRects:
157
status = EmfPlusFillRects (context, flags, data, size);
160
/* unprocessed records, ignore the data */
161
#ifdef DEBUG_EMFPLUS_NOTIMPLEMENTED
162
printf ("Unimplemented_%d (", func);
163
for (j = 0; j < params; j++) {
164
printf (" %d", GETDW(DWP(j)));
172
g_warning ("EMF+ parsing interupted, status %d returned from function %d.", status, func);