1 //////////////////////////////////////////////////////////////////////////
2 //
3 // pgAdmin III - PostgreSQL Tools
4 //
5 // Portions Copyright (C) 1998 - 2011, Julian Smart
6 // Portions Copyright (C) 2011 - 2016, The pgAdmin Development Team
7 // This software is released under the PostgreSQL Licence
8 //
9 // mfutils.cpp - Metafile utillities
10 //
11 //////////////////////////////////////////////////////////////////////////
12
13 #include "pgAdmin3.h"
14
15 #include <wx/metafile.h>
16 #include <wx/utils.h>
17
18 #include "ogl/ogl.h"
19
20 #include <stdio.h>
21
22 static char _buf[1024]; // a temp buffer to use inplace of wxBuffer, which is deprecated.
23
24 // 16-bit unsigned integer
getshort(FILE * fp)25 static unsigned int getshort(FILE *fp)
26 {
27 int c, c1;
28 c = getc(fp);
29 c1 = getc(fp);
30 unsigned int res = ((unsigned int) c) + (((unsigned int) c1) << 8);
31 return res;
32 }
33
34 // 16-bit signed integer
getsignedshort(FILE * fp)35 static int getsignedshort(FILE *fp)
36 {
37 int c, c1;
38 c = getc(fp);
39 c1 = getc(fp);
40 #if 0
41 // this is not used value, no need to execute it
42 int testRes = ((unsigned int) c) + (((unsigned int) c1) << 8);
43 #endif
44 unsigned long res1 = ((unsigned int) c) + (((unsigned int) c1) << 8);
45 int res;
46 if (res1 > 32767)
47 res = (int)(res1 - 65536);
48 else
49 res = (int)(res1);
50 return res;
51 }
52
53 // 32-bit integer
getint(FILE * fp)54 static long getint(FILE *fp)
55 {
56 int c, c1, c2, c3;
57 c = getc(fp);
58 c1 = getc(fp);
59 c2 = getc(fp);
60 c3 = getc(fp);
61 long res = (long)((long) c) +
62 (((long) c1) << 8) +
63 (((long) c2) << 16) +
64 (((long) c3) << 24);
65 return res;
66 }
67
68
69 /* Placeable metafile header
70 struct mfPLACEABLEHEADER {
71 DWORD key; // 32-bit
72 HANDLE hmf; // 16-bit
73 RECT bbox; // 4x16 bit
74 WORD inch; // 16-bit
75 DWORD reserved; // 32-bit
76 WORD checksum; // 16-bit
77 };
78 */
79
~wxMetaRecord(void)80 wxMetaRecord::~wxMetaRecord(void)
81 {
82 if (points) delete[] points;
83 if (stringParam) delete[] stringParam;
84 }
85
wxXMetaFile(const wxChar * file)86 wxXMetaFile::wxXMetaFile(const wxChar *file)
87 {
88 ok = FALSE;
89 top = 0.0;
90 bottom = 0.0;
91 left = 0.0;
92 right = 0.0;
93
94 if (file)
95 ok = ReadFile(file);
96 }
97
98 /*
99 Handle table gdiObjects
100 ------------ ----------
101 [0] wxPen
102 [1]----param2--- wxBrush
103 [2] | wxFont
104 [3] | -> wxPen
105
106 The handle table works as follows.
107 When a GDI object is created whilst reading in the
108 metafile, the (e.g.) createpen record is added to the
109 first free entry in the handle table. The createpen
110 record's param1 is a pointer to the actual wxPen, and
111 its param2 is the index into the gdiObjects list, which only
112 grows and never shrinks (unlike the handle table.)
113
114 When SelectObject(index) is found, the index in the file
115 refers to the position in the handle table. BUT we then
116 set param2 to be the position of the wxPen in gdiObjects,
117 i.e. to param2 of the CreatePen record, itself found in
118 the handle table.
119
120 When an object is deleted, the entry in the handletable is
121 NULLed but the gdiObjects entry is not removed (no point, and
122 allows us to create all GDI objects in advance of playing the
123 metafile).
124 */
125
126
127 static wxMetaRecord *HandleTable[100];
128 static int HandleTableSize = 0;
129
DeleteMetaRecordHandle(int index)130 void DeleteMetaRecordHandle(int index)
131 {
132 HandleTable[index] = NULL;
133 }
134
AddMetaRecordHandle(wxMetaRecord * record)135 int AddMetaRecordHandle(wxMetaRecord *record)
136 {
137 for (int i = 0; i < HandleTableSize; i++)
138 if (!HandleTable[i])
139 {
140 HandleTable[i] = record;
141 return i;
142 }
143 // No free spaces in table, so append.
144
145 HandleTable[HandleTableSize] = record;
146 HandleTableSize ++;
147 return (HandleTableSize - 1);
148 }
149
ReadFile(const wxChar * file)150 bool wxXMetaFile::ReadFile(const wxChar *file)
151 {
152 HandleTableSize = 0;
153
154 FILE *handle = wxFopen(file, wxT("rb"));
155 if (!handle) return FALSE;
156
157 // Read placeable metafile header, if any
158 long key = getint(handle);
159
160 if (key == (long) 0x9AC6CDD7)
161 {
162 /* long hmf = */ getshort(handle);
163 int iLeft, iTop, iRight, iBottom;
164 iLeft = getsignedshort(handle);
165 iTop = getsignedshort(handle);
166 iRight = getsignedshort(handle);
167 iBottom = getsignedshort(handle);
168
169 left = (double)iLeft;
170 top = (double)iTop;
171 right = (double)iRight;
172 bottom = (double)iBottom;
173
174 /* int inch = */
175 getshort(handle);
176 /* long reserved = */
177 getint(handle);
178 /* int checksum = */
179 getshort(handle);
180 /*
181 double widthInUnits = (double)right - left;
182 double heightInUnits = (double)bottom - top;
183 *width = (int)((widthInUnits*1440.0)/inch);
184 *height = (int)((heightInUnits*1440.0)/inch);
185 */
186 }
187 else rewind(handle);
188
189 // Read METAHEADER
190 int mtType = getshort(handle);
191
192 if (mtType != 1 && mtType != 2)
193 {
194 fclose(handle);
195 return FALSE;
196 }
197
198 /* int mtHeaderSize = */ getshort(handle);
199 int mtVersion = getshort(handle);
200
201 if (mtVersion != 0x0300 && mtVersion != 0x0100)
202 {
203 fclose(handle);
204 return FALSE;
205 }
206
207 /* long mtSize = */ getint(handle);
208 /* int mtNoObjects = */
209 getshort(handle);
210 /* long mtMaxRecord = */
211 getint(handle);
212 /* int mtNoParameters = */
213 getshort(handle);
214
215 while (!feof(handle))
216 {
217 long rdSize = getint(handle); // 4 bytes
218 int rdFunction = getshort(handle); // 2 bytes
219 if (feof(handle))
220 break;
221
222 switch (rdFunction)
223 {
224 case META_SETBKCOLOR:
225 {
226 wxMetaRecord *rec = new wxMetaRecord(META_SETBKCOLOR);
227 long colorref = getint(handle); // COLORREF
228 rec->param1 = GetRValue(colorref);
229 rec->param2 = GetGValue(colorref);
230 rec->param3 = GetBValue(colorref);
231 metaRecords.Append(rec);
232 break;
233 }
234 case META_SETBKMODE:
235 {
236 wxMetaRecord *rec = new wxMetaRecord(META_SETBKMODE);
237 rec->param1 = getshort(handle); // Background mode
238 if (rec->param1 == OPAQUE) rec->param1 = wxSOLID;
239 else rec->param1 = wxTRANSPARENT;
240 metaRecords.Append(rec);
241 break;
242 }
243 case META_SETMAPMODE:
244 {
245 wxMetaRecord *rec = new wxMetaRecord(META_SETMAPMODE);
246 rec->param1 = getshort(handle);
247 metaRecords.Append(rec);
248 break;
249 }
250 // case META_SETROP2:
251 // case META_SETRELABS:
252 // case META_SETPOLYFILLMODE:
253 // case META_SETSTRETCHBLTMODE:
254 // case META_SETTEXTCHAREXTRA:
255 case META_SETTEXTCOLOR:
256 {
257 wxMetaRecord *rec = new wxMetaRecord(META_SETTEXTCOLOR);
258 long colorref = getint(handle); // COLORREF
259 rec->param1 = GetRValue(colorref);
260 rec->param2 = GetGValue(colorref);
261 rec->param3 = GetBValue(colorref);
262 metaRecords.Append(rec);
263 break;
264 }
265 // case META_SETTEXTJUSTIFICATION:
266 case META_SETWINDOWORG:
267 {
268 wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWORG);
269 rec->param2 = getshort(handle);
270 rec->param1 = getshort(handle);
271 metaRecords.Append(rec);
272 break;
273 }
274 case META_SETWINDOWEXT:
275 {
276 wxMetaRecord *rec = new wxMetaRecord(META_SETWINDOWEXT);
277 rec->param2 = getshort(handle);
278 rec->param1 = getshort(handle);
279 metaRecords.Append(rec);
280 break;
281 }
282 // case META_SETVIEWPORTORG:
283 // case META_SETVIEWPORTEXT:
284 // case META_OFFSETWINDOWORG:
285 // case META_SCALEWINDOWEXT:
286 // case META_OFFSETVIEWPORTORG:
287 // case META_SCALEVIEWPORTEXT:
288 case META_LINETO:
289 {
290 wxMetaRecord *rec = new wxMetaRecord(META_LINETO);
291 rec->param1 = getshort(handle); // x1
292 rec->param2 = getshort(handle); // y1
293 metaRecords.Append(rec);
294 break;
295 }
296 case META_MOVETO:
297 {
298 wxMetaRecord *rec = new wxMetaRecord(META_MOVETO);
299 rec->param1 = getshort(handle); // x1
300 rec->param2 = getshort(handle); // y1
301 metaRecords.Append(rec);
302 break;
303 }
304 case META_EXCLUDECLIPRECT:
305 {
306 wxMetaRecord *rec = new wxMetaRecord(META_EXCLUDECLIPRECT);
307 rec->param4 = getshort(handle); // y2
308 rec->param3 = getshort(handle); // x2
309 rec->param2 = getshort(handle); // y1
310 rec->param1 = getshort(handle); // x1
311 metaRecords.Append(rec);
312 break;
313 }
314 case META_INTERSECTCLIPRECT:
315 {
316 wxMetaRecord *rec = new wxMetaRecord(META_INTERSECTCLIPRECT);
317 rec->param4 = getshort(handle); // y2
318 rec->param3 = getshort(handle); // x2
319 rec->param2 = getshort(handle); // y1
320 rec->param1 = getshort(handle); // x1
321 metaRecords.Append(rec);
322 break;
323 }
324 // case META_ARC: // DO!!!
325 case META_ELLIPSE:
326 {
327 wxMetaRecord *rec = new wxMetaRecord(META_ELLIPSE);
328 rec->param4 = getshort(handle); // y2
329 rec->param3 = getshort(handle); // x2
330 rec->param2 = getshort(handle); // y1
331 rec->param1 = getshort(handle); // x1
332 metaRecords.Append(rec);
333 break;
334 }
335 // case META_FLOODFILL:
336 // case META_PIE: // DO!!!
337 case META_RECTANGLE:
338 {
339 wxMetaRecord *rec = new wxMetaRecord(META_RECTANGLE);
340 rec->param4 = getshort(handle); // y2
341 rec->param3 = getshort(handle); // x2
342 rec->param2 = getshort(handle); // y1
343 rec->param1 = getshort(handle); // x1
344 metaRecords.Append(rec);
345 break;
346 }
347 case META_ROUNDRECT:
348 {
349 wxMetaRecord *rec = new wxMetaRecord(META_ROUNDRECT);
350 rec->param6 = getshort(handle); // width
351 rec->param5 = getshort(handle); // height
352 rec->param4 = getshort(handle); // y2
353 rec->param3 = getshort(handle); // x2
354 rec->param2 = getshort(handle); // y1
355 rec->param1 = getshort(handle); // x1
356 metaRecords.Append(rec);
357 break;
358 }
359 // case META_PATBLT:
360 // case META_SAVEDC:
361 case META_SETPIXEL:
362 {
363 wxMetaRecord *rec = new wxMetaRecord(META_SETPIXEL);
364 rec->param1 = getshort(handle); // x1
365 rec->param2 = getshort(handle); // y1
366 rec->param3 = getint(handle); // COLORREF
367 metaRecords.Append(rec);
368 break;
369 }
370 // case META_OFFSETCLIPRGN:
371 case META_TEXTOUT:
372 {
373 wxMetaRecord *rec = new wxMetaRecord(META_TEXTOUT);
374 int count = getshort(handle);
375 rec->stringParam = new wxChar[count + 1];
376 fread((void *)rec->stringParam, sizeof(wxChar), count, handle);
377 rec->stringParam[count] = 0;
378 rec->param2 = getshort(handle); // Y
379 rec->param1 = getshort(handle); // X
380 metaRecords.Append(rec);
381 break;
382 }
383 /*
384 case META_EXTTEXTOUT:
385 {
386 wxMetaRecord *rec = new wxMetaRecord(META_EXTTEXTOUT);
387 int cellSpacing = getshort(handle);
388 int count = getshort(handle);
389 rec->stringParam = new char[count+1];
390 fread((void *)rec->stringParam, sizeof(char), count, handle);
391 rec->stringParam[count] = 0;
392 // Rectangle
393 int rectY2 = getshort(handle);
394 int rectX2 = getshort(handle);
395 int rectY1 = getshort(handle);
396 int rectX1 = getshort(handle);
397 int rectType = getshort(handle);
398 rec->param2 = getshort(handle); // Y
399 rec->param1 = getshort(handle); // X
400 metaRecords.Append(rec);
401 break;
402 }
403 */
404 // case META_BITBLT:
405 // case META_STRETCHBLT:
406 case META_POLYGON:
407 {
408 wxMetaRecord *rec = new wxMetaRecord(META_POLYGON);
409 rec->param1 = getshort(handle);
410 rec->points = new wxRealPoint[(int)rec->param1];
411 for (int i = 0; i < rec->param1; i++)
412 {
413 rec->points[i].x = getshort(handle);
414 rec->points[i].y = getshort(handle);
415 }
416
417 metaRecords.Append(rec);
418 break;
419 }
420 case META_POLYLINE:
421 {
422 wxMetaRecord *rec = new wxMetaRecord(META_POLYLINE);
423 rec->param1 = (long)getshort(handle);
424 rec->points = new wxRealPoint[(int)rec->param1];
425 for (int i = 0; i < rec->param1; i++)
426 {
427 rec->points[i].x = getshort(handle);
428 rec->points[i].y = getshort(handle);
429 }
430
431 metaRecords.Append(rec);
432 break;
433 }
434 // case META_ESCAPE:
435 // case META_RESTOREDC:
436 // case META_FILLREGION:
437 // case META_FRAMEREGION:
438 // case META_INVERTREGION:
439 // case META_PAINTREGION:
440 // case META_SELECTCLIPREGION: // DO THIS!
441 case META_SELECTOBJECT:
442 {
443 wxMetaRecord *rec = new wxMetaRecord(META_SELECTOBJECT);
444 rec->param1 = (long)getshort(handle); // Position of object in gdiObjects list
445 metaRecords.Append(rec);
446 // param2 gives the index into gdiObjects, which is different from
447 // the index into the handle table.
448 rec->param2 = HandleTable[(int)rec->param1]->param2;
449 break;
450 }
451 // case META_SETTEXTALIGN:
452 // case META_DRAWTEXT:
453 // case META_CHORD:
454 // case META_SETMAPPERFLAGS:
455 // case META_EXTTEXTOUT:
456 // case META_SETDIBTODEV:
457 // case META_SELECTPALETTE:
458 // case META_REALIZEPALETTE:
459 // case META_ANIMATEPALETTE:
460 // case META_SETPALENTRIES:
461 // case META_POLYPOLYGON:
462 // case META_RESIZEPALETTE:
463 // case META_DIBBITBLT:
464 // case META_DIBSTRETCHBLT:
465 case META_DIBCREATEPATTERNBRUSH:
466 {
467 wxMetaRecord *rec = new wxMetaRecord(META_DIBCREATEPATTERNBRUSH);
468 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
469
470 metaRecords.Append(rec);
471 gdiObjects.Append(rec);
472 AddMetaRecordHandle(rec);
473 rec->param2 = (long)(gdiObjects.GetCount() - 1);
474 break;
475 }
476 // case META_STRETCHDIB:
477 // case META_EXTFLOODFILL:
478 // case META_RESETDC:
479 // case META_STARTDOC:
480 // case META_STARTPAGE:
481 // case META_ENDPAGE:
482 // case META_ABORTDOC:
483 // case META_ENDDOC:
484 case META_DELETEOBJECT:
485 {
486 int index = getshort(handle);
487 DeleteMetaRecordHandle(index);
488 break;
489 }
490 case META_CREATEPALETTE:
491 {
492 wxMetaRecord *rec = new wxMetaRecord(META_CREATEPALETTE);
493 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
494
495 metaRecords.Append(rec);
496 gdiObjects.Append(rec);
497 AddMetaRecordHandle(rec);
498 rec->param2 = (long)(gdiObjects.GetCount() - 1);
499 break;
500 }
501 case META_CREATEBRUSH:
502 {
503 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSH);
504 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
505 metaRecords.Append(rec);
506 gdiObjects.Append(rec);
507 AddMetaRecordHandle(rec);
508 rec->param2 = (long)(gdiObjects.GetCount() - 1);
509 break;
510 }
511 case META_CREATEPATTERNBRUSH:
512 {
513 wxMetaRecord *rec = new wxMetaRecord(META_CREATEPATTERNBRUSH);
514 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
515 metaRecords.Append(rec);
516 gdiObjects.Append(rec);
517 AddMetaRecordHandle(rec);
518 rec->param2 = (long)(gdiObjects.GetCount() - 1);
519 break;
520 }
521 case META_CREATEPENINDIRECT:
522 {
523 wxMetaRecord *rec = new wxMetaRecord(META_CREATEPENINDIRECT);
524 int msStyle = getshort(handle); // Style: 2 bytes
525 int x = getshort(handle); // X: 2 bytes
526 /* int y = */
527 getshort(handle); // Y: 2 bytes
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);
545 rec->param2 = (long)(gdiObjects.GetCount() - 1);
546
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
559 /* int lfWidth = */
560 getshort(handle); // 2 bytes
561 /* int lfEsc = */
562 getshort(handle); // 2 bytes
563 /* int lfOrient = */
564 getshort(handle); // 2 bytes
565 int lfWeight = getshort(handle); // 2 bytes
566 char lfItalic = getc(handle); // 1 byte
567 char lfUnderline = getc(handle); // 1 byte
568 /* char lfStrikeout = */
569 getc(handle); // 1 byte
570 /* char lfCharSet = */
571 getc(handle); // 1 byte
572 /* char lfOutPrecision = */
573 getc(handle); // 1 byte
574 /* char lfClipPrecision = */
575 getc(handle); // 1 byte
576 /* char lfQuality = */
577 getc(handle); // 1 byte
578 char lfPitchAndFamily = getc(handle); // 1 byte (18th)
579 char lfFacename[32];
580 // Read the rest of the record, which is total record size
581 // minus the number of bytes already read (18 record, 6 metarecord
582 // header)
583 fread((void *)lfFacename, sizeof(char), (int)((2 * rdSize) - 18 - 6), handle);
584
585 int family;
586 if (lfPitchAndFamily & FF_MODERN)
587 family = wxMODERN;
588 else if (lfPitchAndFamily & FF_MODERN)
589 family = wxMODERN;
590 else if (lfPitchAndFamily & FF_ROMAN)
591 family = wxROMAN;
592 else if (lfPitchAndFamily & FF_SWISS)
593 family = wxSWISS;
594 else if (lfPitchAndFamily & FF_DECORATIVE)
595 family = wxDECORATIVE;
596 else
597 family = wxDEFAULT;
598
599 int weight;
600 if (lfWeight == 300)
601 weight = wxLIGHT;
602 else if (lfWeight == 400)
603 weight = wxNORMAL;
604 else if (lfWeight == 900)
605 weight = wxBOLD;
606 else weight = wxNORMAL;
607
608 int style;
609 if (lfItalic != 0)
610 style = wxITALIC;
611 else
612 style = wxNORMAL;
613
614 // About how many pixels per inch???
615 int logPixelsY = 100;
616 int pointSize = (int)(lfHeight * 72.0 / logPixelsY);
617
618 wxFont *theFont =
619 wxTheFontList->FindOrCreateFont(pointSize, family, style, weight, (lfUnderline != 0));
620
621 rec->param1 = (long) theFont;
622 metaRecords.Append(rec);
623 gdiObjects.Append(rec);
624 AddMetaRecordHandle(rec);
625 rec->param2 = (long)(gdiObjects.GetCount() - 1);
626 break;
627 }
628 case META_CREATEBRUSHINDIRECT:
629 {
630 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBRUSHINDIRECT);
631 int msStyle = getshort(handle); // Style: 2 bytes
632 long colorref = getint(handle); // COLORREF: 4 bytes
633 int hatchStyle = getshort(handle); // Hatch style 2 bytes
634
635 int style;
636 switch (msStyle)
637 {
638 case BS_HATCHED:
639 {
640 switch (hatchStyle)
641 {
642 case HS_BDIAGONAL:
643 style = wxBDIAGONAL_HATCH;
644 break;
645 case HS_DIAGCROSS:
646 style = wxCROSSDIAG_HATCH;
647 break;
648 case HS_FDIAGONAL:
649 style = wxFDIAGONAL_HATCH;
650 break;
651 case HS_HORIZONTAL:
652 style = wxHORIZONTAL_HATCH;
653 break;
654 case HS_VERTICAL:
655 style = wxVERTICAL_HATCH;
656 break;
657 default:
658 case HS_CROSS:
659 style = wxCROSS_HATCH;
660 break;
661 }
662 break;
663 }
664 case BS_SOLID:
665 default:
666 style = wxSOLID;
667 break;
668 }
669 if (msStyle == PS_DOT)
670 style = wxDOT;
671 else if (msStyle == PS_DASH)
672 style = wxSHORT_DASH;
673 else if (msStyle == PS_NULL)
674 style = wxTRANSPARENT;
675 else style = wxSOLID;
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);
682 rec->param2 = (long)(gdiObjects.GetCount() - 1);
683 break;
684 }
685 case META_CREATEBITMAPINDIRECT:
686 {
687 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAPINDIRECT);
688 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
689
690 metaRecords.Append(rec);
691 gdiObjects.Append(rec);
692 AddMetaRecordHandle(rec);
693 rec->param2 = (long)(gdiObjects.GetCount() - 1);
694 break;
695 }
696 case META_CREATEBITMAP:
697 {
698 wxMetaRecord *rec = new wxMetaRecord(META_CREATEBITMAP);
699 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
700
701 metaRecords.Append(rec);
702 gdiObjects.Append(rec);
703 AddMetaRecordHandle(rec);
704 rec->param2 = (long)(gdiObjects.GetCount() - 1);
705 break;
706 }
707 case META_CREATEREGION:
708 {
709 wxMetaRecord *rec = new wxMetaRecord(META_CREATEREGION);
710 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
711
712 metaRecords.Append(rec);
713 gdiObjects.Append(rec);
714 AddMetaRecordHandle(rec);
715 rec->param2 = (long)(gdiObjects.GetCount() - 1);
716 break;
717 }
718 default:
719 {
720 fread((void *)_buf, sizeof(char), (int)((2 * rdSize) - 6), handle);
721 break;
722 }
723 }
724 }
725 fclose(handle);
726 return TRUE;
727 }
728
~wxXMetaFile(void)729 wxXMetaFile::~wxXMetaFile(void)
730 {
731 wxNode *node = metaRecords.GetFirst();
732 while (node)
733 {
734 wxMetaRecord *rec = (wxMetaRecord *)node->GetData();
735 delete rec;
736 wxNode *next = node->GetNext();
737 delete node;
738 node = next;
739 }
740 }
741
SetClipboard(int WXUNUSED (width),int WXUNUSED (height))742 bool wxXMetaFile::SetClipboard(int WXUNUSED(width), int WXUNUSED(height))
743 {
744 return FALSE;
745 }
746
Play(wxDC * dc)747 bool wxXMetaFile::Play(wxDC *dc)
748 {
749 wxNode *node = metaRecords.GetFirst();
750 while (node)
751 {
752 wxMetaRecord *rec = (wxMetaRecord *)node->GetData();
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 }
870 */
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 }
884 */
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);
920 */
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);
1060 */
1061 break;
1062 }
1063 case META_CREATEBITMAP:
1064 {
1065 /*
1066 fread((void *)wxBuffer, sizeof(char), (int)(rdSize - 3), handle);
1067 */
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 }
1083 node = node->GetNext();
1084 }
1085 return TRUE;
1086 }
1087
1088