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