1 /* libwmf (player.c): library for wmf conversion
2 Copyright (C) 2000,2001 - various; see CREDITS, ChangeLog, and sources
3
4 The libwmf Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The libwmf Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the libwmf Library; see the file COPYING. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
18
19
20 #ifdef HAVE_CONFIG_H
21 #include "wmfconfig.h"
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <math.h>
28
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32
33 #include "wmfdefs.h"
34 #include "metadefs.h"
35
36 #include "player.h"
37 #include "player/region.h" /* Provides: REGION manipulation functions */
38 #include "player/clip.h" /* Provides: clip function */
39 #include "player/color.h" /* Provides: color stuff */
40 #include "player/coord.h" /* Provides: coordinate translations */
41 #include "player/dc.h" /* Provides: dc stack & other dc functions */
42 #include "player/defaults.h" /* Provides: default settings */
43 #include "player/record.h" /* Provides: parameter mechanism */
44 #include "player/meta.h" /* Provides: record interpreters */
45 #include <stdint.h>
46
47 /**
48 * @internal
49 */
wmf_player_init(wmfAPI * API)50 wmf_error_t wmf_player_init (wmfAPI* API)
51 { wmfPlayer_t* P = 0;
52
53 WMF_DEBUG (API,"~~~~~~~~wmf_player_init");
54
55 API->player_data = wmf_malloc (API,sizeof (wmfPlayer_t));
56
57 if (ERR (API))
58 { WMF_DEBUG (API,"bailing...");
59 return (API->err);
60 }
61
62 P = (wmfPlayer_t*) API->player_data;
63
64 P->flags = 0;
65
66 return (API->err);
67 }
68
69 /**
70 * Scan the metafile.
71 *
72 * @param API the API handle
73 * @param flags (unused)
74 * @param d_r for bounding-box return
75 *
76 * Before the metafile can be played, it must be scanned. This is because metafile headers do not always
77 * provide image size information. Although the device layer (the graphics exporter) is initialized in
78 * wmf_api_create(), the output device is not opened until after the metafile is scanned. By scanning,
79 * therefore, the device layer can be provided on opening not only with size information but also a list
80 * of colors to expect (not including those in raster images) and of other required resources, if necessary.
81 * Finally, if scanning fails, then there's certainly no point in playing the metafile.
82 *
83 * The bounding box, in device coordinates, is returned in \p *d_r.
84 *
85 * @return Returns the library error state (\b wmf_E_None on success).
86 */
wmf_scan(wmfAPI * API,unsigned long flags,wmfD_Rect * d_r)87 wmf_error_t wmf_scan (wmfAPI* API,unsigned long flags,wmfD_Rect* d_r)
88 { (void)flags;
89 wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
90
91 WMF_DEBUG (API,"~~~~~~~~wmf_scan");
92
93 if (ERR (API))
94 { WMF_DEBUG (API,"bailing...");
95 return (API->err);
96 }
97
98 /* wmf_scan doesn't allow re-scanning, but I suppose there may be a case
99 * implementing a rescan function (or WMF_RESCAN flag?) at some point ??
100 */
101 if (P->flags & PLAYER_SCANNED)
102 { WMF_DEBUG (API,"already scanned; skipping...");
103 return (API->err);
104 }
105
106 P->dc_stack_maxlen = 0;
107 P->dc_stack = 0;
108
109 P->objects = 0;
110
111 P->D_TL.x = 0;
112 P->D_TL.y = 0;
113 P->D_BR.x = 0;
114 P->D_BR.y = 0;
115
116 d_r->TL = P->D_TL;
117 d_r->BR = P->D_BR;
118
119 P->flags &= ~PLAYER_PLAY; /* Set scan mode */
120
121 wmf_header_read (API);
122
123 if (ERR (API))
124 { WMF_DEBUG (API,"bailing...");
125 return (API->err);
126 }
127
128 if (API->File->wmfheader->NumOfObjects > 0)
129 { P->objects = (wmfObject*) wmf_malloc (API,NUM_OBJECTS (API) * sizeof (wmfObject));
130
131 if (ERR (API))
132 { WMF_DEBUG (API,"bailing...");
133 return (API->err);
134 }
135 }
136
137 if (MAX_REC_SIZE(API) > UINT32_MAX / 2)
138 {
139 API->err = wmf_E_InsMem;
140 WMF_DEBUG (API,"bailing...");
141 return (API->err);
142 }
143
144 U32 nMaxRecordSize = (MAX_REC_SIZE(API) ) * 2 * sizeof (unsigned char);
145 if (nMaxRecordSize)
146 {
147 //before allocating memory do a sanity check on size by seeking
148 //to claimed end to see if its possible. We're constrained here
149 //by the api and existing implementations to not simply seeking
150 //to SEEK_END. So use what we have to skip to the last byte and
151 //try and read it.
152 const long nPos = WMF_TELL (API);
153 WMF_SEEK (API, nPos + nMaxRecordSize - 1);
154 if (ERR (API))
155 { WMF_DEBUG (API,"bailing...");
156 return (API->err);
157 }
158 int byte = WMF_READ (API);
159 if (byte == (-1))
160 { WMF_ERROR (API,"Unexpected EOF!");
161 API->err = wmf_E_EOF;
162 return (API->err);
163 }
164 WMF_SEEK (API, nPos);
165 }
166
167 P->Parameters = (unsigned char*) wmf_malloc (API, nMaxRecordSize);
168
169 if (ERR (API))
170 { WMF_DEBUG (API,"bailing...");
171 return (API->err);
172 }
173
174 WmfPlayMetaFile (API);
175
176 if (ERR (API))
177 { WMF_DEBUG (API,"bailing...");
178 return (API->err);
179 }
180
181 d_r->TL = P->D_TL;
182 d_r->BR = P->D_BR;
183
184 P->flags |= PLAYER_SCANNED;
185
186 return (API->err);
187 }
188
189 /**
190 * Get image size.
191 *
192 * @param API the API handle
193 * @param width width return
194 * @param height height return
195 *
196 * wmf_size() returns image width in \p *width and image height in \p *height. If supplied, the metafile
197 * header values are used, otherwise the width and height found by wmf_scan() are used.
198 *
199 * @return Returns the library error state (\b wmf_E_None on success).
200 * Possible library error state of \b wmf_E_Glitch (the metafile has not been scanned).
201 */
wmf_size(wmfAPI * API,float * width,float * height)202 wmf_error_t wmf_size (wmfAPI* API,float* width,float* height)
203 { wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
204
205 S16 default_width;
206 S16 default_height;
207
208 WMF_DEBUG (API,"~~~~~~~~wmf_size");
209
210 if (ERR (API))
211 { WMF_DEBUG (API,"bailing...");
212 return (API->err);
213 }
214
215 if ((P->flags & PLAYER_SCANNED) == 0)
216 { WMF_ERROR (API,"attempt to determine size of unscanned metafile!");
217 API->err = wmf_E_Glitch;
218 return (API->err);
219 }
220
221 default_width = WMF_BBOX_RIGHT (API) - WMF_BBOX_LEFT (API);
222 default_height = WMF_BBOX_TOP (API) - WMF_BBOX_BOTTOM (API);
223
224 default_width = ABS (default_width );
225 default_height = ABS (default_height);
226
227 if (default_width && default_height)
228 { (*width) = (float) default_width;
229 (*height) = (float) default_height;
230 }
231 else
232 { (*width) = P->D_BR.x - P->D_TL.x;
233 (*height) = P->D_BR.y - P->D_TL.y;
234 }
235
236 return (API->err);
237 }
238
239 /**
240 * Get estimate of image display size.
241 *
242 * @param API the API handle
243 * @param width width return
244 * @param height height return
245 * @param res_x x-resolution of display
246 * @param res_y y-resolution of display
247 *
248 * wmf_display_size() returns image width in \p *width and image height in \p *height.
249 * wmf_size() is used to get the calculated/estimate width and height of the image,
250 * and these values are converted to integer width and height estimates for display.
251 *
252 * @return Returns the library error state (\b wmf_E_None on success).
253 * Possible library error state of \b wmf_E_Glitch (the metafile has not been scanned).
254 */
wmf_display_size(wmfAPI * API,unsigned int * width,unsigned int * height,double res_x,double res_y)255 wmf_error_t wmf_display_size (wmfAPI* API,unsigned int* width,unsigned int* height,
256 double res_x,double res_y)
257 { unsigned int units_per_inch = 1440;
258
259 double disp_width;
260 double disp_height;
261
262 float est_width;
263 float est_height;
264
265 WMF_DEBUG (API,"~~~~~~~~wmf_display_size");
266
267 if (ERR (API))
268 { WMF_DEBUG (API,"bailing...");
269 return (API->err);
270 }
271
272 wmf_size (API, &est_width, &est_height);
273
274 if (ERR (API))
275 { WMF_DEBUG (API,"bailing...");
276 return (API->err);
277 }
278
279 if (PLACEABLE (API))
280 { units_per_inch = DPI (API);
281 }
282 else if ((est_width * est_height) < (1024 * 1024))
283 { units_per_inch = 72;
284 }
285
286 disp_width = ((double) est_width ) * res_x / (double) units_per_inch;
287 disp_height = ((double) est_height) * res_y / (double) units_per_inch;
288
289 if (width) *width = (unsigned int) disp_width;
290 if (height) *height = (unsigned int) disp_height;
291
292 return API->err;
293 }
294
295 /**
296 * Play the metafile.
297 *
298 * @param API the API handle
299 * @param flags (unused)
300 * @param d_r for bounding-box return
301 *
302 * Before the metafile can be played, it must be scanned - see wmf_scan().
303 *
304 * The first time (and only the first time) the metafile is played, it first calls \b device_open() for the
305 * device layer specified (and initialized) in wmf_api_create(). Then, and also each subsequent time the
306 * metafile is played, it calls \b device_begin(), plays the metafile (with calls to various other device
307 * layer functions), and finally it calls \b device_end(). \b device_close() is only ever called via
308 * wmf_api_destroy().
309 *
310 * \p d_r is recomputed, but should not change.
311 *
312 * @return Returns the library error state (\b wmf_E_None on success).
313 */
wmf_play(wmfAPI * API,unsigned long flags,wmfD_Rect * d_r)314 wmf_error_t wmf_play (wmfAPI* API,unsigned long flags,wmfD_Rect* d_r)
315 { (void)flags;
316 wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
317 wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
318
319 WMF_DEBUG (API,"~~~~~~~~wmf_play");
320
321 if (ERR (API))
322 { WMF_DEBUG (API,"bailing...");
323 return (API->err);
324 }
325
326 if ((P->flags & PLAYER_SCANNED) == 0)
327 { WMF_ERROR (API,"attempt to play unscanned metafile!");
328 API->err = wmf_E_Glitch;
329 return (API->err);
330 }
331
332 if ((API->flags & API_DEVICE_OPEN) == 0)
333 { if (FR->device_open) FR->device_open (API);
334
335 if (ERR (API))
336 { WMF_DEBUG (API,"bailing...");
337 return (API->err);
338 }
339
340 API->flags |= API_DEVICE_OPEN;
341 }
342
343 d_r->TL = P->D_TL;
344 d_r->BR = P->D_BR;
345
346 P->flags |= PLAYER_PLAY; /* Set play mode */
347
348 WmfPlayMetaFile (API);
349
350 if (ERR (API))
351 { WMF_DEBUG (API,"bailing...");
352 return (API->err);
353 }
354
355 d_r->TL = P->D_TL;
356 d_r->BR = P->D_BR;
357
358 return (API->err);
359 }
360
WmfPlayMetaFile(wmfAPI * API)361 static wmf_error_t WmfPlayMetaFile (wmfAPI* API)
362 { unsigned int i;
363 int byte;
364 int changed;
365
366 unsigned char* Par;
367
368 unsigned int Function;
369 unsigned long Size;
370 unsigned long number;
371
372 long pos_params;
373 long pos_current;
374 long pos_max;
375
376 wmfObject* objects = 0;
377
378 wmfUserData_t userdata;
379
380 wmfRegion* visible;
381
382 wmfRecord Record;
383
384 wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
385 wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
386 wmfFontData* FD = (wmfFontData*) API->font_data;
387
388 wmfAttributes attrlist;
389 wmfAttributes * atts = 0;
390
391 WMF_DEBUG (API,"~~~~~~~~WmfPlayMetaFile");
392
393 P->dc_stack_length = 0;
394
395 visible = &(P->visible);
396
397 visible->numRects = 0;
398 visible->rects = 0;
399 visible->size = 0;
400
401 P->current.x = 0; /* Should this be in the DC ?? */
402 P->current.y = 0;
403
404 P->Viewport_Origin.x = 0; /* Should this be in the DC ?? */
405 P->Viewport_Origin.y = 0;
406
407 P->Viewport_Width = 1024; /* Should this be in the DC ?? */
408 P->Viewport_Height = 1024;
409
410 /* Can SetDefaults go in player_init ??
411 */
412 if (FD == 0)
413 { WMF_ERROR (API,"Glitch! No font engine interface!");
414 API->err = wmf_E_Glitch;
415 return (API->err);
416 }
417
418 if (FD->map == 0)
419 { WMF_ERROR (API,"Glitch! No font-mapper!");
420 API->err = wmf_E_Glitch;
421 return (API->err);
422 }
423
424 if (FD->stringwidth == 0)
425 { WMF_ERROR (API,"Glitch! No string width function!");
426 API->err = wmf_E_Glitch;
427 return (API->err);
428 }
429
430 if ((API->bbuf.read == 0) || (API->bbuf.seek == 0) || (API->bbuf.tell == 0))
431 { WMF_ERROR (API,"WmfPlayMetaFile: input functions set improperly!");
432 API->err = wmf_E_Glitch;
433 return (API->err);
434 }
435
436 P->dc = dc_copy (API,0);
437
438 if (ERR (API))
439 { WMF_DEBUG (API,"bailing...");
440 return (API->err);
441 }
442
443 WmfSetMapMode (API,(U16)(PLACEABLE (API) ? MM_DPI : MM_TEXT));
444
445 if (PLAY (API))
446 { if (FR->device_begin) FR->device_begin (API);
447
448 if (ERR (API))
449 { WMF_DEBUG (API,"bailing...");
450 return (API->err);
451 }
452 }
453
454 Par = P->Parameters;
455
456 objects = P->objects;
457
458 for (i = 0; i < NUM_OBJECTS (API); i++) objects[i].type = 0;
459
460 WMF_SEEK (API,API->File->pos);
461
462 if (ERR (API))
463 { WMF_DEBUG (API,"bailing...");
464 return (API->err);
465 }
466
467 wmf_attr_new (API, &attrlist);
468
469 if (ERR (API))
470 { WMF_DEBUG (API,"bailing...");
471 return (API->err);
472 }
473
474 number = 0;
475 do
476 { if (++number < API->store.count)
477 { atts = API->store.attrlist + number;
478 }
479 else
480 { atts = &attrlist;
481 wmf_attr_clear (API, atts);
482 }
483
484 Size = wmf_read_32 (API,0,0);
485 Function = wmf_read_16 (API);
486
487 if ((Size == 3) && (Function == 0))
488 { if (SCAN (API)) wmf_write (API, Size, Function, "empty",
489 atts->atts, 0, 0);
490 break; /* Probably final record ?? */
491 }
492
493 /* if ((Size > MAX_REC_SIZE (API)) || (Size < 3))
494 */ if (((Size - 3) > MAX_REC_SIZE (API)) || (Size < 3))
495 { WMF_ERROR (API,"libwmf: wmf with bizarre record size; bailing...");
496 WMF_ERROR (API," please send it to us at http://www.wvware.com/");
497 wmf_printf (API,"maximum record size = %u\n",(unsigned) MAX_REC_SIZE (API));
498 wmf_printf (API,"record size = %u\n",(unsigned) Size);
499 API->err = wmf_E_BadFormat;
500 break;
501 }
502
503 pos_params = WMF_TELL (API);
504
505 if (pos_params < 0)
506 { WMF_ERROR (API,"API's tell() failed on input stream!");
507 API->err = wmf_E_BadFile;
508 break;
509 }
510
511 for (i = 0; i < ((Size - 3) * 2); i++)
512 { byte = WMF_READ (API);
513 if (byte == (-1))
514 { WMF_ERROR (API,"Unexpected EOF!");
515 API->err = wmf_E_EOF;
516 break;
517 }
518 Par[i] = (unsigned char) byte;
519 }
520
521 if (ERR (API))
522 { WMF_DEBUG (API,"bailing...");
523 break;
524 }
525
526 Record.size = Size - 3;
527 Record.function = Function;
528 Record.parameter = Par;
529 Record.position = pos_params;
530
531 switch (Function)
532 {
533 case META_SETMAPMODE:
534 SCAN_DIAGNOSTIC (API,"New Record: SETMAPMODE");
535 changed = meta_mapmode (API,&Record);
536 if (SCAN (API)) wmf_write (API, Size, Function, "setmapmode",
537 atts->atts, Record.parameter, Record.size * 2);
538 if (changed && ((Record.size * 2 + 6) == atts->length))
539 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
540 }
541 SCAN_DIAGNOSTIC (API,"\n");
542 break;
543
544 case META_SETWINDOWORG:
545 SCAN_DIAGNOSTIC (API,"New Record: SETWINDOWORG");
546 changed = meta_orgext (API,&Record);
547 if (SCAN (API)) wmf_write (API, Size, Function, "setwindoworg",
548 atts->atts, Record.parameter, Record.size * 2);
549 if (changed && ((Record.size * 2 + 6) == atts->length))
550 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
551 }
552 SCAN_DIAGNOSTIC (API,"\n");
553 break;
554
555 case META_SETVIEWPORTORG:
556 SCAN_DIAGNOSTIC (API,"New Record: SETVIEWPORTORG");
557 meta_orgext (API,&Record);
558 if (SCAN (API)) wmf_write (API, Size, Function, "setviewportorg",
559 atts->atts, Record.parameter, Record.size * 2);
560 SCAN_DIAGNOSTIC (API,"\n");
561 break;
562
563 case META_SETVIEWPORTEXT:
564 SCAN_DIAGNOSTIC (API,"New Record: SETVIEWPORTEXT");
565 changed = meta_orgext (API,&Record);
566 if (SCAN (API)) wmf_write (API, Size, Function, "setviewportext",
567 atts->atts, Record.parameter, Record.size * 2);
568 if (changed && ((Record.size * 2 + 6) == atts->length))
569 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
570 }
571 SCAN_DIAGNOSTIC (API,"\n");
572 break;
573
574 case META_SETWINDOWEXT:
575 SCAN_DIAGNOSTIC (API,"New Record: SETWINDOWEXT");
576 changed = meta_orgext (API,&Record);
577 if (SCAN (API)) wmf_write (API, Size, Function, "setwindowext",
578 atts->atts, Record.parameter, Record.size * 2);
579 if (changed && ((Record.size * 2 + 6) == atts->length))
580 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
581 }
582 SCAN_DIAGNOSTIC (API,"\n");
583 break;
584
585 case META_OFFSETWINDOWORG:
586 SCAN_DIAGNOSTIC (API,"New Record: OFFSETWINDOWORG");
587 changed = meta_orgext (API,&Record);
588 if (SCAN (API)) wmf_write (API, Size, Function, "offsetwindoworg",
589 atts->atts, Record.parameter, Record.size * 2);
590 if (changed && ((Record.size * 2 + 6) == atts->length))
591 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
592 }
593 SCAN_DIAGNOSTIC (API,"\n");
594 break;
595
596 case META_OFFSETVIEWPORTORG:
597 SCAN_DIAGNOSTIC (API,"New Record: OFFSETVIEWPORTORG");
598 changed = meta_orgext (API,&Record);
599 if (SCAN (API)) wmf_write (API, Size, Function, "offsetviewportorg",
600 atts->atts, Record.parameter, Record.size * 2);
601 if (changed && ((Record.size * 2 + 6) == atts->length))
602 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
603 }
604 SCAN_DIAGNOSTIC (API,"\n");
605 break;
606
607 case META_SCALEWINDOWEXT:
608 SCAN_DIAGNOSTIC (API,"New Record: SCALEWINDOWEXT");
609 changed = meta_scale (API,&Record);
610 if (SCAN (API)) wmf_write (API, Size, Function, "scalewindowext",
611 atts->atts, Record.parameter, Record.size * 2);
612 if (changed && ((Record.size * 2 + 6) == atts->length))
613 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
614 }
615 SCAN_DIAGNOSTIC (API,"\n");
616 break;
617
618 case META_SCALEVIEWPORTEXT:
619 SCAN_DIAGNOSTIC (API,"New Record: SCALEVIEWPORTEXT");
620 changed = meta_scale (API,&Record);
621 if (SCAN (API)) wmf_write (API, Size, Function, "scaleviewportext",
622 atts->atts, Record.parameter, Record.size * 2);
623 if (changed && ((Record.size * 2 + 6) == atts->length))
624 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
625 }
626 SCAN_DIAGNOSTIC (API,"\n");
627 break;
628
629 /* Following were originally play-only:
630 * (a) basic draw
631 * (b) REGION calls
632 * (c) BMP & ROP stuff
633 * (d) DC set
634 * (e) text & font
635 * (f) palette
636 * (g) create & delete; save & restore; ...
637 * (h) ==== other ====
638 */
639
640 /* (a) basic draw
641 */
642 case META_MOVETO:
643 SCAN_DIAGNOSTIC (API,"New Record: MOVETO");
644 changed = meta_moveto (API,&Record);
645 if (SCAN (API)) wmf_write (API, Size, Function, "moveto",
646 atts->atts, Record.parameter, Record.size * 2);
647 if (changed && ((Record.size * 2 + 6) == atts->length))
648 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
649 }
650 SCAN_DIAGNOSTIC (API,"\n");
651 break;
652
653 case META_FLOODFILL:
654 SCAN_DIAGNOSTIC (API,"New Record: FLOODFILL");
655 changed = meta_flood (API,&Record);
656 if (SCAN (API)) wmf_write (API, Size, Function, "floodfill",
657 atts->atts, Record.parameter, Record.size * 2);
658 if (changed && ((Record.size * 2 + 6) == atts->length))
659 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
660 }
661 SCAN_DIAGNOSTIC (API,"\n");
662 break;
663
664 case META_EXTFLOODFILL:
665 SCAN_DIAGNOSTIC (API,"New Record: EXTFLOODFILL");
666 changed = meta_flood (API,&Record);
667 if (SCAN (API)) wmf_write (API, Size, Function, "extfloodfill",
668 atts->atts, Record.parameter, Record.size * 2);
669 if (changed && ((Record.size * 2 + 6) == atts->length))
670 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
671 }
672 SCAN_DIAGNOSTIC (API,"\n");
673 break;
674
675 case META_SETPIXEL:
676 SCAN_DIAGNOSTIC (API,"New Record: SETPIXEL");
677 changed = meta_pixel (API,&Record);
678 if (SCAN (API)) wmf_write (API, Size, Function, "setpixel",
679 atts->atts, Record.parameter, Record.size * 2);
680 if (changed && ((Record.size * 2 + 6) == atts->length))
681 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
682 }
683 SCAN_DIAGNOSTIC (API,"\n");
684 break;
685
686 case META_PIE:
687 SCAN_DIAGNOSTIC (API,"New Record: PIE");
688 changed = meta_arc (API,&Record);
689 if (SCAN (API)) wmf_write (API, Size, Function, "pie",
690 atts->atts, Record.parameter, Record.size * 2);
691 if (changed && ((Record.size * 2 + 6) == atts->length))
692 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
693 }
694 SCAN_DIAGNOSTIC (API,"\n");
695 break;
696
697 case META_CHORD:
698 SCAN_DIAGNOSTIC (API,"New Record: CHORD");
699 changed = meta_arc (API,&Record);
700 if (SCAN (API)) wmf_write (API, Size, Function, "chord",
701 atts->atts, Record.parameter, Record.size * 2);
702 if (changed && ((Record.size * 2 + 6) == atts->length))
703 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
704 }
705 SCAN_DIAGNOSTIC (API,"\n");
706 break;
707
708 case META_ARC:
709 SCAN_DIAGNOSTIC (API,"New Record: ARC");
710 changed = meta_arc (API,&Record);
711 if (SCAN (API)) wmf_write (API, Size, Function, "arc",
712 atts->atts, Record.parameter, Record.size * 2);
713 if (changed && ((Record.size * 2 + 6) == atts->length))
714 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
715 }
716 SCAN_DIAGNOSTIC (API,"\n");
717 break;
718
719 case META_ELLIPSE:
720 SCAN_DIAGNOSTIC (API,"New Record: ELLIPSE");
721 changed = meta_ellipse (API,&Record);
722 if (SCAN (API)) wmf_write (API, Size, Function, "ellipse",
723 atts->atts, Record.parameter, Record.size * 2);
724 if (changed && ((Record.size * 2 + 6) == atts->length))
725 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
726 }
727 SCAN_DIAGNOSTIC (API,"\n");
728 break;
729
730 case META_LINETO:
731 SCAN_DIAGNOSTIC (API,"New Record: LINETO");
732 changed = meta_line (API,&Record);
733 if (SCAN (API)) wmf_write (API, Size, Function, "lineto",
734 atts->atts, Record.parameter, Record.size * 2);
735 if (changed && ((Record.size * 2 + 6) == atts->length))
736 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
737 }
738 SCAN_DIAGNOSTIC (API,"\n");
739 break;
740
741 case META_POLYLINE:
742 SCAN_DIAGNOSTIC (API,"New Record: POLYLINE");
743 changed = meta_lines (API,&Record);
744 if (SCAN (API)) wmf_write (API, Size, Function, "polyline",
745 atts->atts, Record.parameter, Record.size * 2);
746 if (changed && ((Record.size * 2 + 6) == atts->length))
747 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
748 }
749 SCAN_DIAGNOSTIC (API,"\n");
750 break;
751
752 case META_POLYGON:
753 SCAN_DIAGNOSTIC (API,"New Record: POLYGON");
754 changed = meta_polygon (API,&Record);
755 if (SCAN (API)) wmf_write (API, Size, Function, "polygon",
756 atts->atts, Record.parameter, Record.size * 2);
757 if (changed && ((Record.size * 2 + 6) == atts->length))
758 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
759 }
760 SCAN_DIAGNOSTIC (API,"\n");
761 break;
762
763 case META_POLYPOLYGON:
764 SCAN_DIAGNOSTIC (API,"New Record: POLYPOLYGON");
765 changed = meta_polygons (API,&Record);
766 if (SCAN (API)) wmf_write (API, Size, Function, "polypolygon",
767 atts->atts, Record.parameter, Record.size * 2);
768 if (changed && ((Record.size * 2 + 6) == atts->length))
769 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
770 }
771 SCAN_DIAGNOSTIC (API,"\n");
772 break;
773
774 case META_ROUNDRECT:
775 SCAN_DIAGNOSTIC (API,"New Record: ROUNDRECT");
776 changed = meta_round (API,&Record);
777 if (SCAN (API)) wmf_write (API, Size, Function, "roundrect",
778 atts->atts, Record.parameter, Record.size * 2);
779 if (changed && ((Record.size * 2 + 6) == atts->length))
780 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
781 }
782 SCAN_DIAGNOSTIC (API,"\n");
783 break;
784
785 case META_RECTANGLE:
786 SCAN_DIAGNOSTIC (API,"New Record: RECTANGLE");
787 changed = meta_rect (API,&Record);
788 if (SCAN (API)) wmf_write (API, Size, Function, "rectangle",
789 atts->atts, Record.parameter, Record.size * 2);
790 if (changed && ((Record.size * 2 + 6) == atts->length))
791 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
792 }
793 SCAN_DIAGNOSTIC (API,"\n");
794 break;
795
796 /* (b) REGION calls
797 */
798 case META_FRAMEREGION:
799 SCAN_DIAGNOSTIC (API,"New Record: FRAMEREGION");
800 changed = meta_rgn_brush (API,&Record);
801 if (SCAN (API)) wmf_write (API, Size, Function, "frameregion",
802 atts->atts, Record.parameter, Record.size * 2);
803 if (changed && ((Record.size * 2 + 6) == atts->length))
804 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
805 }
806 SCAN_DIAGNOSTIC (API,"\n");
807 break;
808
809 case META_FILLREGION:
810 SCAN_DIAGNOSTIC (API,"New Record: FILLREGION");
811 changed = meta_rgn_brush (API,&Record);
812 if (SCAN (API)) wmf_write (API, Size, Function, "fillregion",
813 atts->atts, Record.parameter, Record.size * 2);
814 if (changed && ((Record.size * 2 + 6) == atts->length))
815 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
816 }
817 SCAN_DIAGNOSTIC (API,"\n");
818 break;
819
820 case META_INVERTREGION:
821 SCAN_DIAGNOSTIC (API,"New Record: INVERTREGION");
822 changed = meta_rgn_paint (API,&Record);
823 if (SCAN (API)) wmf_write (API, Size, Function, "invertregion",
824 atts->atts, Record.parameter, Record.size * 2);
825 if (changed && ((Record.size * 2 + 6) == atts->length))
826 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
827 }
828 SCAN_DIAGNOSTIC (API,"\n");
829 break;
830
831 case META_PAINTREGION:
832 SCAN_DIAGNOSTIC (API,"New Record: PAINTREGION");
833 changed = meta_rgn_paint (API,&Record);
834 if (SCAN (API)) wmf_write (API, Size, Function, "paintregion",
835 atts->atts, Record.parameter, Record.size * 2);
836 if (changed && ((Record.size * 2 + 6) == atts->length))
837 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
838 }
839 SCAN_DIAGNOSTIC (API,"\n");
840 break;
841
842 case META_CREATEREGION:
843 SCAN_DIAGNOSTIC (API,"New Record: CREATEREGION");
844 changed = meta_rgn_create (API,&Record);
845 if (SCAN (API)) wmf_write (API, Size, Function, "createregion",
846 atts->atts, Record.parameter, Record.size * 2);
847 if (changed && ((Record.size * 2 + 6) == atts->length))
848 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
849 }
850 SCAN_DIAGNOSTIC (API,"\n");
851 break;
852
853 case META_SELECTCLIPREGION:
854 SCAN_DIAGNOSTIC (API,"New Record: SELECTCLIPREGION");
855 changed = meta_clip_select (API,&Record);
856 if (SCAN (API)) wmf_write (API, Size, Function, "selectclipregion",
857 atts->atts, Record.parameter, Record.size * 2);
858 if (changed && ((Record.size * 2 + 6) == atts->length))
859 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
860 }
861 SCAN_DIAGNOSTIC (API,"\n");
862 break;
863
864 case META_OFFSETCLIPRGN:
865 SCAN_DIAGNOSTIC (API,"New Record: OFFSETCLIPREGION");
866 changed = meta_clip_offset (API,&Record);
867 if (SCAN (API)) wmf_write (API, Size, Function, "offsetclipregion",
868 atts->atts, Record.parameter, Record.size * 2);
869 if (changed && ((Record.size * 2 + 6) == atts->length))
870 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
871 }
872 SCAN_DIAGNOSTIC (API,"\n");
873 break;
874
875 case META_EXCLUDECLIPRECT:
876 SCAN_DIAGNOSTIC (API,"New Record: EXCLUDECLIPRECT");
877 changed = meta_clip_combine (API,&Record);
878 if (SCAN (API)) wmf_write (API, Size, Function, "excludecliprect",
879 atts->atts, Record.parameter, Record.size * 2);
880 if (changed && ((Record.size * 2 + 6) == atts->length))
881 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
882 }
883 SCAN_DIAGNOSTIC (API,"\n");
884 break;
885
886 case META_INTERSECTCLIPRECT:
887 SCAN_DIAGNOSTIC (API,"New Record: INTERSECTCLIPRECT");
888 changed = meta_clip_combine (API,&Record);
889 if (SCAN (API)) wmf_write (API, Size, Function, "intersectcliprect",
890 atts->atts, Record.parameter, Record.size * 2);
891 if (changed && ((Record.size * 2 + 6) == atts->length))
892 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
893 }
894 SCAN_DIAGNOSTIC (API,"\n");
895 break;
896
897 /* (c) BMP & ROP stuff
898 * Notes: (1) BMP width/height may be signed! ?? i.e., -width,-height ??
899 * (2) Check! Check! Check!
900 */
901 case META_SETDIBTODEV:
902 SCAN_DIAGNOSTIC (API,"New Record: SETDIBTODEV");
903 changed = meta_dib_draw (API,&Record);
904 if (SCAN (API)) wmf_write (API, Size, Function, "setdibtodev",
905 atts->atts, Record.parameter, Record.size * 2);
906 if (changed && ((Record.size * 2 + 6) == atts->length))
907 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
908 }
909 SCAN_DIAGNOSTIC (API,"\n");
910 break;
911
912 case META_STRETCHDIB:
913 SCAN_DIAGNOSTIC (API,"New Record: STRETCHDIB");
914 changed = meta_dib_draw (API,&Record);
915 if (SCAN (API)) wmf_write (API, Size, Function, "stretchdib",
916 atts->atts, Record.parameter, Record.size * 2);
917 if (changed && ((Record.size * 2 + 6) == atts->length))
918 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
919 }
920 SCAN_DIAGNOSTIC (API,"\n");
921 break;
922
923 case META_DIBSTRETCHBLT:
924 SCAN_DIAGNOSTIC (API,"New Record: DIBSTRETCHBLT");
925 changed = meta_dib_draw (API,&Record);
926 if (SCAN (API)) wmf_write (API, Size, Function, "dibstretchblt",
927 atts->atts, Record.parameter, Record.size * 2);
928 if (changed && ((Record.size * 2 + 6) == atts->length))
929 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
930 }
931 SCAN_DIAGNOSTIC (API,"\n");
932 break;
933
934 case META_DIBBITBLT:
935 SCAN_DIAGNOSTIC (API,"New Record: DIBBITBLT");
936 changed = meta_dib_draw (API,&Record);
937 if (SCAN (API)) wmf_write (API, Size, Function, "dibbitblt",
938 atts->atts, Record.parameter, Record.size * 2);
939 if (changed && ((Record.size * 2 + 6) == atts->length))
940 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
941 }
942 SCAN_DIAGNOSTIC (API,"\n");
943 break;
944
945 case META_DIBCREATEPATTERNBRUSH:
946 SCAN_DIAGNOSTIC (API,"New Record: DIBCREATEPATTERNBRUSH");
947 changed = meta_dib_brush (API,&Record);
948 if (SCAN (API)) wmf_write (API, Size, Function, "dibcreatepatternbrush",
949 atts->atts, Record.parameter, Record.size * 2);
950 if (changed && ((Record.size * 2 + 6) == atts->length))
951 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
952 }
953 SCAN_DIAGNOSTIC (API,"\n");
954 break;
955
956 case META_PATBLT:
957 SCAN_DIAGNOSTIC (API,"New Record: PATBLT");
958 changed = meta_rop_draw (API,&Record);
959 if (SCAN (API)) wmf_write (API, Size, Function, "patblt",
960 atts->atts, Record.parameter, Record.size * 2);
961 if (changed && ((Record.size * 2 + 6) == atts->length))
962 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
963 }
964 SCAN_DIAGNOSTIC (API,"\n");
965 break;
966
967 /* (d) DC set
968 */
969 case META_SETROP2:
970 SCAN_DIAGNOSTIC (API,"New Record: SETROP2");
971 changed = meta_dc_set (API,&Record);
972 if (SCAN (API)) wmf_write (API, Size, Function, "setrop2",
973 atts->atts, Record.parameter, Record.size * 2);
974 if (changed && ((Record.size * 2 + 6) == atts->length))
975 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
976 }
977 SCAN_DIAGNOSTIC (API,"\n");
978 break;
979
980 case META_SETTEXTJUSTIFICATION:
981 SCAN_DIAGNOSTIC (API,"New Record: SETTEXTJUSTIFICATION");
982 changed = meta_dc_set (API,&Record);
983 if (SCAN (API)) wmf_write (API, Size, Function, "settextjustification",
984 atts->atts, Record.parameter, Record.size * 2);
985 if (changed && ((Record.size * 2 + 6) == atts->length))
986 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
987 }
988 SCAN_DIAGNOSTIC (API,"\n");
989 break;
990
991 case META_SETTEXTCHAREXTRA:
992 SCAN_DIAGNOSTIC (API,"New Record: SETTEXTCHAREXTRA");
993 changed = meta_dc_set (API,&Record);
994 if (SCAN (API)) wmf_write (API, Size, Function, "settextcharextra",
995 atts->atts, Record.parameter, Record.size * 2);
996 if (changed && ((Record.size * 2 + 6) == atts->length))
997 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
998 }
999 SCAN_DIAGNOSTIC (API,"\n");
1000 break;
1001
1002 case META_SETPOLYFILLMODE:
1003 SCAN_DIAGNOSTIC (API,"New Record: SETPOLYFILLMODE");
1004 changed = meta_dc_set (API,&Record);
1005 if (SCAN (API)) wmf_write (API, Size, Function, "setpolyfillmode",
1006 atts->atts, Record.parameter, Record.size * 2);
1007 if (changed && ((Record.size * 2 + 6) == atts->length))
1008 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1009 }
1010 SCAN_DIAGNOSTIC (API,"\n");
1011 break;
1012
1013 case META_SETSTRETCHBLTMODE:
1014 SCAN_DIAGNOSTIC (API,"New Record: SETSTRETCHBLTMODE");
1015 changed = meta_unused (API,&Record);
1016 if (SCAN (API)) wmf_write (API, Size, Function, "setstretchbltmode",
1017 atts->atts, Record.parameter, Record.size * 2);
1018 if (changed && ((Record.size * 2 + 6) == atts->length))
1019 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1020 }
1021 SCAN_DIAGNOSTIC (API,"\n");
1022 break;
1023
1024 case META_SETTEXTALIGN:
1025 SCAN_DIAGNOSTIC (API,"New Record: SETTEXTALIGN");
1026 changed = meta_dc_set (API,&Record);
1027 if (SCAN (API)) wmf_write (API, Size, Function, "settextalign",
1028 atts->atts, Record.parameter, Record.size * 2);
1029 if (changed && ((Record.size * 2 + 6) == atts->length))
1030 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1031 }
1032 SCAN_DIAGNOSTIC (API,"\n");
1033 break;
1034
1035 case META_SETTEXTCOLOR:
1036 SCAN_DIAGNOSTIC (API,"New Record: SETTEXTCOLOUR");
1037 changed = meta_dc_color (API,&Record,atts);
1038 if (SCAN (API)) wmf_write (API, Size, Function, "settextcolour",
1039 atts->atts, Record.parameter, Record.size * 2);
1040 if (changed && ((Record.size * 2 + 6) == atts->length))
1041 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1042 }
1043 SCAN_DIAGNOSTIC (API,"\n");
1044 break;
1045
1046 case META_SETBKCOLOR:
1047 SCAN_DIAGNOSTIC (API,"New Record: SETBKCOLOR");
1048 changed = meta_dc_color (API,&Record,atts);
1049 if (SCAN (API)) wmf_write (API, Size, Function, "setbkcolor",
1050 atts->atts, Record.parameter, Record.size * 2);
1051 if (changed && ((Record.size * 2 + 6) == atts->length))
1052 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1053 }
1054 SCAN_DIAGNOSTIC (API,"\n");
1055 break;
1056
1057 case META_SETBKMODE:
1058 SCAN_DIAGNOSTIC (API,"New Record: SETBKMODE");
1059 changed = meta_dc_set (API,&Record);
1060 if (SCAN (API)) wmf_write (API, Size, Function, "setbkmode",
1061 atts->atts, Record.parameter, Record.size * 2);
1062 if (changed && ((Record.size * 2 + 6) == atts->length))
1063 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1064 }
1065 SCAN_DIAGNOSTIC (API,"\n");
1066 break;
1067
1068 case META_SELECTOBJECT:
1069 SCAN_DIAGNOSTIC (API,"New Record: SELECTOBJECT");
1070 changed = meta_dc_select (API,&Record);
1071 if (SCAN (API)) wmf_write (API, Size, Function, "selectobject",
1072 atts->atts, Record.parameter, Record.size * 2);
1073 if (changed && ((Record.size * 2 + 6) == atts->length))
1074 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1075 }
1076 SCAN_DIAGNOSTIC (API,"\n");
1077 break;
1078
1079 /* (e) text & font
1080 */
1081 case META_TEXTOUT:
1082 SCAN_DIAGNOSTIC (API,"New Record: TEXTOUT");
1083 changed = meta_text (API,&Record);
1084 if (SCAN (API)) wmf_write (API, Size, Function, "textout",
1085 atts->atts, Record.parameter, Record.size * 2);
1086 if (changed && ((Record.size * 2 + 6) == atts->length))
1087 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1088 }
1089 SCAN_DIAGNOSTIC (API,"\n");
1090 break;
1091
1092 case META_EXTTEXTOUT:
1093 SCAN_DIAGNOSTIC (API,"New Record: EXTTEXTOUT");
1094 changed = meta_text (API,&Record);
1095 if (SCAN (API)) wmf_write (API, Size, Function, "exttextout",
1096 atts->atts, Record.parameter, Record.size * 2);
1097 if (changed && ((Record.size * 2 + 6) == atts->length))
1098 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1099 }
1100 SCAN_DIAGNOSTIC (API,"\n");
1101 break;
1102
1103 case META_CREATEFONTINDIRECT:
1104 SCAN_DIAGNOSTIC (API,"New Record: CREATEFONTINDIRECT");
1105 changed = meta_font_create (API,&Record);
1106 if (SCAN (API)) wmf_write (API, Size, Function, "createfontindirect",
1107 atts->atts, Record.parameter, Record.size * 2);
1108 if (changed && ((Record.size * 2 + 6) == atts->length))
1109 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1110 }
1111 SCAN_DIAGNOSTIC (API,"\n");
1112 break;
1113
1114 case META_SETMAPPERFLAGS:
1115 SCAN_DIAGNOSTIC (API,"New Record: SETMAPPERFLAGS");
1116 changed = meta_unused (API,&Record);
1117 if (SCAN (API)) wmf_write (API, Size, Function, "setmapperflags",
1118 atts->atts, Record.parameter, Record.size * 2);
1119 if (changed && ((Record.size * 2 + 6) == atts->length))
1120 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1121 }
1122 SCAN_DIAGNOSTIC (API,"\n");
1123 break;
1124
1125 /* (f) palette
1126 */
1127 case META_CREATEPALETTE:
1128 SCAN_DIAGNOSTIC (API,"New Record: CREATEPALETTE");
1129 changed = meta_palette_create (API);
1130 if (SCAN (API)) wmf_write (API, Size, Function, "createpalette",
1131 atts->atts, Record.parameter, Record.size * 2);
1132 if (changed && ((Record.size * 2 + 6) == atts->length))
1133 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1134 }
1135 SCAN_DIAGNOSTIC (API,"\n");
1136 break;
1137
1138 case META_REALIZEPALETTE:
1139 SCAN_DIAGNOSTIC (API,"New Record: REALIZEPALETTE");
1140 changed = meta_unused (API,&Record);
1141 if (SCAN (API)) wmf_write (API, Size, Function, "realizepalette",
1142 atts->atts, Record.parameter, Record.size * 2);
1143 if (changed && ((Record.size * 2 + 6) == atts->length))
1144 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1145 }
1146 SCAN_DIAGNOSTIC (API,"\n");
1147 break;
1148
1149 case META_SELECTPALETTE:
1150 SCAN_DIAGNOSTIC (API,"New Record: SELECTPALETTE");
1151 changed = meta_unused (API,&Record);
1152 if (SCAN (API)) wmf_write (API, Size, Function, "selectpalette",
1153 atts->atts, Record.parameter, Record.size * 2);
1154 if (changed && ((Record.size * 2 + 6) == atts->length))
1155 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1156 }
1157 SCAN_DIAGNOSTIC (API,"\n");
1158 break;
1159
1160 case META_SETPALENTRIES:
1161 SCAN_DIAGNOSTIC (API,"New Record: SETPALENTRIES");
1162 changed = meta_unused (API,&Record);
1163 if (SCAN (API)) wmf_write (API, Size, Function, "setpalentries",
1164 atts->atts, Record.parameter, Record.size * 2);
1165 if (changed && ((Record.size * 2 + 6) == atts->length))
1166 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1167 }
1168 SCAN_DIAGNOSTIC (API,"\n");
1169 break;
1170
1171 /* (g) create & delete; save & restore; ...
1172 */
1173 case META_SAVEDC:
1174 SCAN_DIAGNOSTIC (API,"New Record: SAVEDC");
1175 changed = meta_dc_save (API,&Record);
1176 if (SCAN (API)) wmf_write (API, Size, Function, "savedc",
1177 atts->atts, Record.parameter, Record.size * 2);
1178 if (changed && ((Record.size * 2 + 6) == atts->length))
1179 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1180 }
1181 SCAN_DIAGNOSTIC (API,"\n");
1182 break;
1183
1184 case META_RESTOREDC:
1185 SCAN_DIAGNOSTIC (API,"New Record: RESTOREDC");
1186 changed = meta_dc_restore (API,&Record);
1187 if (SCAN (API)) wmf_write (API, Size, Function, "restoredc",
1188 atts->atts, Record.parameter, Record.size * 2);
1189 if (changed && ((Record.size * 2 + 6) == atts->length))
1190 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1191 }
1192 SCAN_DIAGNOSTIC (API,"\n");
1193 break;
1194
1195 case META_CREATEPENINDIRECT:
1196 SCAN_DIAGNOSTIC (API,"New Record: CREATEPENINDIRECT");
1197 changed = meta_pen_create (API,&Record,atts);
1198 if (SCAN (API)) wmf_write (API, Size, Function, "createpenindirect",
1199 atts->atts, Record.parameter, Record.size * 2);
1200 if (changed && ((Record.size * 2 + 6) == atts->length))
1201 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1202 }
1203 SCAN_DIAGNOSTIC (API,"\n");
1204 break;
1205
1206 case META_CREATEBRUSHINDIRECT:
1207 SCAN_DIAGNOSTIC (API,"New Record: CREATEBRUSHINDIRECT");
1208 changed = meta_brush_create (API,&Record,atts);
1209 if (SCAN (API)) wmf_write (API, Size, Function, "createbrushindirect",
1210 atts->atts, Record.parameter, Record.size * 2);
1211 if (changed && ((Record.size * 2 + 6) == atts->length))
1212 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1213 }
1214 SCAN_DIAGNOSTIC (API,"\n");
1215 break;
1216
1217 case META_DELETEOBJECT:
1218 SCAN_DIAGNOSTIC (API,"New Record: DELETEOBJECT");
1219 changed = meta_delete (API,&Record);
1220 if (SCAN (API)) wmf_write (API, Size, Function, "deleteobject",
1221 atts->atts, Record.parameter, Record.size * 2);
1222 if (changed && ((Record.size * 2 + 6) == atts->length))
1223 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1224 }
1225 SCAN_DIAGNOSTIC (API,"\n");
1226 break;
1227
1228 /* (h) ==== other ====
1229 */
1230 case META_ESCAPE:
1231 SCAN_DIAGNOSTIC (API,"New Record: ESCAPE");
1232 changed = meta_unused (API,&Record);
1233 if (SCAN (API)) wmf_write (API, Size, Function, "escape",
1234 atts->atts, Record.parameter, Record.size * 2);
1235 if (changed && ((Record.size * 2 + 6) == atts->length))
1236 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1237 }
1238 SCAN_DIAGNOSTIC (API,"\n");
1239 break;
1240
1241 default:
1242 SCAN_DIAGNOSTIC (API,"New Record: UNKNOWN");
1243 changed = meta_unused (API,&Record);
1244 if (SCAN (API)) wmf_write (API, Size, Function, "unknown",
1245 atts->atts, Record.parameter, Record.size * 2);
1246 if (changed && ((Record.size * 2 + 6) == atts->length))
1247 { memcpy (atts->buffer + 6, Record.parameter, Record.size * 2);
1248 }
1249 SCAN_DIAGNOSTIC (API,"\n");
1250 break;
1251 }
1252
1253 if (PLAY (API) && API->status.function)
1254 { pos_current = WMF_TELL (API);
1255 if (pos_current < 0)
1256 { WMF_ERROR (API,"API's tell() failed on input stream!");
1257 API->err = wmf_E_BadFile;
1258 break;
1259 }
1260 pos_current -= API->File->pos;
1261 pos_max = (FILE_SIZE(API) - API->File->pos)*2;
1262 if (API->status.function (API->status.context,(float) pos_current / (float) pos_max))
1263 { API->err = wmf_E_UserExit;
1264 }
1265 }
1266
1267 } while (API->err == wmf_E_None);
1268
1269 if (Size == 0)
1270 { WMF_DEBUG (API,"size was 0, giving up now silently...");
1271 if (API->err == wmf_E_EOF)
1272 { WMF_DEBUG (API,"discarding an EOF error, however.");
1273 API->err = wmf_E_None;
1274 }
1275 }
1276
1277 if (ERR (API)) /* Quit now ?? */
1278 { WMF_DEBUG (API,"bailing...");
1279 return (API->err);
1280 }
1281
1282 wmf_attr_free (API, &attrlist);
1283
1284 if (SCAN (API)) wmf_write_end (API);
1285
1286 while (P->dc_stack_length)
1287 { if (P->dc)
1288 { userdata.dc = P->dc;
1289 userdata.data = P->dc->userdata;
1290
1291 if (FR->udata_free) FR->udata_free (API,&userdata);
1292 wmf_free (API,P->dc);
1293 }
1294 P->dc = dc_stack_pop (API);
1295 }
1296
1297 if (P->dc)
1298 { userdata.dc = P->dc;
1299 userdata.data = P->dc->userdata;
1300
1301 if (PLAY (API) && FR->udata_free) FR->udata_free (API,&userdata);
1302 wmf_free (API,P->dc);
1303 }
1304
1305 dc_stack_free (API);
1306
1307 for (i = 0; i < NUM_OBJECTS(API); i++)
1308 { if (objects[i].type == OBJ_BRUSH)
1309 { if (objects[i].obj.brush.lbStyle == BS_DIBPATTERN)
1310 { if (objects[i].obj.brush.bmp.data && FR->bmp_free)
1311 { FR->bmp_free (API,&(objects[i].obj.brush.bmp));
1312 }
1313 }
1314 }
1315 else if (objects[i].type == OBJ_REGION)
1316 { wmf_free (API,objects[i].obj.rgn.rects);
1317 }
1318 else if (objects[i].type == OBJ_FONT)
1319 { wmf_free (API,objects[i].obj.font.lfFaceName);
1320 }
1321 }
1322
1323 if (PLAY (API) && FR->device_end) FR->device_end (API);
1324
1325 return (API->err);
1326 }
1327