Coverage Report

Created: 2026-04-01 07:49

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwmf/src/player/meta.h
Line
Count
Source
1
/* libwmf ("player/meta.h"): library for wmf conversion
2
   Copyright (C) 2000 - 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
#ifndef WMFPLAYER_META_H
21
#define WMFPLAYER_META_H
22
23
static int meta_mapmode (wmfAPI* API,wmfRecord* Record)
24
460
{ int changed = 0;
25
26
460
  U16 par_U16;
27
28
460
  if (SCAN (API) && DIAG (API))
29
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
30
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
31
0
  }
32
33
460
  par_U16 = ParU16 (API,Record,0);
34
35
460
  WmfSetMapMode (API,par_U16);
36
37
460
  return (changed);
38
460
}
39
40
static int meta_orgext (wmfAPI* API,wmfRecord* Record)
41
2.59k
{ int changed = 0;
42
43
2.59k
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
44
45
2.59k
  S32 par_S32_x;
46
2.59k
  S32 par_S32_y;
47
48
2.59k
  if (SCAN (API) && DIAG (API))
49
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
50
0
    fprintf (stderr,"\t#par=%lu; max. index = 1",Record->size);
51
0
  }
52
53
2.59k
  par_S32_x = ParS32 (API,Record,1);
54
2.59k
  par_S32_y = ParS32 (API,Record,0);
55
56
2.59k
  switch (Record->function)
57
2.59k
  {
58
403
  case META_SETWINDOWORG:
59
403
    P->dc->Window.Ox = par_S32_x;
60
403
    P->dc->Window.Oy = par_S32_y;
61
403
  break;
62
63
35
  case META_SETVIEWPORTORG:
64
35
    P->Viewport_Origin.x = (float) ((double) par_S32_x * P->dc->pixel_width );
65
35
    P->Viewport_Origin.y = (float) ((double) par_S32_y * P->dc->pixel_height);
66
35
  break;
67
68
70
  case META_SETVIEWPORTEXT:
69
70
    P->Viewport_Width  = par_S32_x;
70
70
    P->Viewport_Height = par_S32_y;
71
70
    PixelWidth (API);
72
70
    PixelHeight (API); /* Recalculate pixel size */
73
70
  break;
74
75
853
  case META_SETWINDOWEXT:
76
853
    P->dc->Window.width  = par_S32_x;
77
853
    P->dc->Window.height = par_S32_y;
78
853
    PixelWidth (API);
79
853
    PixelHeight (API); /* Recalculate pixel size */
80
853
  break;
81
82
7
  case META_OFFSETWINDOWORG:
83
7
    P->dc->Window.Ox += par_S32_x;
84
7
    P->dc->Window.Oy += par_S32_y;
85
7
  break;
86
87
1.23k
  case META_OFFSETVIEWPORTORG:
88
1.23k
    P->Viewport_Origin.x += (float) ((double) par_S32_x * P->dc->pixel_width );
89
1.23k
    P->Viewport_Origin.y += (float) ((double) par_S32_y * P->dc->pixel_height);
90
1.23k
  break;
91
92
0
  default:
93
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
94
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
95
0
    API->err = wmf_E_Glitch;
96
0
  break;
97
2.59k
  }
98
99
2.59k
  return (changed);
100
2.59k
}
101
102
static int meta_scale (wmfAPI* API,wmfRecord* Record)
103
288
{ int changed = 0;
104
105
288
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
106
107
288
  S32 par_S32_x1;
108
288
  S32 par_S32_x2;
109
288
  S32 par_S32_y1;
110
288
  S32 par_S32_y2;
111
112
288
  double x1;
113
288
  double x2;
114
288
  double y1;
115
288
  double y2;
116
117
288
  if (SCAN (API) && DIAG (API))
118
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
119
0
    fprintf (stderr,"\t#par=%lu; max. index = 3",Record->size);
120
0
  }
121
122
288
  par_S32_x2 = ParS32 (API,Record,3);
123
288
  par_S32_x1 = ParS32 (API,Record,2);
124
288
  par_S32_y2 = ParS32 (API,Record,1);
125
288
  par_S32_y1 = ParS32 (API,Record,0);
126
127
288
  if ((par_S32_x1 == 0) || (par_S32_y1 == 0))
128
9
  { WMF_ERROR (API,"meta file attempts division by zero!");
129
9
    API->err = wmf_E_BadFormat;
130
9
    return (changed);
131
9
  }
132
133
279
  x2 = (double) par_S32_x2;
134
279
  x1 = (double) par_S32_x1;
135
279
  y2 = (double) par_S32_y2;
136
279
  y1 = (double) par_S32_y1;
137
138
279
  switch (Record->function)
139
279
  {
140
238
  case META_SCALEWINDOWEXT:
141
238
    P->dc->Window.width  = (S32) (((double) P->dc->Window.width  * x2) / x1);
142
238
    P->dc->Window.height = (S32) (((double) P->dc->Window.height * y2) / y1);
143
238
  break;
144
145
41
  case META_SCALEVIEWPORTEXT:
146
41
    P->Viewport_Width  = (S32) (((double) P->Viewport_Width  * x2) / x1);
147
41
    P->Viewport_Height = (S32) (((double) P->Viewport_Height * y2) / y1);
148
41
  break;
149
150
0
  default:
151
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
152
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
153
0
    API->err = wmf_E_Glitch;
154
0
  break;
155
279
  }
156
157
279
  PixelWidth (API);
158
279
  PixelHeight (API); /* Recalculate pixel size */
159
160
279
  return (changed);
161
279
}
162
163
static int meta_moveto (wmfAPI* API,wmfRecord* Record)
164
189
{ int changed = 0;
165
166
189
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
167
168
189
  U16 par_U16_x;
169
189
  U16 par_U16_y;
170
171
189
  if (SCAN (API) && DIAG (API))
172
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
173
0
    fprintf (stderr,"\t#par=%lu; max. index = 1",Record->size);
174
0
  }
175
176
189
  par_U16_x = ParU16 (API,Record,1);
177
189
  par_U16_y = ParU16 (API,Record,0);
178
179
189
  P->current = L_Coord (par_U16_x,par_U16_y);
180
181
189
  return (changed);
182
189
}
183
184
static int meta_flood (wmfAPI* API,wmfRecord* Record)
185
1.29k
{ int changed = 0;
186
187
1.29k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
188
1.29k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
189
190
1.29k
  wmfL_Coord l_pt;
191
192
1.29k
  wmfFlood_t flood;
193
194
1.29k
  U16 par_U16_x;
195
1.29k
  U16 par_U16_y;
196
1.29k
  U16 par_U16_rg;
197
1.29k
  U16 par_U16_b;
198
1.29k
  U16 par_U16_t;
199
200
1.29k
  if (SCAN (API) && DIAG (API))
201
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
202
0
    fprintf (stderr,"\t#par=%lu; max. index = 4",Record->size);
203
0
  }
204
205
1.29k
  par_U16_x  = ParU16 (API,Record,4);
206
1.29k
  par_U16_y  = ParU16 (API,Record,3);
207
1.29k
  par_U16_b  = ParU16 (API,Record,2);
208
1.29k
  par_U16_rg = ParU16 (API,Record,1);
209
1.29k
  par_U16_t  = ParU16 (API,Record,0);
210
211
1.29k
  l_pt = L_Coord (par_U16_x,par_U16_y);
212
213
1.29k
  flood.pt = wmf_D_Coord_translate (API,l_pt);
214
215
1.29k
  flood.color = rgb (par_U16_rg,par_U16_b);
216
217
1.29k
  if (SCAN (API))
218
901
  { wmf_ipa_color_add (API,&(flood.color));
219
901
    D_Coord_Register (API,flood.pt,0);
220
901
    return (changed);
221
901
  }
222
223
393
  flood.dc = P->dc;
224
225
393
  flood.type = par_U16_t;
226
227
393
  flood.pixel_width  = ABS (P->dc->pixel_width );
228
393
  flood.pixel_height = ABS (P->dc->pixel_height);
229
230
393
  switch (Record->function)
231
393
  {
232
380
  case META_FLOODFILL:
233
380
    if (FR->flood_interior) FR->flood_interior (API,&flood);
234
380
  break;
235
236
13
  case META_EXTFLOODFILL:
237
13
    if (FR->flood_exterior) FR->flood_exterior (API,&flood);
238
13
  break;
239
240
0
  default:
241
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
242
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
243
0
    API->err = wmf_E_Glitch;
244
0
  break;
245
393
  }
246
247
393
  return (changed);
248
393
}
249
250
static int meta_pixel (wmfAPI* API,wmfRecord* Record)
251
3.39k
{ int changed = 0;
252
253
3.39k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
254
3.39k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
255
256
3.39k
  wmfL_Coord l_pt;
257
258
3.39k
  wmfDrawPixel_t drawpixel;
259
260
3.39k
  U16 par_U16_x;
261
3.39k
  U16 par_U16_y;
262
3.39k
  U16 par_U16_rg;
263
3.39k
  U16 par_U16_b;
264
265
3.39k
  float scope;
266
267
3.39k
  if (SCAN (API) && DIAG (API))
268
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
269
0
    fprintf (stderr,"\t#par=%lu; max. index = 3",Record->size);
270
0
  }
271
272
3.39k
  par_U16_x  = ParU16 (API,Record,3);
273
3.39k
  par_U16_y  = ParU16 (API,Record,2);
274
3.39k
  par_U16_b  = ParU16 (API,Record,1);
275
3.39k
  par_U16_rg = ParU16 (API,Record,0);
276
277
3.39k
  l_pt = L_Coord (par_U16_x,par_U16_y);
278
279
3.39k
  drawpixel.pt = wmf_D_Coord_translate (API,l_pt);
280
281
3.39k
  drawpixel.color = rgb (par_U16_rg,par_U16_b);
282
283
3.39k
  drawpixel.pixel_width  = ABS (P->dc->pixel_width );
284
3.39k
  drawpixel.pixel_height = ABS (P->dc->pixel_height);
285
286
3.39k
  if (SCAN (API))
287
2.34k
  { wmf_ipa_color_add (API,&(drawpixel.color));
288
2.34k
    scope = (float) MAX (drawpixel.pixel_width,drawpixel.pixel_height);
289
2.34k
    D_Coord_Register (API,drawpixel.pt,scope);
290
2.34k
    return (changed);
291
2.34k
  }
292
293
1.04k
  drawpixel.dc = P->dc;
294
295
1.04k
  if (FR->draw_pixel) FR->draw_pixel (API,&drawpixel);
296
297
1.04k
  return (changed);
298
3.39k
}
299
300
static int meta_arc (wmfAPI* API,wmfRecord* Record)
301
2.24k
{ int changed = 0;
302
303
2.24k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
304
2.24k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
305
306
2.24k
  wmfL_Coord l_pt;
307
2.24k
  wmfD_Coord d_pt;
308
2.24k
  wmfD_Coord c_pt;
309
310
2.24k
  wmfDrawArc_t drawarc;
311
312
2.24k
  wmfPen* pen = 0;
313
314
2.24k
  U16 par_U16_x;
315
2.24k
  U16 par_U16_y;
316
2.24k
  U16 end_x;
317
2.24k
  U16 end_y;
318
319
2.24k
  char Qs;
320
2.24k
  char Qe;
321
322
2.24k
  float scope = 0;
323
324
2.24k
  if (SCAN (API) && DIAG (API))
325
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
326
0
    fprintf (stderr,"\t#par=%lu; max. index = 7",Record->size);
327
0
  }
328
329
2.24k
  par_U16_x = ParU16 (API,Record,7);
330
2.24k
  par_U16_y = ParU16 (API,Record,6);
331
332
2.24k
  l_pt = L_Coord (par_U16_x,par_U16_y);
333
334
2.24k
  drawarc.TL = wmf_D_Coord_translate (API,l_pt);
335
336
2.24k
  par_U16_x = ParU16 (API,Record,5);
337
2.24k
  par_U16_y = ParU16 (API,Record,4);
338
339
2.24k
  l_pt = L_Coord (par_U16_x,par_U16_y);
340
341
2.24k
  drawarc.BR = wmf_D_Coord_translate (API,l_pt);
342
343
2.24k
  par_U16_x = ParU16 (API,Record,3);
344
2.24k
  par_U16_y = ParU16 (API,Record,2);
345
346
2.24k
  l_pt = L_Coord (par_U16_x,par_U16_y);
347
348
2.24k
  drawarc.end = wmf_D_Coord_translate (API,l_pt);
349
350
2.24k
  end_x = par_U16_x;
351
2.24k
  end_y = par_U16_y;
352
353
2.24k
  par_U16_x = ParU16 (API,Record,1);
354
2.24k
  par_U16_y = ParU16 (API,Record,0);
355
356
2.24k
  if ((end_x == par_U16_x) && (end_y == par_U16_y))
357
106
  { /* start == end: This is probably an ellipse... TODO */
358
106
  }
359
360
2.24k
  l_pt = L_Coord (par_U16_x,par_U16_y);
361
362
2.24k
  drawarc.start = wmf_D_Coord_translate (API,l_pt);
363
364
2.24k
  if (SCAN (API))
365
1.74k
  { pen = WMF_DC_PEN (P->dc);
366
367
1.74k
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
368
369
1.74k
    D_Coord_Register (API,drawarc.end,scope);
370
1.74k
    D_Coord_Register (API,drawarc.start,scope);
371
1.74k
  }
372
373
2.24k
  c_pt.x = (drawarc.TL.x + drawarc.BR.x) / 2; /* ellipse origin */
374
2.24k
  c_pt.y = (drawarc.TL.y + drawarc.BR.y) / 2;
375
376
2.24k
  drawarc.start.x -= c_pt.x;
377
2.24k
  drawarc.start.y -= c_pt.y;
378
379
2.24k
  drawarc.end.x -= c_pt.x;
380
2.24k
  drawarc.end.y -= c_pt.y;
381
382
2.24k
  if (SCAN (API))
383
1.74k
  { if ((drawarc.start.x > 0) && (drawarc.start.y >= 0)) Qs = '1';
384
1.51k
    else if ((drawarc.start.x <= 0) && (drawarc.start.y > 0)) Qs = '2';
385
1.04k
    else if ((drawarc.start.x < 0) && (drawarc.start.y <= 0)) Qs = '3';
386
395
    else Qs = '4';
387
388
1.74k
    if ((drawarc.end.x > 0) && (drawarc.end.y >= 0)) Qe = '1';
389
1.45k
    else if ((drawarc.end.x <= 0) && (drawarc.end.y > 0)) Qe = '2';
390
1.08k
    else if ((drawarc.end.x < 0) && (drawarc.end.y <= 0)) Qe = '3';
391
549
    else Qe = '4';
392
393
1.74k
    switch (Qs)
394
1.74k
    {
395
232
    case '1':
396
232
      switch (Qe)
397
232
      {
398
101
      case '1':
399
101
        if ( (drawarc.end.x < drawarc.start.x)
400
86
          || (drawarc.end.y < drawarc.start.y)) break;
401
43
        d_pt.x = drawarc.BR.x;
402
43
        d_pt.y = c_pt.y;
403
43
        D_Coord_Register (API,d_pt,scope);
404
        /* fallthrough */
405
97
      case '4':
406
97
        d_pt.x = c_pt.x;
407
97
        d_pt.y = drawarc.BR.y;
408
97
        D_Coord_Register (API,d_pt,scope);
409
        /* fallthrough */
410
137
      case '3':
411
137
        d_pt.x = drawarc.TL.x;
412
137
        d_pt.y = c_pt.y;
413
137
        D_Coord_Register (API,d_pt,scope);
414
        /* fallthrough */
415
137
      default:
416
174
      case '2':
417
174
        d_pt.x = c_pt.x;
418
174
        d_pt.y = drawarc.TL.y;
419
174
        D_Coord_Register (API,d_pt,scope);
420
174
      break;
421
232
      }
422
232
    break;
423
424
475
    case '2':
425
475
      switch (Qe)
426
475
      {
427
214
      case '2':
428
214
        if ( (drawarc.end.x < drawarc.start.x)
429
193
          || (drawarc.end.y > drawarc.start.y)) break;
430
77
        d_pt.x = c_pt.x;
431
77
        d_pt.y = drawarc.TL.y;
432
77
        D_Coord_Register (API,d_pt,scope);
433
        /* fallthrough */
434
161
      case '1':
435
161
        d_pt.x = drawarc.BR.x;
436
161
        d_pt.y = c_pt.y;
437
161
        D_Coord_Register (API,d_pt,scope);
438
        /* fallthrough */
439
186
      case '4':
440
186
        d_pt.x = c_pt.x;
441
186
        d_pt.y = drawarc.BR.y;
442
186
        D_Coord_Register (API,d_pt,scope);
443
        /* fallthrough */
444
186
      default:
445
338
      case '3':
446
338
        d_pt.x = drawarc.TL.x;
447
338
        d_pt.y = c_pt.y;
448
338
        D_Coord_Register (API,d_pt,scope);
449
338
      break;
450
475
      }
451
475
    break;
452
453
647
    case '3':
454
647
      switch (Qe)
455
647
      {
456
283
      case '3':
457
283
        if ( (drawarc.end.x > drawarc.start.x)
458
206
          || (drawarc.end.y > drawarc.start.y)) break;
459
77
        d_pt.x = drawarc.TL.x;
460
77
        d_pt.y = c_pt.y;
461
77
        D_Coord_Register (API,d_pt,scope);
462
        /* fallthrough */
463
122
      case '2':
464
122
        d_pt.x = c_pt.x;
465
122
        d_pt.y = drawarc.TL.y;
466
122
        D_Coord_Register (API,d_pt,scope);
467
        /* fallthrough */
468
149
      case '1':
469
149
        d_pt.x = drawarc.BR.x;
470
149
        d_pt.y = c_pt.y;
471
149
        D_Coord_Register (API,d_pt,scope);
472
        /* fallthrough */
473
149
      default:
474
441
      case '4':
475
441
        d_pt.x = c_pt.x;
476
441
        d_pt.y = drawarc.BR.y;
477
441
        D_Coord_Register (API,d_pt,scope);
478
441
      break;
479
647
      }
480
647
    break;
481
482
647
    case '4':
483
395
    default:
484
395
      switch (Qe)
485
395
      {
486
178
      case '4':
487
178
        if ( (drawarc.end.x > drawarc.start.x)
488
152
          || (drawarc.end.y < drawarc.start.y)) break;
489
134
        d_pt.x = c_pt.x;
490
134
        d_pt.y = drawarc.BR.y;
491
134
        D_Coord_Register (API,d_pt,scope);
492
        /* fallthrough */
493
194
      case '3':
494
194
        d_pt.x = drawarc.TL.x;
495
194
        d_pt.y = c_pt.y;
496
194
        D_Coord_Register (API,d_pt,scope);
497
        /* fallthrough */
498
268
      case '2':
499
268
        d_pt.x = c_pt.x;
500
268
        d_pt.y = drawarc.TL.y;
501
268
        D_Coord_Register (API,d_pt,scope);
502
        /* fallthrough */
503
268
      default:
504
351
      case '1':
505
351
        d_pt.x = drawarc.BR.x;
506
351
        d_pt.y = c_pt.y;
507
351
        D_Coord_Register (API,d_pt,scope);
508
351
      break;
509
395
      }
510
395
    break;
511
1.74k
    }
512
513
1.74k
    return (changed);
514
1.74k
  }
515
516
498
  d_pt.x = (drawarc.BR.x - drawarc.TL.x) / 2; /* elliptic axes */
517
498
  d_pt.y = (drawarc.BR.y - drawarc.TL.y) / 2;
518
519
498
  if ((drawarc.start.x == 0) && (drawarc.start.y == 0)) drawarc.start.x = d_pt.x;
520
521
498
  if (drawarc.start.x >   d_pt.x ) drawarc.start.x =   d_pt.x;
522
498
  if (drawarc.start.x < (-d_pt.x)) drawarc.start.x = - d_pt.x;
523
498
  if (drawarc.start.y >   d_pt.y ) drawarc.start.y =   d_pt.y;
524
498
  if (drawarc.start.y < (-d_pt.y)) drawarc.start.y = - d_pt.y;
525
526
498
  if ((drawarc.end.x == 0) && (drawarc.end.y == 0)) drawarc.end.x = d_pt.x;
527
528
498
  if (drawarc.end.x >   d_pt.x ) drawarc.end.x =   d_pt.x;
529
498
  if (drawarc.end.x < (-d_pt.x)) drawarc.end.x = - d_pt.x;
530
498
  if (drawarc.end.y >   d_pt.y ) drawarc.end.y =   d_pt.y;
531
498
  if (drawarc.end.y < (-d_pt.y)) drawarc.end.y = - d_pt.y;
532
533
498
  drawarc.dc = P->dc;
534
535
498
  switch (Record->function)
536
498
  {
537
38
  case META_PIE:
538
38
    if (FR->draw_pie) FR->draw_pie (API,&drawarc);
539
38
  break;
540
541
54
  case META_CHORD:
542
54
    if (FR->draw_chord) FR->draw_chord (API,&drawarc);
543
54
  break;
544
545
406
  case META_ARC:
546
406
    if (FR->draw_arc) FR->draw_arc (API,&drawarc);
547
406
  break;
548
549
0
  default:
550
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
551
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
552
0
    API->err = wmf_E_Glitch;
553
0
  break;
554
498
  }
555
556
498
  return (changed);
557
498
}
558
559
static int meta_ellipse (wmfAPI* API,wmfRecord* Record)
560
629
{ int changed = 0;
561
562
629
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
563
629
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
564
565
629
  wmfL_Coord l_pt;
566
567
629
  wmfDrawArc_t drawarc;
568
569
629
  wmfPen* pen = 0;
570
571
629
  U16 par_U16_x;
572
629
  U16 par_U16_y;
573
574
629
  float scope;
575
576
629
  if (SCAN (API) && DIAG (API))
577
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
578
0
    fprintf (stderr,"\t#par=%lu; max. index = 3",Record->size);
579
0
  }
580
581
629
  par_U16_x = ParU16 (API,Record,3);
582
629
  par_U16_y = ParU16 (API,Record,2);
583
584
629
  l_pt = L_Coord (par_U16_x,par_U16_y);
585
586
629
  drawarc.TL = wmf_D_Coord_translate (API,l_pt);
587
588
629
  par_U16_x = ParU16 (API,Record,1);
589
629
  par_U16_y = ParU16 (API,Record,0);
590
591
629
  l_pt = L_Coord (par_U16_x,par_U16_y);
592
593
629
  drawarc.BR = wmf_D_Coord_translate (API,l_pt);
594
595
629
  if (SCAN (API))
596
495
  { pen = WMF_DC_PEN (P->dc);
597
598
495
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
599
600
495
    D_Coord_Register (API,drawarc.TL,scope);
601
495
    D_Coord_Register (API,drawarc.BR,scope);
602
495
    return (changed);
603
495
  }
604
605
134
  drawarc.dc = P->dc;
606
607
134
  if (FR->draw_ellipse) FR->draw_ellipse (API,&drawarc);
608
609
134
  return (changed);
610
629
}
611
612
static int meta_line (wmfAPI* API,wmfRecord* Record)
613
7.21k
{ int changed = 0;
614
615
7.21k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
616
7.21k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
617
618
7.21k
  wmfL_Coord l_pt;
619
620
7.21k
  wmfDrawLine_t drawline;
621
622
7.21k
  wmfPen* pen = 0;
623
624
7.21k
  U16 par_U16_x;
625
7.21k
  U16 par_U16_y;
626
627
7.21k
  float scope;
628
629
7.21k
  if (SCAN (API) && DIAG (API))
630
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
631
0
    fprintf (stderr,"\t#par=%lu; max. index = 1",Record->size);
632
0
  }
633
634
7.21k
  drawline.from = wmf_D_Coord_translate (API,P->current);
635
636
7.21k
  par_U16_x = ParU16 (API,Record,1);
637
7.21k
  par_U16_y = ParU16 (API,Record,0);
638
639
7.21k
  l_pt = L_Coord (par_U16_x,par_U16_y);
640
641
7.21k
  drawline.to = wmf_D_Coord_translate (API,l_pt);
642
643
7.21k
  P->current = l_pt;
644
645
7.21k
  if (SCAN (API))
646
4.04k
  { pen = WMF_DC_PEN (P->dc);
647
648
4.04k
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
649
650
4.04k
    D_Coord_Register (API,drawline.from,scope);
651
4.04k
    D_Coord_Register (API,drawline.to,scope);
652
4.04k
    return (changed);
653
4.04k
  }
654
655
3.16k
  drawline.dc = P->dc;
656
657
3.16k
  if (FR->draw_line) FR->draw_line (API,&drawline);
658
659
3.16k
  return (changed);
660
7.21k
}
661
662
static int meta_lines (wmfAPI* API,wmfRecord* Record)
663
748
{ int changed = 0;
664
665
748
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
666
748
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
667
668
748
  wmfL_Coord l_pt;
669
748
  wmfD_Coord d_pt;
670
671
748
  wmfPolyLine_t polyline;
672
673
748
  wmfPen* pen = 0;
674
675
748
  U16 par_U16_x;
676
748
  U16 par_U16_y;
677
678
748
  U16 i;
679
680
748
  unsigned long index;
681
682
748
  float scope;
683
684
748
  if (SCAN (API) && DIAG (API))
685
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
686
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
687
0
  }
688
689
748
  polyline.count = ParU16 (API,Record,0);
690
691
748
  if (SCAN (API) && DIAG (API))
692
0
  { fprintf (stderr,",%lu",(unsigned long) (2 * polyline.count));
693
0
  }
694
695
748
  if (SCAN (API))
696
552
  { pen = WMF_DC_PEN (P->dc);
697
698
552
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
699
700
552
    index = 1;
701
987k
    for (i = 0; i < polyline.count; i++)
702
986k
    { par_U16_x = ParU16 (API,Record,index);
703
986k
      index++;
704
986k
      par_U16_y = ParU16 (API,Record,index);
705
986k
      index++;
706
986k
      l_pt = L_Coord (par_U16_x,par_U16_y);
707
986k
      d_pt = wmf_D_Coord_translate (API,l_pt);
708
986k
      D_Coord_Register (API,d_pt,scope);
709
986k
    }
710
552
    return (changed);
711
552
  }
712
713
196
  polyline.pt = (wmfD_Coord*) wmf_malloc (API,polyline.count * sizeof (wmfD_Coord));
714
715
196
  if (ERR (API))
716
0
  { WMF_DEBUG (API,"bailing...");
717
0
    return (changed);
718
0
  }
719
720
196
  index = 1;
721
5.07k
  for (i = 0; i < polyline.count; i++)
722
4.87k
  { par_U16_x = ParU16 (API,Record,index);
723
4.87k
    index++;
724
4.87k
    par_U16_y = ParU16 (API,Record,index);
725
4.87k
    index++;
726
4.87k
    l_pt = L_Coord (par_U16_x,par_U16_y);
727
4.87k
    polyline.pt[i] = wmf_D_Coord_translate (API,l_pt);
728
4.87k
  }
729
730
196
  polyline.dc = P->dc;
731
732
196
  if (FR->poly_line) FR->poly_line (API,&polyline);
733
734
196
  wmf_free (API,polyline.pt);
735
736
196
  return (changed);
737
196
}
738
739
static int meta_polygon (wmfAPI* API,wmfRecord* Record)
740
6.50k
{ int changed = 0;
741
742
6.50k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
743
6.50k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
744
745
6.50k
  wmfL_Coord l_pt;
746
6.50k
  wmfD_Coord d_pt;
747
748
6.50k
  wmfPolyLine_t polyline;
749
750
6.50k
  wmfPen* pen = 0;
751
752
6.50k
  U16 par_U16_x;
753
6.50k
  U16 par_U16_y;
754
755
6.50k
  U16 i;
756
757
6.50k
  unsigned long index;
758
759
6.50k
  float scope;
760
761
6.50k
  if (SCAN (API) && DIAG (API))
762
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
763
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
764
0
  }
765
766
6.50k
  polyline.count = ParU16 (API,Record,0);
767
768
6.50k
  if (SCAN (API) && DIAG (API))
769
0
  { fprintf (stderr,",%lu",(unsigned long) (2 * polyline.count));
770
0
  }
771
772
6.50k
  if (SCAN (API))
773
4.82k
  { pen = WMF_DC_PEN (P->dc);
774
775
4.82k
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
776
777
4.82k
    index = 1;
778
1.08M
    for (i = 0; i < polyline.count; i++)
779
1.08M
    { par_U16_x = ParU16 (API,Record,index);
780
1.08M
      index++;
781
1.08M
      par_U16_y = ParU16 (API,Record,index);
782
1.08M
      index++;
783
1.08M
      l_pt = L_Coord (par_U16_x,par_U16_y);
784
1.08M
      d_pt = wmf_D_Coord_translate (API,l_pt);
785
1.08M
      D_Coord_Register (API,d_pt,scope);
786
1.08M
    }
787
4.82k
    return (changed);
788
4.82k
  }
789
790
1.68k
  polyline.pt = (wmfD_Coord*) wmf_malloc (API,polyline.count * sizeof (wmfD_Coord));
791
792
1.68k
  if (ERR (API))
793
0
  { WMF_DEBUG (API,"bailing...");
794
0
    return (changed);
795
0
  }
796
797
1.68k
  index = 1;
798
68.0k
  for (i = 0; i < polyline.count; i++)
799
66.3k
  { par_U16_x = ParU16 (API,Record,index);
800
66.3k
    index++;
801
66.3k
    par_U16_y = ParU16 (API,Record,index);
802
66.3k
    index++;
803
66.3k
    l_pt = L_Coord (par_U16_x,par_U16_y);
804
66.3k
    polyline.pt[i] = wmf_D_Coord_translate (API,l_pt);
805
66.3k
  }
806
807
1.68k
  polyline.dc = P->dc;
808
809
1.68k
  if (FR->draw_polygon) FR->draw_polygon (API,&polyline);
810
811
1.68k
  wmf_free (API,polyline.pt);
812
813
1.68k
  return (changed);
814
1.68k
}
815
816
static int meta_polygons (wmfAPI* API,wmfRecord* Record)
817
391
{ int changed = 0;
818
819
391
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
820
391
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
821
822
391
  wmfL_Coord l_pt;
823
391
  wmfD_Coord d_pt;
824
825
391
  wmfPolyLine_t polyline;
826
391
  wmfPolyPoly_t polypoly;
827
828
391
  wmfRecord Polygon;
829
830
391
  wmfPen* pen = 0;
831
832
391
  U16 par_U16_x;
833
391
  U16 par_U16_y;
834
835
391
  U16 num_pars;
836
391
  U16 count;
837
391
  U16 style;
838
839
391
  U16 i;
840
391
  U16 j;
841
842
391
  unsigned long index;
843
844
391
  float scope;
845
846
391
  int skip_record;
847
848
391
  if (SCAN (API) && DIAG (API))
849
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
850
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
851
0
  }
852
853
391
  polypoly.npoly = ParU16 (API,Record,0);
854
855
391
  if (polypoly.npoly == 0) return (changed);
856
857
387
  if (SCAN (API) && DIAG (API))
858
0
  { fprintf (stderr,",%lu",(unsigned long) polypoly.npoly);
859
0
  }
860
861
387
  polypoly.pt = (wmfD_Coord**) wmf_malloc (API, polypoly.npoly * sizeof (wmfD_Coord*));
862
863
387
  if (ERR (API))
864
0
  { WMF_DEBUG (API,"bailing...");
865
0
    return (changed);
866
0
  }
867
868
387
  polypoly.count = (U16*) wmf_malloc (API, polypoly.npoly * sizeof (U16));
869
870
387
  if (ERR (API))
871
0
  { WMF_DEBUG (API,"bailing...");
872
0
    return (changed);
873
0
  }
874
875
387
  count = 0;
876
387
  num_pars = 0;
877
387
  skip_record = 0;
878
579k
  for (i = 0; i < polypoly.npoly; i++)
879
579k
  { polypoly.count[i] = ParU16 (API,Record,(unsigned long) (1 + i));
880
579k
    count += polypoly.count[i] + 2; /* for polypoly->polyline fill constructor */
881
579k
    num_pars += polypoly.count[i];
882
579k
    if ((polypoly.count[i] < 3) && (skip_record == 0))
883
30
    { WMF_DEBUG (API,"strange polygon in polypolygon list; skipping record...");
884
30
      skip_record = 1;
885
30
    }
886
579k
    if (skip_record)
887
577k
    { polypoly.pt[i] = 0;
888
577k
    }
889
1.70k
    else
890
1.70k
    { polypoly.pt[i] = (wmfD_Coord*) wmf_malloc (API, polypoly.count[i] * sizeof (wmfD_Coord));
891
1.70k
      if (ERR (API)) break;
892
1.70k
    }
893
579k
  }
894
387
  if (skip_record)
895
30
  {
896
578k
    for (i = 0; i < polypoly.npoly; i++)
897
578k
    { if (polypoly.pt[i]) wmf_free (API, polypoly.pt[i]);
898
578k
    }
899
30
    wmf_free (API, polypoly.pt);
900
30
    wmf_free (API, polypoly.count);
901
30
    return (changed);
902
30
  }
903
357
  if (ERR (API))
904
0
  { WMF_DEBUG (API,"bailing...");
905
0
    return (changed);
906
0
  }
907
908
357
  if (SCAN (API) && DIAG (API))
909
0
  { fprintf (stderr,",%lu",(unsigned long) (polypoly.npoly + 2 * num_pars));
910
0
  }
911
912
357
  if (SCAN (API))
913
220
  { pen = WMF_DC_PEN (P->dc);
914
915
220
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
916
917
220
    index = 1 + polypoly.npoly;
918
1.14M
    for (i = 0; i < num_pars; i++)
919
1.14M
    { par_U16_x = ParU16 (API,Record,index);
920
1.14M
      index++;
921
1.14M
      par_U16_y = ParU16 (API,Record,index);
922
1.14M
      index++;
923
1.14M
      l_pt = L_Coord (par_U16_x,par_U16_y);
924
1.14M
      d_pt = wmf_D_Coord_translate (API,l_pt);
925
1.14M
      D_Coord_Register (API,d_pt,scope);
926
1.14M
    }
927
220
    return (changed);
928
220
  }
929
930
137
  polypoly.dc = P->dc;
931
932
137
  Polygon = OffsetRecord (API,Record,(unsigned long) (1 + polypoly.npoly));
933
934
456
  for (i = 0; i < polypoly.npoly; i++)
935
319
  { polyline.count = polypoly.count[i];
936
319
    index = 0;
937
1.32M
    for (j = 0; j < polyline.count; j++)
938
1.32M
    { par_U16_x = ParU16 (API,&Polygon,index);
939
1.32M
      index++;
940
1.32M
      par_U16_y = ParU16 (API,&Polygon,index);
941
1.32M
      index++;
942
1.32M
      l_pt = L_Coord (par_U16_x,par_U16_y);
943
1.32M
      polypoly.pt[i][j] = wmf_D_Coord_translate (API,l_pt);
944
1.32M
    }
945
319
    Polygon = OffsetRecord (API,&Polygon,index);
946
319
  }
947
948
137
  if (FR->draw_polypolygon)
949
137
  { FR->draw_polypolygon (API,&polypoly);
950
137
  }
951
0
  else if (FR->draw_polygon)
952
0
  { if (TO_FILL (&polypoly))
953
0
    { style = polypoly.dc->pen->lopnStyle; /* [TODO: use macros ??] */
954
0
      polypoly.dc->pen->lopnStyle = PS_NULL;
955
956
0
      polyline.dc = polypoly.dc;
957
0
      polyline.pt = (wmfD_Coord*) wmf_malloc (API, count * sizeof (wmfD_Coord));
958
0
      polyline.count = 0;
959
960
0
      if (ERR (API))
961
0
      { WMF_DEBUG (API,"bailing...");
962
0
        return (changed);
963
0
      }
964
965
0
      polypoly_construct (API, &polypoly, &polyline, 0);
966
967
0
      if (polyline.count > 2) FR->draw_polygon (API,&polyline);
968
969
0
      wmf_free (API, polyline.pt);
970
971
0
      polypoly.dc->pen->lopnStyle = style;
972
0
    }
973
0
    if (TO_DRAW (&polypoly))
974
0
    { style = polypoly.dc->brush->lbStyle; /* [TODO: use macros ??] */
975
0
      polypoly.dc->brush->lbStyle = BS_NULL;
976
0
      for (i = 0; i < polypoly.npoly; i++)
977
0
      { polyline.dc = polypoly.dc;
978
0
        polyline.pt = polypoly.pt[i];
979
0
        polyline.count = polypoly.count[i];
980
0
        if ((polyline.count > 2) && polyline.pt)
981
0
        { FR->draw_polygon (API,&polyline);
982
0
        }
983
0
      }
984
0
      polypoly.dc->brush->lbStyle = style;
985
0
    }
986
0
  }
987
988
456
  for (i = 0; i < polypoly.npoly; i++)
989
319
  { if (polypoly.pt[i]) wmf_free (API, polypoly.pt[i]);
990
319
  }
991
137
  wmf_free (API, polypoly.pt);
992
137
  wmf_free (API, polypoly.count);
993
994
137
  return (changed);
995
137
}
996
997
static void polypoly_construct (wmfAPI* API,wmfPolyPoly_t* polypoly,wmfPolyLine_t* polyline,U16 ipoly)
998
0
{ U16 count = polypoly->count[ipoly];
999
0
  U16 i;
1000
0
  U16 imin;
1001
0
  U16 last;
1002
1003
0
  double x2;
1004
0
  double y2;
1005
0
  double r2;
1006
0
  double r2_min = 0;
1007
1008
0
  if ((polyline->pt == 0) || (polypoly->pt == 0)) return; /* erk!! */
1009
1010
0
  if ((polypoly->pt[ipoly] == 0) || (polypoly->count[ipoly] < 3)) return;
1011
1012
0
  while ((polypoly->pt[ipoly][0].x == polypoly->pt[ipoly][count-1].x)
1013
0
      && (polypoly->pt[ipoly][0].y == polypoly->pt[ipoly][count-1].y))
1014
0
  {
1015
0
    count--;
1016
0
    if (count < 3) break;
1017
0
  }
1018
0
  if (count < 3) return;
1019
1020
0
  last = 0;
1021
0
  if (ipoly < (polypoly->npoly - 1))
1022
0
  { if ((polypoly->pt[ipoly+1] == 0) || (polypoly->count[ipoly+1] < 3))
1023
0
    { last = 1; /* erk!! */
1024
0
    }
1025
0
  }
1026
0
  else
1027
0
  { last = 1; /* last poly, yay! */
1028
0
  }
1029
0
  if (last)
1030
0
  { for (i = 0; i < count; i++)
1031
0
    { polyline->pt[polyline->count].x = polypoly->pt[ipoly][i].x;
1032
0
      polyline->pt[polyline->count].y = polypoly->pt[ipoly][i].y;
1033
0
      polyline->count++;
1034
0
    }
1035
0
    polyline->pt[polyline->count].x = polypoly->pt[ipoly][0].x;
1036
0
    polyline->pt[polyline->count].y = polypoly->pt[ipoly][0].y;
1037
0
    polyline->count++;
1038
1039
0
    return;
1040
0
  }
1041
1042
  /* find polygon point closest to point 0 in next polygon [TODO: improve this??]
1043
   */
1044
0
  imin = 0;
1045
0
  for (i = 0; i < count; i++)
1046
0
  { x2 = (double) polypoly->pt[ipoly][i].x - (double) polypoly->pt[ipoly+1][0].x;
1047
0
    x2 *= x2;
1048
0
    y2 = (double) polypoly->pt[ipoly][i].y - (double) polypoly->pt[ipoly+1][0].y;
1049
0
    y2 *= y2;
1050
0
    r2 = x2 + y2;
1051
0
    if (i == 0)
1052
0
    { r2_min = r2;
1053
0
    }
1054
0
    else if (r2 < r2_min)
1055
0
    { r2_min = r2;
1056
0
      imin = i;
1057
0
    }
1058
0
  }
1059
1060
0
  for (i = 0; i <= imin; i++)
1061
0
  { polyline->pt[polyline->count].x = polypoly->pt[ipoly][i].x;
1062
0
    polyline->pt[polyline->count].y = polypoly->pt[ipoly][i].y;
1063
0
    polyline->count++;
1064
0
  }
1065
1066
0
  polypoly_construct (API, polypoly, polyline, (U16)(ipoly + 1));
1067
1068
0
  for (i = imin; i < count; i++)
1069
0
  { polyline->pt[polyline->count].x = polypoly->pt[ipoly][i].x;
1070
0
    polyline->pt[polyline->count].y = polypoly->pt[ipoly][i].y;
1071
0
    polyline->count++;
1072
0
  }
1073
0
  polyline->pt[polyline->count].x = polypoly->pt[ipoly][0].x;
1074
0
  polyline->pt[polyline->count].y = polypoly->pt[ipoly][0].y;
1075
0
  polyline->count++;
1076
0
}
1077
1078
static int meta_round (wmfAPI* API,wmfRecord* Record)
1079
6.53k
{ int changed = 0;
1080
1081
6.53k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
1082
6.53k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
1083
1084
6.53k
  wmfL_Coord l_pt;
1085
1086
6.53k
  wmfDrawRectangle_t drawrect;
1087
1088
6.53k
  wmfPen* pen = 0;
1089
1090
6.53k
  U16 par_U16_x;
1091
6.53k
  U16 par_U16_y;
1092
1093
6.53k
  float scope;
1094
1095
6.53k
  if (SCAN (API) && DIAG (API))
1096
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1097
0
    fprintf (stderr,"\t#par=%lu; max. index = 5",Record->size);
1098
0
  }
1099
1100
6.53k
  par_U16_x = ParU16 (API,Record,5);
1101
6.53k
  par_U16_y = ParU16 (API,Record,4);
1102
1103
6.53k
  l_pt = L_Coord (par_U16_x,par_U16_y);
1104
1105
6.53k
  drawrect.TL = wmf_D_Coord_translate (API,l_pt);
1106
1107
6.53k
  par_U16_x = ParU16 (API,Record,3);
1108
6.53k
  par_U16_y = ParU16 (API,Record,2);
1109
1110
6.53k
  l_pt = L_Coord (par_U16_x,par_U16_y);
1111
1112
6.53k
  drawrect.BR = wmf_D_Coord_translate (API,l_pt);
1113
1114
6.53k
  if (SCAN (API))
1115
3.67k
  { pen = WMF_DC_PEN (P->dc);
1116
1117
3.67k
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
1118
1119
3.67k
    D_Coord_Register (API,drawrect.TL,scope);
1120
3.67k
    D_Coord_Register (API,drawrect.BR,scope);
1121
3.67k
    return (changed);
1122
3.67k
  }
1123
1124
2.86k
  par_U16_x = ParU16 (API,Record,1);
1125
2.86k
  par_U16_y = ParU16 (API,Record,0);
1126
1127
2.86k
  drawrect.width  = (float) ((double) par_U16_x * ABS (P->dc->pixel_width ));
1128
2.86k
  drawrect.height = (float) ((double) par_U16_y * ABS (P->dc->pixel_height));
1129
1130
2.86k
  drawrect.dc = P->dc;
1131
1132
2.86k
  if (FR->draw_rectangle) FR->draw_rectangle (API,&drawrect);
1133
1134
2.86k
  return (changed);
1135
6.53k
}
1136
1137
static int meta_rect (wmfAPI* API,wmfRecord* Record)
1138
991
{ int changed = 0;
1139
1140
991
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
1141
991
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
1142
1143
991
  wmfL_Coord l_pt;
1144
1145
991
  wmfDrawRectangle_t drawrect;
1146
1147
991
  wmfPen* pen = 0;
1148
1149
991
  U16 par_U16_x;
1150
991
  U16 par_U16_y;
1151
1152
991
  float scope;
1153
1154
991
  if (SCAN (API) && DIAG (API))
1155
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1156
0
    fprintf (stderr,"\t#par=%lu; max. index = 3",Record->size);
1157
0
  }
1158
1159
991
  par_U16_x = ParU16 (API,Record,3);
1160
991
  par_U16_y = ParU16 (API,Record,2);
1161
1162
991
  l_pt = L_Coord (par_U16_x,par_U16_y);
1163
1164
991
  drawrect.TL = wmf_D_Coord_translate (API,l_pt);
1165
1166
991
  par_U16_x = ParU16 (API,Record,1);
1167
991
  par_U16_y = ParU16 (API,Record,0);
1168
1169
991
  l_pt = L_Coord (par_U16_x,par_U16_y);
1170
1171
991
  drawrect.BR = wmf_D_Coord_translate (API,l_pt);
1172
1173
991
  if (SCAN (API))
1174
700
  { pen = WMF_DC_PEN (P->dc);
1175
1176
700
    scope = (float) (MAX (WMF_PEN_WIDTH (pen),WMF_PEN_HEIGHT (pen))) / 2;
1177
1178
700
    D_Coord_Register (API,drawrect.TL,scope);
1179
700
    D_Coord_Register (API,drawrect.BR,scope);
1180
700
    return (changed);
1181
700
  }
1182
1183
291
  drawrect.width  = 0;
1184
291
  drawrect.height = 0;
1185
1186
291
  drawrect.dc = P->dc;
1187
1188
291
  if (FR->draw_rectangle) FR->draw_rectangle (API,&drawrect);
1189
1190
291
  return (changed);
1191
991
}
1192
1193
static int meta_rgn_brush (wmfAPI* API,wmfRecord* Record)
1194
19
{ int changed = 0;
1195
1196
19
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
1197
19
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
1198
1199
19
  wmfObject* objects;
1200
19
  wmfObject* obj_region;
1201
19
  wmfObject* obj_brush;
1202
1203
19
  wmfRegion* region;
1204
19
  wmfRegion* clip;
1205
1206
19
  wmfBrush* brush;
1207
19
  wmfBrush* temp_brush;
1208
1209
19
  wmfD_Coord d_pt;
1210
1211
19
  wmfPolyRectangle_t polyrect;
1212
1213
19
  U16 oid_region;
1214
19
  U16 oid_brush;
1215
1216
19
  U16 par_U16_x;
1217
19
  U16 par_U16_y;
1218
1219
19
  unsigned int i;
1220
1221
19
  unsigned long max_index;
1222
1223
19
  float width;
1224
19
  float height;
1225
1226
19
  objects = P->objects;
1227
1228
19
  if (Record->function == META_FRAMEREGION)
1229
15
  { max_index = 3;
1230
15
  }
1231
4
  else
1232
4
  { max_index = 1;
1233
4
  }
1234
1235
19
  if (SCAN (API) && DIAG (API))
1236
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1237
0
    fprintf (stderr,"\t#par=%lu; max. index = %lu",Record->size,max_index);
1238
0
  }
1239
1240
19
  oid_region = ParU16 (API,Record,0);
1241
19
  oid_brush  = ParU16 (API,Record,1);
1242
1243
19
  if ((oid_region >= NUM_OBJECTS (API)) || (oid_brush >= NUM_OBJECTS (API)))
1244
17
  { WMF_ERROR (API,"Object out of range!");
1245
17
    API->err = wmf_E_BadFormat;
1246
17
    return (changed);
1247
17
  }
1248
1249
2
  obj_region = objects + oid_region;
1250
2
  obj_brush  = objects + oid_brush;
1251
1252
2
  if (SCAN (API) && DIAG (API))
1253
0
  { diagnose_object (API,(unsigned int) oid_region,obj_region);
1254
0
    diagnose_object (API,(unsigned int) oid_brush, obj_brush );
1255
0
  }
1256
1257
2
  if ((obj_region->type != OBJ_REGION) || (obj_brush->type != OBJ_BRUSH))
1258
2
  { WMF_ERROR (API,"libwmf: have lost track of the objects in this metafile");
1259
2
    WMF_ERROR (API,"        please send it to us at http://www.wvware.com/");
1260
2
    API->err = wmf_E_Glitch;
1261
2
    return (changed);
1262
2
  }
1263
1264
0
  region = &(obj_region->obj.rgn);
1265
0
  brush = &(obj_brush->obj.brush);
1266
1267
0
  if (Record->function == META_FRAMEREGION)
1268
0
  { par_U16_x = ParU16 (API,Record,3);
1269
0
    par_U16_y = ParU16 (API,Record,2);
1270
1271
0
    width  = (float) ((double) par_U16_x * ABS (P->dc->pixel_width ));
1272
0
    height = (float) ((double) par_U16_y * ABS (P->dc->pixel_height));
1273
0
  }
1274
0
  else
1275
0
  { width  = 0;
1276
0
    height = 0;
1277
0
  }
1278
1279
0
  if (SCAN (API))
1280
0
  { d_pt = region->extents.TL;
1281
0
    d_pt.x -= width;
1282
0
    d_pt.y -= height;
1283
0
    D_Coord_Register (API,d_pt,0);
1284
1285
0
    d_pt = region->extents.BR;
1286
0
    d_pt.x += width;
1287
0
    d_pt.y += height;
1288
0
    D_Coord_Register (API,d_pt,0);
1289
1290
0
    return (changed);
1291
0
  }
1292
1293
0
  polyrect.dc = P->dc;
1294
1295
0
  polyrect.TL = 0;
1296
0
  polyrect.BR = 0;
1297
1298
0
  polyrect.count = 0;
1299
1300
0
  polyrect.width  = 0;
1301
0
  polyrect.height = 0;
1302
1303
0
  if (FR->region_clip) FR->region_clip (API,&polyrect); /* i.e., none */
1304
1305
0
  clip = (wmfRegion*) P->dc->clip;
1306
1307
0
  polyrect.count = MAX (clip->numRects,region->numRects + 1);
1308
1309
0
  polyrect.TL = (wmfD_Coord*) wmf_malloc (API,polyrect.count * sizeof (wmfD_Coord));
1310
1311
0
  if (ERR (API))
1312
0
  { WMF_DEBUG (API,"bailing...");
1313
0
    return (changed);
1314
0
  }
1315
1316
0
  polyrect.BR = (wmfD_Coord*) wmf_malloc (API,polyrect.count * sizeof (wmfD_Coord));
1317
1318
0
  if (ERR (API))
1319
0
  { WMF_DEBUG (API,"bailing...");
1320
0
    return (changed);
1321
0
  }
1322
1323
0
  polyrect.count = region->numRects;
1324
0
  for (i = 0; i < polyrect.count; i++)
1325
0
  { polyrect.TL[i] = region->rects[i].TL;
1326
0
    polyrect.BR[i] = region->rects[i].BR;
1327
0
  }
1328
0
  i = polyrect.count;
1329
0
  polyrect.TL[i] = region->extents.TL;
1330
0
  polyrect.BR[i] = region->extents.BR;
1331
1332
0
  polyrect.width  = width;
1333
0
  polyrect.height = height;
1334
1335
0
  switch (Record->function)
1336
0
  {
1337
0
  case META_FRAMEREGION:
1338
0
    if (FR->region_frame)
1339
0
    { temp_brush = WMF_DC_BRUSH (polyrect.dc); /* ultimately redundant ?? */
1340
1341
0
      WMF_DC_SET_BRUSH (polyrect.dc,brush);
1342
1343
0
      FR->region_frame (API,&polyrect);
1344
1345
0
      WMF_DC_SET_BRUSH (polyrect.dc,temp_brush); /* ultimately redundant ?? */
1346
0
    }
1347
0
  break;
1348
1349
0
  case META_FILLREGION:
1350
0
    if (FR->region_paint)
1351
0
    { temp_brush = WMF_DC_BRUSH (polyrect.dc); /* ultimately redundant ?? */
1352
1353
0
      WMF_DC_SET_BRUSH (polyrect.dc,brush);
1354
1355
0
      FR->region_paint (API,&polyrect);
1356
1357
0
      WMF_DC_SET_BRUSH (polyrect.dc,temp_brush); /* ultimately redundant ?? */
1358
0
    }
1359
0
  break;
1360
1361
0
  default:
1362
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
1363
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
1364
0
    API->err = wmf_E_Glitch;
1365
0
  break;
1366
0
  }
1367
1368
0
  polyrect.count = clip->numRects;
1369
0
  for (i = 0; i < polyrect.count; i++)
1370
0
  { polyrect.TL[i] = clip->rects[i].TL;
1371
0
    polyrect.BR[i] = clip->rects[i].BR;
1372
0
  }
1373
1374
0
  polyrect.width  = 0;
1375
0
  polyrect.height = 0;
1376
1377
0
  if (FR->region_clip) FR->region_clip (API,&polyrect);
1378
1379
0
  wmf_free (API,polyrect.TL);
1380
0
  wmf_free (API,polyrect.BR);
1381
1382
0
  return (changed);
1383
0
}
1384
1385
static int meta_rgn_paint (wmfAPI* API,wmfRecord* Record)
1386
6
{ int changed = 0;
1387
1388
6
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
1389
6
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
1390
1391
6
  wmfObject* objects;
1392
6
  wmfObject* obj_region;
1393
1394
6
  wmfRegion* region;
1395
6
  wmfRegion* clip;
1396
1397
6
  wmfD_Coord d_pt;
1398
1399
6
  wmfPolyRectangle_t polyrect;
1400
1401
6
  U16 oid_region;
1402
1403
6
  U16 temp_rop;
1404
1405
6
  unsigned int i;
1406
1407
6
  objects = P->objects;
1408
1409
6
  if (SCAN (API) && DIAG (API))
1410
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1411
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
1412
0
  }
1413
1414
6
  oid_region = ParU16 (API,Record,0);
1415
1416
6
  if (oid_region >= NUM_OBJECTS (API))
1417
4
  { WMF_ERROR (API,"Object out of range!");
1418
4
    API->err = wmf_E_BadFormat;
1419
4
    return (changed);
1420
4
  }
1421
1422
2
  obj_region = objects + oid_region;
1423
1424
2
  if (SCAN (API) && DIAG (API))
1425
0
  { diagnose_object (API,(unsigned int) oid_region,obj_region);
1426
0
  }
1427
1428
2
  if (obj_region->type != OBJ_REGION)
1429
2
  { WMF_ERROR (API,"libwmf: have lost track of the objects in this metafile");
1430
2
    WMF_ERROR (API,"        please send it to us at http://www.wvware.com/");
1431
2
    API->err = wmf_E_Glitch;
1432
2
    return (changed);
1433
2
  }
1434
1435
0
  region = &(obj_region->obj.rgn);
1436
1437
0
  if (SCAN (API))
1438
0
  { d_pt = region->extents.TL;
1439
0
    D_Coord_Register (API,d_pt,0);
1440
1441
0
    d_pt = region->extents.BR;
1442
0
    D_Coord_Register (API,d_pt,0);
1443
1444
0
    return (changed);
1445
0
  }
1446
1447
0
  polyrect.dc = P->dc;
1448
1449
0
  polyrect.TL = 0;
1450
0
  polyrect.BR = 0;
1451
1452
0
  polyrect.count = 0;
1453
1454
0
  polyrect.width  = 0;
1455
0
  polyrect.height = 0;
1456
1457
0
  if (FR->region_clip) FR->region_clip (API,&polyrect); /* i.e., none */
1458
1459
0
  clip = (wmfRegion*) P->dc->clip;
1460
1461
0
  polyrect.count = MAX (clip->numRects,region->numRects + 1);
1462
1463
0
  polyrect.TL = (wmfD_Coord*) wmf_malloc (API,polyrect.count * sizeof (wmfD_Coord));
1464
1465
0
  if (ERR (API))
1466
0
  { WMF_DEBUG (API,"bailing...");
1467
0
    return (changed);
1468
0
  }
1469
1470
0
  polyrect.BR = (wmfD_Coord*) wmf_malloc (API,polyrect.count * sizeof (wmfD_Coord));
1471
1472
0
  if (ERR (API))
1473
0
  { WMF_DEBUG (API,"bailing...");
1474
0
    return (changed);
1475
0
  }
1476
1477
0
  polyrect.count = region->numRects;
1478
0
  for (i = 0; i < polyrect.count; i++)
1479
0
  { polyrect.TL[i] = region->rects[i].TL;
1480
0
    polyrect.BR[i] = region->rects[i].BR;
1481
0
  }
1482
0
  i = polyrect.count;
1483
0
  polyrect.TL[i] = region->extents.TL;
1484
0
  polyrect.BR[i] = region->extents.BR;
1485
1486
0
  switch (Record->function)
1487
0
  {
1488
0
  case META_INVERTREGION:
1489
0
    if (FR->region_paint)
1490
0
    { temp_rop = WMF_DC_ROP (polyrect.dc); /* ultimately redundant ?? */
1491
1492
0
      WMF_DC_SET_ROP (polyrect.dc,R2_NOT);
1493
1494
0
      FR->region_paint (API,&polyrect);
1495
1496
0
      WMF_DC_SET_ROP (polyrect.dc,temp_rop); /* ultimately redundant ?? */
1497
0
    }
1498
0
  break;
1499
1500
0
  case META_PAINTREGION:
1501
0
    if (FR->region_paint) FR->region_paint (API,&polyrect);
1502
0
  break;
1503
1504
0
  default:
1505
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
1506
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
1507
0
    API->err = wmf_E_Glitch;
1508
0
  break;
1509
0
  }
1510
1511
0
  polyrect.count = clip->numRects;
1512
0
  for (i = 0; i < polyrect.count; i++)
1513
0
  { polyrect.TL[i] = clip->rects[i].TL;
1514
0
    polyrect.BR[i] = clip->rects[i].BR;
1515
0
  }
1516
1517
0
  if (FR->region_clip) FR->region_clip (API,&polyrect);
1518
1519
0
  wmf_free (API,polyrect.TL);
1520
0
  wmf_free (API,polyrect.BR);
1521
1522
0
  return (changed);
1523
0
}
1524
1525
static int meta_rgn_create (wmfAPI* API,wmfRecord* Record)
1526
90
{ int changed = 0;
1527
1528
90
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
1529
1530
90
  wmfRecord start;
1531
90
  wmfRecord end;
1532
1533
90
  wmfObject* objects;
1534
90
  wmfObject* obj_region;
1535
1536
90
  wmfRegion* region;
1537
90
  wmfRegion  temp_region;
1538
1539
90
  wmfD_Rect d_r;
1540
1541
90
  U16 i;
1542
90
  U16 oid_region;
1543
1544
90
  U16 x1;
1545
90
  U16 x2;
1546
90
  U16 y1;
1547
90
  U16 y2;
1548
1549
90
  U16 band;
1550
90
  U16 num_band;
1551
90
  U16 num_pair;
1552
1553
90
  U16 count;
1554
1555
90
  unsigned long max_index;
1556
1557
90
  objects = P->objects;
1558
1559
90
  i = 0;
1560
201
  while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
1561
1562
90
  if (i == NUM_OBJECTS (API))
1563
1
  { WMF_ERROR (API,"Object out of range!");
1564
1
    API->err = wmf_E_BadFormat;
1565
1
    return (changed);
1566
1
  }
1567
1568
89
  oid_region = i;
1569
89
  obj_region = objects + oid_region;
1570
1571
89
  obj_region->type = OBJ_REGION;
1572
1573
89
  region = &(obj_region->obj.rgn);
1574
1575
89
  region->rects = (wmfD_Rect*) wmf_malloc (API,8 * sizeof (wmfD_Rect));
1576
89
  region->size = 8;
1577
1578
89
  if (ERR (API))
1579
0
  { WMF_DEBUG (API,"bailing...");
1580
0
    return (changed);
1581
0
  }
1582
1583
89
  WmfSetRectRgn (region,0);
1584
1585
89
  if (SCAN (API) && DIAG (API))
1586
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1587
0
    fprintf (stderr,"\t#par=%lu; index 0-4,6-10 skipped; max. index = 5",Record->size);
1588
1589
0
    diagnose_object (API,(unsigned int) oid_region,obj_region);
1590
0
  }
1591
1592
89
  num_band = ParU16 (API,Record,5);
1593
1594
89
  if (num_band == 0) return (changed);
1595
1596
47
  temp_region.rects = (wmfD_Rect*) wmf_malloc (API,8 * sizeof (wmfD_Rect));
1597
47
  temp_region.size = 8;
1598
1599
47
  if (ERR (API))
1600
0
  { WMF_DEBUG (API,"bailing...");
1601
0
    return (changed);
1602
0
  }
1603
1604
47
  WmfSetRectRgn (&temp_region,0);
1605
1606
47
  end = OffsetRecord (API,Record,10);
1607
47
  max_index = 10;
1608
355k
  for (band = 0; band < num_band; band++)
1609
355k
  { max_index++;
1610
355k
    if (SCAN (API) && DIAG (API))
1611
0
    { fprintf (stderr,",%lu",max_index);
1612
0
    }
1613
1614
355k
    start = OffsetRecord (API,&end,1);
1615
1616
355k
    count = ParU16 (API,&start,0);
1617
1618
355k
    if (count & 1)
1619
6
    { WMF_ERROR (API,"Delimiter not even!");
1620
6
      API->err = wmf_E_BadFormat;
1621
6
      break;
1622
6
    }
1623
1624
355k
    num_pair = count >> 1;
1625
1626
355k
    max_index += count + 3;
1627
355k
    if (SCAN (API) && DIAG (API))
1628
0
    { fprintf (stderr,",%lu",max_index);
1629
0
    }
1630
1631
355k
    end = OffsetRecord (API,&start,(unsigned long) (count + 3));
1632
1633
355k
    if (ParU16 (API,&end,0) != count)
1634
21
    { WMF_ERROR (API,"Mismatched delimiters!");
1635
21
      API->err = wmf_E_BadFormat;
1636
21
      break;
1637
21
    }
1638
1639
355k
    y1 = ParU16 (API,&start,1);
1640
355k
    y2 = ParU16 (API,&start,2);
1641
1642
355k
    for (i = 0; i < num_pair; i++)
1643
56
    { x1 = ParU16 (API,&start,(unsigned long) (3 + 2 * i));
1644
56
      x2 = ParU16 (API,&start,(unsigned long) (4 + 2 * i));
1645
1646
56
      D_Rect (API,&d_r,x1,y1,x2,y2);
1647
1648
56
      WmfSetRectRgn (&temp_region,&d_r);
1649
56
      WmfCombineRgn (API,region,region,&temp_region,RGN_OR);
1650
56
    }
1651
355k
  }
1652
1653
47
  wmf_free (API,temp_region.rects);
1654
1655
47
  return (changed);
1656
47
}
1657
1658
static int meta_clip_select (wmfAPI* API,wmfRecord* Record)
1659
96
{ int changed = 0;
1660
1661
96
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
1662
1663
96
  wmfObject* objects;
1664
96
  wmfObject* obj_region;
1665
1666
96
  wmfRegion* region;
1667
96
  wmfRegion* clip;
1668
1669
96
  U16 oid_region;
1670
1671
96
  objects = P->objects;
1672
1673
96
  if (SCAN (API) && DIAG (API))
1674
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1675
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
1676
0
  }
1677
1678
96
  oid_region = ParU16 (API,Record,0);
1679
1680
96
  if (oid_region >= NUM_OBJECTS (API))
1681
4
  { WMF_ERROR (API,"Object out of range!");
1682
4
    API->err = wmf_E_BadFormat;
1683
4
    return (changed);
1684
4
  }
1685
1686
92
  obj_region = objects + oid_region;
1687
1688
92
  if (SCAN (API) && DIAG (API))
1689
0
  { diagnose_object (API,(unsigned int) oid_region,obj_region);
1690
0
  }
1691
1692
92
  if (obj_region->type != OBJ_REGION)
1693
92
  { if (API->flags & WMF_OPT_IGNORE_NONFATAL)
1694
92
    { /* Some metafiles use this even though no region-objects have been defined,
1695
       * so I have some doubt about the correctness of this handler; perhaps
1696
       * this should reset the clip region to the entire space?
1697
       * 
1698
       * Anyway, I am making this particular error non-fatal.
1699
       */
1700
92
      WMF_DEBUG (API,"libwmf: have lost track of the objects in this metafile");
1701
92
      WMF_DEBUG (API,"        please send it to us at http://www.wvware.com/");
1702
92
    }
1703
0
    else
1704
0
    { WMF_ERROR (API,"libwmf: have lost track of the objects in this metafile");
1705
0
      WMF_ERROR (API,"        please send it to us at http://www.wvware.com/");
1706
0
      API->err = wmf_E_Glitch;
1707
0
    }
1708
92
    return (changed);
1709
92
  }
1710
1711
0
  region = &(obj_region->obj.rgn);
1712
1713
0
  clip = (wmfRegion*) P->dc->clip;
1714
1715
0
  WmfCombineRgn (API,clip,region,0,RGN_COPY);
1716
1717
0
  return (changed);
1718
92
}
1719
1720
static int meta_clip_offset (wmfAPI* API,wmfRecord* Record)
1721
1.09k
{ int changed = 0;
1722
1723
1.09k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
1724
1.09k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
1725
1726
1.09k
  wmfRegion* clip;
1727
1728
1.09k
  wmfPolyRectangle_t polyrect;
1729
1730
1.09k
  wmfL_Coord l_pt;
1731
1732
1.09k
  U16 par_U16_x;
1733
1.09k
  U16 par_U16_y;
1734
1735
1.09k
  unsigned int i;
1736
1737
1.09k
  if (SCAN (API) && DIAG (API))
1738
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1739
0
    fprintf (stderr,"\t#par=%lu; max. index = 1",Record->size);
1740
0
  }
1741
1742
1.09k
  clip = (wmfRegion*) P->dc->clip;
1743
1744
1.09k
  par_U16_x = ParU16 (API,Record,1);
1745
1.09k
  par_U16_y = ParU16 (API,Record,0);
1746
1747
1.09k
  l_pt = L_Coord (par_U16_x,par_U16_y);
1748
1749
1.29k
  for (i = 0; i < clip->numRects; i++)
1750
204
  { clip->rects[i].TL.x += l_pt.x;
1751
204
    clip->rects[i].TL.y += l_pt.y;
1752
204
    clip->rects[i].BR.x += l_pt.x;
1753
204
    clip->rects[i].BR.y += l_pt.y;
1754
204
  }
1755
1.09k
  clip->extents.TL.x += l_pt.x;
1756
1.09k
  clip->extents.TL.y += l_pt.y;
1757
1.09k
  clip->extents.BR.x += l_pt.x;
1758
1.09k
  clip->extents.BR.y += l_pt.y;
1759
      
1760
1.09k
  if (SCAN (API)) return (changed);
1761
1762
484
  polyrect.TL = (wmfD_Coord*) wmf_malloc (API,clip->numRects * sizeof (wmfD_Coord));
1763
1764
484
  if (ERR (API))
1765
0
  { WMF_DEBUG (API,"bailing...");
1766
0
    return (changed);
1767
0
  }
1768
1769
484
  polyrect.BR = (wmfD_Coord*) wmf_malloc (API,clip->numRects * sizeof (wmfD_Coord));
1770
1771
484
  if (ERR (API))
1772
0
  { WMF_DEBUG (API,"bailing...");
1773
0
    return (changed);
1774
0
  }
1775
1776
484
  polyrect.count = clip->numRects;
1777
561
  for (i = 0; i < polyrect.count; i++)
1778
77
  { polyrect.TL[i] = clip->rects[i].TL;
1779
77
    polyrect.BR[i] = clip->rects[i].BR;
1780
77
  }
1781
1782
484
  polyrect.dc = P->dc;
1783
1784
484
  polyrect.width  = 0;
1785
484
  polyrect.height = 0;
1786
1787
484
  if (FR->region_clip) FR->region_clip (API,&polyrect);
1788
1789
484
  wmf_free (API,polyrect.TL);
1790
484
  wmf_free (API,polyrect.BR);
1791
1792
484
  return (changed);
1793
484
}
1794
1795
static int meta_clip_combine (wmfAPI* API,wmfRecord* Record)
1796
117k
{ int changed = 0;
1797
1798
117k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
1799
117k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
1800
1801
117k
  wmfRegion* visible;
1802
117k
  wmfRegion* clip;
1803
1804
117k
  wmfPolyRectangle_t polyrect;
1805
1806
117k
  wmfD_Rect d_r;
1807
1808
117k
  U16 x1;
1809
117k
  U16 x2;
1810
117k
  U16 y1;
1811
117k
  U16 y2;
1812
1813
117k
  unsigned int i;
1814
1815
117k
  visible = &(P->visible);
1816
1817
117k
  if (SCAN (API) && DIAG (API))
1818
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1819
0
    fprintf (stderr,"\t#par=%lu; max. index = 3",Record->size);
1820
0
  }
1821
1822
117k
  x1 = ParU16 (API,Record,3);
1823
117k
  y1 = ParU16 (API,Record,2);
1824
117k
  x2 = ParU16 (API,Record,1);
1825
117k
  y2 = ParU16 (API,Record,0);
1826
1827
117k
  D_Rect (API,&d_r,x1,y1,x2,y2);
1828
1829
117k
  clip = (wmfRegion*) P->dc->clip;
1830
1831
117k
  switch (Record->function)
1832
117k
  {
1833
114k
  case META_EXCLUDECLIPRECT:
1834
114k
    Clipping (API,clip,visible,&d_r,CLIP_EXCLUDE);
1835
114k
  break;
1836
1837
2.45k
  case META_INTERSECTCLIPRECT:
1838
2.45k
    Clipping (API,clip,visible,&d_r,CLIP_INTERSECT);
1839
2.45k
  break;
1840
1841
0
  default:
1842
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
1843
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
1844
0
    API->err = wmf_E_Glitch;
1845
0
  break;
1846
117k
  }
1847
1848
117k
  if (ERR (API))
1849
7
  { WMF_DEBUG (API,"bailing...");
1850
7
    return (changed);
1851
7
  }
1852
1853
117k
  if (SCAN (API)) return (changed);
1854
1855
3.12k
  polyrect.TL = (wmfD_Coord*) wmf_malloc (API,clip->numRects * sizeof (wmfD_Coord));
1856
1857
3.12k
  if (ERR (API))
1858
0
  { WMF_DEBUG (API,"bailing...");
1859
0
    return (changed);
1860
0
  }
1861
1862
3.12k
  polyrect.BR = (wmfD_Coord*) wmf_malloc (API,clip->numRects * sizeof (wmfD_Coord));
1863
1864
3.12k
  if (ERR (API))
1865
0
  { WMF_DEBUG (API,"bailing...");
1866
0
    return (changed);
1867
0
  }
1868
1869
3.12k
  polyrect.count = clip->numRects;
1870
18.7k
  for (i = 0; i < polyrect.count; i++)
1871
15.6k
  { polyrect.TL[i] = clip->rects[i].TL;
1872
15.6k
    polyrect.BR[i] = clip->rects[i].BR;
1873
15.6k
  }
1874
1875
3.12k
  polyrect.dc = P->dc;
1876
1877
3.12k
  polyrect.width  = 0;
1878
3.12k
  polyrect.height = 0;
1879
1880
3.12k
  if (FR->region_clip) FR->region_clip (API,&polyrect);
1881
1882
3.12k
  wmf_free (API,polyrect.TL);
1883
3.12k
  wmf_free (API,polyrect.BR);
1884
1885
3.12k
  return (changed);
1886
3.12k
}
1887
1888
static int meta_dib_draw (wmfAPI* API,wmfRecord* Record)
1889
25.5k
{ int changed = 0;
1890
1891
25.5k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
1892
25.5k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
1893
1894
25.5k
  wmfRecord bmp_record;
1895
1896
25.5k
  wmfBMP_Read_t bmp_read;
1897
25.5k
  wmfBMP_Draw_t bmp_draw;
1898
1899
25.5k
  wmfL_Coord l_pt_TL;
1900
25.5k
  wmfL_Coord l_pt;
1901
25.5k
  wmfD_Coord d_pt;
1902
1903
25.5k
  U16 par_U16_x = 0;
1904
25.5k
  U16 par_U16_y = 0;
1905
25.5k
  U16 par_U16_w = 0;
1906
25.5k
  U16 par_U16_h = 0;
1907
1908
25.5k
  S32 width;
1909
25.5k
  S32 height;
1910
1911
25.5k
  long pos_current;
1912
1913
25.5k
  double stretch_x;
1914
25.5k
  double stretch_y;
1915
1916
25.5k
  if ((Record->function == META_DIBBITBLT) && ((Record->size) == 9)) /* Special case... */
1917
617
  { changed = meta_rop_draw (API,Record);
1918
617
    return (changed);
1919
617
  }
1920
1921
24.9k
  if (SCAN (API) && DIAG (API))
1922
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
1923
0
  }
1924
1925
24.9k
  switch (Record->function)
1926
24.9k
  {
1927
30
  case META_SETDIBTODEV:
1928
30
    if (SCAN (API) && DIAG (API))
1929
0
    { fprintf (stderr,"\t#par=%lu; index 0 skipped; max. index = 8",Record->size);
1930
0
    }
1931
1932
30
    par_U16_x = ParU16 (API,Record,8);
1933
30
    par_U16_y = ParU16 (API,Record,7);
1934
1935
30
    par_U16_w = ParU16 (API,Record,6);
1936
30
    par_U16_h = ParU16 (API,Record,5);
1937
1938
30
    bmp_draw.crop.w = par_U16_w;
1939
30
    bmp_draw.crop.h = par_U16_h;
1940
1941
30
    bmp_draw.crop.x = ParU16 (API,Record,4);
1942
30
    bmp_draw.crop.y = ParU16 (API,Record,3);
1943
1944
30
    bmp_read.width  = ParU16 (API,Record,2); /* uncertain about this ?? */
1945
30
    bmp_read.height = ParU16 (API,Record,1);
1946
1947
30
    bmp_draw.type = SRCCOPY;
1948
1949
30
    bmp_record = OffsetRecord (API,Record,9);
1950
30
  break;
1951
1952
24.6k
  case META_STRETCHDIB:
1953
24.6k
    if (SCAN (API) && DIAG (API))
1954
0
    { fprintf (stderr,"\t#par=%lu; index 2 skipped; max. index = 10",Record->size);
1955
0
    }
1956
1957
24.6k
    par_U16_x = ParU16 (API,Record,10);
1958
24.6k
    par_U16_y = ParU16 (API,Record,9);
1959
1960
24.6k
    par_U16_w = ParU16 (API,Record,8);
1961
24.6k
    par_U16_h = ParU16 (API,Record,7);
1962
1963
24.6k
    bmp_draw.crop.x = ParU16 (API,Record,6);
1964
24.6k
    bmp_draw.crop.y = ParU16 (API,Record,5);
1965
1966
24.6k
    bmp_draw.crop.w = ParU16 (API,Record,4);
1967
24.6k
    bmp_draw.crop.h = ParU16 (API,Record,3);
1968
1969
24.6k
    bmp_read.width  = 0;
1970
24.6k
    bmp_read.height = 0;
1971
1972
24.6k
    bmp_draw.type = (U32) ParU16 (API,Record,0) + (((U32) ParU16 (API,Record,1)) << 16);
1973
1974
24.6k
    bmp_record = OffsetRecord (API,Record,11);
1975
24.6k
  break;
1976
1977
187
  case META_DIBSTRETCHBLT:
1978
187
    if (SCAN (API) && DIAG (API))
1979
0
    { fprintf (stderr,"\t#par=%lu; max. index = 9",Record->size);
1980
0
    }
1981
1982
187
    par_U16_x = ParU16 (API,Record,9);
1983
187
    par_U16_y = ParU16 (API,Record,8);
1984
1985
187
    par_U16_w = ParU16 (API,Record,7);
1986
187
    par_U16_h = ParU16 (API,Record,6);
1987
1988
187
    bmp_draw.crop.x = ParU16 (API,Record,5);
1989
187
    bmp_draw.crop.y = ParU16 (API,Record,4);
1990
1991
187
    bmp_draw.crop.w = ParU16 (API,Record,3);
1992
187
    bmp_draw.crop.h = ParU16 (API,Record,2);
1993
1994
187
    bmp_read.width  = 0;
1995
187
    bmp_read.height = 0;
1996
1997
187
    bmp_draw.type = (U32) ParU16 (API,Record,0) + (((U32) ParU16 (API,Record,1)) << 16);
1998
1999
187
    bmp_record = OffsetRecord (API,Record,10);
2000
187
  break;
2001
2002
54
  case META_DIBBITBLT: WMF_DEBUG (API,"(play) META_DIBBITBLT");
2003
54
    if (SCAN (API) && DIAG (API))
2004
0
    { fprintf (stderr,"\t#par=%lu; max. index = 7",Record->size);
2005
0
    }
2006
2007
54
    par_U16_x = ParU16 (API,Record,7);
2008
54
    par_U16_y = ParU16 (API,Record,6);
2009
2010
54
    par_U16_w = ParU16 (API,Record,5);
2011
54
    par_U16_h = ParU16 (API,Record,4);
2012
2013
54
    bmp_draw.crop.x = ParU16 (API,Record,3);
2014
54
    bmp_draw.crop.y = ParU16 (API,Record,2);
2015
2016
54
    bmp_draw.crop.w = par_U16_w;
2017
54
    bmp_draw.crop.h = par_U16_h;
2018
2019
54
    bmp_read.width  = 0;
2020
54
    bmp_read.height = 0;
2021
2022
54
    bmp_draw.type = (U32) ParU16 (API,Record,0) + (((U32) ParU16 (API,Record,1)) << 16);
2023
2024
54
    bmp_record = OffsetRecord (API,Record,8);
2025
54
  break;
2026
2027
0
  default:
2028
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
2029
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
2030
0
    API->err = wmf_E_Glitch;
2031
0
  break;
2032
24.9k
  }
2033
2034
24.9k
  if (ERR (API))
2035
16
  { WMF_DEBUG (API,"bailing...");
2036
16
    return (changed);
2037
16
  }
2038
2039
24.9k
  if ((par_U16_w == 0) || (par_U16_h == 0) || (bmp_draw.crop.w == 0) || (bmp_draw.crop.h == 0))
2040
1.15k
  { return (changed);
2041
1.15k
  }
2042
2043
23.7k
  l_pt_TL = L_Coord (par_U16_x,par_U16_y);
2044
2045
23.7k
  bmp_draw.pt = wmf_D_Coord_translate (API,l_pt_TL);
2046
2047
23.7k
  l_pt = L_Coord (par_U16_w,par_U16_h);
2048
2049
23.7k
  width  = ABS (l_pt.x);
2050
23.7k
  height = ABS (l_pt.y);
2051
2052
23.7k
  if (SCAN (API))
2053
12.0k
  { D_Coord_Register (API,bmp_draw.pt,0);
2054
2055
12.0k
    l_pt.x = l_pt_TL.x + width;
2056
12.0k
    l_pt.y = l_pt_TL.y + height;
2057
12.0k
    d_pt = wmf_D_Coord_translate (API,l_pt);
2058
12.0k
    D_Coord_Register (API,d_pt,0);
2059
2060
12.0k
    return (changed);
2061
12.0k
  }
2062
2063
11.6k
  pos_current = WMF_TELL (API);
2064
11.6k
  if (pos_current < 0)
2065
0
  { WMF_ERROR (API,"API's tell() failed on input stream!");
2066
0
    API->err = wmf_E_BadFile;
2067
0
    return (changed);
2068
0
  }
2069
2070
11.6k
  bmp_read.offset = bmp_record.position;
2071
11.6k
  bmp_read.buffer = bmp_record.parameter;
2072
11.6k
  bmp_read.length = (long) (bmp_record.size) * 2;
2073
2074
11.6k
  bmp_read.bmp.data = 0;
2075
2076
11.6k
  if (FR->bmp_read) FR->bmp_read (API,&bmp_read);
2077
2078
11.6k
  if (ERR (API) || (bmp_read.bmp.data == 0))
2079
8.85k
  { WMF_DEBUG (API,"bailing...");
2080
8.85k
    return (changed);
2081
8.85k
  }
2082
2083
2.81k
  if (WMF_SEEK (API,pos_current) == (-1))
2084
0
  { WMF_ERROR (API,"API's seek() failed on input stream!");
2085
0
    API->err = wmf_E_BadFile;
2086
0
    return (changed);
2087
0
  }
2088
2089
2.81k
  bmp_draw.dc = P->dc;
2090
2.81k
  bmp_draw.bmp = bmp_read.bmp;
2091
2.81k
  if (bmp_draw.crop.x >= bmp_read.bmp.width ) bmp_draw.crop.x = 0;
2092
2.81k
  if (bmp_draw.crop.y >= bmp_read.bmp.height) bmp_draw.crop.y = 0;
2093
2.81k
  if (bmp_draw.crop.x + bmp_draw.crop.w >= bmp_read.bmp.width)
2094
2.70k
  { bmp_draw.crop.w = bmp_read.bmp.width - bmp_draw.crop.x;
2095
2.70k
  }
2096
2.81k
  if (bmp_draw.crop.y + bmp_draw.crop.h >= bmp_read.bmp.height)
2097
2.66k
  { bmp_draw.crop.h = bmp_read.bmp.height - bmp_draw.crop.y;
2098
2.66k
  }
2099
2100
2.81k
  stretch_x = (double) par_U16_w / (double) bmp_draw.crop.w;
2101
2.81k
  stretch_y = (double) par_U16_h / (double) bmp_draw.crop.h;
2102
2103
2.81k
  bmp_draw.pixel_width  = ABS (P->dc->pixel_width ) * stretch_x;
2104
2.81k
  bmp_draw.pixel_height = ABS (P->dc->pixel_height) * stretch_y;
2105
2106
2.81k
  if (FR->bmp_draw) FR->bmp_draw (API,&bmp_draw);
2107
2108
2.81k
  if (FR->bmp_free) FR->bmp_free (API,&(bmp_draw.bmp));
2109
2110
2.81k
  return (changed);
2111
2.81k
}
2112
2113
static int meta_dib_brush (wmfAPI* API,wmfRecord* Record)
2114
147
{ int changed = 0;
2115
2116
147
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
2117
147
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
2118
2119
147
  wmfRecord bmp_record;
2120
2121
147
  wmfObject* objects;
2122
147
  wmfObject* obj_brush;
2123
2124
147
  wmfBrush* brush;
2125
2126
147
  wmfBMP_Read_t bmp_read;
2127
2128
147
  U16 oid_brush;
2129
2130
147
  unsigned int i;
2131
2132
147
  long pos_current;
2133
2134
147
  objects = P->objects;
2135
2136
147
  i = 0;
2137
501
  while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
2138
2139
147
  if (i == NUM_OBJECTS (API))
2140
1
  { WMF_ERROR (API,"Object out of range!");
2141
1
    API->err = wmf_E_BadFormat;
2142
1
    return (changed);
2143
1
  }
2144
2145
146
  oid_brush = i;
2146
146
  obj_brush = objects + oid_brush;
2147
2148
146
  obj_brush->type = OBJ_BRUSH;
2149
2150
146
  brush = &(obj_brush->obj.brush);
2151
2152
146
  if (SCAN (API) && DIAG (API))
2153
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
2154
0
    fprintf (stderr,"\t#par=%lu; max. index = ?",Record->size);
2155
2156
0
    diagnose_object (API,(unsigned int) oid_brush,obj_brush);
2157
0
  }
2158
2159
146
  bmp_record = OffsetRecord (API,Record,2);
2160
2161
146
  pos_current = WMF_TELL (API);
2162
146
  if (pos_current < 0)
2163
0
  { WMF_ERROR (API,"API's tell() failed on input stream!");
2164
0
    API->err = wmf_E_BadFile;
2165
0
    return (changed);
2166
0
  }
2167
2168
146
  bmp_read.offset = bmp_record.position;
2169
146
  bmp_read.buffer = bmp_record.parameter;
2170
146
  bmp_read.length = (long) (bmp_record.size) * 2;
2171
2172
146
  bmp_read.width  = 0;
2173
146
  bmp_read.height = 0;
2174
2175
146
  bmp_read.bmp.width  = 0;
2176
146
  bmp_read.bmp.height = 0;
2177
146
  bmp_read.bmp.data = 0;
2178
2179
146
  if (PLAY (API) && FR->bmp_read) FR->bmp_read (API,&bmp_read);
2180
2181
146
  if (ERR (API))
2182
1
  { WMF_DEBUG (API,"bailing...");
2183
1
    return (changed);
2184
1
  }
2185
2186
145
  if (WMF_SEEK (API,pos_current) == (-1))
2187
0
  { WMF_ERROR (API,"API's seek() failed on input stream!");
2188
0
    API->err = wmf_E_BadFile;
2189
0
    return (changed);
2190
0
  }
2191
2192
145
  WMF_BRUSH_SET_STYLE (brush,BS_DIBPATTERN);
2193
2194
145
  WMF_BRUSH_SET_COLOR (brush,&wmf_black);
2195
2196
145
  WMF_BRUSH_SET_BITMAP (brush,&(bmp_read.bmp));
2197
2198
145
  if (SCAN (API)) wmf_ipa_color_add (API,WMF_BRUSH_COLOR (brush));
2199
2200
145
  WMF_DC_SET_BRUSH (P->dc,brush);
2201
2202
145
  return (changed);
2203
145
}
2204
2205
static int meta_rop_draw (wmfAPI* API,wmfRecord* Record)
2206
1.94k
{ int changed = 0;
2207
2208
1.94k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
2209
1.94k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
2210
2211
1.94k
  wmfROP_Draw_t rop_draw;
2212
2213
1.94k
  wmfL_Coord l_pt_TL;
2214
1.94k
  wmfL_Coord l_pt;
2215
2216
1.94k
  U16 par_U16_x = 0;
2217
1.94k
  U16 par_U16_y = 0;
2218
1.94k
  U16 par_U16_w = 0;
2219
1.94k
  U16 par_U16_h = 0;
2220
2221
1.94k
  S32 width;
2222
1.94k
  S32 height;
2223
2224
1.94k
  if (SCAN (API) && DIAG (API))
2225
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
2226
0
  }
2227
2228
1.94k
  switch (Record->function)
2229
1.94k
  {
2230
617
  case META_DIBBITBLT: /* META_DIBBITBLT: Special case: Size = 12 */
2231
617
    if (SCAN (API) && DIAG (API))
2232
0
    { fprintf (stderr,"\t#par=%lu; index 2-4 skipped; max. index = 8",Record->size);
2233
0
    }
2234
2235
617
    par_U16_x = ParU16 (API,Record,8);
2236
617
    par_U16_y = ParU16 (API,Record,7);
2237
2238
617
    par_U16_w = ParU16 (API,Record,6);
2239
617
    par_U16_h = ParU16 (API,Record,5);
2240
2241
617
    rop_draw.ROP = (U32) ParU16 (API,Record,0) + (((U32) ParU16 (API,Record,1)) << 16);
2242
617
  break;
2243
2244
1.32k
  case META_PATBLT:
2245
1.32k
    if (SCAN (API) && DIAG (API))
2246
0
    { fprintf (stderr,"\t#par=%lu; max. index = 5",Record->size);
2247
0
    }
2248
2249
1.32k
    par_U16_x = ParU16 (API,Record,5);
2250
1.32k
    par_U16_y = ParU16 (API,Record,4);
2251
2252
1.32k
    par_U16_w = ParU16 (API,Record,3);
2253
1.32k
    par_U16_h = ParU16 (API,Record,2);
2254
2255
1.32k
    rop_draw.ROP = (U32) ParU16 (API,Record,0) + (((U32) ParU16 (API,Record,1)) << 16);
2256
1.32k
  break;
2257
2258
0
  default:
2259
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
2260
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
2261
0
    API->err = wmf_E_Glitch;
2262
0
  break;
2263
1.94k
  }
2264
2265
1.94k
  if (ERR (API))
2266
4
  { WMF_DEBUG (API,"bailing...");
2267
4
    return (changed);
2268
4
  }
2269
2270
1.94k
  l_pt_TL = L_Coord (par_U16_x,par_U16_y);
2271
2272
1.94k
  rop_draw.TL = wmf_D_Coord_translate (API,l_pt_TL);
2273
2274
1.94k
  l_pt = L_Coord (par_U16_w,par_U16_h);
2275
2276
1.94k
  width  = ABS (l_pt.x);
2277
1.94k
  height = ABS (l_pt.y);
2278
2279
1.94k
  l_pt.x = l_pt_TL.x + width;
2280
1.94k
  l_pt.y = l_pt_TL.y + height;
2281
2282
1.94k
  rop_draw.BR = wmf_D_Coord_translate (API,l_pt);
2283
2284
1.94k
  if (SCAN (API))
2285
1.30k
  { D_Coord_Register (API,rop_draw.TL,0);
2286
1.30k
    D_Coord_Register (API,rop_draw.BR,0);
2287
1.30k
    return (changed);
2288
1.30k
  }
2289
2290
632
  rop_draw.dc = P->dc;
2291
2292
632
  rop_draw.pixel_width  = ABS (P->dc->pixel_width );
2293
632
  rop_draw.pixel_height = ABS (P->dc->pixel_height);
2294
2295
632
  if (FR->rop_draw) FR->rop_draw (API,&rop_draw);
2296
2297
632
  return (changed);
2298
1.94k
}
2299
2300
static int meta_dc_set (wmfAPI* API,wmfRecord* Record)
2301
3.48k
{ int changed = 0;
2302
2303
3.48k
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
2304
2305
3.48k
  U16 par_U16;
2306
2307
3.48k
  if (SCAN (API) && DIAG (API))
2308
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
2309
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
2310
0
  }
2311
2312
3.48k
  par_U16 = ParU16 (API,Record,0);
2313
2314
3.48k
  switch (Record->function)
2315
3.48k
  {
2316
1.12k
  case META_SETROP2:
2317
1.12k
    WMF_DC_SET_ROP (P->dc,par_U16);
2318
1.12k
  break;
2319
2320
58
  case META_SETTEXTJUSTIFICATION:
2321
58
    WMF_DC_SET_BREAKEXTRA (P->dc,par_U16);
2322
58
  break;
2323
2324
116
  case META_SETTEXTCHAREXTRA:
2325
116
    WMF_DC_SET_CHAREXTRA (P->dc,par_U16);
2326
116
  break;
2327
2328
1.12k
  case META_SETPOLYFILLMODE:
2329
1.12k
    WMF_DC_SET_POLYFILL (P->dc,par_U16);
2330
1.12k
  break;
2331
2332
520
  case META_SETTEXTALIGN:
2333
520
    WMF_DC_SET_TEXTALIGN (P->dc,par_U16);
2334
520
  break;
2335
2336
541
  case META_SETBKMODE:
2337
541
    if (par_U16 == TRANSPARENT)
2338
351
    { WMF_DC_SET_TRANSPARENT (P->dc);
2339
351
    }
2340
190
    else
2341
190
    { WMF_DC_SET_OPAQUE (P->dc);
2342
190
      if (par_U16 != OPAQUE) { WMF_DEBUG (API,"unexpected background mode; assuming opaque..."); }
2343
190
    }
2344
541
  break;
2345
2346
0
  default:
2347
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
2348
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
2349
0
    API->err = wmf_E_Glitch;
2350
0
  break;
2351
3.48k
  }
2352
2353
3.48k
  return (changed);
2354
3.48k
}
2355
2356
static int meta_dc_color (wmfAPI* API,wmfRecord* Record,wmfAttributes* attrlist)
2357
1.14k
{ int changed = 0;
2358
2359
1.14k
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
2360
2361
1.14k
  wmfRGB color;
2362
2363
1.14k
  U16 par_U16_rg;
2364
1.14k
  U16 par_U16_b;
2365
2366
1.14k
  const char * value = 0;
2367
1.14k
  char hash[8];
2368
1.14k
  unsigned long rgbhex;
2369
2370
1.14k
  static char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
2371
2372
1.14k
  if (SCAN (API) && DIAG (API))
2373
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
2374
0
    fprintf (stderr,"\t#par=%lu; max. index = 1",Record->size);
2375
0
  }
2376
2377
1.14k
  if (API->flags & API_ENABLE_EDITING)
2378
0
  { if ((value = wmf_attr_query (API, attrlist, "color")))
2379
0
    { if ((*value) == '#')
2380
0
      { if (sscanf (value+1, "%lx", &rgbhex) == 1)
2381
0
        { par_U16_rg = (U16) ((rgbhex >> 8) & 0xffff);
2382
0
          par_U16_b  = (U16) ( rgbhex       & 0x00ff);
2383
2384
0
          if (PutParU16 (API,Record,1,par_U16_b )) changed = 1;
2385
0
          if (PutParU16 (API,Record,0,par_U16_rg)) changed = 1;
2386
0
        }
2387
0
        else
2388
0
        { value = 0; /* force a re-write below */
2389
0
        }
2390
0
      }
2391
0
      else
2392
0
      { value = 0; /* force a re-write below */
2393
0
      }
2394
0
    }
2395
0
  }
2396
2397
1.14k
  par_U16_b  = ParU16 (API,Record,1);
2398
1.14k
  par_U16_rg = ParU16 (API,Record,0);
2399
2400
1.14k
  color = rgb (par_U16_rg,par_U16_b);
2401
2402
1.14k
  if ((API->flags & API_ENABLE_EDITING) && ((value == 0) || changed))
2403
0
  { hash[0] = '#';
2404
0
    hash[1] = hex[(color.r >> 4) & 0x0f];
2405
0
    hash[2] = hex[ color.r       & 0x0f];
2406
0
    hash[3] = hex[(color.g >> 4) & 0x0f];
2407
0
    hash[4] = hex[ color.g       & 0x0f];
2408
0
    hash[5] = hex[(color.b >> 4) & 0x0f];
2409
0
    hash[6] = hex[ color.b       & 0x0f];
2410
0
    hash[7] = 0;
2411
0
    wmf_attr_add (API, attrlist, "color", hash);
2412
0
  }
2413
2414
1.14k
  if (SCAN (API)) wmf_ipa_color_add (API,&color);
2415
2416
1.14k
  switch (Record->function)
2417
1.14k
  {
2418
251
  case META_SETTEXTCOLOR:
2419
251
    WMF_DC_SET_TEXTCOLOR (P->dc,&color);
2420
251
  break;
2421
2422
893
  case META_SETBKCOLOR:
2423
893
    WMF_DC_SET_BACKGROUND (P->dc,&color);
2424
893
  break;
2425
2426
0
  default:
2427
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
2428
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
2429
0
    API->err = wmf_E_Glitch;
2430
0
  break;
2431
1.14k
  }
2432
2433
1.14k
  return (changed);
2434
1.14k
}
2435
2436
static int meta_dc_select (wmfAPI* API,wmfRecord* Record)
2437
15.6k
{ int changed = 0;
2438
2439
15.6k
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
2440
2441
15.6k
  wmfObject* objects;
2442
15.6k
  wmfObject* obj;
2443
2444
15.6k
  U16 oid;
2445
2446
15.6k
  objects = P->objects;
2447
2448
15.6k
  if (SCAN (API) && DIAG (API))
2449
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
2450
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
2451
0
  }
2452
2453
15.6k
  oid = ParU16 (API,Record,0);
2454
2455
15.6k
  if (oid >= NUM_OBJECTS (API))
2456
7
  { WMF_ERROR (API,"Object out of range!");
2457
7
    API->err = wmf_E_BadFormat;
2458
7
    return (changed);
2459
7
  }
2460
2461
15.6k
  obj = objects + oid;
2462
2463
15.6k
  if (SCAN (API) && DIAG (API))
2464
0
  { diagnose_object (API,(unsigned int) oid,obj);
2465
0
  }
2466
2467
15.6k
  switch (obj->type)
2468
15.6k
  {
2469
7.90k
  case OBJ_BRUSH:
2470
7.90k
    WMF_DC_SET_BRUSH (P->dc,&(obj->obj.brush));
2471
7.90k
  break;
2472
2473
6.64k
  case OBJ_PEN:
2474
6.64k
    WMF_DC_SET_PEN (P->dc,&(obj->obj.pen));
2475
6.64k
  break;
2476
2477
461
  case OBJ_FONT:
2478
461
    WMF_DC_SET_FONT (P->dc,&(obj->obj.font));
2479
461
  break;
2480
2481
595
  default:
2482
595
    WMF_DEBUG (API,"unexpected object type!");
2483
595
  break;
2484
15.6k
  }
2485
2486
15.6k
  return (changed);
2487
15.6k
}
2488
2489
static int meta_dc_save (wmfAPI* API,wmfRecord* Record) /* complete ?? */
2490
3.61k
{ int changed = 0;
2491
2492
3.61k
  wmfPlayer_t* P = (wmfPlayer_t*) API->player_data;
2493
2494
3.61k
  if (SCAN (API) && DIAG (API))
2495
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
2496
0
    fprintf (stderr,"\t#par=%lu; max. index = ?",Record->size);
2497
0
  }
2498
2499
3.61k
  dc_stack_push (API,P->dc);
2500
2501
3.61k
  P->dc = dc_copy (API,P->dc);
2502
2503
3.61k
  return (changed);
2504
3.61k
}
2505
2506
static int meta_dc_restore (wmfAPI* API,wmfRecord* Record)
2507
405
{ int changed = 0;
2508
2509
405
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
2510
405
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
2511
2512
405
  wmfRegion* clip;
2513
2514
405
  wmfPolyRectangle_t polyrect;
2515
405
  wmfUserData_t      userdata;
2516
2517
405
  unsigned int i;
2518
2519
405
  if (SCAN (API) && DIAG (API))
2520
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
2521
0
    fprintf (stderr,"\t#par=%lu; max. index = ?",Record->size);
2522
0
  }
2523
2524
  /* for (i = PAR(0); i < 0; i++) *//* Implies PAR(0) is signed ?? */
2525
2526
405
  userdata.dc = P->dc;
2527
405
  userdata.data = P->dc->userdata;
2528
2529
405
  if (PLAY (API) && FR->udata_free) FR->udata_free (API,&userdata);
2530
2531
405
  clip = (wmfRegion*) P->dc->clip;
2532
2533
405
  wmf_free (API,clip->rects);
2534
2535
405
  wmf_free (API,P->dc->clip);
2536
405
  wmf_free (API,P->dc);
2537
2538
405
  P->dc = dc_stack_pop (API);
2539
2540
405
  if (ERR (API))
2541
1
  { WMF_DEBUG (API,"bailing...");
2542
1
    return (changed);
2543
1
  }
2544
2545
404
  if (SCAN (API)) return (changed);
2546
2547
21
  userdata.dc = P->dc;
2548
21
  userdata.data = P->dc->userdata;
2549
2550
21
  if (FR->udata_set) FR->udata_set (API,&userdata);
2551
      
2552
21
  clip = (wmfRegion*) P->dc->clip;
2553
2554
21
  polyrect.dc = P->dc;
2555
2556
21
  polyrect.width  = 0;
2557
21
  polyrect.height = 0;
2558
2559
21
  if (clip->numRects)
2560
0
  { polyrect.TL = (wmfD_Coord*) wmf_malloc (API,clip->numRects * sizeof (wmfD_Coord));
2561
2562
0
    if (ERR (API))
2563
0
    { WMF_DEBUG (API,"bailing...");
2564
0
      return (changed);
2565
0
    }
2566
2567
0
    polyrect.BR = (wmfD_Coord*) wmf_malloc (API,clip->numRects * sizeof (wmfD_Coord));
2568
2569
0
    if (ERR (API))
2570
0
    { WMF_DEBUG (API,"bailing...");
2571
0
      return (changed);
2572
0
    }
2573
2574
0
    polyrect.count = clip->numRects;
2575
0
    for (i = 0; i < polyrect.count; i++)
2576
0
    { polyrect.TL[i] = clip->rects[i].TL;
2577
0
      polyrect.BR[i] = clip->rects[i].BR;
2578
0
    }
2579
2580
0
    if (FR->region_clip) FR->region_clip (API,&polyrect);
2581
2582
0
    wmf_free (API,polyrect.TL);
2583
0
    wmf_free (API,polyrect.BR);
2584
0
  }
2585
21
  else
2586
21
  { polyrect.TL = 0;
2587
21
    polyrect.BR = 0;
2588
2589
21
    polyrect.count = 0;
2590
  
2591
21
    if (FR->region_clip) FR->region_clip (API,&polyrect);
2592
21
  }
2593
2594
2595
21
  return (changed);
2596
21
}
2597
2598
static int meta_text (wmfAPI* API,wmfRecord* Record)
2599
946
{ int changed = 0;
2600
2601
946
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
2602
946
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
2603
946
  wmfFontData*          FD = (wmfFontData*)          API->font_data;
2604
2605
946
  wmfRecord str_record;
2606
946
  wmfRecord lpDx_record;
2607
2608
946
  wmfL_Coord l_pt;
2609
2610
946
  wmfD_Coord d_pt;
2611
946
  wmfD_Coord t_pt;
2612
946
  wmfD_Coord o_pt;
2613
2614
946
  wmfDrawText_t drawtext;
2615
2616
946
  wmfFont* font = 0;
2617
2618
946
  U16 par_U16;
2619
946
  U16 par_U16_x;
2620
946
  U16 par_U16_y;
2621
2622
946
  U16 i;
2623
946
  U16 length = 0;
2624
2625
946
  U16 bbox_info = 0;
2626
2627
946
  U16 l_width;
2628
2629
946
  U16* lpDx = 0;
2630
2631
946
  char buffer[2];
2632
2633
946
  char* str_save;
2634
2635
946
  double theta;
2636
946
  double ratio;
2637
2638
946
  float cos_theta;
2639
946
  float sin_theta;
2640
2641
946
  float width;
2642
2643
946
  switch (Record->function)
2644
946
  {
2645
119
  case META_TEXTOUT:
2646
119
    if (SCAN (API) && DIAG (API))
2647
0
    { fprintf (stderr,"\t[0x%04x]",Record->function);
2648
0
      fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
2649
0
    }
2650
2651
119
    if (WMF_DC_TEXTALIGN (P->dc) & TA_UPDATECP)
2652
0
    { if ((Record->size) < (unsigned int)(1 + (length + 1) / 2))
2653
0
      { WMF_ERROR (API,"Record is too short!");
2654
0
        API->err = wmf_E_BadFormat;
2655
0
        break;
2656
0
      }
2657
2658
0
      l_pt = P->current;
2659
0
    }
2660
119
    else
2661
119
    { if ((Record->size) < (unsigned int)(3 + (length + 1) / 2))
2662
1
      { WMF_ERROR (API,"Record is too short!");
2663
1
        API->err = wmf_E_BadFormat;
2664
1
        break;
2665
1
      }
2666
2667
118
      if (SCAN (API) && DIAG (API))
2668
0
      { fprintf (stderr,",-2,-1");
2669
0
      }
2670
2671
118
      par_U16_x  = ParU16 (API,Record,(Record->size)-1);
2672
118
      par_U16_y  = ParU16 (API,Record,(Record->size)-2);
2673
2674
118
      l_pt = L_Coord (par_U16_x,par_U16_y);
2675
118
    }
2676
2677
118
    drawtext.pt = wmf_D_Coord_translate (API,l_pt);
2678
2679
118
    length = ParU16 (API,Record,0);
2680
2681
118
    if (length == 0) break;
2682
2683
115
    drawtext.TL.x = 0;
2684
115
    drawtext.TL.y = 0;
2685
2686
115
    drawtext.BR.x = 0;
2687
115
    drawtext.BR.y = 0;
2688
2689
115
    str_record = OffsetRecord (API,Record,1);
2690
115
  break;
2691
2692
827
  case META_EXTTEXTOUT:
2693
827
    if (SCAN (API) && DIAG (API))
2694
0
    { fprintf (stderr,"\t[0x%04x]",Record->function);
2695
0
    }
2696
2697
827
    if (WMF_DC_TEXTALIGN (P->dc) & TA_UPDATECP)
2698
42
    { if (SCAN (API) && DIAG (API))
2699
0
      { fprintf (stderr,"\t#par=%lu; index 0-1 ignored; max. index = 3",Record->size);
2700
0
      }
2701
2702
42
      l_pt = P->current;
2703
42
    }
2704
785
    else
2705
785
    { if (SCAN (API) && DIAG (API))
2706
0
      { fprintf (stderr,"\t#par=%lu; max. index = 3",Record->size);
2707
0
      }
2708
2709
785
      par_U16_x  = ParU16 (API,Record,1);
2710
785
      par_U16_y  = ParU16 (API,Record,0);
2711
2712
785
      l_pt = L_Coord (par_U16_x,par_U16_y);
2713
785
    }
2714
2715
827
    drawtext.pt = wmf_D_Coord_translate (API,l_pt);
2716
2717
827
    length = ParU16 (API,Record,2);
2718
2719
827
    if (length == 0) break;
2720
2721
797
    bbox_info = ParU16 (API,Record,3);
2722
797
    if (bbox_info)
2723
169
    { if (SCAN (API) && DIAG (API))
2724
0
      { fprintf (stderr,",7");
2725
0
      }
2726
2727
169
      par_U16_x  = ParU16 (API,Record,4); /* Is this right ?? */
2728
169
      par_U16_y  = ParU16 (API,Record,5);
2729
2730
169
      l_pt = L_Coord (par_U16_x,par_U16_y);
2731
2732
169
      drawtext.TL = wmf_D_Coord_translate (API,l_pt);
2733
2734
169
      par_U16_x  = ParU16 (API,Record,6); /* Is this right ?? */
2735
169
      par_U16_y  = ParU16 (API,Record,7);
2736
2737
169
      l_pt = L_Coord (par_U16_x,par_U16_y);
2738
2739
169
      drawtext.BR = wmf_D_Coord_translate (API,l_pt);
2740
2741
169
      if (SCAN (API))
2742
138
      { D_Coord_Register (API,drawtext.TL,0);
2743
138
        D_Coord_Register (API,drawtext.BR,0);
2744
138
      }
2745
2746
169
      str_record = OffsetRecord (API,Record,8);
2747
169
    }
2748
628
    else
2749
628
    { drawtext.TL.x = 0;
2750
628
      drawtext.TL.y = 0;
2751
2752
628
      drawtext.BR.x = 0;
2753
628
      drawtext.BR.y = 0;
2754
2755
628
      str_record = OffsetRecord (API,Record,4);
2756
628
    }
2757
797
  break;
2758
2759
0
  default:
2760
0
    WMF_ERROR (API,"libwmf: erk! programmer's error...");
2761
0
    WMF_ERROR (API,"        please contact us at http://www.wvware.com/");
2762
0
    API->err = wmf_E_Glitch;
2763
0
  break;
2764
946
  }
2765
2766
946
  if (ERR (API)) return (changed);
2767
2768
937
  if (length == 0) return (changed);
2769
2770
906
  drawtext.str = (char*) wmf_malloc (API,length + 1);
2771
2772
906
  if (ERR (API))
2773
0
  { WMF_DEBUG (API,"bailing...");
2774
0
    return (changed);
2775
0
  }
2776
2777
906
  font = WMF_DC_FONT (P->dc);
2778
2779
        /* FIXME: bug here?  Negative font height is supposed to represent absolute font pointsize */
2780
906
  drawtext.font_height = (double) WMF_FONT_HEIGHT (font) * ABS (P->dc->pixel_height);
2781
2782
        /* FIXME: bug here, WMF_FONT_WIDTH and  WMF_FONT_HEIGHT do not necessarily have same scale! */
2783
906
  drawtext.font_ratio = (double) WMF_FONT_WIDTH (font) / (double) WMF_FONT_HEIGHT (font);
2784
2785
906
  par_U16 = 0;
2786
1.59M
  for (i = 0; i < length; i++)
2787
1.59M
  { if (i & 1)
2788
796k
    { drawtext.str[i] =  (par_U16 >> 8) & 0xff;
2789
796k
    }
2790
797k
    else
2791
797k
    { par_U16 = ParU16 (API,&str_record,i/2);
2792
797k
      drawtext.str[i] =  par_U16 & 0xff;
2793
797k
    }
2794
1.59M
  }
2795
906
  drawtext.str[length] = '\0';
2796
2797
906
  width = FD->stringwidth (API,font,drawtext.str);
2798
2799
906
  width = (float) ((double) width * drawtext.font_height * drawtext.font_ratio);
2800
2801
906
  lpDx_record = OffsetRecord (API,&str_record,(length+1)/2);
2802
2803
906
  if ((Record->function == META_EXTTEXTOUT) && ((lpDx_record.size) >= length))
2804
319
  { lpDx = (U16*) wmf_malloc (API,length * sizeof (U16));
2805
2806
319
    if (ERR (API))
2807
0
    { WMF_DEBUG (API,"bailing...");
2808
0
      return (changed);
2809
0
    }
2810
2811
319
    l_width = 0;
2812
3.75k
    for (i = 0; i < length; i++)
2813
3.43k
    { lpDx[i] = ParU16 (API,&lpDx_record,i);
2814
3.43k
      l_width += lpDx[i];
2815
3.43k
    }
2816
2817
319
    l_pt = L_Coord (0,0);
2818
319
    t_pt = wmf_D_Coord_translate (API,l_pt);
2819
319
    l_pt = L_Coord (l_width,0);
2820
319
    d_pt = wmf_D_Coord_translate (API,l_pt);
2821
2822
319
    width = d_pt.x - t_pt.x;
2823
319
  }
2824
2825
906
  theta = - WMF_TEXT_ANGLE (font);
2826
2827
906
  cos_theta = (float) cos (theta);
2828
906
  sin_theta = (float) sin (theta);
2829
2830
  /* Okay, have text reference point, string width & font height, & angle (in radians)
2831
   * Compute bounding box and adjust for alignment:
2832
   */
2833
906
  if (WMF_DC_TEXTALIGN (P->dc) & TA_BASELINE)
2834
545
  { /* */
2835
545
  }
2836
361
  else if (WMF_DC_TEXTALIGN (P->dc) & TA_BOTTOM)
2837
0
  { d_pt.y = - drawtext.font_height / 3; /* This is only approximate... */
2838
0
    t_pt.x = - d_pt.y * sin_theta;
2839
0
    t_pt.y =   d_pt.y * cos_theta;
2840
0
    drawtext.pt.x += t_pt.x;
2841
0
    drawtext.pt.y += t_pt.y;
2842
0
  }
2843
361
  else /* if (WMF_DC_TEXTALIGN (P->dc) & TA_TOP) */
2844
361
  { d_pt.y = drawtext.font_height;       /* This is only approximate... */
2845
361
    t_pt.x = - d_pt.y * sin_theta;
2846
361
    t_pt.y =   d_pt.y * cos_theta;
2847
361
    drawtext.pt.x += t_pt.x;
2848
361
    drawtext.pt.y += t_pt.y;
2849
361
  }
2850
2851
906
  if (WMF_DC_TEXTALIGN (P->dc) & TA_CENTER)
2852
138
  { d_pt.x = width / 2;
2853
138
    d_pt.y = - drawtext.font_height * 0.77;
2854
138
    t_pt.x = d_pt.x * cos_theta - d_pt.y * sin_theta;
2855
138
    t_pt.y = d_pt.x * sin_theta + d_pt.y * cos_theta;
2856
138
    drawtext.bbox.TR.x = drawtext.pt.x + t_pt.x;
2857
138
    drawtext.bbox.TR.y = drawtext.pt.y + t_pt.y;
2858
138
    D_Coord_Register (API,drawtext.bbox.TR,0);
2859
2860
138
    drawtext.bbox.BL.x = drawtext.pt.x - t_pt.x;
2861
138
    drawtext.bbox.BL.y = drawtext.pt.y - t_pt.y;
2862
138
    D_Coord_Register (API,drawtext.bbox.BL,0);
2863
2864
138
    d_pt.x = width / 2;
2865
138
    d_pt.y = drawtext.font_height * 0.23;
2866
138
    t_pt.x = d_pt.x * cos_theta - d_pt.y * sin_theta;
2867
138
    t_pt.y = d_pt.x * sin_theta + d_pt.y * cos_theta;
2868
138
    drawtext.bbox.BR.x = drawtext.pt.x + t_pt.x;
2869
138
    drawtext.bbox.BR.y = drawtext.pt.y + t_pt.y;
2870
138
    D_Coord_Register (API,drawtext.bbox.BR,0);
2871
2872
138
    drawtext.bbox.TL.x = drawtext.pt.x - t_pt.x;
2873
138
    drawtext.bbox.TL.y = drawtext.pt.y - t_pt.y;
2874
138
    D_Coord_Register (API,drawtext.bbox.TL,0);
2875
2876
138
    d_pt.x = - width / 2;
2877
138
    t_pt.x = d_pt.x * cos_theta;
2878
138
    t_pt.y = d_pt.x * sin_theta;
2879
138
    drawtext.pt.x += t_pt.x;
2880
138
    drawtext.pt.y += t_pt.y;
2881
138
  }
2882
768
  else if (WMF_DC_TEXTALIGN (P->dc) & TA_RIGHT)
2883
0
  { d_pt.y = - drawtext.font_height * 0.77;
2884
0
    t_pt.x = - d_pt.y * sin_theta;
2885
0
    t_pt.y =   d_pt.y * cos_theta;
2886
0
    drawtext.bbox.TR.x = drawtext.pt.x + t_pt.x;
2887
0
    drawtext.bbox.TR.y = drawtext.pt.y + t_pt.y;
2888
0
    D_Coord_Register (API,drawtext.bbox.TR,0);
2889
2890
0
    d_pt.y = drawtext.font_height * 0.23;
2891
0
    t_pt.x = - d_pt.y * sin_theta;
2892
0
    t_pt.y =   d_pt.y * cos_theta;
2893
0
    drawtext.bbox.BR.x = drawtext.pt.x + t_pt.x;
2894
0
    drawtext.bbox.BR.y = drawtext.pt.y + t_pt.y;
2895
0
    D_Coord_Register (API,drawtext.bbox.BR,0);
2896
2897
0
    d_pt.x = - width;
2898
0
    d_pt.y = - drawtext.font_height * 0.77;
2899
0
    t_pt.x = d_pt.x * cos_theta - d_pt.y * sin_theta;
2900
0
    t_pt.y = d_pt.x * sin_theta + d_pt.y * cos_theta;
2901
0
    drawtext.bbox.TL.x = drawtext.pt.x + t_pt.x;
2902
0
    drawtext.bbox.TL.y = drawtext.pt.y + t_pt.y;
2903
0
    D_Coord_Register (API,drawtext.bbox.TL,0);
2904
2905
0
    d_pt.x = - width;
2906
0
    d_pt.y = drawtext.font_height * 0.23;
2907
0
    t_pt.x = d_pt.x * cos_theta - d_pt.y * sin_theta;
2908
0
    t_pt.y = d_pt.x * sin_theta + d_pt.y * cos_theta;
2909
0
    drawtext.bbox.BL.x = drawtext.pt.x + t_pt.x;
2910
0
    drawtext.bbox.BL.y = drawtext.pt.y + t_pt.y;
2911
0
    D_Coord_Register (API,drawtext.bbox.BL,0);
2912
2913
0
    d_pt.x = - width;
2914
0
    t_pt.x = d_pt.x * cos_theta;
2915
0
    t_pt.y = d_pt.x * sin_theta;
2916
0
    d_pt.x = drawtext.pt.x + t_pt.x;
2917
0
    d_pt.y = drawtext.pt.y + t_pt.y;
2918
2919
0
    drawtext.pt = d_pt;
2920
2921
0
    if (WMF_DC_TEXTALIGN (P->dc) & TA_UPDATECP)
2922
0
    { P->current = wmf_L_Coord_translate (API,drawtext.pt);
2923
0
    }
2924
0
  }
2925
768
  else /* if (WMF_DC_TEXTALIGN (P->dc) & TA_LEFT) */
2926
768
  { d_pt.y = - drawtext.font_height * 0.77;
2927
768
    t_pt.x = - d_pt.y * sin_theta;
2928
768
    t_pt.y =   d_pt.y * cos_theta;
2929
768
    drawtext.bbox.TL.x = drawtext.pt.x + t_pt.x;
2930
768
    drawtext.bbox.TL.y = drawtext.pt.y + t_pt.y;
2931
768
    D_Coord_Register (API,drawtext.bbox.TL,0);
2932
2933
768
    d_pt.y = drawtext.font_height * 0.23;
2934
768
    t_pt.x = - d_pt.y * sin_theta;
2935
768
    t_pt.y =   d_pt.y * cos_theta;
2936
768
    drawtext.bbox.BL.x = drawtext.pt.x + t_pt.x;
2937
768
    drawtext.bbox.BL.y = drawtext.pt.y + t_pt.y;
2938
768
    D_Coord_Register (API,drawtext.bbox.BL,0);
2939
2940
768
    d_pt.x = width;
2941
768
    d_pt.y = - drawtext.font_height * 0.77;
2942
768
    t_pt.x = d_pt.x * cos_theta - d_pt.y * sin_theta;
2943
768
    t_pt.y = d_pt.x * sin_theta + d_pt.y * cos_theta;
2944
768
    drawtext.bbox.TR.x = drawtext.pt.x + t_pt.x;
2945
768
    drawtext.bbox.TR.y = drawtext.pt.y + t_pt.y;
2946
768
    D_Coord_Register (API,drawtext.bbox.TR,0);
2947
2948
768
    d_pt.x = width;
2949
768
    d_pt.y = drawtext.font_height * 0.23;
2950
768
    t_pt.x = d_pt.x * cos_theta - d_pt.y * sin_theta;
2951
768
    t_pt.y = d_pt.x * sin_theta + d_pt.y * cos_theta;
2952
768
    drawtext.bbox.BR.x = drawtext.pt.x + t_pt.x;
2953
768
    drawtext.bbox.BR.y = drawtext.pt.y + t_pt.y;
2954
768
    D_Coord_Register (API,drawtext.bbox.BR,0);
2955
2956
768
    if (WMF_DC_TEXTALIGN (P->dc) & TA_UPDATECP)
2957
3
    { d_pt.x = width;
2958
3
      t_pt.x = d_pt.x * cos_theta;
2959
3
      t_pt.y = d_pt.x * sin_theta;
2960
3
      d_pt.x = drawtext.pt.x + t_pt.x;
2961
3
      d_pt.y = drawtext.pt.y + t_pt.y;
2962
2963
3
      P->current = wmf_L_Coord_translate (API,drawtext.pt);
2964
3
    }
2965
768
  }
2966
2967
906
  if (SCAN (API))
2968
670
  { wmf_free (API,drawtext.str);
2969
670
    if (lpDx) wmf_free (API,lpDx);
2970
670
    return (changed);
2971
670
  }
2972
2973
236
  drawtext.dc = P->dc;
2974
2975
236
  drawtext.flags = bbox_info;
2976
2977
236
  if (lpDx)
2978
83
  { str_save = drawtext.str;
2979
83
    drawtext.str = buffer;
2980
83
    t_pt = drawtext.pt;
2981
83
    ratio = drawtext.font_ratio;
2982
83
    l_width = 0;
2983
719
    for (i = 0; i < length; i++)
2984
636
    { buffer[0] = str_save[i];
2985
636
      buffer[1] = 0;
2986
2987
636
      l_pt = L_Coord (0,0);
2988
636
      o_pt = wmf_D_Coord_translate (API,l_pt);
2989
636
      l_pt = L_Coord (l_width,0);
2990
636
      d_pt = wmf_D_Coord_translate (API,l_pt);
2991
636
      d_pt.x -= o_pt.x;
2992
636
      d_pt.y -= o_pt.y;
2993
636
      drawtext.pt.x = t_pt.x + d_pt.x * cos_theta;
2994
636
      drawtext.pt.y = t_pt.y + d_pt.x * sin_theta;
2995
2996
636
      l_pt = L_Coord (0,0);
2997
636
      o_pt = wmf_D_Coord_translate (API,l_pt);
2998
636
      l_pt = L_Coord (lpDx[i],0);
2999
636
      d_pt = wmf_D_Coord_translate (API,l_pt);
3000
636
      d_pt.x -= o_pt.x;
3001
636
      d_pt.y -= o_pt.y;
3002
636
      width = FD->stringwidth (API,font,drawtext.str);
3003
636
      width = (float) ((double) width * drawtext.font_height * ratio);
3004
636
      if (d_pt.x < width)
3005
177
      { drawtext.font_ratio = ratio * (d_pt.x / width);
3006
177
      }
3007
459
      else
3008
459
      { drawtext.font_ratio = ratio;
3009
459
      }
3010
3011
636
      if (FR->draw_text) FR->draw_text (API,&drawtext);
3012
3013
636
      l_width += lpDx[i];
3014
3015
636
      drawtext.bbox.TL.x = 0;
3016
636
      drawtext.bbox.TL.y = 0;
3017
636
      drawtext.bbox.TR.x = 0;
3018
636
      drawtext.bbox.TR.y = 0;
3019
636
      drawtext.bbox.BL.x = 0;
3020
636
      drawtext.bbox.BL.y = 0;
3021
636
      drawtext.bbox.BR.x = 0;
3022
636
      drawtext.bbox.BR.y = 0;
3023
636
    }
3024
83
    wmf_free (API,lpDx);
3025
83
  }
3026
153
  else
3027
153
  { if (FR->draw_text) FR->draw_text (API,&drawtext);
3028
153
  }
3029
3030
236
  wmf_free (API,drawtext.str);
3031
3032
236
  return (changed);
3033
906
}
3034
3035
static int meta_pen_create (wmfAPI* API,wmfRecord* Record,wmfAttributes* attrlist) /* complete, I think */
3036
4.30k
{ int changed = 0;
3037
3038
4.30k
  wmfPlayer_t* P  = (wmfPlayer_t*) API->player_data;
3039
3040
4.30k
  wmfObject* objects = 0;
3041
4.30k
  wmfObject* obj_pen = 0;
3042
3043
4.30k
  wmfRGB color;
3044
3045
4.30k
  wmfPen* pen = 0;
3046
3047
4.30k
  U16 par_U16_rg;
3048
4.30k
  U16 par_U16_b;
3049
4.30k
  U16 par_U16_w;
3050
4.30k
  U16 par_U16_s;
3051
3052
4.30k
  U16 oid_pen;
3053
3054
4.30k
  U16 i;
3055
3056
4.30k
  const char * value = 0;
3057
4.30k
  char hash[8];
3058
4.30k
  unsigned long rgbhex;
3059
3060
4.30k
  static char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
3061
3062
4.30k
  objects = P->objects;
3063
3064
4.30k
  i = 0;
3065
56.6k
  while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
3066
3067
4.30k
  if (i == NUM_OBJECTS (API))
3068
1
  { WMF_ERROR (API,"Object out of range!");
3069
1
    API->err = wmf_E_BadFormat;
3070
1
    return (changed);
3071
1
  }
3072
3073
4.30k
  oid_pen = i;
3074
4.30k
  obj_pen = objects + oid_pen;
3075
3076
4.30k
  obj_pen->type = OBJ_PEN;
3077
3078
4.30k
  pen = &(obj_pen->obj.pen);
3079
3080
4.30k
  if (SCAN (API) && DIAG (API))
3081
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
3082
0
    fprintf (stderr,"\t#par=%lu; index 2 skipped; max. index = 4",Record->size);
3083
3084
0
    diagnose_object (API,(unsigned int) oid_pen,obj_pen);
3085
0
  }
3086
3087
4.30k
  par_U16_s = ParU16 (API,Record,0);
3088
3089
4.30k
  WMF_PEN_SET_STYLE  (pen,par_U16_s); /* Need to do all of these separately... */
3090
4.30k
  WMF_PEN_SET_ENDCAP (pen,par_U16_s);
3091
4.30k
  WMF_PEN_SET_JOIN   (pen,par_U16_s);
3092
4.30k
  WMF_PEN_SET_TYPE   (pen,par_U16_s);
3093
3094
4.30k
  par_U16_w = ParU16 (API,Record,1);
3095
3096
4.30k
  par_U16_w = MAX (1,par_U16_w);
3097
3098
4.30k
  WMF_PEN_SET_WIDTH  (pen,(double) par_U16_w * ABS (P->dc->pixel_width ));
3099
4.30k
  WMF_PEN_SET_HEIGHT (pen,(double) par_U16_w * ABS (P->dc->pixel_height));
3100
3101
4.30k
  if (API->flags & API_ENABLE_EDITING)
3102
0
  { if ((value = wmf_attr_query (API, attrlist, "color")))
3103
0
    { if ((*value) == '#')
3104
0
      { if (sscanf (value+1, "%lx", &rgbhex) == 1)
3105
0
        { par_U16_rg = (U16) ((rgbhex >> 8) & 0xffff);
3106
0
          par_U16_b  = (U16) ( rgbhex       & 0x00ff);
3107
3108
0
          if (PutParU16 (API,Record,4,par_U16_b )) changed = 1;
3109
0
          if (PutParU16 (API,Record,3,par_U16_rg)) changed = 1;
3110
0
        }
3111
0
        else
3112
0
        { value = 0; /* force a re-write below */
3113
0
        }
3114
0
      }
3115
0
      else
3116
0
      { value = 0; /* force a re-write below */
3117
0
      }
3118
0
    }
3119
0
  }
3120
3121
4.30k
  par_U16_b  = ParU16 (API,Record,4);
3122
4.30k
  par_U16_rg = ParU16 (API,Record,3);
3123
3124
4.30k
  color = rgb (par_U16_rg,par_U16_b);
3125
3126
4.30k
  if ((API->flags & API_ENABLE_EDITING) && ((value == 0) || changed))
3127
0
  { hash[0] = '#';
3128
0
    hash[1] = hex[(color.r >> 4) & 0x0f];
3129
0
    hash[2] = hex[ color.r       & 0x0f];
3130
0
    hash[3] = hex[(color.g >> 4) & 0x0f];
3131
0
    hash[4] = hex[ color.g       & 0x0f];
3132
0
    hash[5] = hex[(color.b >> 4) & 0x0f];
3133
0
    hash[6] = hex[ color.b       & 0x0f];
3134
0
    hash[7] = 0;
3135
0
    wmf_attr_add (API, attrlist, "color", hash);
3136
0
  }
3137
3138
4.30k
  WMF_PEN_SET_COLOR (pen,&color);
3139
3140
4.30k
  if (SCAN (API)) wmf_ipa_color_add (API,&color);
3141
3142
4.30k
  if (WMF_PEN_STYLE (pen) != PS_NULL) { WMF_DEBUG (API,"Non-null pen style..."); }
3143
3144
4.30k
  WMF_DC_SET_PEN (P->dc,pen);
3145
3146
4.30k
  return (changed);
3147
4.30k
}
3148
3149
static int meta_brush_create (wmfAPI* API,wmfRecord* Record,wmfAttributes* attrlist) /* unfinished */
3150
8.54k
{ int changed = 0;
3151
3152
8.54k
  wmfPlayer_t* P  = (wmfPlayer_t*) API->player_data;
3153
3154
8.54k
  wmfObject* objects = 0;
3155
8.54k
  wmfObject* obj_brush = 0;
3156
3157
8.54k
  wmfRGB color;
3158
3159
8.54k
  wmfBrush* brush = 0;
3160
3161
8.54k
  wmfBMP bmp;
3162
3163
8.54k
  U16 par_U16_rg;
3164
8.54k
  U16 par_U16_b;
3165
3166
8.54k
  U16 oid_brush;
3167
3168
8.54k
  U16 i;
3169
3170
8.54k
  const char * value = 0;
3171
8.54k
  char hash[8];
3172
8.54k
  unsigned long rgbhex;
3173
3174
8.54k
  static char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
3175
3176
8.54k
  objects = P->objects;
3177
3178
8.54k
  i = 0;
3179
66.3k
  while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
3180
3181
8.54k
  if (i == NUM_OBJECTS (API))
3182
1
  { WMF_ERROR (API,"Object out of range!");
3183
1
    API->err = wmf_E_BadFormat;
3184
1
    return (changed);
3185
1
  }
3186
3187
8.53k
  oid_brush = i;
3188
8.53k
  obj_brush = objects + oid_brush;
3189
3190
8.53k
  obj_brush->type = OBJ_BRUSH;
3191
3192
8.53k
  brush = &(obj_brush->obj.brush);
3193
3194
8.53k
  if (SCAN (API) && DIAG (API))
3195
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
3196
0
    fprintf (stderr,"\t#par=%lu; max. index = 3",Record->size);
3197
3198
0
    diagnose_object (API,(unsigned int) oid_brush,obj_brush);
3199
0
  }
3200
3201
8.53k
  WMF_BRUSH_SET_STYLE (brush,ParU16 (API,Record,0));
3202
3203
8.53k
  if (API->flags & API_ENABLE_EDITING)
3204
0
  { if ((value = wmf_attr_query (API, attrlist, "color")))
3205
0
    { if ((*value) == '#')
3206
0
      { if (sscanf (value+1, "%lx", &rgbhex) == 1)
3207
0
        { par_U16_rg = (U16) ((rgbhex >> 8) & 0xffff);
3208
0
          par_U16_b  = (U16) ( rgbhex       & 0x00ff);
3209
3210
0
          if (PutParU16 (API,Record,2,par_U16_b )) changed = 1;
3211
0
          if (PutParU16 (API,Record,1,par_U16_rg)) changed = 1;
3212
0
        }
3213
0
        else
3214
0
        { value = 0; /* force a re-write below */
3215
0
        }
3216
0
      }
3217
0
      else
3218
0
      { value = 0; /* force a re-write below */
3219
0
      }
3220
0
    }
3221
0
  }
3222
3223
8.53k
  par_U16_b  = ParU16 (API,Record,2);
3224
8.53k
  par_U16_rg = ParU16 (API,Record,1);
3225
3226
8.53k
  color = rgb (par_U16_rg,par_U16_b);
3227
3228
8.53k
  if ((API->flags & API_ENABLE_EDITING) && ((value == 0) || changed))
3229
0
  { hash[0] = '#';
3230
0
    hash[1] = hex[(color.r >> 4) & 0x0f];
3231
0
    hash[2] = hex[ color.r       & 0x0f];
3232
0
    hash[3] = hex[(color.g >> 4) & 0x0f];
3233
0
    hash[4] = hex[ color.g       & 0x0f];
3234
0
    hash[5] = hex[(color.b >> 4) & 0x0f];
3235
0
    hash[6] = hex[ color.b       & 0x0f];
3236
0
    hash[7] = 0;
3237
0
    wmf_attr_add (API, attrlist, "color", hash);
3238
0
  }
3239
3240
8.53k
  WMF_BRUSH_SET_COLOR (brush,&color);
3241
3242
8.53k
  WMF_BRUSH_SET_HATCH (brush,ParU16 (API,Record,3));
3243
3244
8.53k
  bmp.width  = 0;
3245
8.53k
  bmp.height = 0;
3246
3247
8.53k
  bmp.data = 0;
3248
3249
8.53k
  WMF_BRUSH_SET_BITMAP (brush,&bmp);
3250
3251
8.53k
  if (SCAN (API)) wmf_ipa_color_add (API,&color);
3252
3253
8.53k
  WMF_DC_SET_BRUSH (P->dc,brush);
3254
3255
8.53k
  return (changed);
3256
8.54k
}
3257
3258
static int meta_font_create (wmfAPI* API,wmfRecord* Record)
3259
653
{ int changed = 0;
3260
3261
653
  wmfPlayer_t* P  = (wmfPlayer_t*) API->player_data;
3262
653
  wmfFontData* FD = (wmfFontData*) API->font_data;
3263
3264
653
  wmfRecord name_record;
3265
3266
653
  wmfObject* objects = 0;
3267
653
  wmfObject* obj_font = 0;
3268
3269
653
  wmfFont* font = 0;
3270
3271
653
  U16 oid_font;
3272
3273
653
  U16 par_U16;
3274
3275
653
  S16 par_S16_w;
3276
653
  S16 par_S16_h;
3277
3278
653
  unsigned long i;
3279
653
  unsigned long length;
3280
3281
653
  char* fontname = 0;
3282
3283
653
  objects = P->objects;
3284
3285
653
  i = 0;
3286
3.02k
  while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
3287
3288
653
  if (i == NUM_OBJECTS (API))
3289
2
  { WMF_ERROR (API,"Object out of range!");
3290
2
    API->err = wmf_E_BadFormat;
3291
2
    return (changed);
3292
2
  }
3293
3294
651
  oid_font = i;
3295
651
  obj_font = objects + oid_font;
3296
3297
651
  obj_font->type = OBJ_FONT;
3298
3299
651
  font = &(obj_font->obj.font);
3300
3301
651
  if (SCAN (API) && DIAG (API))
3302
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
3303
0
    fprintf (stderr,"\t#par=%lu; max. index = 8",Record->size);
3304
3305
0
    diagnose_object (API,(unsigned int) oid_font,obj_font);
3306
0
  }
3307
3308
651
  par_S16_w = ParS16 (API,Record,1);
3309
651
  par_S16_h = ParS16 (API,Record,0);
3310
3311
651
  WMF_FONT_SET_HEIGHT (font,ABS (par_S16_h));
3312
651
  WMF_FONT_SET_WIDTH  (font,ABS (par_S16_w));
3313
3314
651
  WMF_FONT_SET_ESCAPEMENT  (font,ParS16 (API,Record,2)); /* text angle */
3315
651
  WMF_FONT_SET_ORIENTATION (font,ParS16 (API,Record,3));
3316
3317
651
  WMF_FONT_SET_WEIGHT (font,ParU16 (API,Record,4));
3318
3319
651
  par_U16 = ParU16 (API,Record,5);
3320
651
  WMF_FONT_SET_ITALIC (font,par_U16 & 0xff);
3321
3322
651
  WMF_TEXT_SET_UNDERLINE (font,(par_U16 >> 8) & 0xff);
3323
3324
651
  par_U16 = ParU16 (API,Record,6);
3325
651
  WMF_TEXT_SET_STRIKEOUT (font,par_U16 & 0xff);
3326
3327
651
  WMF_FONT_SET_CHARSET (font,(par_U16 >> 8) & 0xff);
3328
3329
651
  par_U16 = ParU16 (API,Record,7);
3330
651
  WMF_FONT_SET_OUT (font,par_U16 & 0xff);
3331
3332
651
  WMF_FONT_SET_CLIP (font,(par_U16 >> 8) & 0xff);
3333
3334
651
  par_U16 = ParU16 (API,Record,8);
3335
651
  WMF_FONT_SET_QUALITY (font,par_U16 & 0xff);
3336
3337
651
  WMF_FONT_SET_PITCH (font,(par_U16 >> 8) & 0xff);
3338
3339
651
  if (WMF_FONT_WIDTH (font) == 0)
3340
362
  { WMF_FONT_SET_WIDTH (font,WMF_FONT_HEIGHT (font));
3341
362
  }
3342
3343
651
  name_record = OffsetRecord (API,Record,9);
3344
3345
651
  length = (name_record.size) * 2;
3346
3347
651
  fontname = (char*) wmf_malloc (API,length + 1);
3348
3349
651
  if (ERR (API))
3350
9
  { WMF_DEBUG (API,"bailing...");
3351
9
    return (changed);
3352
9
  }
3353
3354
642
  par_U16 = 0;
3355
18.9k
  for (i = 0; i < length; i++)
3356
18.3k
  { if (i & 1)
3357
9.16k
    { fontname[i] = (par_U16 >> 8) & 0xff;
3358
9.16k
    }
3359
9.16k
    else
3360
9.16k
    { par_U16 = ParU16 (API,&name_record,i/2);
3361
9.16k
      fontname[i] = par_U16 & 0xff;
3362
9.16k
    }
3363
18.3k
  }
3364
642
  fontname[length] = '\0';
3365
3366
642
  WMF_FONT_SET_NAME (font,fontname); /* must not free fontname */
3367
3368
642
  font->user_data = 0;
3369
3370
642
  FD->map (API,font); /* Determine/Load freetype face */
3371
3372
642
  if (ERR (API))
3373
0
  { WMF_DEBUG (API,"bailing...");
3374
0
    return (changed);
3375
0
  }
3376
3377
642
  WMF_DC_SET_FONT (P->dc,font);
3378
3379
642
  return (changed);
3380
642
}
3381
3382
static int meta_palette_create (wmfAPI* API)
3383
99
{ int changed = 0;
3384
3385
99
  wmfPlayer_t* P  = (wmfPlayer_t*) API->player_data;
3386
3387
99
  wmfObject* objects = 0;
3388
3389
99
  unsigned long i;
3390
3391
99
  objects = P->objects;
3392
3393
99
  i = 0;
3394
1.01k
  while ((i < NUM_OBJECTS (API)) && objects[i].type) i++;
3395
3396
99
  if (i == NUM_OBJECTS (API))
3397
1
  { WMF_ERROR (API,"Object out of range!");
3398
1
    API->err = wmf_E_BadFormat;
3399
1
    return (changed);
3400
1
  }
3401
3402
98
  objects[i].type = OBJ_PAL;
3403
3404
98
  return (changed);
3405
99
}
3406
3407
static int meta_delete (wmfAPI* API,wmfRecord* Record)
3408
6.00k
{ int changed = 0;
3409
3410
6.00k
  wmfPlayer_t*          P  = (wmfPlayer_t*)          API->player_data;
3411
6.00k
  wmfFunctionReference* FR = (wmfFunctionReference*) API->function_reference;
3412
3413
6.00k
  wmfObject* objects;
3414
6.00k
  wmfObject* obj;
3415
3416
6.00k
  U16 oid;
3417
3418
6.00k
  objects = P->objects;
3419
3420
6.00k
  if (SCAN (API) && DIAG (API))
3421
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
3422
0
    fprintf (stderr,"\t#par=%lu; max. index = 0",Record->size);
3423
0
  }
3424
3425
6.00k
  oid = ParU16 (API,Record,0);
3426
3427
6.00k
  if (oid >= NUM_OBJECTS (API))
3428
5
  { WMF_ERROR (API,"Object out of range!");
3429
5
    API->err = wmf_E_BadFormat;
3430
5
    return (changed);
3431
5
  }
3432
3433
5.99k
  obj = objects + oid;
3434
3435
5.99k
  if (SCAN (API) && DIAG (API))
3436
0
  { diagnose_object (API,(unsigned int) oid,obj);
3437
0
  }
3438
3439
5.99k
  if (obj->type == OBJ_BRUSH)
3440
4.20k
  { if (obj->obj.brush.lbStyle == BS_DIBPATTERN)
3441
60
    { if (PLAY (API) && FR->bmp_free) FR->bmp_free (API,&(obj->obj.brush.bmp));
3442
60
    }
3443
4.20k
  }
3444
1.79k
  else if (obj->type == OBJ_REGION)
3445
0
  { wmf_free (API,obj->obj.rgn.rects);
3446
0
  }
3447
3448
5.99k
  obj->type = 0;
3449
3450
5.99k
  return (changed);
3451
6.00k
}
3452
3453
static int meta_unused (wmfAPI* API,wmfRecord* Record)
3454
56.9k
{ int changed = 0;
3455
3456
56.9k
  if (SCAN (API) && DIAG (API))
3457
0
  { fprintf (stderr,"\t[0x%04x]",Record->function);
3458
0
    fprintf (stderr,"\t#par=%lu; max. index = ?",Record->size);
3459
0
  }
3460
3461
  /* META_SETSTRETCHBLTMODE: not all that important really */
3462
3463
  /* META_SETMAPPERFLAGS:
3464
extract from http://www.melander.dk/lib/windows/gdi/fontmap.htm
3465
          {
3466
          Windows Font Mapping
3467
3468
          Ron Gery 
3469
          Microsoft Developer Network Technology Group 
3470
3471
          Created: June 8, 1992 
3472
3473
          Filters
3474
3475
An application can, to some extent, filter which physical fonts are examined by the font mapper. 
3476
Aspect-ratio filtering, which is available in both Windows versions 3.0 and 3.1, allows an 
3477
application to specify that only fonts designed for the device's aspect ratio should be considered 
3478
by the font mapper. An application enables and disables this filter by using the SetMapperFlags 
3479
function. Because nonscaling raster fonts are designed with a certain aspect ratio in mind, it is 
3480
sometimes desirable to ensure that only fonts actually designed for the device are used. When this 
3481
filter is enabled, the font mapper does not consider any physical fonts whose design aspect ratio 
3482
does not match that of the device. Aspect-ratio filtering does not affect TrueType fonts because 
3483
they can scale to match any aspect ratio. This filter affects all font selections to the DC until 
3484
the filter is turned off. Aspect-ratio filtering is a holdover from earlier times and is not a 
3485
recommended approach in today's font world. 
3486
          }
3487
3488
  So we're going to ignore this call entirely */
3489
3490
  /* META_REALIZEPALETTE:
3491
     META_SELECTPALETTE:
3492
     META_SETPALENTRIES:
3493
  as these set and fiddle with the palette i don't think
3494
  they have much relevence to our converter, we will
3495
  do our own color management elsewhere (if we do it
3496
  at all), so i think we can safely ignore these things. */
3497
3498
  /* META_ESCAPE: ?? */
3499
3500
56.9k
  return (changed);
3501
56.9k
}
3502
3503
static void diagnose_object (wmfAPI* API,unsigned int oid,wmfObject* obj)
3504
0
{ fprintf (stderr,"\toid=%u / %u ",(unsigned) oid,(unsigned) NUM_OBJECTS (API));
3505
3506
0
  switch (obj->type)
3507
0
  {
3508
0
  case OBJ_BRUSH:
3509
0
    fprintf (stderr,"(brush)");
3510
0
  break;
3511
3512
0
  case OBJ_PEN:
3513
0
    fprintf (stderr,"(pen)");
3514
0
  break;
3515
3516
0
  case OBJ_FONT:
3517
0
    fprintf (stderr,"(font)");
3518
0
  break;
3519
3520
0
  case OBJ_REGION:
3521
0
    fprintf (stderr,"(region)");
3522
0
  break;
3523
3524
0
  case OBJ_PAL:
3525
0
    fprintf (stderr,"(palette)");
3526
0
  break;
3527
3528
0
  default:
3529
    fprintf (stderr,"(other [%u])",(unsigned) obj->type);
3530
0
  break;
3531
0
  }
3532
0
}
3533
3534
#endif /* ! WMFPLAYER_META_H */