]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/ogl/mfutils.cpp
This should work on SuSE and Mandrake icon themes.
[wxWidgets.git] / contrib / src / ogl / mfutils.cpp
CommitLineData
1fc25a89
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: mfutils.cpp
3// Purpose: Metafile utillities
4// Author: Julian Smart
5// Modified by:
6// Created: 12/07/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "mfutils.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
92a19c2e 17#include "wx/wxprec.h"
1fc25a89
JS
18
19#ifdef __BORLANDC__
20#pragma hdrstop
21#endif
22
23#ifndef WX_PRECOMP
24#include <wx/wx.h>
25#endif
26
27#include <wx/metafile.h>
28#include <wx/utils.h>
29
5f331691
RD
30#include "wx/ogl/ogl.h"
31
1fc25a89
JS
32#include <stdio.h>
33
59840ba3
RD
34static char _buf[1024]; // a temp buffer to use inplace of wxBuffer, which is deprecated.
35
1fc25a89
JS
36// 16-bit unsigned integer
37static unsigned int getshort(FILE *fp)
38{
39 int c, c1;
40 c = getc(fp); c1 = getc(fp);
41 unsigned int res = ((unsigned int) c) + (((unsigned int) c1) << 8);
42 return res;
43}
44
45// 16-bit signed integer
46static int getsignedshort(FILE *fp)
47{
48 int c, c1;
49 c = getc(fp); c1 = getc(fp);
1484b5cc
VS
50#if 0
51 // this is not used value, no need to execute it
1fc25a89 52 int testRes = ((unsigned int) c) + (((unsigned int) c1) << 8);
1484b5cc 53#endif
1fc25a89 54 unsigned long res1 = ((unsigned int) c) + (((unsigned int) c1) << 8);
8552e6f0 55 int res;
1fc25a89
JS
56 if (res1 > 32767)
57 res = (int)(res1 - 65536);
58 else
59 res = (int)(res1);
60 return res;
61}
62
63// 32-bit integer
64static long getint(FILE *fp)
65{
66 int c, c1, c2, c3;
67 c = getc(fp); c1 = getc(fp); c2 = getc(fp); c3 = getc(fp);
68 long res = (long)((long) c) +
59840ba3 69 (((long) c1) << 8) +
1fc25a89
JS
70 (((long) c2) << 16) +
71 (((long) c3) << 24);
72 return res;
73}
74
75
76/* Placeable metafile header
77struct mfPLACEABLEHEADER {
78 DWORD key; // 32-bit
79 HANDLE hmf; // 16-bit
80 RECT bbox; // 4x16 bit
81 WORD inch; // 16-bit
82 DWORD reserved; // 32-bit
83 WORD checksum; // 16-bit
84};
85*/
86
87wxMetaRecord::~wxMetaRecord(void)
88{
89 if (points) delete[] points;
90 if (stringParam) delete[] stringParam;
91}
92
9e053640 93wxXMetaFile::wxXMetaFile(const wxChar *file)
1fc25a89
JS
94{
95 ok = FALSE;
96 top = 0.0;
97 bottom = 0.0;
98 left = 0.0;
99 right = 0.0;
59840ba3 100
1fc25a89
JS
101 if (file)
102 ok = ReadFile(file);
103}
104
105/*
106 Handle table gdiObjects
107 ------------ ----------
108 [0] wxPen
109 [1]----param2--- wxBrush
110 [2] | wxFont
111 [3] | -> wxPen
59840ba3 112
1fc25a89
JS
113 The handle table works as follows.
114 When a GDI object is created whilst reading in the
115 metafile, the (e.g.) createpen record is added to the
116 first free entry in the handle table. The createpen
117 record's param1 is a pointer to the actual wxPen, and
118 its param2 is the index into the gdiObjects list, which only
119 grows and never shrinks (unlike the handle table.)
59840ba3 120
1fc25a89
JS
121 When SelectObject(index) is found, the index in the file
122 refers to the position in the handle table. BUT we then
123 set param2 to be the position of the wxPen in gdiObjects,
124 i.e. to param2 of the CreatePen record, itself found in
125 the handle table.
126
127 When an object is deleted, the entry in the handletable is
128 NULLed but the gdiObjects entry is not removed (no point, and
129 allows us to create all GDI objects in advance of playing the
130 metafile).
131*/
59840ba3 132
1fc25a89
JS
133
134static wxMetaRecord *HandleTable[100];
135static int HandleTableSize = 0;
136
137void DeleteMetaRecordHandle(int index)
138{
139 HandleTable[index] = NULL;
140}
141
142int AddMetaRecordHandle(wxMetaRecord *record)
143{
144 for (int i = 0; i < HandleTableSize; i++)
145 if (!HandleTable[i])
146 {
147 HandleTable[i] = record;
148 return i;
149 }
150 // No free spaces in table, so append.
59840ba3 151
1fc25a89
JS
152 HandleTable[HandleTableSize] = record;
153 HandleTableSize ++;
154 return (HandleTableSize - 1);
155}
156
9e053640 157bool wxXMetaFile::ReadFile(const wxChar *file)
1fc25a89
JS
158{
159 HandleTableSize = 0;
59840ba3 160
9e053640 161 FILE *handle = wxFopen(file, wxT("rb"));
1fc25a89
JS
162 if (!handle) return FALSE;
163
164 // Read placeable metafile header, if any
165 long key = getint(handle);
59840ba3 166
1fc25a89
JS
167 if (key == (long) 0x9AC6CDD7)
168 {
1484b5cc 169 /* long hmf = */ getshort(handle);
1fc25a89
JS
170 int iLeft, iTop, iRight, iBottom;
171 iLeft = getsignedshort(handle);
172 iTop = getsignedshort(handle);
173 iRight = getsignedshort(handle);
174 iBottom = getsignedshort(handle);
175
176 left = (double)iLeft;
177 top = (double)iTop;
178 right = (double)iRight;
179 bottom = (double)iBottom;
180
1484b5cc
VS
181 /* int inch = */ getshort(handle);
182 /* long reserved = */ getint(handle);
183 /* int checksum = */ getshort(handle);
1fc25a89
JS
184/*
185 double widthInUnits = (double)right - left;
186 double heightInUnits = (double)bottom - top;
187 *width = (int)((widthInUnits*1440.0)/inch);
188 *height = (int)((heightInUnits*1440.0)/inch);
189*/
190 }
191 else rewind(handle);
192
193 // Read METAHEADER
194 int mtType = getshort(handle);
195
196 if (mtType != 1 && mtType != 2)
197 {
198 fclose(handle);
199 return FALSE;
200 }
201
1484b5cc 202 /* int mtHeaderSize = */ getshort(handle);
1fc25a89
JS
203 int mtVersion = getshort(handle);
204
205 if (mtVersion != 0x0300 && mtVersion != 0x0100)
206 {
207 fclose(handle);
208 return FALSE;
209 }
59840ba3 210
1484b5cc
VS
211 /* long mtSize = */ getint(handle);
212 /* int mtNoObjects = */ getshort(handle);
213 /* long mtMaxRecord = */ getint(handle);
214 /* int mtNoParameters = */ getshort(handle);
1fc25a89
JS
215
216 while (!feof(handle))
217 {
218 long rdSize = getint(handle); // 4 bytes
219 int rdFunction = getshort(handle); // 2 bytes
220 if (feof(handle))
221 break;
222
223 switch (rdFunction)
224 {
225 case META_SETBKCOLOR:
226 {
227 wxMetaRecord *rec = new wxMetaRecord(META_SETBKCOLOR);
228 long colorref = getint(handle); // COLORREF
229 rec->param1 = GetRValue(colorref);
230 rec->param2 = GetGValue(colorref);
231 rec->param3 = GetBValue(colorref);
232 metaRecords.Append(rec);
233 break;
234 }
235 case META_SETBKMODE:
236 {
237 wxMetaRecord *rec = new wxMetaRecord(META_SETBKMODE);
238 rec->param1 = getshort(handle); // Background mode
239 if (rec->param1 == OPAQUE) rec->param1 = wxSOLID;
240 else rec->param1 = wxTRANSPARENT;
241 metaRecords.Append(rec);
242 break;
243 }
244 case META_SETMAPMODE:
245 {
246 wxMetaRecord *rec = new wxMetaRecord(META_SETMAPMODE);
247 rec->param1 = getshort(handle);
248 metaRecords.Append(rec);
249 break;
250 }
251// case META_SETROP2:
252// case META_SETRELABS:
253// case META_SETPOLYFILLMODE:
254// case META_SETSTRETCHBLTMODE:
255// case META_SETTEXTCHAREXTRA:
256 case META_SETTEXTCOLOR:
257 {
258 wxMetaRecord *rec = new wxMetaRecord(META_SETTEXTCOLOR);
259 long colorref = getint(handle); // COLORREF
260 rec->param1 = GetRValue(colorref);
261 rec->param2 = GetGValue(colorref);
262 rec->param3 = GetBValue(colorref);
263 metaRecords.Append(rec);
264 break;
265 }
266// case META_SETTEXTJUSTIFICATION:
267 case META_SETWINDOWORG:
268 {
269 wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWORG);
270 rec->param2 = getshort(handle);
271 rec->param1 = getshort(handle);
272 metaRecords.Append(rec);
273 break;
274 }
275 case META_SETWINDOWEXT:
276 {
277 wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWEXT);
278 rec->param2 = getshort(handle);
279 rec->param1 = getshort(handle);
280 metaRecords.Append(rec);
281 break;
282 }
283// case META_SETVIEWPORTORG:
284// case META_SETVIEWPORTEXT:
285// case META_OFFSETWINDOWORG:
286// case META_SCALEWINDOWEXT:
287// case META_OFFSETVIEWPORTORG:
288// case META_SCALEVIEWPORTEXT:
289 case META_LINETO:
290 {
291 wxMetaRecord *rec = new wxMetaRecord(META_LINETO);
292 rec->param1 = getshort(handle); // x1
293 rec->param2 = getshort(handle); // y1
294 metaRecords.Append(rec);
295 break;
296 }
297 case META_MOVETO:
298 {
299 wxMetaRecord *rec = new wxMetaRecord(META_MOVETO);
300 rec->param1 = getshort(handle); // x1
301 rec->param2 = getshort(handle); // y1
302 metaRecords.Append(rec);
303 break;
304 }
305 case META_EXCLUDECLIPRECT:
306 {
307 wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT);
308 rec->param4 = getshort(handle); // y2
309 rec->param3 = getshort(handle); // x2
310 rec->param2 = getshort(handle); // y1
311 rec->param1 = getshort(handle); // x1
312 metaRecords.Append(rec);
313 break;
314 }
315 case META_INTERSECTCLIPRECT:
316 {
317 wxMetaRecord *rec = new wxMetaRecord(META_INTERSECTCLIPRECT);
318 rec->param4 = getshort(handle); // y2
319 rec->param3 = getshort(handle); // x2
320 rec->param2 = getshort(handle); // y1
321 rec->param1 = getshort(handle); // x1
322 metaRecords.Append(rec);
323 break;
324 }
325// case META_ARC: // DO!!!
326 case META_ELLIPSE:
327 {
328 wxMetaRecord *rec = new wxMetaRecord(META_ELLIPSE);
329 rec->param4 = getshort(handle); // y2
330 rec->param3 = getshort(handle); // x2
331 rec->param2 = getshort(handle); // y1
332 rec->param1 = getshort(handle); // x1
333 metaRecords.Append(rec);
334 break;
335 }
336// case META_FLOODFILL:
337// case META_PIE: // DO!!!
338 case META_RECTANGLE:
339 {
340 wxMetaRecord *rec = new wxMetaRecord(META_RECTANGLE);
341 rec->param4 = getshort(handle); // y2
342 rec->param3 = getshort(handle); // x2
343 rec->param2 = getshort(handle); // y1
344 rec->param1 = getshort(handle); // x1
345 metaRecords.Append(rec);
346 break;
347 }
348 case META_ROUNDRECT:
349 {
350 wxMetaRecord *rec = new wxMetaRecord(META_ROUNDRECT);
351 rec->param6 = getshort(handle); // width
352 rec->param5 = getshort(handle); // height
353 rec->param4 = getshort(handle); // y2
354 rec->param3 = getshort(handle); // x2
355 rec->param2 = getshort(handle); // y1
356 rec->param1 = getshort(handle); // x1
357 metaRecords.Append(rec);
358 break;
359 }
360// case META_PATBLT:
361// case META_SAVEDC:
362 case META_SETPIXEL:
363 {
364 wxMetaRecord *rec = new wxMetaRecord(META_SETPIXEL);
365 rec->param1 = getshort(handle); // x1
366 rec->param2 = getshort(handle); // y1
367 rec->param3 = getint(handle); // COLORREF
368 metaRecords.Append(rec);
369 break;
370 }
371// case META_OFFSETCLIPRGN:
372 case META_TEXTOUT:
373 {
374 wxMetaRecord *rec = new wxMetaRecord(META_TEXTOUT);
375 int count = getshort(handle);
c1fa2fda
RD
376 rec->stringParam = new wxChar[count+1];
377 fread((void *)rec->stringParam, sizeof(wxChar), count, handle);
1fc25a89
JS
378 rec->stringParam[count] = 0;
379 rec->param2 = getshort(handle); // Y
380 rec->param1 = getshort(handle); // X
381 metaRecords.Append(rec);
382 break;
383 }
384/*
385 case META_EXTTEXTOUT:
386 {
387 wxMetaRecord *rec = new wxMetaRecord(META_EXTTEXTOUT);
388 int cellSpacing = getshort(handle);
389 int count = getshort(handle);
390 rec->stringParam = new char[count+1];
391 fread((void *)rec->stringParam, sizeof(char), count, handle);
392 rec->stringParam[count] = 0;
393 // Rectangle
394 int rectY2 = getshort(handle);
395 int rectX2 = getshort(handle);
396 int rectY1 = getshort(handle);
397 int rectX1 = getshort(handle);
398 int rectType = getshort(handle);
399 rec->param2 = getshort(handle); // Y
400 rec->param1 = getshort(handle); // X
401 metaRecords.Append(rec);
402 break;
403 }
404*/
405// case META_BITBLT:
406// case META_STRETCHBLT:
407 case META_POLYGON:
408 {
409 wxMetaRecord *rec = new wxMetaRecord(META_POLYGON);
410 rec->param1 = getshort(handle);
411 rec->points = new wxRealPoint[(int)rec->param1];
412 for (int i = 0; i < rec->param1; i++)
413 {
414 rec->points[i].x = getshort(handle);
415 rec->points[i].y = getshort(handle);
416 }
59840ba3 417
1fc25a89
JS
418 metaRecords.Append(rec);
419 break;
420 }
421 case META_POLYLINE:
422 {
423 wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE);
424 rec->param1 = (long)getshort(handle);
425 rec->points = new wxRealPoint[(int)rec->param1];
426 for (int i = 0; i < rec->param1; i++)
427 {
428 rec->points[i].x = getshort(handle);
429 rec->points[i].y = getshort(handle);
430 }
59840ba3 431
1fc25a89
JS
432 metaRecords.Append(rec);
433 break;
434 }
435// case META_ESCAPE:
436// case META_RESTOREDC:
437// case META_FILLREGION:
438// case META_FRAMEREGION:
439// case META_INVERTREGION:
440// case META_PAINTREGION:
441// case META_SELECTCLIPREGION: // DO THIS!
442 case META_SELECTOBJECT:
443 {
444 wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT);
445 rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list
446 metaRecords.Append(rec);
447 // param2 gives the index into gdiObjects, which is different from
448 // the index into the handle table.
449 rec->param2 = HandleTable[(int)rec->param1]->param2;
450 break;
451 }
452// case META_SETTEXTALIGN:
453// case META_DRAWTEXT:
454// case META_CHORD:
455// case META_SETMAPPERFLAGS:
456// case META_EXTTEXTOUT:
457// case META_SETDIBTODEV:
458// case META_SELECTPALETTE:
459// case META_REALIZEPALETTE:
460// case META_ANIMATEPALETTE:
461// case META_SETPALENTRIES:
462// case META_POLYPOLYGON:
463// case META_RESIZEPALETTE:
464// case META_DIBBITBLT:
465// case META_DIBSTRETCHBLT:
466 case META_DIBCREATEPATTERNBRUSH:
467 {
468 wxMetaRecord *rec = new wxMetaRecord(META_DIBCREATEPATTERNBRUSH);
59840ba3
RD
469 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
470
1fc25a89
JS
471 metaRecords.Append(rec);
472 gdiObjects.Append(rec);
473 AddMetaRecordHandle(rec);
b9ac87bc 474 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
475 break;
476 }
477// case META_STRETCHDIB:
478// case META_EXTFLOODFILL:
479// case META_RESETDC:
480// case META_STARTDOC:
481// case META_STARTPAGE:
482// case META_ENDPAGE:
483// case META_ABORTDOC:
484// case META_ENDDOC:
485 case META_DELETEOBJECT:
486 {
487 int index = getshort(handle);
488 DeleteMetaRecordHandle(index);
489 break;
490 }
491 case META_CREATEPALETTE:
492 {
493 wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE);
59840ba3
RD
494 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
495
1fc25a89
JS
496 metaRecords.Append(rec);
497 gdiObjects.Append(rec);
498 AddMetaRecordHandle(rec);
b9ac87bc 499 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
500 break;
501 }
502 case META_CREATEBRUSH:
503 {
504 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSH);
59840ba3 505 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
1fc25a89
JS
506 metaRecords.Append(rec);
507 gdiObjects.Append(rec);
508 AddMetaRecordHandle(rec);
b9ac87bc 509 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
510 break;
511 }
512 case META_CREATEPATTERNBRUSH:
513 {
514 wxMetaRecord *rec = new wxMetaRecord(META_CREATEPATTERNBRUSH);
59840ba3 515 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
1fc25a89
JS
516 metaRecords.Append(rec);
517 gdiObjects.Append(rec);
518 AddMetaRecordHandle(rec);
b9ac87bc 519 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
520 break;
521 }
522 case META_CREATEPENINDIRECT:
523 {
524 wxMetaRecord *rec = new wxMetaRecord(META_CREATEPENINDIRECT);
525 int msStyle = getshort(handle); // Style: 2 bytes
526 int x = getshort(handle); // X: 2 bytes
1484b5cc 527 /* int y = */ getshort(handle); // Y: 2 bytes
1fc25a89
JS
528 long colorref = getint(handle); // COLORREF 4 bytes
529
530 int style;
531 if (msStyle == PS_DOT)
532 style = wxDOT;
533 else if (msStyle == PS_DASH)
534 style = wxSHORT_DASH;
535 else if (msStyle == PS_NULL)
536 style = wxTRANSPARENT;
537 else style = wxSOLID;
538
539 wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
540 rec->param1 = (long)wxThePenList->FindOrCreatePen(colour, x, style);
541 metaRecords.Append(rec);
542 gdiObjects.Append(rec);
543
544 AddMetaRecordHandle(rec);
b9ac87bc 545 rec->param2 = (long)(gdiObjects.GetCount() - 1);
59840ba3 546
1fc25a89
JS
547 // For some reason, the size of this record is sometimes 9 words!!!
548 // instead of the usual 8. So read 2 characters extra.
549 if (rdSize == 9)
550 {
551 (void) getshort(handle);
552 }
553 break;
554 }
555 case META_CREATEFONTINDIRECT:
556 {
557 wxMetaRecord *rec = new wxMetaRecord(META_CREATEFONTINDIRECT);
558 int lfHeight = getshort(handle); // 2 bytes
1484b5cc
VS
559 /* int lfWidth = */ getshort(handle); // 2 bytes
560 /* int lfEsc = */ getshort(handle); // 2 bytes
561 /* int lfOrient = */ getshort(handle); // 2 bytes
1fc25a89
JS
562 int lfWeight = getshort(handle); // 2 bytes
563 char lfItalic = getc(handle); // 1 byte
564 char lfUnderline = getc(handle); // 1 byte
1484b5cc
VS
565 /* char lfStrikeout = */ getc(handle); // 1 byte
566 /* char lfCharSet = */ getc(handle); // 1 byte
567 /* char lfOutPrecision = */ getc(handle); // 1 byte
568 /* char lfClipPrecision = */ getc(handle); // 1 byte
569 /* char lfQuality = */ getc(handle); // 1 byte
1fc25a89
JS
570 char lfPitchAndFamily = getc(handle); // 1 byte (18th)
571 char lfFacename[32];
572 // Read the rest of the record, which is total record size
573 // minus the number of bytes already read (18 record, 6 metarecord
574 // header)
575 fread((void *)lfFacename, sizeof(char), (int)((2*rdSize) - 18 - 6), handle);
576
577 int family;
578 if (lfPitchAndFamily & FF_MODERN)
579 family = wxMODERN;
580 else if (lfPitchAndFamily & FF_MODERN)
581 family = wxMODERN;
582 else if (lfPitchAndFamily & FF_ROMAN)
583 family = wxROMAN;
584 else if (lfPitchAndFamily & FF_SWISS)
585 family = wxSWISS;
586 else if (lfPitchAndFamily & FF_DECORATIVE)
587 family = wxDECORATIVE;
588 else
589 family = wxDEFAULT;
590
591 int weight;
592 if (lfWeight == 300)
593 weight = wxLIGHT;
594 else if (lfWeight == 400)
595 weight = wxNORMAL;
596 else if (lfWeight == 900)
597 weight = wxBOLD;
598 else weight = wxNORMAL;
599
600 int style;
601 if (lfItalic != 0)
602 style = wxITALIC;
603 else
604 style = wxNORMAL;
605
606 // About how many pixels per inch???
607 int logPixelsY = 100;
608 int pointSize = (int)(lfHeight*72.0/logPixelsY);
609
610 wxFont *theFont =
611 wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (lfUnderline != 0));
612
613 rec->param1 = (long) theFont;
614 metaRecords.Append(rec);
615 gdiObjects.Append(rec);
616 AddMetaRecordHandle(rec);
b9ac87bc 617 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
618 break;
619 }
620 case META_CREATEBRUSHINDIRECT:
621 {
622 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSHINDIRECT);
623 int msStyle = getshort(handle); // Style: 2 bytes
624 long colorref = getint(handle); // COLORREF: 4 bytes
625 int hatchStyle = getshort(handle); // Hatch style 2 bytes
626
627 int style;
628 switch (msStyle)
629 {
630 case BS_HATCHED:
631 {
632 switch (hatchStyle)
633 {
634 case HS_BDIAGONAL:
635 style = wxBDIAGONAL_HATCH;
636 break;
637 case HS_DIAGCROSS:
638 style = wxCROSSDIAG_HATCH;
639 break;
640 case HS_FDIAGONAL:
641 style = wxFDIAGONAL_HATCH;
642 break;
643 case HS_HORIZONTAL:
644 style = wxHORIZONTAL_HATCH;
645 break;
646 case HS_VERTICAL:
647 style = wxVERTICAL_HATCH;
648 break;
649 default:
650 case HS_CROSS:
651 style = wxCROSS_HATCH;
652 break;
653 }
654 break;
655 }
93210c68
JS
656#if PS_DOT != BS_HATCHED
657 /* ABX 30.12.2003 */
658 /* in microsoft/include/wingdi.h both are the same */
659 /* in fact I'm not sure why pen related PS_XXX and */
660 /* BS_XXX constants are all mixed into single style */
661 case PS_DOT:
662 style = wxDOT;
663 break;
664#endif
665 case PS_DASH:
666 style = wxSHORT_DASH;
667 break;
668 case PS_NULL:
669 style = wxTRANSPARENT;
670 break;
1fc25a89
JS
671 case BS_SOLID:
672 default:
673 style = wxSOLID;
674 break;
675 }
1fc25a89
JS
676
677 wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
678 rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(colour, style);
679 metaRecords.Append(rec);
680 gdiObjects.Append(rec);
681 AddMetaRecordHandle(rec);
b9ac87bc 682 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
683 break;
684 }
685 case META_CREATEBITMAPINDIRECT:
686 {
687 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAPINDIRECT);
59840ba3
RD
688 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
689
1fc25a89
JS
690 metaRecords.Append(rec);
691 gdiObjects.Append(rec);
692 AddMetaRecordHandle(rec);
b9ac87bc 693 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
694 break;
695 }
696 case META_CREATEBITMAP:
697 {
698 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAP);
59840ba3
RD
699 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
700
1fc25a89
JS
701 metaRecords.Append(rec);
702 gdiObjects.Append(rec);
703 AddMetaRecordHandle(rec);
b9ac87bc 704 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
705 break;
706 }
707 case META_CREATEREGION:
708 {
709 wxMetaRecord *rec = new wxMetaRecord(META_CREATEREGION);
59840ba3 710 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
1fc25a89
JS
711
712 metaRecords.Append(rec);
713 gdiObjects.Append(rec);
714 AddMetaRecordHandle(rec);
b9ac87bc 715 rec->param2 = (long)(gdiObjects.GetCount() - 1);
1fc25a89
JS
716 break;
717 }
718 default:
719 {
59840ba3 720 fread((void *)_buf, sizeof(char), (int)((2*rdSize) - 6), handle);
1fc25a89
JS
721 break;
722 }
723 }
724 }
725 fclose(handle);
726 return TRUE;
727}
728
729wxXMetaFile::~wxXMetaFile(void)
730{
b9ac87bc 731 wxNode *node = metaRecords.GetFirst();
1fc25a89
JS
732 while (node)
733 {
b9ac87bc 734 wxMetaRecord *rec = (wxMetaRecord *)node->GetData();
1fc25a89 735 delete rec;
b9ac87bc 736 wxNode *next = node->GetNext();
1fc25a89
JS
737 delete node;
738 node = next;
739 }
740}
741
1484b5cc 742bool wxXMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height))
1fc25a89
JS
743{
744 return FALSE;
745}
746
747bool wxXMetaFile::Play(wxDC *dc)
748{
b9ac87bc 749 wxNode *node = metaRecords.GetFirst();
1fc25a89
JS
750 while (node)
751 {
b9ac87bc 752 wxMetaRecord *rec = (wxMetaRecord *)node->GetData();
1fc25a89
JS
753 int rdFunction = rec->metaFunction;
754
755 switch (rdFunction)
756 {
757 case META_SETBKCOLOR:
758 {
759 break;
760 }
761 case META_SETBKMODE:
762 {
763 break;
764 }
765 case META_SETMAPMODE:
766 {
767 break;
768 }
769// case META_SETROP2:
770// case META_SETRELABS:
771// case META_SETPOLYFILLMODE:
772// case META_SETSTRETCHBLTMODE:
773// case META_SETTEXTCHAREXTRA:
774 case META_SETTEXTCOLOR:
775 {
776 break;
777 }
778// case META_SETTEXTJUSTIFICATION:
779 case META_SETWINDOWORG:
780 {
781 break;
782 }
783 case META_SETWINDOWEXT:
784 {
785 break;
786 }
787// case META_SETVIEWPORTORG:
788// case META_SETVIEWPORTEXT:
789// case META_OFFSETWINDOWORG:
790// case META_SCALEWINDOWEXT:
791// case META_OFFSETVIEWPORTORG:
792// case META_SCALEVIEWPORTEXT:
793 case META_LINETO:
794 {
795 long x1 = rec->param1;
796 long y1 = rec->param2;
797 dc->DrawLine((long) lastX, (long) lastY, x1, y1);
798 break;
799 }
800 case META_MOVETO:
801 {
802 lastX = (double)rec->param1;
803 lastY = (double)rec->param2;
804 break;
805 }
806 case META_EXCLUDECLIPRECT:
807 {
808 break;
809 }
810 case META_INTERSECTCLIPRECT:
811 {
812 break;
813 }
814// case META_ARC: // DO!!!
815 case META_ELLIPSE:
816 {
817 break;
818 }
819// case META_FLOODFILL:
820// case META_PIE: // DO!!!
821 case META_RECTANGLE:
822 {
823 dc->DrawRectangle((long)rec->param1, (long)rec->param2,
824 (long)rec->param3 - rec->param1,
825 (long)rec->param4 - rec->param2);
826 break;
827 }
828 case META_ROUNDRECT:
829 {
830 dc->DrawRoundedRectangle((long)rec->param1, (long)rec->param2,
831 (long)rec->param3 - rec->param1,
832 (long)rec->param4 - rec->param2,
833 (long)rec->param5);
834 break;
835 }
836// case META_PATBLT:
837// case META_SAVEDC:
838 case META_SETPIXEL:
839 {
840// rec->param1 = getshort(handle); // x1
841// rec->param2 = getshort(handle); // y1
842// rec->param3 = getint(handle); // COLORREF
843 break;
844 }
845// case META_OFFSETCLIPRGN:
846 case META_TEXTOUT:
847 {
848/*
849 int count = getshort(handle);
850 rec->stringParam = new char[count+1];
851 fread((void *)rec->stringParam, sizeof(char), count, handle);
852 rec->stringParam[count] = 0;
853 rec->param2 = getshort(handle); // Y
854 rec->param1 = getshort(handle); // X
855*/
856 break;
857 }
858// case META_BITBLT:
859// case META_STRETCHBLT:
860 case META_POLYGON:
861 {
862/*
863 rec->param1 = getshort(handle);
864 rec->points = new wxRealPoint[(int)rec->param1];
865 for (int i = 0; i < rec->param1; i++)
866 {
867 rec->points[i].x = getshort(handle);
868 rec->points[i].y = getshort(handle);
869 }
59840ba3 870*/
1fc25a89
JS
871 break;
872 }
873 case META_POLYLINE:
874 {
875/*
876 wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE);
877 rec->param1 = (long)getshort(handle);
878 rec->points = new wxRealPoint[(int)rec->param1];
879 for (int i = 0; i < rec->param1; i++)
880 {
881 rec->points[i].x = getshort(handle);
882 rec->points[i].y = getshort(handle);
883 }
59840ba3 884*/
1fc25a89
JS
885 break;
886 }
887// case META_ESCAPE:
888// case META_RESTOREDC:
889// case META_FILLREGION:
890// case META_FRAMEREGION:
891// case META_INVERTREGION:
892// case META_PAINTREGION:
893// case META_SELECTCLIPREGION: // DO THIS!
894 case META_SELECTOBJECT:
895 {
896/*
897 wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT);
898 rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list
899*/
900 break;
901 }
902// case META_SETTEXTALIGN:
903// case META_DRAWTEXT:
904// case META_CHORD:
905// case META_SETMAPPERFLAGS:
906// case META_EXTTEXTOUT:
907// case META_SETDIBTODEV:
908// case META_SELECTPALETTE:
909// case META_REALIZEPALETTE:
910// case META_ANIMATEPALETTE:
911// case META_SETPALENTRIES:
912// case META_POLYPOLYGON:
913// case META_RESIZEPALETTE:
914// case META_DIBBITBLT:
915// case META_DIBSTRETCHBLT:
916 case META_DIBCREATEPATTERNBRUSH:
917 {
918/*
919 fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
59840ba3 920*/
1fc25a89
JS
921 break;
922 }
923// case META_STRETCHDIB:
924// case META_EXTFLOODFILL:
925// case META_RESETDC:
926// case META_STARTDOC:
927// case META_STARTPAGE:
928// case META_ENDPAGE:
929// case META_ABORTDOC:
930// case META_ENDDOC:
931// case META_DELETEOBJECT: // DO!!
932 case META_CREATEPALETTE:
933 {
934/*
935 wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE);
936 fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
937*/
938 break;
939 }
940 case META_CREATEBRUSH:
941 {
942/*
943 fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
944*/
945 break;
946 }
947 case META_CREATEPATTERNBRUSH:
948 {
949/*
950 fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
951*/
952 break;
953 }
954 case META_CREATEPENINDIRECT:
955 {
956/*
957 int msStyle = getshort(handle); // Style: 2 bytes
958 int x = getshort(handle); // X: 2 bytes
959 int y = getshort(handle); // Y: 2 bytes
960 int colorref = getint(handle); // COLORREF 4 bytes
961
962 int style;
963 if (msStyle == PS_DOT)
964 style = wxDOT;
965 else if (msStyle == PS_DASH)
966 style = wxSHORT_DASH;
967 else if (msStyle == PS_NULL)
968 style = wxTRANSPARENT;
969 else style = wxSOLID;
970
971 wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
972 rec->param1 = (long)wxThePenList->FindOrCreatePen(&colour, x, style);
973*/
974 break;
975 }
976 case META_CREATEFONTINDIRECT:
977 {
978/*
979 int lfHeight = getshort(handle);
980 int lfWidth = getshort(handle);
981 int lfEsc = getshort(handle);
982 int lfOrient = getshort(handle);
983 int lfWeight = getshort(handle);
984 char lfItalic = getc(handle);
985 char lfUnderline = getc(handle);
986 char lfStrikeout = getc(handle);
987 char lfCharSet = getc(handle);
988 char lfOutPrecision = getc(handle);
989 char lfClipPrecision = getc(handle);
990 char lfQuality = getc(handle);
991 char lfPitchAndFamily = getc(handle);
992 char lfFacename[32];
993 fread((void *)lfFacename, sizeof(char), 32, handle);
994
995 int family;
996 if (lfPitchAndFamily & FF_MODERN)
997 family = wxMODERN;
998 else if (lfPitchAndFamily & FF_MODERN)
999 family = wxMODERN;
1000 else if (lfPitchAndFamily & FF_ROMAN)
1001 family = wxROMAN;
1002 else if (lfPitchAndFamily & FF_SWISS)
1003 family = wxSWISS;
1004 else if (lfPitchAndFamily & FF_DECORATIVE)
1005 family = wxDECORATIVE;
1006 else
1007 family = wxDEFAULT;
1008
1009 int weight;
1010 if (lfWeight == 300)
1011 weight = wxLIGHT;
1012 else if (lfWeight == 400)
1013 weight = wxNORMAL;
1014 else if (lfWeight == 900)
1015 weight = wxBOLD;
1016 else weight = wxNORMAL;
1017
1018 int style;
1019 if ((bool)lfItalic)
1020 style = wxITALIC;
1021 else
1022 style = wxNORMAL;
1023
1024 // About how many pixels per inch???
1025 int logPixelsY = 100;
1026 int pointSize = (int)(lfHeight*72.0/logPixelsY);
1027
1028 wxFont *theFont =
1029 wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (bool)lfUnderline);
1030
1031 rec->param1 = (long)theFont;
1032*/
1033 break;
1034 }
1035 case META_CREATEBRUSHINDIRECT:
1036 {
1037/*
1038 int msStyle = getshort(handle); // Style: 2 bytes
1039 int colorref = getint(handle); // COLORREF: 4 bytes
1040 int hatchStyle = getshort(handle); // Hatch style 2 bytes
1041
1042 int style;
1043 if (msStyle == PS_DOT)
1044 style = wxDOT;
1045 else if (msStyle == PS_DASH)
1046 style = wxSHORT_DASH;
1047 else if (msStyle == PS_NULL)
1048 style = wxTRANSPARENT;
1049 else style = wxSOLID;
1050
1051 wxColour colour(GetRValue(colorref), GetGValue(colorref), GetBValue(colorref));
1052 rec->param1 = (long)wxTheBrushList->FindOrCreateBrush(&colour, wxSOLID);
1053*/
1054 break;
1055 }
1056 case META_CREATEBITMAPINDIRECT:
1057 {
1058/*
1059 fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
59840ba3 1060*/
1fc25a89
JS
1061 break;
1062 }
1063 case META_CREATEBITMAP:
1064 {
1065/*
1066 fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
59840ba3 1067*/
1fc25a89
JS
1068 break;
1069 }
1070 case META_CREATEREGION:
1071 {
1072 dc->DestroyClippingRegion();
1073/*
1074 rec->param1 = getshort(handle); // Style: 2 bytes
1075*/
1076 break;
1077 }
1078 default:
1079 {
1080 break;
1081 }
1082 }
b9ac87bc 1083 node = node->GetNext();
1fc25a89
JS
1084 }
1085 return TRUE;
1086}
1087