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