~ubuntu-branches/ubuntu/jaunty/libgdiplus/jaunty-updates

« back to all changes in this revision

Viewing changes to src/emfplus.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2007-05-17 13:38:42 UTC
  • mfrom: (1.1.13 upstream)
  • Revision ID: james.westby@ubuntu.com-20070517133842-t8b8d4lxmhb3vnp0
Tags: 1.2.4-1ubuntu1
* Sync with Debian:
  + debian/control:
    - Add sparc to archs
    - Set Maintainer field...

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007 Novell, Inc (http://www.novell.com)
 
3
 *
 
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:
 
9
 *
 
10
 * The above copyright notice and this permission notice shall be included in all copies or substantial
 
11
 * portions of the Software.
 
12
 *
 
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.
 
18
 *
 
19
 * Authors:
 
20
 *      Sebastien Pouliot  <sebastien@ximian.com>
 
21
 */
 
22
 
 
23
#include "emfplus.h"
 
24
 
 
25
//#define DEBUG_EMFPLUS_ALL
 
26
#ifdef DEBUG_EMFPLUS_ALL
 
27
#define DEBUG_EMFPLUS
 
28
#define DEBUG_EMFPLUS_2
 
29
#define DEBUG_EMFPLUS_3
 
30
#define DEBUG_EMFPLUS_NOTIMPLEMENTED
 
31
#endif
 
32
 
 
33
 
 
34
/* http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/Header.html */
 
35
static GpStatus
 
36
EmfPlusHeader (MetafilePlayContext *context, WORD flags, BYTE* data, int size)
 
37
{
 
38
#ifdef DEBUG_EMFPLUS
 
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));
 
46
#endif
 
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) */
 
51
        return Ok;
 
52
}
 
53
 
 
54
/* http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/EndOfFile.html */
 
55
static GpStatus
 
56
EmfPlusEndOfFile (MetafilePlayContext *context, WORD flags, BYTE* data, int size)
 
57
{
 
58
#ifdef DEBUG_EMFPLUS
 
59
        printf ("EmfPlusRecordTypeEndOfFile flags %X", flags);
 
60
#endif
 
61
        return Ok;
 
62
}
 
63
 
 
64
/* http://www.aces.uiuc.edu/~jhtodd/Metafile/MetafileRecords/FillRects.html */
 
65
static GpStatus
 
66
EmfPlusFillRects (MetafilePlayContext *context, WORD flags, BYTE* data, int size)
 
67
{
 
68
        GpStatus status = Ok;
 
69
        GpSolidFill *solid = NULL;
 
70
        GpBrush *brush = NULL;
 
71
 
 
72
#ifdef DEBUG_EMFPLUS
 
73
        printf ("EmfPlusRecordTypeFillRects flags %X", flags, size);
 
74
        printf ("\n\tColor: 0x%X", GETDW(DWP2));
 
75
        printf ("\n\t#rect: %d", GETDW(DWP3));
 
76
#endif
 
77
        BOOL use_int16 = (flags & 0x4000);
 
78
        BOOL use_color = (flags & 0x8000);
 
79
        DWORD num = GETDW(DWP3);
 
80
        int i = 0;
 
81
        int n = 3;
 
82
 
 
83
        if (use_color) {
 
84
                status = GdipCreateSolidFill (GETDW(DWP2), &solid);
 
85
                if (status != Ok)
 
86
                        return status;
 
87
                brush = (GpBrush*)solid;
 
88
        } else {
 
89
                /* TODO - get brush from index */
 
90
        }
 
91
 
 
92
        while ((i++ < num) && (status == Ok)) {
 
93
                float x, y, w, h;
 
94
                if (use_int16) {
 
95
                        DWORD xy = GETDW(DWP(n++));
 
96
                        x = (xy >> 16);
 
97
                        y = (WORD)xy;
 
98
                        DWORD wh = GETDW(DWP(n++));
 
99
                        w = (wh >> 16);
 
100
                        h = (WORD)wh;
 
101
                } else {
 
102
                        x = (float) GETDW(DWP(n++));
 
103
                        y = (float) GETDW(DWP(n++));
 
104
                        w = (float) GETDW(DWP(n++));
 
105
                        h = (float) GETDW(DWP(n++));
 
106
                }
 
107
#ifdef DEBUG_EMFPLUS_2
 
108
                printf ("\n\t\t%d - x %g, y %g, w %g, h %g", i, x, y, w, h);
 
109
#endif
 
110
                status = GdipFillRectangle (context->graphics, brush, x, y, w, h);
 
111
        }
 
112
 
 
113
        if (solid)
 
114
                GdipDeleteBrush (brush); /* brush == a GpBrush* typecasted solid, if used */
 
115
        return status;
 
116
}
 
117
 
 
118
GpStatus
 
119
gdip_metafile_play_emfplus_block (MetafilePlayContext *context, BYTE* data, int length)
 
120
{
 
121
        GpStatus status = Ok;
 
122
        BYTE *end = data + length;
 
123
#ifdef DEBUG_EMFPLUS
 
124
        int i = 1, j;
 
125
#endif
 
126
 
 
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);
 
135
                }
 
136
                /* no header, continue */
 
137
                return Ok;
 
138
        }
 
139
 
 
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);
 
147
#ifdef DEBUG_EMFPLUS
 
148
                printf ("\n\tEMF+[#%d] size %d ", i++, size);
 
149
#endif
 
150
                switch (func) {
 
151
                case EmfPlusRecordTypeHeader:
 
152
                        status = EmfPlusHeader (context, flags, data, size);
 
153
                        break;
 
154
                case EmfPlusRecordTypeEndOfFile:
 
155
                        return EmfPlusEndOfFile (context, flags, data, size);
 
156
                case EmfPlusRecordTypeFillRects:
 
157
                        status = EmfPlusFillRects (context, flags, data, size);
 
158
                        break;
 
159
                default:
 
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)));
 
165
                        }
 
166
                        printf (" )");
 
167
#endif
 
168
                        break;
 
169
                }
 
170
 
 
171
                if (status != Ok) {
 
172
                        g_warning ("EMF+ parsing interupted, status %d returned from function %d.", status, func);
 
173
                        goto cleanup;
 
174
                }
 
175
 
 
176
                data += size;
 
177
        }
 
178
cleanup:
 
179
        return status;
 
180
}