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