EMF  1.0
libemf.h
1 /* -*- c++ -*-
2  * EMF: A library for generating ECMA-234 Enhanced Metafiles
3  * Copyright (C) 2002, 2003 lignum Computing, Inc. <dallenbarnett@users.sourceforge.net>
4  * $Id: libemf.h 106 2026-04-18 11:59:51Z dallenbarnett $
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 #ifndef _LIBEMF_H
22 #define _LIBEMF_H 1
23 
24 #include <cmath>
25 #include <vector>
26 #include <map>
27 #include <algorithm>
28 #include <stdexcept>
29 #include <memory>
30 
31 #include <config.h>
32 #include <libEMF/emf.h>
33 
34 #include <libEMF/wine/w16.h>
35 
36 #ifdef ENABLE_EDITING
37 #include <iconv.h>
38 #include <errno.h>
39 #endif
40 
41 #define EMF_UNUSED(x) (void)x;
42 
43 namespace EMF {
48 #if 1
49  const int XMAX_PIXELS = 1024; /*(INT_MAX)*/
50 #else
51  const int XMAX_PIXELS = 1280; /*(INT_MAX)*/
52 #endif
57 #if 1
58  const int YMAX_PIXELS = 768; /*(INT_MAX)*/
59 #else
60  const int YMAX_PIXELS = 1024; /*(INT_MAX)*/
61 #endif
67  const int XMAX_MM = 320;
73  const int YMAX_MM = 240;
77  const int RESOLUTION = 96;
81  static inline DWORD ROUND_TO_LONG ( DWORD n ) { return ((n+3)/4)*4; }
82 
83  static bool bigEndian ( void );
84 
86 
91  struct WCHARSTR {
92  WCHAR *const string_;
93  const int length_;
99  WCHARSTR ( WCHAR *const string, const int length )
100  : string_( string ), length_( length ) {}
101  };
102 
104 
109  struct CHARSTR {
110  CHAR *const string_;
111  const int length_;
117  CHARSTR ( CHAR *const string, const int length )
118  : string_( string ), length_( length ) {}
119  };
120 
122 
126  struct BYTEARRAY {
127  BYTE *const array_;
128  const int n_;
134  BYTEARRAY ( BYTE *const array, const int n )
135  : array_( array ), n_( n ) {}
136  };
137 
139 
142  struct POINTLARRAY {
143  POINTL *const points_;
144  const DWORD n_;
150  POINTLARRAY ( POINTL *const points, const DWORD n )
151  : points_( points ), n_( n ) {}
152  };
153 
155 
158  struct POINT16ARRAY {
159  POINT16 *const points_;
160  const DWORD n_;
166  POINT16ARRAY ( POINT16 *const points, const DWORD n )
167  : points_( points ), n_( n ) {}
168  };
169 
171 
174  struct INTARRAY {
175  INT *const ints_;
176  const DWORD n_;
182  INTARRAY ( INT *const ints, const DWORD n )
183  : ints_( ints ), n_( n ) {}
184  };
185 
187 
190  struct DWORDARRAY {
191  DWORD *const dwords_;
192  const DWORD n_;
198  DWORDARRAY ( DWORD *const dwords, const DWORD n )
199  : dwords_( dwords ), n_( n ) {}
200  };
201 
203 
206  struct PADDING {
207  static const char padding_[4];
208  const int size_;
213  PADDING ( const int size ) : size_( size ) {}
214  };
215 
217 
224  class DATASTREAM {
225  bool swap_;
226  ::FILE* fp_;
227  public:
233  DATASTREAM ( ::FILE* fp = 0 ) : swap_( bigEndian() ), fp_( fp ) {}
238  void setStream ( ::FILE* fp ) { fp_ = fp; }
243  DATASTREAM& operator<< ( const BYTE& byte )
244  {
245  fwrite( &byte, sizeof(BYTE), 1, fp_ );
246  return *this;
247  }
252  DATASTREAM& operator>> ( BYTE& byte )
253  {
254  fread( &byte, sizeof(BYTE), 1, fp_ );
255  return *this;
256  }
261  DATASTREAM& operator<< ( const WORD& word )
262  {
263  if ( swap_ ) {
264  unsigned char const * p = (unsigned char const*)&word;
265  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
266  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
267  }
268  else
269  fwrite( &word, sizeof(WORD), 1, fp_ );
270  return *this;
271  }
276  DATASTREAM& operator>> ( WORD& word )
277  {
278  if ( swap_ ) {
279  unsigned char* p = (unsigned char*)&word;
280  fread( &p[1], sizeof(unsigned char), 1, fp_ );
281  fread( &p[0], sizeof(unsigned char), 1, fp_ );
282  }
283  else
284  fread( &word, sizeof(WORD), 1, fp_ );
285  return *this;
286  }
291  DATASTREAM& operator<< ( const INT16& word )
292  {
293  if ( swap_ ) {
294  unsigned char const * p = (unsigned char const*)&word;
295  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
296  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
297  }
298  else
299  fwrite( &word, sizeof(INT16), 1, fp_ );
300  return *this;
301  }
306  DATASTREAM& operator>> ( INT16& word )
307  {
308  if ( swap_ ) {
309  unsigned char* p = (unsigned char*)&word;
310  fread( &p[1], sizeof(unsigned char), 1, fp_ );
311  fread( &p[0], sizeof(unsigned char), 1, fp_ );
312  }
313  else
314  fread( &word, sizeof(INT16), 1, fp_ );
315  return *this;
316  }
321  DATASTREAM& operator<< ( const DWORD& dword )
322  {
323  if ( swap_ ) {
324  unsigned char const* p = (unsigned char const*)&dword;
325  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
326  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
327  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
328  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
329  }
330  else
331  fwrite( &dword, sizeof(DWORD), 1, fp_ );
332  return *this;
333  }
338  DATASTREAM& operator>> ( DWORD& dword )
339  {
340  if ( swap_ ) {
341  unsigned char* p = (unsigned char*)&dword;
342  fread( &p[3], sizeof(unsigned char), 1, fp_ );
343  fread( &p[2], sizeof(unsigned char), 1, fp_ );
344  fread( &p[1], sizeof(unsigned char), 1, fp_ );
345  fread( &p[0], sizeof(unsigned char), 1, fp_ );
346  }
347  else
348  fread( &dword, sizeof(DWORD), 1, fp_ );
349  return *this;
350  }
351 #if !defined( __LP64__ )
356  DATASTREAM& operator<< ( const LONG& long_ )
357  {
358  if ( swap_ ) {
359  unsigned char const* p = (unsigned char const*)&long_;
360  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
361  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
362  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
363  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
364  }
365  else
366  fwrite( &long_, sizeof(LONG), 1, fp_ );
367  return *this;
368  }
373  DATASTREAM& operator>> ( LONG& long_ )
374  {
375  if ( swap_ ) {
376  unsigned char* p = (unsigned char*)&long_;
377  fread( &p[3], sizeof(unsigned char), 1, fp_ );
378  fread( &p[2], sizeof(unsigned char), 1, fp_ );
379  fread( &p[1], sizeof(unsigned char), 1, fp_ );
380  fread( &p[0], sizeof(unsigned char), 1, fp_ );
381  }
382  else
383  fread( &long_, sizeof(LONG), 1, fp_ );
384  return *this;
385  }
386 #endif /* __x86_64__ */
391  DATASTREAM& operator<< ( const INT& int_ )
392  {
393  if ( swap_ ) {
394  unsigned char const* p = (unsigned char const*)&int_;
395  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
396  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
397  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
398  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
399  }
400  else
401  fwrite( &int_, sizeof(INT), 1, fp_ );
402  return *this;
403  }
408  DATASTREAM& operator>> ( INT& int_ )
409  {
410  if ( swap_ ) {
411  unsigned char* p = (unsigned char*)&int_;
412  fread( &p[3], sizeof(unsigned char), 1, fp_ );
413  fread( &p[2], sizeof(unsigned char), 1, fp_ );
414  fread( &p[1], sizeof(unsigned char), 1, fp_ );
415  fread( &p[0], sizeof(unsigned char), 1, fp_ );
416  }
417  else
418  fread( &int_, sizeof(INT), 1, fp_ );
419  return *this;
420  }
421 #if !defined(__LP64__)
426  DATASTREAM& operator<< ( const UINT& uint )
427  {
428  if ( swap_ ) {
429  unsigned char const* p = (unsigned char const*)&uint;
430  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
431  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
432  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
433  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
434  }
435  else
436  fwrite( &uint, sizeof(UINT), 1, fp_ );
437  return *this;
438  }
443  DATASTREAM& operator>> ( UINT& uint )
444  {
445  if ( swap_ ) {
446  unsigned char* p = (unsigned char*)&uint;
447  fread( &p[3], sizeof(unsigned char), 1, fp_ );
448  fread( &p[2], sizeof(unsigned char), 1, fp_ );
449  fread( &p[1], sizeof(unsigned char), 1, fp_ );
450  fread( &p[0], sizeof(unsigned char), 1, fp_ );
451  }
452  else
453  fread( &uint, sizeof(UINT), 1, fp_ );
454  return *this;
455  }
456 #endif /* !__x86_64__ */
461  DATASTREAM& operator<< ( const FLOAT& float_ )
462  {
463  if ( swap_ ) {
464  unsigned char const* p = (unsigned char const*)&float_;
465  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
466  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
467  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
468  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
469  }
470  else
471  fwrite( &float_, sizeof(FLOAT), 1, fp_ );
472  return *this;
473  }
478  DATASTREAM& operator>> ( FLOAT& float_ )
479  {
480  if ( swap_ ) {
481  unsigned char* p = (unsigned char*)&float_;
482  fread( &p[3], sizeof(unsigned char), 1, fp_ );
483  fread( &p[2], sizeof(unsigned char), 1, fp_ );
484  fread( &p[1], sizeof(unsigned char), 1, fp_ );
485  fread( &p[0], sizeof(unsigned char), 1, fp_ );
486  }
487  else
488  fread( &float_, sizeof(FLOAT), 1, fp_ );
489  return *this;
490  }
495  DATASTREAM& operator<< ( const PADDING& padding )
496  {
497  if ( padding.size_ != 0 )
498  fwrite( &padding.padding_, sizeof(CHAR), padding.size_, fp_ );
499  return *this;
500  }
505  DATASTREAM& operator<< ( const RECTL& rectl )
506  {
507  *this << rectl.left << rectl.top << rectl.right << rectl.bottom;
508  return *this;
509  }
514  DATASTREAM& operator>> ( RECTL& rectl )
515  {
516  *this >> rectl.left >> rectl.top >> rectl.right >> rectl.bottom;
517  return *this;
518  }
523  DATASTREAM& operator<< ( const SIZEL& sizel )
524  {
525  *this << sizel.cx << sizel.cy;
526  return *this;
527  }
532  DATASTREAM& operator>> ( SIZEL& sizel )
533  {
534  *this >> sizel.cx >> sizel.cy;
535  return *this;
536  }
541  DATASTREAM& operator<< ( const WCHARSTR& wcharstr )
542  {
543  for ( int i = 0; i < wcharstr.length_; i++ )
544  *this << wcharstr.string_[i];
545  return *this;
546  }
552  {
553  for ( int i = 0; i < wcharstr.length_; i++ )
554  *this >> wcharstr.string_[i];
555  return *this;
556  }
561  DATASTREAM& operator<< ( const CHARSTR& charstr )
562  {
563  fwrite( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
564  return *this;
565  }
571  {
572  fread( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
573  return *this;
574  }
579  DATASTREAM& operator<< ( const ::EMR& emr )
580  {
581  *this << emr.iType << emr.nSize;
582  return *this;
583  }
588  DATASTREAM& operator>> ( ::EMR& emr )
589  {
590  *this >> emr.iType >> emr.nSize;
591  return *this;
592  }
597  DATASTREAM& operator<< ( const POINT& point )
598  {
599  *this << point.x << point.y;
600  return *this;
601  }
606  DATASTREAM& operator>> ( POINT& point )
607  {
608  *this >> point.x >> point.y;
609  return *this;
610  }
615  DATASTREAM& operator<< ( const POINTL& pointl )
616  {
617  *this << pointl.x << pointl.y;
618  return *this;
619  }
624  DATASTREAM& operator>> ( POINTL& pointl )
625  {
626  *this >> pointl.x >> pointl.y;
627  return *this;
628  }
633  DATASTREAM& operator<< ( const POINT16& point )
634  {
635  *this << point.x << point.y;
636  return *this;
637  }
642  DATASTREAM& operator>> ( POINT16& point )
643  {
644  *this >> point.x >> point.y;
645  return *this;
646  }
651  DATASTREAM& operator<< ( const XFORM& xform )
652  {
653  *this << xform.eM11 << xform.eM12 << xform.eM21 << xform.eM22
654  << xform.eDx << xform.eDy;
655  return *this;
656  }
661  DATASTREAM& operator>> ( XFORM& xform )
662  {
663  *this >> xform.eM11 >> xform.eM12 >> xform.eM21 >> xform.eM22
664  >> xform.eDx >> xform.eDy;
665  return *this;
666  }
672  {
673  fwrite( array.array_, sizeof(BYTE), array.n_, fp_ );
674  return *this;
675  }
681  {
682  fread( array.array_, sizeof(BYTE), array.n_, fp_ );
683  return *this;
684  }
690  {
691  for ( unsigned int i = 0; i < array.n_; i++ )
692  *this << array.points_[i];
693  return *this;
694  }
700  {
701  for ( unsigned int i = 0; i < array.n_; i++ )
702  *this >> array.points_[i];
703  return *this;
704  }
710  {
711  for ( unsigned int i = 0; i < array.n_; i++ )
712  *this << array.points_[i];
713  return *this;
714  }
720  {
721  for ( unsigned int i = 0; i < array.n_; i++ )
722  *this >> array.points_[i];
723  return *this;
724  }
729  DATASTREAM& operator<< ( const INTARRAY& array )
730  {
731  for ( unsigned int i = 0; i < array.n_; i++ )
732  *this << array.ints_[i];
733  return *this;
734  }
740  {
741  for ( unsigned int i = 0; i < array.n_; i++ )
742  *this >> array.ints_[i];
743  return *this;
744  }
750  {
751  for ( unsigned int i = 0; i < array.n_; i++ )
752  *this << array.dwords_[i];
753  return *this;
754  }
760  {
761  for ( unsigned int i = 0; i < array.n_; i++ )
762  *this >> array.dwords_[i];
763  return *this;
764  }
769  DATASTREAM& operator<< ( const ::EMRTEXT& text )
770  {
771  *this << text.ptlReference << text.nChars << text.offString << text.fOptions
772  << text.rcl << text.offDx;
773  return *this;
774  }
779  DATASTREAM& operator>> ( ::EMRTEXT& text )
780  {
781  *this >> text.ptlReference >> text.nChars >> text.offString >> text.fOptions
782  >> text.rcl >> text.offDx;
783  return *this;
784  }
789  DATASTREAM& operator<< ( const LOGPEN& pen )
790  {
791  *this << pen.lopnStyle << pen.lopnWidth << pen.lopnColor;
792  return *this;
793  }
798  DATASTREAM& operator>> ( LOGPEN& pen )
799  {
800  *this >> pen.lopnStyle >> pen.lopnWidth >> pen.lopnColor;
801  return *this;
802  }
807  DATASTREAM& operator<< ( const EXTLOGPEN& pen )
808  {
809  // *** How big is this structure if there are no style entries? ***
810  *this << pen.elpPenStyle << pen.elpWidth << pen.elpBrushStyle << pen.elpColor
811  << pen.elpHatch << pen.elpNumEntries;
812  return *this;
813  }
818  DATASTREAM& operator>> ( EXTLOGPEN& pen )
819  {
820  // *** How big is this structure if there are no style entries? ***
821  *this >> pen.elpPenStyle >> pen.elpWidth >> pen.elpBrushStyle >> pen.elpColor
822  >> pen.elpHatch >> pen.elpNumEntries;
823  return *this;
824  }
829  DATASTREAM& operator<< ( const LOGBRUSH& brush )
830  {
831  *this << brush.lbStyle << brush.lbColor << brush.lbHatch;
832  return *this;
833  }
838  DATASTREAM& operator>> ( LOGBRUSH& brush )
839  {
840  *this >> brush.lbStyle >> brush.lbColor >> brush.lbHatch;
841  return *this;
842  }
847  DATASTREAM& operator<< ( const LOGFONTW& font )
848  {
849  *this << font.lfHeight << font.lfWidth << font.lfEscapement
850  << font.lfOrientation << font.lfWeight << font.lfItalic
851  << font.lfUnderline << font.lfStrikeOut << font.lfCharSet
852  << font.lfOutPrecision << font.lfClipPrecision << font.lfQuality
853  << font.lfPitchAndFamily
854  << WCHARSTR( const_cast<WCHAR*>(font.lfFaceName), LF_FACESIZE );
855  return *this;
856  }
861  DATASTREAM& operator>> ( LOGFONTW& font )
862  {
863  WCHARSTR wFaceName( font.lfFaceName, LF_FACESIZE );
864 
865  *this >> font.lfHeight >> font.lfWidth >> font.lfEscapement
866  >> font.lfOrientation >> font.lfWeight >> font.lfItalic
867  >> font.lfUnderline >> font.lfStrikeOut >> font.lfCharSet
868  >> font.lfOutPrecision >> font.lfClipPrecision >> font.lfQuality
869  >> font.lfPitchAndFamily
870  >> wFaceName;
871  return *this;
872  }
877  DATASTREAM& operator<< ( const PANOSE& panose )
878  {
879  fwrite( &panose, sizeof(PANOSE), 1, fp_ );
880  return *this;
881  }
886  DATASTREAM& operator>> ( PANOSE& panose )
887  {
888  fread( &panose, sizeof(PANOSE), 1, fp_ );
889  return *this;
890  }
895  DATASTREAM& operator<< ( const EXTLOGFONTW& font )
896  {
897  *this << font.elfLogFont
898  << WCHARSTR( const_cast<WCHAR*>(font.elfFullName),
899  LF_FULLFACESIZE )
900  << WCHARSTR( const_cast<WCHAR*>(font.elfStyle), LF_FACESIZE )
901  << font.elfVersion << font.elfStyleSize << font.elfMatch
902  << font.elfReserved
903  << BYTEARRAY( const_cast<BYTE*>(font.elfVendorId),
904  ELF_VENDOR_SIZE )
905  << font.elfCulture << font.elfPanose;
906  return *this;
907  }
912  DATASTREAM& operator>> ( EXTLOGFONTW& font )
913  {
914  WCHARSTR wFullName( font.elfFullName, LF_FULLFACESIZE );
915  WCHARSTR wStyle( font.elfStyle, LF_FACESIZE );
916  BYTEARRAY bVendorId( font.elfVendorId, ELF_VENDOR_SIZE );
917  *this >> font.elfLogFont
918  >> wFullName >> wStyle
919  >> font.elfVersion >> font.elfStyleSize >> font.elfMatch
920  >> font.elfReserved >> bVendorId
921  >> font.elfCulture >> font.elfPanose;
922  return *this;
923  }
928  DATASTREAM& operator<< ( const LOGPALETTE& palette )
929  {
930  // *** How big is this structure if the palette is empty? ***
931  *this << palette.palVersion << palette.palNumEntries;
932  return *this;
933  }
938  DATASTREAM& operator>> ( LOGPALETTE& palette )
939  {
940  // *** How big is this structure if the palette is empty? ***
941  *this >> palette.palVersion >> palette.palNumEntries;
942  return *this;
943  }
944  private:
954  void fread ( void* ptr, size_t size, size_t nmemb, FILE* stream )
955  {
956  size_t res = ::fread( ptr, size, nmemb, stream );
957  if ( res < nmemb ) {
958  throw std::runtime_error( "Premature EOF on EMF stream" );
959  }
960  }
970  void fwrite ( const void* ptr, size_t size, size_t nmemb, FILE* stream )
971  {
972  size_t res = ::fwrite( ptr, size, nmemb, stream );
973  if ( res < nmemb ) {
974  throw std::runtime_error( "error writing EMF stream" );
975  }
976  }
977  };
978 
979  class METAFILEDEVICECONTEXT;
980 
982 
988  class METARECORD {
989  public:
996  virtual void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const = 0;
1003  virtual bool serialize ( DATASTREAM ds ) = 0;
1009  virtual int size ( void ) const = 0;
1015  virtual ~METARECORD( ) { }
1016 #ifdef ENABLE_EDITING
1021  virtual void edit ( void ) const {}
1022 #endif
1023  };
1024 
1025 #ifdef ENABLE_EDITING
1026  /* Miscellaneous editing routines */
1027  inline void edit_rectl ( const char* tag, const RECTL& rectl )
1028  {
1029 #if defined(__LP64__)
1030  const char* FMT = "\t%s\t: (%d, %d) - (%d, %d)\n";
1031 #else
1032  const char* FMT = "\t%s\t: (%ld, %ld) - (%ld, %ld)\n";
1033 #endif /* __x86_64__ */
1034  printf( FMT, tag, rectl.left, rectl.top, rectl.right, rectl.bottom );
1035  }
1036 
1037  inline void edit_xform ( const char* tag, const XFORM& xform )
1038  {
1039  printf( "\t%s.eM11\t: %f\n", tag, xform.eM11 );
1040  printf( "\t%s.eM12\t: %f\n", tag, xform.eM12 );
1041  printf( "\t%s.eM21\t: %f\n", tag, xform.eM21 );
1042  printf( "\t%s.eM22\t: %f\n", tag, xform.eM22 );
1043  printf( "\t%s.eDx\t: %f\n", tag, xform.eDx );
1044  printf( "\t%s.eDy\t: %f\n", tag, xform.eDy );
1045  }
1046 
1047  inline void edit_color ( const char* tag, const COLORREF& color )
1048  {
1049 #if defined(__LP64__)
1050  const char* FMT = "\t%s\t: R(0x%02x) G(0x%02x) B(0x%02x)\n";
1051 #else
1052  const char* FMT = "\t%s\t: R(0x%02lx) G(0x%02lx) B(0x%02lx)\n";
1053 #endif /* __x86_64__ */
1054  printf( FMT, tag,
1055  GetRValue( color ), GetGValue( color ), GetBValue( color ) );
1056  }
1057 
1058  inline void edit_sizel ( const char* tag, const SIZEL& size )
1059  {
1060 #if defined(__LP64__)
1061  const char* FMT = "\t%s\t: (%d, %d)\n";
1062 #else
1063  const char* FMT = "\t%s\t: (%ld, %ld)\n";
1064 #endif /* __x86_64__ */
1065  printf( FMT, tag, size.cx, size.cy );
1066  }
1067 
1068  inline void edit_pointl ( const char* tag, const POINTL& point )
1069  {
1070 #if defined(__LP64__)
1071  const char* FMT = "\t%s\t: (%d, %d)\n";
1072 #else
1073  const char* FMT = "\t%s\t: (%ld, %ld)\n";
1074 #endif /* __x86_64__ */
1075  printf( FMT, tag, point.x, point.y );
1076  }
1077 
1078  inline void edit_pointlarray ( const char* tag, const DWORD cptl,
1079  const POINTL* points )
1080  {
1081 #if defined(__LP64__)
1082  const char* FMT0 = "\tcptl%s\t: %d\n";
1083  const char* FMT1 = "%d, %d\n";
1084  const char* FMT2 = "\t\t%s %d, %d\n";
1085 #else
1086  const char* FMT0 = "\tcptl%s\t: %ld\n";
1087  const char* FMT1 = "%ld, %ld\n";
1088  const char* FMT2 = "\t\t%s %ld, %ld\n";
1089 #endif /* __x86_64__ */
1090  printf( FMT0, tag, cptl );
1091  printf( "\taptl%s\t: ", tag );
1092  if ( cptl > 0 )
1093  printf( FMT1, points[0].x, points[0].y );
1094  else
1095  puts( "" );
1096  for ( DWORD i = 1; i < cptl; i++ )
1097  printf( FMT2, tag, points[i].x, points[i].y );
1098  }
1099 
1100  inline void edit_point16array ( const char* tag, const unsigned int cpts,
1101  const POINT16* points )
1102  {
1103  printf( "\tcpts%s\t: %d\n", tag, cpts );
1104  printf( "\tapts%s\t: ", tag );
1105  if ( cpts > 0 )
1106  printf( "%d, %d\n", points[0].x, points[0].y );
1107  else
1108  puts( "" );
1109  for ( unsigned int i = 1; i < cpts; i++ )
1110  printf( "\t\t%s %d, %d\n", tag, points[i].x, points[i].y );
1111  }
1112 
1113  inline void edit_pen_style ( const char* tag, DWORD style )
1114  {
1115  printf( "\t%s\t: ", tag );
1116  switch ( style & PS_STYLE_MASK ) {
1117  case PS_SOLID: printf( "PS_SOLID" ); break;
1118  case PS_DASH: printf( "PS_DASH" ); break;
1119  case PS_DOT: printf( "PS_DOT" ); break;
1120  case PS_DASHDOT: printf( "PS_DASHDOT" ); break;
1121  case PS_DASHDOTDOT: printf( "PS_DASHDOTDOT" ); break;
1122  case PS_NULL: printf( "PS_NULL" ); break;
1123  case PS_INSIDEFRAME: printf( "PS_INSIDEFRAME" ); break;
1124  case PS_USERSTYLE: printf( "PS_USERSTYLE" ); break;
1125  case PS_ALTERNATE: printf( "PS_ALTERNATE" ); break;
1126  }
1127  switch ( style & PS_ENDCAP_MASK ) {
1128  case PS_ENDCAP_ROUND: printf( " | PS_ENDCAP_ROUND" ); break;
1129  case PS_ENDCAP_SQUARE: printf( " | PS_ENDCAP_SQUARE" ); break;
1130  case PS_ENDCAP_FLAT: printf( " | PS_ENDCAP_FLAT" ); break;
1131  }
1132  switch ( style & PS_JOIN_MASK ) {
1133  case PS_JOIN_ROUND: printf( " | PS_JOIN_ROUND" ); break;
1134  case PS_JOIN_BEVEL: printf( " | PS_JOIN_BEVEL" ); break;
1135  case PS_JOIN_MITER: printf( " | PS_JOIN_MITER" ); break;
1136  }
1137  switch ( style & PS_TYPE_MASK ) {
1138  case PS_COSMETIC: printf( " | PS_COSMETIC" ); break;
1139  case PS_GEOMETRIC: printf( " | PS_GEOMETRIC" ); break;
1140  }
1141  printf( "\n" );
1142  }
1143 
1144  inline void edit_brush_style ( const char* tag, DWORD style )
1145  {
1146 #if defined(__LP64__)
1147  const char* FMT = "unknown(%d)";
1148 #else
1149  const char* FMT = "unknown(%ld)";
1150 #endif /* __x86_64__ */
1151  printf( "\t%s\t: ", tag );
1152  switch ( style ) {
1153  case BS_SOLID: printf( "BS_SOLID" ); break;
1154  case BS_NULL: printf( "BS_NULL" ); break;
1155  case BS_HATCHED: printf( "BS_HATCHED" ); break;
1156  case BS_PATTERN: printf( "BS_PATTERN" ); break;
1157  case BS_INDEXED: printf( "BS_INDEXED" ); break;
1158  case BS_DIBPATTERN: printf( "BS_DIBPATTERN" ); break;
1159  case BS_DIBPATTERNPT: printf( "BS_DIBPATTERNPT" ); break;
1160  case BS_PATTERN8X8: printf( "BS_PATTERN8X8" ); break;
1161  case BS_DIBPATTERN8X8: printf( "BS_DIBPATTERN8X8" ); break;
1162  case BS_MONOPATTERN: printf( "BS_DIBPATTERN8X8" ); break;
1163  default: printf( FMT, style );
1164  }
1165  printf( "\n" );
1166  }
1167 
1168  inline void edit_brush_hatch ( const char* tag, DWORD hatch )
1169  {
1170 #if defined(__LP64__)
1171  const char* FMT = "unknown(%d)";
1172 #else
1173  const char* FMT = "unknown(%ld)";
1174 #endif /* __x86_64__ */
1175  printf( "\t%s\t: ", tag );
1176  switch ( hatch ) {
1177  case HS_HORIZONTAL: printf( "HS_HORIZONTAL" ); break;
1178  case HS_VERTICAL: printf( "HS_VERTICAL" ); break;
1179  case HS_FDIAGONAL: printf( "HS_FDIAGONAL" ); break;
1180  case HS_BDIAGONAL: printf( "HS_BDIAGONAL" ); break;
1181  case HS_CROSS: printf( "HS_CROSS" ); break;
1182  case HS_DIAGCROSS: printf( "HS_DIAGCROSS" ); break;
1183  default: printf( FMT, hatch );
1184  }
1185  printf( "\n" );
1186  }
1187 #endif
1195  enum OBJECTTYPE { O_METAFILEDEVICECONTEXT = OBJ_METADC,
1196  O_FONT = OBJ_FONT,
1197  O_PEN = OBJ_PEN,
1198  O_EXTPEN = OBJ_EXTPEN,
1199  O_BRUSH = OBJ_BRUSH,
1200  O_PALETTE = OBJ_PAL };
1201 #if 0
1205  static char* typStr ( OBJECTTYPE type )
1206  {
1207  switch (type) {
1208  case O_METAFILEDEVICECONTEXT:
1209  return "metafile device context";
1210  case O_FONT:
1211  return "font";
1212  case O_PEN:
1213  return "pen";
1214  case O_EXTPEN:
1215  return "extended pen";
1216  case O_BRUSH:
1217  return "brush";
1218  case O_PALETTE:
1219  return "palette";
1220  }
1221  return "unknown object";
1222  }
1223 #endif
1225 
1230  class OBJECT {
1231  public:
1232  HGDIOBJ handle;
1234  virtual ~OBJECT () {}
1239  OBJECT ( void ) : handle( 0 ) {}
1243  virtual OBJECTTYPE getType ( void ) const = 0;
1244  };
1245 
1247 
1252  class GRAPHICSOBJECT : public OBJECT {
1253  public:
1255  virtual ~GRAPHICSOBJECT () {}
1260  std::map< HDC, HGDIOBJ > contexts;
1267  virtual METARECORD* newEMR ( HDC dc, HGDIOBJ handle ) = 0;
1268  };
1269 
1270  typedef METARECORD*(*METARECORDCTOR)(DATASTREAM&);
1271 
1279  std::vector<OBJECT*> objects;
1280 
1287  std::map< DWORD, METARECORDCTOR > new_records;
1288 
1289  public:
1290  GLOBALOBJECTS ( void );
1291  ~GLOBALOBJECTS ( void );
1292  HGDIOBJ add ( OBJECT* object );
1293  OBJECT* find ( const HGDIOBJ handle );
1294  void remove ( const OBJECT* object );
1295 
1299  auto begin ( void ) const { return objects.begin(); }
1300 
1304  auto end ( void ) const { return objects.end(); }
1305 
1306  METARECORDCTOR newRecord ( DWORD iType ) const;
1307 
1309  static EMF::METARECORD* new_eof ( DATASTREAM& ds );
1331  static EMF::METARECORD* new_setbkcolor ( DATASTREAM& ds );
1333  static EMF::METARECORD* new_setbkmode ( DATASTREAM& ds );
1337  static EMF::METARECORD* new_setmapmode ( DATASTREAM& ds );
1343  static EMF::METARECORD* new_movetoex ( DATASTREAM& ds );
1345  static EMF::METARECORD* new_lineto ( DATASTREAM& ds );
1347  static EMF::METARECORD* new_arc ( DATASTREAM& ds );
1349  static EMF::METARECORD* new_arcto ( DATASTREAM& ds );
1351  static EMF::METARECORD* new_rectangle ( DATASTREAM& ds );
1353  static EMF::METARECORD* new_ellipse ( DATASTREAM& ds );
1355  static EMF::METARECORD* new_polyline ( DATASTREAM& ds );
1357  static EMF::METARECORD* new_polyline16 ( DATASTREAM& ds );
1359  static EMF::METARECORD* new_polygon ( DATASTREAM& ds );
1361  static EMF::METARECORD* new_polygon16 ( DATASTREAM& ds );
1363  static EMF::METARECORD* new_polypolygon ( DATASTREAM& ds );
1367  static EMF::METARECORD* new_polybezier ( DATASTREAM& ds );
1375  static EMF::METARECORD* new_polylineto ( DATASTREAM& ds );
1379  static EMF::METARECORD* new_exttextouta ( DATASTREAM& ds );
1381  static EMF::METARECORD* new_exttextoutw ( DATASTREAM& ds );
1383  static EMF::METARECORD* new_setpixelv ( DATASTREAM& ds );
1385  static EMF::METARECORD* new_createpen ( DATASTREAM& ds );
1393  static EMF::METARECORD* new_fillpath ( DATASTREAM& ds );
1395  static EMF::METARECORD* new_strokepath ( DATASTREAM& ds );
1399  static EMF::METARECORD* new_beginpath ( DATASTREAM& ds );
1401  static EMF::METARECORD* new_endpath ( DATASTREAM& ds );
1403  static EMF::METARECORD* new_closefigure ( DATASTREAM& ds );
1405  static EMF::METARECORD* new_savedc ( DATASTREAM& ds );
1407  static EMF::METARECORD* new_restoredc ( DATASTREAM& ds );
1409  static EMF::METARECORD* new_setmetargn ( DATASTREAM& ds );
1412  };
1413 
1414  extern GLOBALOBJECTS globalObjects;
1415 
1417 
1423  class ENHMETAHEADER : public METARECORD, public ::ENHMETAHEADER {
1424 
1425  LPWSTR description_w{ nullptr };
1426  int description_size{ 0 };
1427 
1428  public:
1435  ENHMETAHEADER ( LPCWSTR description = 0 )
1436  : description_w( 0 ), description_size( 0 )
1437  {
1438  iType = EMR_HEADER;
1439  nSize = sizeof( ::ENHMETAHEADER );
1440 
1441  // Compute the bounds
1442  RECTL default_bounds = { 0, 0, 0, 0 };
1443  rclBounds = default_bounds;
1444  RECTL default_frame = { 0, 0, 0, 0 };
1445  rclFrame = default_frame;
1446  dSignature = ENHMETA_SIGNATURE;
1447  nVersion = 0x10000;
1448  nBytes = nSize;
1449  nRecords = 1;
1450  nHandles = 0;
1451  sReserved = 0;
1452  nDescription = 0;
1453  offDescription = 0;
1454  nPalEntries = 0;
1455  szlDevice.cx = XMAX_PIXELS;
1456  szlDevice.cy = YMAX_PIXELS;
1457  szlMillimeters.cx = XMAX_MM;
1458  szlMillimeters.cy = YMAX_MM;
1459  //
1460  cbPixelFormat = 0;
1461  offPixelFormat = 0;
1462  bOpenGL = FALSE;
1463  //
1464 #if 1
1465  szlMicrometers.cx = 1000 * szlMillimeters.cx;
1466  szlMicrometers.cy = 1000 * szlMillimeters.cy;
1467 #endif
1468  if ( description ) {
1469  // Count the number of characters in the description
1470  int description_count = 0, nulls = 0;
1471  LPCWSTR description_p = description;
1472  while ( nulls < 3 ) {
1473  description_count++;
1474  if ( (*description_p++) == 0 ) nulls++;
1475  }
1476 
1477  // Make sure that the TOTAL record length will be a multiple of 4
1478 
1479  int record_size = ROUND_TO_LONG( sizeof( ::ENHMETAHEADER ) +
1480  sizeof( WCHAR ) * description_count );
1481  description_size =
1482  (record_size - sizeof( ::ENHMETAHEADER )) / sizeof( WCHAR );
1483 
1484  std::unique_ptr<WCHAR[]>
1485  description_tmp( new WCHAR[ description_size ] );
1486 
1487  description_w = description_tmp.release();
1488 
1489  memset( description_w, 0, sizeof(WCHAR) * description_size );
1490 
1491  for ( int i=0; i<description_count; i++ )
1492  description_w[i] = *description++;
1493 
1494  nSize = nBytes = record_size;
1495  nDescription = description_count;
1496  offDescription = sizeof( ::ENHMETAHEADER );
1497  }
1498  }
1499 
1504  {
1505  if ( description_w ) delete[] description_w;
1506  }
1511  bool serialize ( DATASTREAM ds )
1512  {
1513  ds << iType << nSize
1514  << rclBounds << rclFrame
1515  << dSignature << nVersion << nBytes << nRecords << nHandles << sReserved
1516  << nDescription << offDescription << nPalEntries
1517  << szlDevice << szlMillimeters
1518  << cbPixelFormat << offPixelFormat << bOpenGL
1519  << szlMicrometers
1520  << WCHARSTR( description_w, description_size );
1521  return true;
1522  }
1527  {
1528  ds >> iType >> nSize
1529  >> rclBounds >> rclFrame
1530  >> dSignature >> nVersion >> nBytes >> nRecords >> nHandles >> sReserved
1531  >> nDescription >> offDescription >> nPalEntries
1532  >> szlDevice >> szlMillimeters;
1533 
1534  // Some elements of the metafile header were added at later dates
1535 
1536 #define OffsetOf( a, b ) ((unsigned int)(((char*)&(((::ENHMETAHEADER*)a)->b)) - \
1537 (char*)((::ENHMETAHEADER*)a)))
1538  if ( OffsetOf( this, szlMicrometers ) <= offDescription )
1539  ds >> cbPixelFormat >> offPixelFormat >> bOpenGL;
1540 #undef OffsetOf
1541  if ( sizeof(::ENHMETAHEADER) <= offDescription )
1542  ds >> szlMicrometers;
1543 
1544  // Should now probably check that the offset is correct...
1545 
1546  int description_size_to_read = ( nSize - offDescription ) / sizeof(WCHAR);
1547 
1548  if ( description_size_to_read < (int)nDescription ) {
1549  throw std::runtime_error( "record size inconsistent with description size" );
1550  }
1551 
1552  description_size = max( 2, description_size_to_read );
1553 
1554  std::unique_ptr<WCHAR[]> buffer( new WCHAR[description_size] );
1555 
1556  WCHARSTR description( buffer.get(), description_size_to_read );
1557 
1558  ds >> description;
1559 
1560  description_w = buffer.release();
1561 
1562  // Make sure it's terminated properly.
1563  description_w[description_size-1] = 0;
1564  description_w[description_size-2] = 0;
1565 
1566  return true;
1567  }
1571  int size ( void ) const { return nSize; }
1577  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1578  {
1579  // Actually handled by the destination device context.
1580  EMF_UNUSED(source);
1581  EMF_UNUSED(dc);
1582  }
1583 #ifdef ENABLE_EDITING
1587  void edit ( void ) const
1588  {
1589 #if defined(__LP64__)
1590  const char* FMT0 = "\tiType\t\t\t: %d\n";
1591  const char* FMT1 = "\tnSize\t\t\t: %d\n";
1592  const char* FMT2 = "\tnBytes\t\t\t: %d\n";
1593  const char* FMT3 = "\tnRecords\t\t: %d\n";
1594  const char* FMT4 = "\tnDescription\t\t: %d\n";
1595  const char* FMT5 = "\toffDescription\t\t: %d\n";
1596  const char* FMT6 = "\tnPalEntries\t\t: %d\n";
1597  const char* FMT7 = "\tcbPixelFormat\t\t: %d\n";
1598  const char* FMT8 = "\toffPixelFormat\t\t: %d\n";
1599  const char* FMT9 = "\tbOpenGL\t\t\t: %d\n";
1600 #else
1601  const char* FMT0 = "\tiType\t\t\t: %ld\n";
1602  const char* FMT1 = "\tnSize\t\t\t: %ld\n";
1603  const char* FMT2 = "\tnBytes\t\t\t: %ld\n";
1604  const char* FMT3 = "\tnRecords\t\t: %ld\n";
1605  const char* FMT4 = "\tnDescription\t\t: %ld\n";
1606  const char* FMT5 = "\toffDescription\t\t: %ld\n";
1607  const char* FMT6 = "\tnPalEntries\t\t: %ld\n";
1608  const char* FMT7 = "\tcbPixelFormat\t\t: %ld\n";
1609  const char* FMT8 = "\toffPixelFormat\t\t: %ld\n";
1610  const char* FMT9 = "\tbOpenGL\t\t\t: %ld\n";
1611 #endif
1612  printf( "*HEADER*\n" );
1613  printf( FMT0, iType );
1614  printf( FMT1, nSize );
1615  edit_rectl( "rclBounds\t", rclBounds );
1616  edit_rectl( "rclFrame\t", rclFrame );
1617  printf( "\tdSignature\t\t: %.4s\n", (const char*)&dSignature );
1618  printf( "\tnVersion\t\t: 0x%x\n", (unsigned int)nVersion );
1619  printf( FMT2, nBytes );
1620  printf( FMT3, nRecords );
1621  printf( "\tnHandles\t\t: %d\n", nHandles );
1622  printf( FMT4, nDescription );
1623  printf( FMT5, offDescription );
1624  printf( FMT6, nPalEntries );
1625  edit_sizel( "szlDevice\t", szlDevice );
1626  edit_sizel( "szlMillimeters\t", szlMillimeters );
1627 
1628  /* Make a crude guess as to the age of this file */
1629 #define OffsetOf( a, b ) ((unsigned int)(((const char*)&(((const ::ENHMETAHEADER*)a)->b)) - \
1630 (const char*)((const ::ENHMETAHEADER*)a)))
1631 
1632  if ( OffsetOf( this, cbPixelFormat ) <= offDescription ) {
1633  printf( FMT7, cbPixelFormat );
1634  printf( FMT8, offPixelFormat );
1635  printf( FMT9, bOpenGL );
1636 #if 1
1637  if ( sizeof(::ENHMETAHEADER) <= offDescription ) {
1638  edit_sizel( "szlMicrometers\t", szlMicrometers );
1639  }
1640 #endif
1641  }
1642 
1643 #undef OffsetOf
1644 
1645  if ( nDescription != 0 ) {
1646 
1647  wchar_t last_w = 0;
1648  WCHAR* description = description_w;
1649 
1650  printf( "\tDescription:" );
1651 
1652  for ( DWORD i = 0; i < nDescription; i++ ) {
1653 
1654  wchar_t w = *description++; /* This is not true, really. UNICODE is not
1655  * glibc's wide character representation */
1656 
1657  if ( w != 0 ) {
1658  if ( last_w == 0 ) printf( "\n\t\t" );
1659  putchar( w );
1660  }
1661 
1662  last_w = w;
1663  }
1664  printf( "\n" );
1665  }
1666  }
1667 #endif /* ENABLE_EDITING */
1668  };
1669 
1671 
1676  class EMREOF : public METARECORD, ::EMREOF {
1677  public:
1681  EMREOF ( void )
1682  {
1683  emr.iType = EMR_EOF;
1684  emr.nSize = sizeof( ::EMREOF );
1685  nPalEntries = 0;
1686  offPalEntries = 0;
1687  nSizeLast = 0;
1688  }
1689 
1695  {
1696  ds >> emr >> nPalEntries >> offPalEntries >> nSizeLast;
1697  }
1698 
1702  bool serialize ( DATASTREAM ds )
1703  {
1704  ds << emr << nPalEntries << offPalEntries << nSizeLast;
1705  return true;
1706  }
1710  int size ( void ) const { return emr.nSize; }
1716  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1717  {
1718  // Actually handled by the destination device context.
1719  EMF_UNUSED(source);
1720  EMF_UNUSED(dc);
1721  }
1722 #ifdef ENABLE_EDITING
1726  void edit ( void ) const
1727  {
1728  printf( "*EOF*\n" );
1729  }
1730 #endif /* ENABLE_EDITING */
1731  };
1732 
1734 
1740  public:
1745  EMRSETVIEWPORTORGEX ( INT x, INT y )
1746  {
1747  emr.iType = EMR_SETVIEWPORTORGEX;
1748  emr.nSize = sizeof( ::EMRSETVIEWPORTORGEX );
1749  ptlOrigin.x = x;
1750  ptlOrigin.y = y;
1751  }
1757  {
1758  ds >> emr >> ptlOrigin;
1759  }
1763  bool serialize ( DATASTREAM ds )
1764  {
1765  ds << emr << ptlOrigin;
1766  return true;
1767  }
1771  int size ( void ) const { return emr.nSize; }
1777  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1778  {
1779  EMF_UNUSED(source);
1780  SetViewportOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
1781  }
1782 #ifdef ENABLE_EDITING
1786  void edit ( void ) const
1787  {
1788  printf( "*SETVIEWPORTORGEX*\n" );
1789  edit_pointl( "ptlOrigin", ptlOrigin );
1790  }
1791 #endif /* ENABLE_EDITING */
1792  };
1793 
1795 
1803  public:
1808  EMRSETWINDOWORGEX ( INT x, INT y )
1809  {
1810  emr.iType = EMR_SETWINDOWORGEX;
1811  emr.nSize = sizeof( ::EMRSETWINDOWORGEX );
1812  ptlOrigin.x = x;
1813  ptlOrigin.y = y;
1814  }
1820  {
1821  ds >> emr >> ptlOrigin;
1822  }
1826  bool serialize ( DATASTREAM ds )
1827  {
1828  ds << emr << ptlOrigin;
1829  return true;
1830  }
1834  int size ( void ) const { return emr.nSize; }
1840  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1841  {
1842  EMF_UNUSED(source);
1843  SetWindowOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
1844  }
1845 #ifdef ENABLE_EDITING
1849  void edit ( void ) const
1850  {
1851  printf( "*SETWINDOWORGEX*\n" );
1852  edit_pointl( "ptlOrigin", ptlOrigin );
1853  }
1854 #endif /* ENABLE_EDITING */
1855  };
1856 
1858 
1864  public:
1869  EMRSETVIEWPORTEXTEX ( INT cx, INT cy )
1870  {
1871  emr.iType = EMR_SETVIEWPORTEXTEX;
1872  emr.nSize = sizeof( ::EMRSETVIEWPORTEXTEX );
1873  szlExtent.cx = cx;
1874  szlExtent.cy = cy;
1875  }
1881  {
1882  ds >> emr >> szlExtent;
1883  }
1887  bool serialize ( DATASTREAM ds )
1888  {
1889  ds << emr << szlExtent;
1890  return true;
1891  }
1895  int size ( void ) const { return emr.nSize; }
1901  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1902  {
1903  EMF_UNUSED(source);
1904  SetViewportExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
1905  }
1906 #ifdef ENABLE_EDITING
1910  void edit ( void ) const
1911  {
1912  printf( "*SETVIEWPORTEXTEX*\n" );
1913  edit_sizel( "szlExtent", szlExtent );
1914  }
1915 #endif /* ENABLE_EDITING */
1916  };
1917 
1919 
1925  public:
1932  EMRSCALEVIEWPORTEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
1933  {
1934  emr.iType = EMR_SCALEVIEWPORTEXTEX;
1935  emr.nSize = sizeof( ::EMRSCALEVIEWPORTEXTEX );
1936  xNum = x_num;
1937  xDenom = x_den;
1938  yNum = y_num;
1939  yDenom = y_den;
1940  }
1946  {
1947  ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
1948  }
1952  bool serialize ( DATASTREAM ds )
1953  {
1954  ds << emr << xNum << xDenom << yNum << yDenom;
1955  return true;
1956  }
1960  int size ( void ) const { return emr.nSize; }
1966  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1967  {
1968  EMF_UNUSED(source);
1969  ScaleViewportExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
1970  }
1971 #ifdef ENABLE_EDITING
1975  void edit ( void ) const
1976  {
1977 #if defined(__LP64__)
1978  const char* FMT0 = "\txNum\t: %d\n";
1979  const char* FMT1 = "\txDenom\t: %d\n";
1980  const char* FMT2 = "\tyNum\t: %d\n";
1981  const char* FMT3 = "\tyDenom\t: %d\n";
1982 #else
1983  const char* FMT0 = "\txNum\t: %ld\n";
1984  const char* FMT1 = "\txDenom\t: %ld\n";
1985  const char* FMT2 = "\tyNum\t: %ld\n";
1986  const char* FMT3 = "\tyDenom\t: %ld\n";
1987 #endif
1988  printf( "*SCALEVIEWPORTEXTEX*\n" );
1989  printf( FMT0, xNum );
1990  printf( FMT1, xDenom );
1991  printf( FMT2, yNum );
1992  printf( FMT3, yDenom );
1993  }
1994 #endif /* ENABLE_EDITING */
1995  };
1996 
1998 
2004  public:
2009  EMRSETWINDOWEXTEX ( INT cx, INT cy )
2010  {
2011  emr.iType = EMR_SETWINDOWEXTEX;
2012  emr.nSize = sizeof( ::EMRSETWINDOWEXTEX );
2013  szlExtent.cx = cx;
2014  szlExtent.cy = cy;
2015  }
2021  {
2022  ds >> emr >> szlExtent;
2023  }
2027  bool serialize ( DATASTREAM ds )
2028  {
2029  ds << emr << szlExtent;
2030  return true;
2031  }
2035  int size ( void ) const { return emr.nSize; }
2041  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2042  {
2043  EMF_UNUSED(source);
2044  SetWindowExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
2045  }
2046 #ifdef ENABLE_EDITING
2050  void edit ( void ) const
2051  {
2052  printf( "*SETWINDOWEXTEX*\n" );
2053  edit_sizel( "szlExtent", szlExtent );
2054  }
2055 #endif /* ENABLE_EDITING */
2056  };
2057 
2059 
2065  public:
2072  EMRSCALEWINDOWEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
2073  {
2074  emr.iType = EMR_SCALEWINDOWEXTEX;
2075  emr.nSize = sizeof( ::EMRSCALEWINDOWEXTEX );
2076  xNum = x_num;
2077  xDenom = x_den;
2078  yNum = y_num;
2079  yDenom = y_den;
2080  }
2086  {
2087  ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
2088  }
2092  bool serialize ( DATASTREAM ds )
2093  {
2094  ds << emr << xNum << xDenom << yNum << yDenom;
2095  return true;
2096  }
2100  int size ( void ) const { return emr.nSize; }
2106  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2107  {
2108  EMF_UNUSED(source);
2109  ScaleWindowExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
2110  }
2111 #ifdef ENABLE_EDITING
2115  void edit ( void ) const
2116  {
2117 #if defined(__LP64__)
2118  const char* FMT0 = "\txNum\t: %d\n";
2119  const char* FMT1 = "\txDenom\t: %d\n";
2120  const char* FMT2 = "\tyNum\t: %d\n";
2121  const char* FMT3 = "\tyDenom\t: %d\n";
2122 #else
2123  const char* FMT0 = "\txNum\t: %ld\n";
2124  const char* FMT1 = "\txDenom\t: %ld\n";
2125  const char* FMT2 = "\tyNum\t: %ld\n";
2126  const char* FMT3 = "\tyDenom\t: %ld\n";
2127 #endif
2128  printf( "*SCALEWINDOWEXTEX*\n" );
2129  printf( FMT0, xNum );
2130  printf( FMT1, xDenom );
2131  printf( FMT2, yNum );
2132  printf( FMT3, yDenom );
2133  }
2134 #endif /* ENABLE_EDITING */
2135  };
2136 
2138 
2145  public:
2151  EMRMODIFYWORLDTRANSFORM ( const XFORM* transform, DWORD mode )
2152  {
2153  emr.iType = EMR_MODIFYWORLDTRANSFORM;
2154  emr.nSize = sizeof( ::EMRMODIFYWORLDTRANSFORM );
2155  xform = *transform;
2156  iMode = mode;
2157  }
2163  {
2164  ds >> emr >> xform >> iMode;
2165  }
2169  bool serialize ( DATASTREAM ds )
2170  {
2171  ds << emr << xform << iMode;
2172  return true;
2173  }
2177  int size ( void ) const { return emr.nSize; }
2183  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2184  {
2185  EMF_UNUSED(source);
2186  ModifyWorldTransform( dc, &xform, iMode );
2187  }
2188 #ifdef ENABLE_EDITING
2192  void edit ( void ) const
2193  {
2194 #if defined(__LP64__)
2195  const char* FMT = "unknown(%d)\n";
2196 #else
2197  const char* FMT = "unknown(%ld)\n";
2198 #endif /* __x86_64__ */
2199  printf( "*MODIFYWORLDTRANSFORM*\n" );
2200  edit_xform( "xform", xform );
2201  printf( "\tiMode\t\t: " );
2202  switch ( iMode ) {
2203  case MWT_IDENTITY: printf( "MWT_IDENTITY\n" ); break;
2204  case MWT_LEFTMULTIPLY: printf( "MWT_LEFTMULTIPLY\n" ); break;
2205  case MWT_RIGHTMULTIPLY: printf( "MWT_RIGHTMULTIPLY\n" ); break;
2206  default: printf( FMT, iMode );
2207  }
2208  }
2209 #endif /* ENABLE_EDITING */
2210  };
2211 
2213 
2220  public:
2224  EMRSETWORLDTRANSFORM ( const XFORM* transform )
2225  {
2226  emr.iType = EMR_SETWORLDTRANSFORM;
2227  emr.nSize = sizeof( ::EMRSETWORLDTRANSFORM );
2228  xform = *transform;
2229  }
2235  {
2236  ds >> emr >> xform;
2237  }
2241  bool serialize ( DATASTREAM ds )
2242  {
2243  ds << emr << xform;
2244  return true;
2245  }
2249  int size ( void ) const { return emr.nSize; }
2255  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2256  {
2257  EMF_UNUSED(source);
2258  SetWorldTransform( dc, &xform );
2259  }
2260 #ifdef ENABLE_EDITING
2264  void edit ( void ) const
2265  {
2266  printf( "*SETWORLDTRANSFORM*\n" );
2267  edit_xform( "xform", xform );
2268  }
2269 #endif /* ENABLE_EDITING */
2270  };
2271 
2273 
2277  public:
2281  EMRSETTEXTALIGN ( UINT mode )
2282  {
2283  emr.iType = EMR_SETTEXTALIGN;
2284  emr.nSize = sizeof( ::EMRSETTEXTALIGN );
2285  iMode = mode;
2286  }
2292  {
2293  ds >> emr >> iMode;
2294  }
2298  bool serialize ( DATASTREAM ds )
2299  {
2300  ds << emr << iMode;
2301  return true;
2302  }
2306  int size ( void ) const { return emr.nSize; }
2312  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2313  {
2314  EMF_UNUSED(source);
2315  SetTextAlign( dc, iMode );
2316  }
2317 #ifdef ENABLE_EDITING
2321  void edit ( void ) const
2322  {
2323 #if defined(__LP64__)
2324  const char* FMT = "| unknown bits(0x%x)";
2325 #else
2326  const char* FMT = "| unknown bits(0x%lx)";
2327 #endif /* __x86_64__ */
2328  unsigned int known_bits = TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING;
2329  unsigned int unknown_bits = ~known_bits;
2330 
2331  printf( "*SETTEXTALIGN*\n" );
2332  printf( "\tiMode\t: " );
2333  if ( iMode & TA_UPDATECP )
2334  printf( "TA_UPDATECP" );
2335  else
2336  printf( "TA_NOUPDATECP" );
2337  if ( iMode & TA_CENTER )
2338  printf( " | TA_CENTER" );
2339  else if ( iMode & TA_RIGHT )
2340  printf( " | TA_RIGHT" );
2341  else
2342  printf( " | TA_LEFT" );
2343  if ( iMode & TA_BASELINE )
2344  printf( " | TA_BASELINE" );
2345  else if ( iMode & TA_BOTTOM )
2346  printf( " | TA_BOTTOM" );
2347  else
2348  printf( " | TA_TOP" );
2349  if ( iMode & TA_RTLREADING )
2350  printf( " | TA_RTLREADING" );
2351  if ( iMode & unknown_bits )
2352  printf( FMT, iMode & unknown_bits );
2353  printf( "\n" );
2354  }
2355 #endif /* ENABLE_EDITING */
2356  };
2357 
2359 
2363  public:
2367  EMRSETTEXTCOLOR ( COLORREF color )
2368  {
2369  emr.iType = EMR_SETTEXTCOLOR;
2370  emr.nSize = sizeof( ::EMRSETTEXTCOLOR );
2371  crColor = color;
2372  }
2378  {
2379  ds >> emr >> crColor;
2380  }
2384  bool serialize ( DATASTREAM ds )
2385  {
2386  ds << emr << crColor;
2387  return true;
2388  }
2392  int size ( void ) const { return emr.nSize; }
2398  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2399  {
2400  EMF_UNUSED(source);
2401  SetTextColor( dc, crColor );
2402  }
2403 #ifdef ENABLE_EDITING
2407  void edit ( void ) const
2408  {
2409  printf( "*SETTEXTCOLOR*\n" );
2410  edit_color( "crColor", crColor );
2411  }
2412 #endif /* ENABLE_EDITING */
2413  };
2414 
2416 
2420  public:
2424  EMRSETBKCOLOR ( COLORREF color )
2425  {
2426  emr.iType = EMR_SETBKCOLOR;
2427  emr.nSize = sizeof( ::EMRSETBKCOLOR );
2428  crColor = color;
2429  }
2435  {
2436  ds >> emr >> crColor;
2437  }
2441  bool serialize ( DATASTREAM ds )
2442  {
2443  ds << emr << crColor;
2444  return true;
2445  }
2449  int size ( void ) const { return emr.nSize; }
2455  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2456  {
2457  EMF_UNUSED(source);
2458  SetBkColor( dc, crColor );
2459  }
2460 #ifdef ENABLE_EDITING
2464  void edit ( void ) const
2465  {
2466  printf( "*SETBKCOLOR*\n" );
2467  edit_color( "crColor", crColor );
2468  }
2469 #endif /* ENABLE_EDITING */
2470  };
2471 
2473 
2478  public:
2482  EMRSETBKMODE ( DWORD mode )
2483  {
2484  emr.iType = EMR_SETBKMODE;
2485  emr.nSize = sizeof( ::EMRSETBKMODE );
2486  iMode = mode;
2487  }
2493  {
2494  ds >> emr >> iMode;
2495  }
2499  bool serialize ( DATASTREAM ds )
2500  {
2501  ds << emr << iMode;
2502  return true;
2503  }
2507  int size ( void ) const { return emr.nSize; }
2513  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2514  {
2515  EMF_UNUSED(source);
2516  SetBkMode( dc, iMode );
2517  }
2518 #ifdef ENABLE_EDITING
2522  void edit ( void ) const
2523  {
2524 #if defined(__LP64__)
2525  const char* FMT = "unknown(%d)\n";
2526 #else
2527  const char* FMT = "unknown(%ld)\n";
2528 #endif /* __x86_64__ */
2529  printf( "*SETBKMODE*\n" );
2530  printf( "\tiMode\t: " );
2531  switch ( iMode ) {
2532  case TRANSPARENT: printf( "TRANSPARENT\n" ); break;
2533  case OPAQUE: printf( "OPAQUE\n" ); break;
2534  default: printf( FMT, iMode );
2535  }
2536  }
2537 #endif /* ENABLE_EDITING */
2538  };
2539 
2541 
2545  public:
2549  EMRSETPOLYFILLMODE ( DWORD mode )
2550  {
2551  emr.iType = EMR_SETPOLYFILLMODE;
2552  emr.nSize = sizeof( ::EMRSETPOLYFILLMODE );
2553  iMode = mode;
2554  }
2560  {
2561  ds >> emr >> iMode;
2562  }
2566  bool serialize ( DATASTREAM ds )
2567  {
2568  ds << emr << iMode;
2569  return true;
2570  }
2574  int size ( void ) const { return emr.nSize; }
2580  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2581  {
2582  EMF_UNUSED(source);
2583  SetPolyFillMode( dc, iMode );
2584  }
2585 #ifdef ENABLE_EDITING
2589  void edit ( void ) const
2590  {
2591 #if defined(__LP64__)
2592  const char* FMT = "unknown(%d)\n";
2593 #else
2594  const char* FMT = "unknown(%ld)\n";
2595 #endif /* __x86_64__ */
2596  printf( "*SETPOLYFILLMODE*\n" );
2597  printf( "\tiMode: " );
2598  switch ( iMode ) {
2599  case ALTERNATE: printf( "ALTERNATE\n" ); break;
2600  case WINDING: printf( "WINDING\n" ); break;
2601  default: printf( FMT, iMode );
2602  }
2603  }
2604 #endif /* ENABLE_EDITING */
2605  };
2606 
2608 
2613  public:
2617  EMRSETMAPMODE ( DWORD mode )
2618  {
2619  emr.iType = EMR_SETMAPMODE;
2620  emr.nSize = sizeof( ::EMRSETMAPMODE );
2621  iMode = mode;
2622  }
2628  {
2629  ds >> emr >> iMode;
2630  }
2634  bool serialize ( DATASTREAM ds )
2635  {
2636  ds << emr << iMode;
2637  return true;
2638  }
2642  int size ( void ) const { return emr.nSize; }
2648  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2649  {
2650  EMF_UNUSED(source);
2651  SetMapMode( dc, iMode );
2652  }
2653 #ifdef ENABLE_EDITING
2657  void edit ( void ) const
2658  {
2659 #if defined(__LP64__)
2660  const char* FMT = "unknown(%d)\n";
2661 #else
2662  const char* FMT = "unknown(%ld)\n";
2663 #endif /* __x86_64__ */
2664  printf( "*SETMAPMODE*\n" );
2665  printf( "\tiMode\t: " );
2666  switch ( iMode ) {
2667  case MM_TEXT: printf( "MM_TEXT\n" ); break;
2668  case MM_LOMETRIC: printf( "MM_LOMETRIC\n" ); break;
2669  case MM_HIMETRIC: printf( "MM_HIMETRIC\n" ); break;
2670  case MM_LOENGLISH: printf( "MM_LOENGLISH\n" ); break;
2671  case MM_HIENGLISH: printf( "MM_HIENGLISH\n" ); break;
2672  case MM_TWIPS: printf( "MM_TWIPS\n" ); break;
2673  case MM_ISOTROPIC: printf( "MM_ISOTROPIC\n" ); break;
2674  case MM_ANISOTROPIC: printf( "MM_ANISOTROPIC\n" ); break;
2675  default: printf( FMT, iMode );
2676  }
2677  }
2678 #endif /* ENABLE_EDITING */
2679  };
2680 
2682 
2686  public:
2690  EMRSELECTOBJECT ( HGDIOBJ object )
2691  {
2692  emr.iType = EMR_SELECTOBJECT;
2693  emr.nSize = sizeof( ::EMRSELECTOBJECT );
2694  ihObject = object;
2695  }
2701  {
2702  ds >> emr >> ihObject;
2703  }
2707  bool serialize ( DATASTREAM ds )
2708  {
2709  ds << emr << ihObject;
2710  return true;
2711  }
2715  int size ( void ) const { return emr.nSize; }
2721  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
2722 #ifdef ENABLE_EDITING
2726  void edit ( void ) const
2727  {
2728 #if defined(__LP64__)
2729  const char* FMT = "\tihObject\t: 0x%x\n";
2730 #else
2731  const char* FMT = "\tihObject\t: 0x%lx\n";
2732 #endif /* __x86_64__ */
2733  printf( "*SELECTOBJECT*\n" );
2734  printf( FMT, ihObject );
2735  }
2736 #endif /* ENABLE_EDITING */
2737  };
2738 
2740 
2744  public:
2748  EMRDELETEOBJECT ( HGDIOBJ object )
2749  {
2750  emr.iType = EMR_DELETEOBJECT;
2751  emr.nSize = sizeof( ::EMRDELETEOBJECT );
2752  ihObject = object;
2753  }
2759  {
2760  ds >> emr >> ihObject;
2761  }
2765  bool serialize ( DATASTREAM ds )
2766  {
2767  ds << emr << ihObject;
2768  return true;
2769  }
2773  int size ( void ) const { return emr.nSize; }
2779  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
2780 #ifdef ENABLE_EDITING
2784  void edit ( void ) const
2785  {
2786 #if defined(__LP64__)
2787  const char* FMT = "\tihObject\t: 0x%x\n";
2788 #else
2789  const char* FMT = "\tihObject\t: 0x%lx\n";
2790 #endif /* __x86_64__ */
2791  printf( "*DELETEOBJECT*\n" );
2792  printf( FMT, ihObject );
2793  }
2794 #endif /* ENABLE_EDITING */
2795  };
2796 
2798 
2802  public:
2807  EMRMOVETOEX ( INT x, INT y )
2808  {
2809  emr.iType = EMR_MOVETOEX;
2810  emr.nSize = sizeof( ::EMRMOVETOEX );
2811  ptl.x = x;
2812  ptl.y = y;
2813  }
2819  {
2820  ds >> emr >> ptl;
2821  }
2825  bool serialize ( DATASTREAM ds )
2826  {
2827  ds << emr << ptl;
2828  return true;
2829  }
2833  int size ( void ) const { return emr.nSize; }
2839  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2840  {
2841  EMF_UNUSED(source);
2842  MoveToEx( dc, ptl.x, ptl.y, 0 );
2843  }
2844 #ifdef ENABLE_EDITING
2848  void edit ( void ) const
2849  {
2850  printf( "*MOVETOEX*\n" );
2851  edit_pointl( "ptl", ptl );
2852  }
2853 #endif /* ENABLE_EDITING */
2854  };
2855 
2857 
2861  public:
2866  EMRLINETO ( INT x, INT y )
2867  {
2868  emr.iType = EMR_LINETO;
2869  emr.nSize = sizeof( ::EMRLINETO );
2870  ptl.x = x;
2871  ptl.y = y;
2872  }
2878  {
2879  ds >> emr >> ptl;
2880  }
2884  bool serialize ( DATASTREAM ds )
2885  {
2886  ds << emr << ptl;
2887  return true;
2888  }
2892  int size ( void ) const { return emr.nSize; }
2898  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2899  {
2900  EMF_UNUSED(source);
2901  LineTo( dc, ptl.x, ptl.y );
2902  }
2903 #ifdef ENABLE_EDITING
2907  void edit ( void ) const
2908  {
2909  printf( "*LINETO*\n" );
2910  edit_pointl( "ptl", ptl );
2911  }
2912 #endif /* ENABLE_EDITING */
2913  };
2914 
2916 
2919  class EMRARC : public METARECORD, ::EMRARC {
2920  public:
2932  EMRARC ( INT left, INT top, INT right, INT bottom, INT xstart,
2933  INT ystart, INT xend, INT yend )
2934  {
2935  emr.iType = EMR_ARC;
2936  emr.nSize = sizeof( ::EMRARC );
2937  rclBox.left = left;
2938  rclBox.right = right;
2939  rclBox.bottom = bottom;
2940  rclBox.top = top;
2941  ptlStart.x = xstart;
2942  ptlStart.y = ystart;
2943  ptlEnd.x = xend;
2944  ptlEnd.y = yend;
2945  }
2951  {
2952  ds >> emr >> rclBox >> ptlStart >> ptlEnd;
2953  }
2957  bool serialize ( DATASTREAM ds )
2958  {
2959  ds << emr << rclBox << ptlStart << ptlEnd;
2960  return true;
2961  }
2965  int size ( void ) const { return emr.nSize; }
2971  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2972  {
2973  EMF_UNUSED(source);
2974  Arc( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
2975  ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
2976  }
2977 #ifdef ENABLE_EDITING
2981  void edit ( void ) const
2982  {
2983  printf( "*ARC*\n" );
2984  edit_rectl( "rclBox\t", rclBox );
2985  edit_pointl( "ptlStart", ptlStart );
2986  edit_pointl( "ptlEnd\t", ptlEnd );
2987  }
2988 #endif /* ENABLE_EDITING */
2989  };
2990 
2992 
2995  class EMRARCTO : public METARECORD, ::EMRARCTO {
2996  public:
3008  EMRARCTO ( INT left, INT top, INT right, INT bottom, INT xstart,
3009  INT ystart, INT xend, INT yend )
3010  {
3011  emr.iType = EMR_ARCTO;
3012  emr.nSize = sizeof( ::EMRARCTO );
3013  rclBox.left = left;
3014  rclBox.right = right;
3015  rclBox.bottom = bottom;
3016  rclBox.top = top;
3017  ptlStart.x = xstart;
3018  ptlStart.y = ystart;
3019  ptlEnd.x = xend;
3020  ptlEnd.y = yend;
3021  }
3027  {
3028  ds >> emr >> rclBox >> ptlStart >> ptlEnd;
3029  }
3033  bool serialize ( DATASTREAM ds )
3034  {
3035  ds << emr << rclBox << ptlStart << ptlEnd;
3036  return true;
3037  }
3041  int size ( void ) const { return emr.nSize; }
3047  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3048  {
3049  EMF_UNUSED(source);
3050  ArcTo( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
3051  ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
3052  }
3053 #ifdef ENABLE_EDITING
3057  void edit ( void ) const
3058  {
3059  printf( "*ARCTO*\n" );
3060  edit_rectl( "rclBox\t", rclBox );
3061  edit_pointl( "ptlStart", ptlStart );
3062  edit_pointl( "ptlEnd\t", ptlEnd );
3063  }
3064 #endif /* ENABLE_EDITING */
3065  };
3066 
3068 
3072  public:
3079  EMRRECTANGLE ( INT left, INT top, INT right, INT bottom )
3080  {
3081  emr.iType = EMR_RECTANGLE;
3082  emr.nSize = sizeof( ::EMRRECTANGLE );
3083  rclBox.left = left;
3084  rclBox.right = right;
3085  rclBox.bottom = bottom;
3086  rclBox.top = top;
3087  }
3093  {
3094  ds >> emr >> rclBox;
3095  }
3099  bool serialize ( DATASTREAM ds )
3100  {
3101  ds << emr << rclBox;
3102  return true;
3103  }
3107  int size ( void ) const { return emr.nSize; }
3113  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3114  {
3115  EMF_UNUSED(source);
3116  Rectangle( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
3117  }
3118 #ifdef ENABLE_EDITING
3122  void edit ( void ) const
3123  {
3124  printf( "*RECTANGLE*\n" );
3125  edit_rectl( "rclBox", rclBox );
3126  }
3127 #endif /* ENABLE_EDITING */
3128  };
3129 
3131 
3135  public:
3143  EMRELLIPSE ( INT left, INT top, INT right, INT bottom )
3144  {
3145  emr.iType = EMR_ELLIPSE;
3146  emr.nSize = sizeof( ::EMRELLIPSE );
3147  rclBox.left = left;
3148  rclBox.right = right;
3149  rclBox.bottom = bottom;
3150  rclBox.top = top;
3151  }
3157  {
3158  ds >> emr >> rclBox;
3159  }
3163  bool serialize ( DATASTREAM ds )
3164  {
3165  ds << emr << rclBox;
3166  return true;
3167  }
3171  int size ( void ) const { return emr.nSize; }
3177  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3178  {
3179  EMF_UNUSED(source);
3180  Ellipse( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
3181  }
3182 #ifdef ENABLE_EDITING
3186  void edit ( void ) const
3187  {
3188  printf( "*ELLIPSE*\n" );
3189  edit_rectl( "rclBox", rclBox );
3190  }
3191 #endif /* ENABLE_EDITING */
3192  };
3193 
3195 
3199  POINTL* lpoints{nullptr};
3200  public:
3206  EMRPOLYLINE ( const RECTL* bounds, const POINT* points, INT n )
3207  {
3208  cptl = n;
3209  aptl[0].x = 0; // Really unused
3210  aptl[0].y = 0;
3211 
3212  emr.iType = EMR_POLYLINE;
3213  // The (cptl - 1) below is to account for aptl, which isn't written out
3214  emr.nSize = sizeof( ::EMRPOLYLINE ) + sizeof( POINTL ) * ( cptl - 1);
3215 
3216  lpoints = new POINTL[cptl];
3217 
3218  for (int i=0; i<n; i++) {
3219  lpoints[i].x = points[i].x;
3220  lpoints[i].y = points[i].y;
3221  }
3222 
3223  rclBounds = *bounds;
3224  }
3229  {
3230  if ( lpoints ) delete[] lpoints;
3231  }
3237  {
3238  ds >> emr >> rclBounds >> cptl;
3239 
3240  if ( emr.nSize - (sizeof(::EMRPOLYLINE)-sizeof(POINTL) ) <
3241  sizeof(POINTL) * cptl ) {
3242  throw std::runtime_error( "Invalid record size" );
3243  }
3244 
3245  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
3246  POINTLARRAY points( buffer.get(), cptl );
3247 
3248  ds >> points;
3249 
3250  lpoints = buffer.release();
3251  }
3255  bool serialize ( DATASTREAM ds )
3256  {
3257  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
3258  return true;
3259  }
3263  int size ( void ) const { return emr.nSize; }
3269  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3270  {
3271  EMF_UNUSED(source);
3272  // According to the wine windef.h header, POINT and POINTL are equivalent
3273  Polyline( dc, (POINT*)lpoints, cptl );
3274  }
3275 #ifdef ENABLE_EDITING
3279  void edit ( void ) const
3280  {
3281  printf( "*POLYLINE*\n" );
3282  edit_rectl( "rclBounds", rclBounds );
3283  edit_pointlarray( "\t", cptl, lpoints );
3284  }
3285 #endif /* ENABLE_EDITING */
3286  };
3287 
3289 
3293  POINT16* lpoints{ nullptr };
3294  public:
3300  EMRPOLYLINE16 ( const RECTL* bounds, const POINT16* points, INT n )
3301  {
3302  cpts = n;
3303  apts[0].x = 0; // Really unused
3304  apts[0].y = 0;
3305 
3306  emr.iType = EMR_POLYLINE16;
3307  // The (cptl - 1) below is to account for aptl, which isn't written out
3308  emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
3309 
3310  lpoints = new POINT16[cpts];
3311 
3312  for (int i=0; i<n; i++) {
3313  lpoints[i].x = points[i].x;
3314  lpoints[i].y = points[i].y;
3315  }
3316 
3317  rclBounds = *bounds;
3318  }
3325  EMRPOLYLINE16 ( const RECTL* bounds, const POINT* points, INT n )
3326  {
3327  cpts = n;
3328  apts[0].x = 0; // Really unused
3329  apts[0].y = 0;
3330 
3331  emr.iType = EMR_POLYLINE16;
3332  // The (cptl - 1) below is to account for aptl, which isn't written out
3333  emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
3334 
3335  lpoints = new POINT16[cpts];
3336 
3337  for (int i=0; i<n; i++) {
3338  lpoints[i].x = points[i].x;
3339  lpoints[i].y = points[i].y;
3340  }
3341 
3342  rclBounds = *bounds;
3343  }
3348  {
3349  if ( lpoints ) delete[] lpoints;
3350  }
3356  {
3357  ds >> emr >> rclBounds >> cpts;
3358 
3359  if ( emr.nSize - (sizeof(::EMRPOLYLINE16)-sizeof(POINT16) ) <
3360  sizeof(POINT16) * cpts ) {
3361  throw std::runtime_error( "Invalid record size" );
3362  }
3363 
3364  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
3365 
3366  POINT16ARRAY points( buffer.get(), cpts );
3367 
3368  ds >> points;
3369 
3370  lpoints = buffer.release();
3371  }
3375  bool serialize ( DATASTREAM ds )
3376  {
3377  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
3378  return true;
3379  }
3383  int size ( void ) const { return emr.nSize; }
3389  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3390  {
3391  EMF_UNUSED(source);
3392  // According to the wine windef.h header, POINT and POINTL are equivalent
3393  Polyline16( dc, lpoints, cpts );
3394  }
3395 #ifdef ENABLE_EDITING
3399  void edit ( void ) const
3400  {
3401  printf( "*POLYLINE16*\n" );
3402  edit_rectl( "rclBounds", rclBounds );
3403  edit_point16array( "\t", cpts, lpoints );
3404  }
3405 #endif /* ENABLE_EDITING */
3406  };
3407 
3409 
3413  POINTL* lpoints{ nullptr };
3414  public:
3420  EMRPOLYGON ( const RECTL* bounds, const POINT* points, INT n )
3421  {
3422  cptl = n;
3423  aptl[0].x = 0; // Really unused
3424  aptl[0].y = 0;
3425 
3426  emr.iType = EMR_POLYGON;
3427  // The (cptl-1) below is to account for aptl, which isn't written out
3428  emr.nSize = sizeof( ::EMRPOLYGON ) + sizeof( POINTL ) * (cptl-1);
3429 
3430  lpoints = new POINTL[cptl];
3431 
3432  for (int i=0; i<n; i++) {
3433  lpoints[i].x = points[i].x;
3434  lpoints[i].y = points[i].y;
3435  }
3436 
3437  rclBounds = *bounds;
3438  }
3444  {
3445  ds >> emr >> rclBounds >> cptl;
3446 
3447  if ( emr.nSize - (sizeof(::EMRPOLYGON) - sizeof(POINTL)) <
3448  cptl * sizeof(POINTL) ) {
3449  throw std::runtime_error( "Invalid record size" );
3450  }
3451 
3452  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
3453 
3454  POINTLARRAY points( buffer.get(), cptl );
3455 
3456  ds >> points;
3457 
3458  lpoints = buffer.release();
3459  }
3464  {
3465  if ( lpoints ) delete[] lpoints;
3466  }
3470  bool serialize ( DATASTREAM ds )
3471  {
3472  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
3473  return true;
3474  }
3478  int size ( void ) const { return emr.nSize; }
3484  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3485  {
3486  EMF_UNUSED(source);
3487  // According to the wine windef.h header, POINT and POINTL are equivalent
3488  Polygon( dc, (POINT*)lpoints, cptl );
3489  }
3490 #ifdef ENABLE_EDITING
3494  void edit ( void ) const
3495  {
3496  printf( "*POLYGON*\n" );
3497  edit_rectl( "rclBounds", rclBounds );
3498  edit_pointlarray( "\t", cptl, lpoints );
3499  }
3500 #endif /* ENABLE_EDITING */
3501  };
3502 
3504 
3508  POINT16* lpoints{ nullptr };
3509  public:
3515  EMRPOLYGON16 ( const RECTL* bounds, const POINT* points, INT16 n )
3516  {
3517  cpts = n;
3518  apts[0].x = 0; // Really unused
3519  apts[0].y = 0;
3520 
3521  emr.iType = EMR_POLYGON16;
3522  // The (cptl-1) below is to account for aptl, which isn't written out
3523  emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
3524 
3525  lpoints = new POINT16[cpts];
3526 
3527  for (int i=0; i<n; i++) {
3528  lpoints[i].x = points[i].x;
3529  lpoints[i].y = points[i].y;
3530  }
3531 
3532  rclBounds = *bounds;
3533  }
3540  EMRPOLYGON16 ( const RECTL* bounds, const POINT16* points, INT16 n )
3541  {
3542  cpts = n;
3543  apts[0].x = 0; // Really unused
3544  apts[0].y = 0;
3545 
3546  emr.iType = EMR_POLYGON16;
3547  // The (cptl-1) below is to account for aptl, which isn't written out
3548  emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
3549 
3550  lpoints = new POINT16[cpts];
3551 
3552  for (int i=0; i<n; i++) {
3553  lpoints[i].x = points[i].x;
3554  lpoints[i].y = points[i].y;
3555  }
3556 
3557  rclBounds = *bounds;
3558  }
3564  {
3565  ds >> emr >> rclBounds >> cpts;
3566 
3567  if ( emr.nSize - (sizeof(::EMRPOLYGON16) - sizeof(POINT16)) <
3568  cpts * sizeof(POINT16) ) {
3569  throw std::runtime_error( "Invalid record size" );
3570  }
3571 
3572  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
3573 
3574  POINT16ARRAY points( buffer.get(), cpts );
3575 
3576  ds >> points;
3577 
3578  lpoints = buffer.release();
3579  }
3584  {
3585  if ( lpoints ) delete[] lpoints;
3586  }
3590  bool serialize ( DATASTREAM ds )
3591  {
3592  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
3593  return true;
3594  }
3598  int size ( void ) const { return emr.nSize; }
3604  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3605  {
3606  EMF_UNUSED(source);
3607  // According to the wine windef.h header, POINT and POINTL are equivalent
3608  Polygon16( dc, lpoints, cpts );
3609  }
3610 #ifdef ENABLE_EDITING
3614  void edit ( void ) const
3615  {
3616  printf( "*POLYGON16*\n" );
3617  edit_rectl( "rclBounds", rclBounds );
3618  edit_point16array( "\t", cpts, lpoints );
3619  }
3620 #endif /* ENABLE_EDITING */
3621  };
3622 
3624 
3628  DWORD* lcounts{ nullptr };
3629  POINTL* lpoints{ nullptr };
3630  public:
3637  EMRPOLYPOLYGON ( const RECTL* bounds, const POINT* points, const INT* counts,
3638  UINT polygons )
3639  {
3640  nPolys = polygons;
3641  // Count the number of points in points
3642  int n = 0;
3643  for ( unsigned int i = 0; i < nPolys; i++ )
3644  n += counts[i];
3645 
3646  cptl = n;
3647  aPolyCounts[0] = 0; // Really unused
3648  aptl[0].x = 0;
3649  aptl[0].y = 0;
3650 
3651  emr.iType = EMR_POLYPOLYGON;
3652  // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
3653  // aren't directly written out
3654  emr.nSize = sizeof( ::EMRPOLYPOLYGON ) + sizeof( POINTL ) * (cptl-1)
3655  + sizeof( DWORD ) * (nPolys-1);
3656 
3657  lcounts = new DWORD[nPolys];
3658 
3659  for ( unsigned int i = 0; i < nPolys; i++ )
3660  lcounts[i] = counts[i];
3661 
3662  lpoints = new POINTL[cptl];
3663 
3664  for (int i=0; i<n; i++) {
3665  lpoints[i].x = points[i].x;
3666  lpoints[i].y = points[i].y;
3667  }
3668 
3669  rclBounds = *bounds;
3670  }
3675  {
3676  if ( lcounts ) delete[] lcounts;
3677  if ( lpoints ) delete[] lpoints;
3678  }
3684  {
3685  ds >> emr >> rclBounds >> nPolys >> cptl;
3686 
3687  if ( emr.nSize - ( sizeof( ::EMRPOLYPOLYGON ) - sizeof(POINTL) - sizeof(DWORD) ) <
3688  sizeof( POINTL ) * cptl + sizeof( DWORD ) * nPolys ) {
3689  throw std::runtime_error( "Invalid record size" );
3690  }
3691 
3692  std::unique_ptr<DWORD[]> cbuffer( new DWORD[nPolys] );
3693 
3694  DWORDARRAY counts( cbuffer.get(), nPolys );
3695 
3696  ds >> counts;
3697 
3698  // Counts have to add up to less than the number of points
3699  // we have. DWORD is unsigned so we most care about overflow.
3700  DWORD n{0}, n_old{0};
3701  for ( DWORD c{0}; c < nPolys; ++c ) {
3702  n_old = n;
3703  n += cbuffer[c];
3704  if ( n < n_old ) {
3705  throw std::runtime_error( "Unsigned overflow" );
3706  }
3707  }
3708  if ( n > cptl ) {
3709  throw std::runtime_error( "Too few points" );
3710  }
3711 
3712  std::unique_ptr<POINTL[]> pbuffer( new POINTL[cptl] );
3713 
3714  POINTLARRAY points( pbuffer.get(), cptl );
3715 
3716  ds >> points;
3717 
3718  // Don't do this until we won't have any more exceptions.
3719  lcounts = cbuffer.release();
3720  lpoints = pbuffer.release();
3721  }
3725  bool serialize ( DATASTREAM ds )
3726  {
3727  ds << emr << rclBounds << nPolys << cptl << DWORDARRAY( lcounts, nPolys )
3728  << POINTLARRAY( lpoints, cptl );
3729  return true;
3730  }
3734  int size ( void ) const { return emr.nSize; }
3740  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3741  {
3742  EMF_UNUSED(source);
3743  // According to the wine windef.h header, POINT and POINTL are equivalent
3744  // (but DWORD and INT are not)
3745  std::vector<INT> countsv( lcounts, lcounts + nPolys );
3746 
3747  PolyPolygon( dc, (POINT*)lpoints, countsv.data(), nPolys );
3748  }
3749 #ifdef ENABLE_EDITING
3753  void edit ( void ) const
3754  {
3755 #if defined(__LP64__)
3756  const char* FMT0 = "\tnPolys\t\t: %d\n";
3757  const char* FMT1 = "\tcptl\t\t: %d\n";
3758  const char* FMT2 = "%d\n";
3759  const char* FMT3 = "\t\t\t %d\n";
3760  const char* FMT4 = "%d, %d\n";
3761  const char* FMT5 = "\t\t\t %d, %d\n";
3762 #else
3763  const char* FMT0 = "\tnPolys\t\t: %ld\n";
3764  const char* FMT1 = "\tcptl\t\t: %ld\n";
3765  const char* FMT2 = "%ld\n";
3766  const char* FMT3 = "\t\t\t %ld\n";
3767  const char* FMT4 = "%ld, %ld\n";
3768  const char* FMT5 = "\t\t\t %ld, %ld\n";
3769 #endif /* __x86_64__ */
3770  printf( "*POLYPOLYGON*\n" );
3771  edit_rectl( "rclBounds", rclBounds );
3772  printf( FMT0, nPolys );
3773  printf( FMT1, cptl );
3774  printf( "\taPolyCounts\t: " );
3775  if ( nPolys > 0 )
3776  printf( FMT2, lcounts[0] );
3777  else
3778  puts( "" );
3779  for ( unsigned int i = 1; i < nPolys; i++ )
3780  printf( FMT3, lcounts[i] );
3781  printf( "\tapts\t\t: " );
3782  if ( cptl > 0 )
3783  printf( FMT4, lpoints[0].x, lpoints[0].y );
3784  else
3785  puts( "" );
3786  for ( unsigned int i = 1; i < cptl; i++ )
3787  printf( FMT5, lpoints[i].x, lpoints[i].y );
3788  }
3789 #endif /* ENABLE_EDITING */
3790  };
3791 
3793 
3797  DWORD* lcounts{ nullptr };
3798  POINT16* lpoints{ nullptr };
3799  public:
3806  EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT* points,
3807  const INT* counts, UINT polygons )
3808  {
3809  nPolys = polygons;
3810  // Count the number of points in points
3811  int n = 0;
3812  for ( unsigned int i = 0; i < nPolys; i++ )
3813  n += counts[i];
3814 
3815  cpts = n;
3816  aPolyCounts[0] = 0; // Really unused
3817  apts[0].x = 0;
3818  apts[0].y = 0;
3819 
3820  emr.iType = EMR_POLYPOLYGON16;
3821  // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
3822  // aren't directly written out
3823  emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
3824  + sizeof( DWORD ) * (nPolys-1);
3825 
3826  lcounts = new DWORD[nPolys];
3827 
3828  for ( unsigned int i = 0; i < nPolys; i++ )
3829  lcounts[i] = counts[i];
3830 
3831  lpoints = new POINT16[cpts];
3832 
3833  for (int i=0; i<n; i++) {
3834  lpoints[i].x = points[i].x;
3835  lpoints[i].y = points[i].y;
3836  }
3837 
3838  rclBounds = *bounds;
3839  }
3847  EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT16* points,
3848  const INT* counts, UINT16 polygons )
3849  {
3850  nPolys = polygons;
3851  // Count the number of points in points
3852  int n = 0;
3853  for ( unsigned int i = 0; i < nPolys; i++ )
3854  n += counts[i];
3855 
3856  cpts = n;
3857  aPolyCounts[0] = 0; // Really unused
3858  apts[0].x = 0;
3859  apts[0].y = 0;
3860 
3861  emr.iType = EMR_POLYPOLYGON16;
3862  // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
3863  // aren't directly written out
3864  emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
3865  + sizeof( DWORD ) * (nPolys-1);
3866 
3867  lcounts = new DWORD[nPolys];
3868 
3869  for ( unsigned int i = 0; i < nPolys; i++ )
3870  lcounts[i] = counts[i];
3871 
3872  lpoints = new POINT16[cpts];
3873 
3874  for (int i=0; i<n; i++) {
3875  lpoints[i].x = points[i].x;
3876  lpoints[i].y = points[i].y;
3877  }
3878 
3879  rclBounds = *bounds;
3880  }
3885  {
3886  if ( lcounts ) delete[] lcounts;
3887  if ( lpoints ) delete[] lpoints;
3888  }
3894  {
3895  ds >> emr >> rclBounds >> nPolys >> cpts;
3896 
3897  if ( emr.nSize - ( sizeof( ::EMRPOLYPOLYGON16 ) - sizeof(POINT16) - sizeof(DWORD) ) <
3898  sizeof( POINT16 ) * cpts + sizeof( DWORD ) * nPolys ) {
3899  throw std::runtime_error( "Invalid record size" );
3900  }
3901 
3902  std::unique_ptr<DWORD[]> cbuffer( new DWORD[nPolys] );
3903 
3904  DWORDARRAY counts( cbuffer.get(), nPolys );
3905 
3906  ds >> counts;
3907 
3908  // Counts have to add up to less than the number of points
3909  // we have. DWORD is unsigned so we most care about overflow.
3910  DWORD n{0}, n_old{0};
3911  for ( DWORD c{0}; c < nPolys; ++c ) {
3912  n_old = n;
3913  n += cbuffer[c];
3914  if ( n < n_old ) {
3915  throw std::runtime_error( "Unsigned overflow" );
3916  }
3917  }
3918  if ( n > cpts ) {
3919  throw std::runtime_error( "Too few points" );
3920  }
3921 
3922  std::unique_ptr<POINT16[]> pbuffer( new POINT16[cpts] );
3923 
3924  POINT16ARRAY points( pbuffer.get(), cpts );
3925 
3926  ds >> points;
3927 
3928  lcounts = cbuffer.release();
3929  lpoints = pbuffer.release();
3930  }
3934  bool serialize ( DATASTREAM ds )
3935  {
3936  ds << emr << rclBounds << nPolys << cpts << DWORDARRAY( lcounts, nPolys )
3937  << POINT16ARRAY( lpoints, cpts );
3938  return true;
3939  }
3943  int size ( void ) const { return emr.nSize; }
3949  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3950  {
3951  EMF_UNUSED(source);
3952  // According to the wine windef.h header, POINT and POINTL are equivalent
3953  // (but DWORD and INT are not)
3954  std::vector<INT> counts( lcounts, lcounts + nPolys );
3955 
3956  PolyPolygon16( dc, lpoints, counts.data(), nPolys );
3957  }
3958 #ifdef ENABLE_EDITING
3962  void edit ( void ) const
3963  {
3964 #if defined(__LP64__)
3965  const char* FMT0 = "\tnPolys\t\t: %d\n";
3966  const char* FMT1 = "\tcptl\t\t: %d\n";
3967  const char* FMT2 = "%d\n";
3968  const char* FMT3 = "\t\t\t %d\n";
3969 #else
3970  const char* FMT0 = "\tnPolys\t\t: %ld\n";
3971  const char* FMT1 = "\tcptl\t\t: %ld\n";
3972  const char* FMT2 = "%ld\n";
3973  const char* FMT3 = "\t\t\t %ld\n";
3974 #endif /* __x86_64__ */
3975  printf( "*POLYPOLYGON16*\n" );
3976  edit_rectl( "rclBounds", rclBounds );
3977  printf( FMT0, nPolys );
3978  printf( FMT1, cpts );
3979  printf( "\taPolyCounts\t: " );
3980  if ( nPolys > 0 )
3981  printf( FMT2, lcounts[0] );
3982  else
3983  puts( "" );
3984  for ( unsigned int i = 1; i < nPolys; i++ )
3985  printf( FMT3, lcounts[i] );
3986  printf( "\tapts\t\t: " );
3987  if ( cpts > 0 )
3988  printf( "%d, %d\n", lpoints[0].x, lpoints[0].y );
3989  else
3990  puts( "" );
3991  for ( unsigned int i = 1; i < cpts; i++ )
3992  printf( "\t\t\t %d, %d\n", lpoints[i].x, lpoints[i].y );
3993  }
3994 #endif /* ENABLE_EDITING */
3995  };
3996 
3998 
4002  POINTL* lpoints{ nullptr };
4003  public:
4009  EMRPOLYBEZIER ( const RECTL* bounds, const POINT* points, INT n )
4010  {
4011  cptl = n;
4012  aptl[0].x = 0; // Really unused
4013  aptl[0].y = 0;
4014 
4015  emr.iType = EMR_POLYBEZIER;
4016  // The (cptl-1) below is to account for aptl, which isn't written out
4017  emr.nSize = sizeof( ::EMRPOLYBEZIER ) + sizeof( POINTL ) * (cptl-1);
4018 
4019  lpoints = new POINTL[cptl];
4020 
4021  for (int i=0; i<n; i++) {
4022  lpoints[i].x = points[i].x;
4023  lpoints[i].y = points[i].y;
4024  }
4025 
4026  rclBounds = *bounds;
4027  }
4033  {
4034  ds >> emr >> rclBounds >> cptl;
4035 
4036  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIER ) - sizeof(POINTL)) <
4037  sizeof( POINTL ) * cptl ) {
4038  throw std::runtime_error( "Invalid record size" );
4039  }
4040 
4041  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
4042 
4043  POINTLARRAY points( buffer.get(), cptl );
4044 
4045  ds >> points;
4046 
4047  lpoints = buffer.release();
4048  }
4053  {
4054  if ( lpoints ) delete[] lpoints;
4055  }
4059  bool serialize ( DATASTREAM ds )
4060  {
4061  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
4062  return true;
4063  }
4067  int size ( void ) const { return emr.nSize; }
4073  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4074  {
4075  EMF_UNUSED(source);
4076  // According to the wine windef.h header, POINT and POINTL are equivalent
4077  PolyBezier( dc, (POINT*)lpoints, cptl );
4078  }
4079 #ifdef ENABLE_EDITING
4083  void edit ( void ) const
4084  {
4085  printf( "*POLYBEZIER*\n" );
4086  edit_rectl( "rclBounds", rclBounds );
4087  edit_pointlarray( "\t", cptl, lpoints );
4088  }
4089 #endif /* ENABLE_EDITING */
4090  };
4091 
4093 
4097  POINT16* lpoints{ nullptr };
4098  public:
4104  EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT16* points, INT n )
4105  {
4106  cpts = n;
4107  apts[0].x = 0; // Really unused
4108  apts[0].y = 0;
4109 
4110  emr.iType = EMR_POLYBEZIER16;
4111  // The (cptl-1) below is to account for aptl, which isn't written out
4112  emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
4113 
4114  lpoints = new POINT16[cpts];
4115 
4116  for (int i=0; i<n; i++) {
4117  lpoints[i].x = points[i].x;
4118  lpoints[i].y = points[i].y;
4119  }
4120 
4121  rclBounds = *bounds;
4122  }
4129  EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT* points, INT n )
4130  {
4131  cpts = n;
4132  apts[0].x = 0; // Really unused
4133  apts[0].y = 0;
4134 
4135  emr.iType = EMR_POLYBEZIER16;
4136  // The (cptl-1) below is to account for aptl, which isn't written out
4137  emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
4138 
4139  lpoints = new POINT16[cpts];
4140 
4141  for (int i=0; i<n; i++) {
4142  lpoints[i].x = points[i].x;
4143  lpoints[i].y = points[i].y;
4144  }
4145 
4146  rclBounds = *bounds;
4147  }
4153  {
4154  ds >> emr >> rclBounds >> cpts;
4155 
4156  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIER16 ) - sizeof(POINT16)) <
4157  sizeof( POINT16 ) * cpts ) {
4158  throw std::runtime_error( "Invalid record size" );
4159  }
4160 
4161  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
4162 
4163  POINT16ARRAY points( buffer.get(), cpts );
4164 
4165  ds >> points;
4166 
4167  lpoints = buffer.release();
4168  }
4173  {
4174  if ( lpoints ) delete[] lpoints;
4175  }
4179  bool serialize ( DATASTREAM ds )
4180  {
4181  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
4182  return true;
4183  }
4187  int size ( void ) const { return emr.nSize; }
4193  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4194  {
4195  EMF_UNUSED(source);
4196  // According to the wine windef.h header, POINT and POINTL are equivalent
4197  PolyBezier16( dc, lpoints, cpts );
4198  }
4199 #ifdef ENABLE_EDITING
4203  void edit ( void ) const
4204  {
4205  printf( "*POLYBEZIER16*\n" );
4206  edit_rectl( "rclBounds", rclBounds );
4207  edit_point16array( "\t", cpts, lpoints );
4208  }
4209 #endif /* ENABLE_EDITING */
4210  };
4211 
4213 
4217  POINTL* lpoints{ nullptr };
4218  public:
4224  EMRPOLYBEZIERTO ( const RECTL* bounds, const POINT* points, INT n )
4225  {
4226  cptl = n;
4227  aptl[0].x = 0; // Really unused
4228  aptl[0].y = 0;
4229 
4230  emr.iType = EMR_POLYBEZIERTO;
4231  // The (cptl-1) below is to account for aptl, which isn't written out
4232  emr.nSize = sizeof( ::EMRPOLYBEZIERTO ) + sizeof( POINTL ) * (cptl-1);
4233 
4234  lpoints = new POINTL[cptl];
4235 
4236  for (int i=0; i<n; i++) {
4237  lpoints[i].x = points[i].x;
4238  lpoints[i].y = points[i].y;
4239  }
4240 
4241  rclBounds = *bounds;
4242  }
4248  {
4249  ds >> emr >> rclBounds >> cptl;
4250 
4251  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIERTO ) - sizeof(POINTL)) <
4252  sizeof( POINTL ) * cptl ) {
4253  throw std::runtime_error( "Invalid record size" );
4254  }
4255 
4256  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
4257 
4258  POINTLARRAY points( buffer.get(), cptl );
4259 
4260  ds >> points;
4261 
4262  lpoints = buffer.release();
4263  }
4268  {
4269  if ( lpoints ) delete[] lpoints;
4270  }
4274  bool serialize ( DATASTREAM ds )
4275  {
4276  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
4277  return true;
4278  }
4282  int size ( void ) const { return emr.nSize; }
4288  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4289  {
4290  EMF_UNUSED(source);
4291  // According to the wine windef.h header, POINT and POINTL are equivalent
4292  PolyBezierTo( dc, (POINT*)lpoints, cptl );
4293  }
4294 #ifdef ENABLE_EDITING
4298  void edit ( void ) const
4299  {
4300  printf( "*POLYBEZIERTO*\n" );
4301  edit_rectl( "rclBounds", rclBounds );
4302  edit_pointlarray( "\t", cptl, lpoints );
4303  }
4304 #endif /* ENABLE_EDITING */
4305  };
4306 
4308 
4312  POINT16* lpoints{ nullptr };
4313  public:
4319  EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT16* points, INT n )
4320  {
4321  cpts = n;
4322  apts[0].x = 0; // Really unused
4323  apts[0].y = 0;
4324 
4325  emr.iType = EMR_POLYBEZIERTO16;
4326  // The (cptl-1) below is to account for aptl, which isn't written out
4327  emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
4328 
4329  lpoints = new POINT16[cpts];
4330 
4331  for (int i=0; i<n; i++) {
4332  lpoints[i].x = points[i].x;
4333  lpoints[i].y = points[i].y;
4334  }
4335 
4336  rclBounds = *bounds;
4337  }
4344  EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT* points, INT n )
4345  {
4346  cpts = n;
4347  apts[0].x = 0; // Really unused
4348  apts[0].y = 0;
4349 
4350  emr.iType = EMR_POLYBEZIERTO16;
4351  // The (cptl-1) below is to account for aptl, which isn't written out
4352  emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
4353 
4354  lpoints = new POINT16[cpts];
4355 
4356  for (int i=0; i<n; i++) {
4357  lpoints[i].x = points[i].x;
4358  lpoints[i].y = points[i].y;
4359  }
4360 
4361  rclBounds = *bounds;
4362  }
4368  {
4369  ds >> emr >> rclBounds >> cpts;
4370 
4371  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIERTO16 ) - sizeof(POINT16)) <
4372  sizeof( POINT16 ) * cpts ) {
4373  throw std::runtime_error( "Invalid record size" );
4374  }
4375 
4376  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
4377 
4378  POINT16ARRAY points( buffer.get(), cpts );
4379 
4380  ds >> points;
4381 
4382  lpoints = buffer.release();
4383  }
4388  {
4389  if ( lpoints ) delete[] lpoints;
4390  }
4394  bool serialize ( DATASTREAM ds )
4395  {
4396  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
4397  return true;
4398  }
4402  int size ( void ) const { return emr.nSize; }
4408  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4409  {
4410  EMF_UNUSED(source);
4411  // According to the wine windef.h header, POINT and POINTL are equivalent
4412  PolyBezierTo16( dc, lpoints, cpts );
4413  }
4414 #ifdef ENABLE_EDITING
4418  void edit ( void ) const
4419  {
4420  printf( "*POLYBEZIERTO16*\n" );
4421  edit_rectl( "rclBounds", rclBounds );
4422  edit_point16array( "\t", cpts, lpoints );
4423  }
4424 #endif /* ENABLE_EDITING */
4425  };
4426 
4428 
4432  POINTL* lpoints{ nullptr };
4433  public:
4439  EMRPOLYLINETO ( const RECTL* bounds, const POINT* points, INT n )
4440  {
4441  cptl = n;
4442  aptl[0].x = 0;
4443  aptl[0].y = 0;
4444 
4445  emr.iType = EMR_POLYLINETO;
4446  // The (cptl-1) below is to account for aptl, which isn't written out
4447  emr.nSize = sizeof( ::EMRPOLYLINETO ) + sizeof( POINTL ) * (cptl-1);
4448 
4449  lpoints = new POINTL[cptl];
4450 
4451  for (int i=0; i<n; i++) {
4452  lpoints[i].x = points[i].x;
4453  lpoints[i].y = points[i].y;
4454  }
4455 
4456  rclBounds = *bounds;
4457  }
4463  {
4464  ds >> emr >> rclBounds >> cptl;
4465 
4466  if ( emr.nSize - (sizeof( ::EMRPOLYLINETO ) - sizeof(POINTL)) <
4467  sizeof( POINTL ) * cptl ) {
4468  throw std::runtime_error( "Invalid record size" );
4469  }
4470 
4471  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
4472 
4473  POINTLARRAY points( buffer.get(), cptl );
4474 
4475  ds >> points;
4476 
4477  lpoints = buffer.release();
4478  }
4483  {
4484  if ( lpoints ) delete[] lpoints;
4485  }
4489  bool serialize ( DATASTREAM ds )
4490  {
4491  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
4492  return true;
4493  }
4497  int size ( void ) const { return emr.nSize; }
4503  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4504  {
4505  EMF_UNUSED(source);
4506  // According to the wine windef.h header, POINT and POINTL are equivalent
4507  PolylineTo( dc, (POINT*)lpoints, cptl );
4508  }
4509 #ifdef ENABLE_EDITING
4513  void edit ( void ) const
4514  {
4515  printf( "*POLYLINETO*\n" );
4516  edit_rectl( "rclBounds", rclBounds );
4517  edit_pointlarray( "\t", cptl, lpoints );
4518  }
4519 #endif /* ENABLE_EDITING */
4520  };
4521 
4523 
4527  POINT16* lpoints{ nullptr };
4528  public:
4534  EMRPOLYLINETO16 ( const RECTL* bounds, const POINT16* points, INT n )
4535  {
4536  cpts = n;
4537  apts[0].x = 0;
4538  apts[0].y = 0;
4539 
4540  emr.iType = EMR_POLYLINETO16;
4541  // The (cptl-1) below is to account for aptl, which isn't written out
4542  emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
4543 
4544  lpoints = new POINT16[cpts];
4545 
4546  for (int i=0; i<n; i++) {
4547  lpoints[i].x = points[i].x;
4548  lpoints[i].y = points[i].y;
4549  }
4550 
4551  rclBounds = *bounds;
4552  }
4559  EMRPOLYLINETO16 ( const RECTL* bounds, const POINT* points, INT n )
4560  {
4561  cpts = n;
4562  apts[0].x = 0;
4563  apts[0].y = 0;
4564 
4565  emr.iType = EMR_POLYLINETO16;
4566  // The (cptl-1) below is to account for aptl, which isn't written out
4567  emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
4568 
4569  lpoints = new POINT16[cpts];
4570 
4571  for (int i=0; i<n; i++) {
4572  lpoints[i].x = points[i].x;
4573  lpoints[i].y = points[i].y;
4574  }
4575 
4576  rclBounds = *bounds;
4577  }
4583  {
4584  ds >> emr >> rclBounds >> cpts;
4585 
4586  if ( emr.nSize - (sizeof( ::EMRPOLYLINETO16 ) - sizeof(POINT16)) <
4587  sizeof( POINT16 ) * cpts ) {
4588  throw std::runtime_error( "Invalid record size" );
4589  }
4590 
4591  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
4592 
4593  POINT16ARRAY points( buffer.get(), cpts );
4594 
4595  ds >> points;
4596 
4597  lpoints = buffer.release();
4598  }
4603  {
4604  if ( lpoints ) delete[] lpoints;
4605  }
4609  bool serialize ( DATASTREAM ds )
4610  {
4611  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
4612  return true;
4613  }
4617  int size ( void ) const { return emr.nSize; }
4623  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4624  {
4625  EMF_UNUSED(source);
4626  // According to the wine windef.h header, POINT and POINTL are equivalent
4627  PolylineTo16( dc, lpoints, cpts );
4628  }
4629 #ifdef ENABLE_EDITING
4633  void edit ( void ) const
4634  {
4635  printf( "*POLYLINETO16*\n" );
4636  edit_rectl( "rclBounds", rclBounds );
4637  edit_point16array( "\t", cpts, lpoints );
4638  }
4639 #endif /* ENABLE_EDITING */
4640  };
4641 
4643 
4649  PSTR string_a{ nullptr };
4650  int string_size;
4651 
4652  INT* dx_i{ nullptr };
4653  public:
4663  EMREXTTEXTOUTA ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
4664  FLOAT yScale, const PEMRTEXT text, LPCSTR string,
4665  const INT* dx )
4666  {
4667  emr.iType = EMR_EXTTEXTOUTA;
4668  emr.nSize = sizeof( ::EMREXTTEXTOUTA );
4669 
4670  rclBounds = *bounds;
4671 
4672  iGraphicsMode = graphicsMode;
4673  exScale = xScale;
4674  eyScale = yScale;
4675 
4676  emrtext = *text;
4677 
4678  string_size = ROUND_TO_LONG( emrtext.nChars );
4679 
4680  string_a = new CHAR[ string_size ];
4681 
4682  memset( string_a, 0, sizeof(CHAR) * string_size );
4683 
4684  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4685  string_a[i] = *string++;
4686 
4687  emrtext.offString = emr.nSize;
4688  emr.nSize += string_size * sizeof(CHAR);
4689 #if 0
4690 /*
4691 Test only - Problem: Windows requires this dx to be set - at least from 2K on
4692 but to calculate real dx values is hard
4693 For pstoedit - this is "fixed" now by estimating dx in pstoedit
4694 */
4695  if ( !dx ) {
4696  int * dxn = new int [string_size];
4697  for (unsigned int i=0; i < string_size; i++) dxn[i] = 10;
4698  dx = dxn;
4699  }
4700 #endif
4701 
4702  if ( dx ) {
4703 
4704  dx_i = new INT[ emrtext.nChars ];
4705 
4706  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4707  dx_i[i] = *dx++;
4708 
4709  emrtext.offDx = emr.nSize;
4710  emr.nSize += emrtext.nChars * sizeof(INT);
4711  }
4712  else {
4713  emrtext.offDx = 0;
4714  dx_i = 0;
4715  }
4716  }
4722  {
4723  ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
4724 
4725  if ( emrtext.nChars > 0 and emrtext.offString == 0 ) {
4726  throw std::runtime_error( "Invalid text specification" );
4727  }
4728 
4729  if ( emrtext.nChars > emr.nSize - emrtext.offString ) {
4730  throw std::runtime_error( "Invalid text specification" );
4731  }
4732 
4733  std::unique_ptr<char[]> cbuffer;
4734  std::unique_ptr<INT[]> ibuffer;
4735 
4736  if ( emrtext.offString != 0 ) {
4737  string_size = ROUND_TO_LONG( emrtext.nChars );
4738 
4739  cbuffer.reset( new char[string_size] );
4740 
4741  memset( cbuffer.get(), 0, sizeof(CHAR) * string_size );
4742 
4743  CHARSTR string( cbuffer.get(), string_size );
4744 
4745  ds >> string;
4746  }
4747 
4748  if ( emrtext.offDx ) {
4749  ibuffer.reset( new INT[emrtext.nChars] );
4750 
4751  INTARRAY dx_is( ibuffer.get(), emrtext.nChars );
4752 
4753  ds >> dx_is;
4754  }
4755 
4756  string_a = cbuffer.release();
4757  dx_i = ibuffer.release();
4758  }
4764  {
4765  if ( string_a ) delete[] string_a;
4766  if ( dx_i ) delete[] dx_i;
4767  }
4771  bool serialize ( DATASTREAM ds )
4772  {
4773  ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
4774  << emrtext << CHARSTR( string_a, string_size );
4775  if ( dx_i )
4776  ds << INTARRAY( dx_i, emrtext.nChars );
4777  return true;
4778  }
4782  int size ( void ) const { return emr.nSize; }
4788  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4789  {
4790  EMF_UNUSED(source);
4791  RECT rect;
4792  rect.left = emrtext.rcl.left;
4793  rect.top = emrtext.rcl.top;
4794  rect.right = emrtext.rcl.right;
4795  rect.bottom = emrtext.rcl.bottom;
4796 
4797  ExtTextOutA( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
4798  emrtext.fOptions, &rect, string_a, emrtext.nChars,
4799  dx_i );
4800  }
4801 #ifdef ENABLE_EDITING
4805  void edit ( void ) const
4806  {
4807 #if defined(__LP64__)
4808  const char* FMT0 = "unknown(%d)\n";
4809  const char* FMT1 = "\tptlReference\t: (%d,%d)\n";
4810  const char* FMT2 = "\tnChars\t\t: %d\n";
4811  const char* FMT3 = "\toffString\t: %d\n";
4812  const char* FMT4 = "\toffDx\t\t: %d\n";
4813 #else
4814  const char* FMT0 = "unknown(%ld)\n";
4815  const char* FMT1 = "\tptlReference\t: (%ld,%ld)\n";
4816  const char* FMT2 = "\tnChars\t\t: %ld\n";
4817  const char* FMT3 = "\toffString\t: %ld\n";
4818  const char* FMT4 = "\toffDx\t\t: %ld\n";
4819 #endif /* __x86_64__ */
4820  printf( "*EXTTEXTOUTA*\n" );
4821  edit_rectl( "rclBounds", rclBounds );
4822  printf( "\tiGraphicsMode\t: " );
4823  switch ( iGraphicsMode ) {
4824  case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
4825  case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
4826  default: printf( FMT0, iGraphicsMode );
4827  }
4828  printf( "\texScale\t\t: %f\n", exScale );
4829  printf( "\teyScale\t\t: %f\n", eyScale );
4830  printf( FMT1, emrtext.ptlReference.x, emrtext.ptlReference.y );
4831  printf( FMT2, emrtext.nChars );
4832  printf( FMT3, emrtext.offString );
4833  printf( "\tfOptions\t: " );
4834  if ( emrtext.fOptions == 0 )
4835  printf( "None" );
4836  else {
4837  if ( emrtext.fOptions & ETO_GRAYED ) {
4838  printf( "ETO_GRAYED" );
4839  if ( emrtext.fOptions & ~ETO_GRAYED )
4840  printf( " | " );
4841  }
4842  if ( emrtext.fOptions & ETO_OPAQUE ) {
4843  printf( "ETO_OPAQUE" );
4844  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
4845  printf( " | " );
4846  }
4847  if ( emrtext.fOptions & ETO_CLIPPED ) {
4848  printf( "ETO_CLIPPED" );
4849  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
4850  printf( " | " );
4851  }
4852  if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
4853  printf( "ETO_GLYPH_INDEX" );
4854  if ( emrtext.fOptions &
4855  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
4856  printf( " | " );
4857  }
4858  if ( emrtext.fOptions & ETO_RTLREADING ) {
4859  printf( "ETO_RTLREADING" );
4860  if ( emrtext.fOptions &
4861  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
4862  ETO_RTLREADING) )
4863  printf( " | " );
4864  }
4865  if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
4866  printf( "ETO_IGNORELANGUAGE" );
4867  }
4868  printf( "\n" );
4869  edit_rectl( "rcl\t", emrtext.rcl );
4870  printf( FMT4, emrtext.offDx );
4871  printf( "\tString:\n\t\t" );
4872  if ( emrtext.nChars > 0 ) {
4873  for ( DWORD i = 0; i < emrtext.nChars; ++i ) {
4874  putchar( string_a[i] );
4875  }
4876  }
4877  else {
4878  printf( "<empty>" );
4879  }
4880  putchar( '\n' );
4881  if ( emrtext.offDx != 0 ) {
4882  printf( "\tOffsets:\n\t\t" );
4883  for ( unsigned int i = 0; i < emrtext.nChars; i++ )
4884  printf( "%d ", dx_i[i] );
4885  printf( "\n" );
4886  }
4887  }
4888 #endif /* ENABLE_EDITING */
4889  };
4891 
4897  PWSTR string_a{ nullptr };
4898  int string_size;
4899 
4900  INT* dx_i{ nullptr };
4901  public:
4911  EMREXTTEXTOUTW ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
4912  FLOAT yScale, const PEMRTEXT text, LPCWSTR string,
4913  const INT* dx )
4914  {
4915  emr.iType = EMR_EXTTEXTOUTW;
4916  emr.nSize = sizeof( ::EMREXTTEXTOUTW );
4917 
4918  rclBounds = *bounds;
4919 
4920  iGraphicsMode = graphicsMode;
4921  exScale = xScale;
4922  eyScale = yScale;
4923 
4924  emrtext = *text;
4925 
4926  string_size = ROUND_TO_LONG( emrtext.nChars );
4927 
4928  string_a = new WCHAR[ string_size ];
4929 
4930  memset( string_a, 0, sizeof(WCHAR) * string_size );
4931 
4932  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4933  string_a[i] = *string++;
4934 
4935  emrtext.offString = emr.nSize;
4936  emr.nSize += string_size * sizeof(WCHAR);
4937 #if 0
4938 /*
4939 Test only - Problem: Windows requires this dx to be set - at least from 2K on
4940 but to calculate real dx values is hard
4941 For pstoedit - this is "fixed" now by estimating dx in pstoedit
4942 */
4943  if ( !dx ) {
4944  int * dxn = new int [string_size];
4945  for (unsigned int i=0; i < string_size; i++) dxn[i] = 10;
4946  dx = dxn;
4947  }
4948 #endif
4949 
4950  if ( dx ) {
4951 
4952  dx_i = new INT[ emrtext.nChars ];
4953 
4954  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4955  dx_i[i] = *dx++;
4956 
4957  emrtext.offDx = emr.nSize;
4958  emr.nSize += emrtext.nChars * sizeof(INT);
4959  }
4960  else {
4961  emrtext.offDx = 0;
4962  dx_i = 0;
4963  }
4964  }
4970  {
4971  ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
4972 
4973  if ( emrtext.nChars > 0 and emrtext.offString == 0 ) {
4974  throw std::runtime_error( "Invalid text specification" );
4975  }
4976 
4977  if ( emrtext.nChars > emr.nSize - emrtext.offString ) {
4978  throw std::runtime_error( "Invalid text specification" );
4979  }
4980 
4981  std::unique_ptr<WCHAR[]> cbuffer;
4982  std::unique_ptr<INT[]> ibuffer;
4983 
4984  if ( emrtext.offString != 0 ) { // So, what is the point of this check?
4985  string_size = ROUND_TO_LONG( emrtext.nChars );
4986 
4987  cbuffer.reset( new WCHAR[string_size] );
4988 
4989  memset( cbuffer.get(), 0, sizeof(WCHAR) * string_size );
4990 
4991  WCHARSTR string( cbuffer.get(), string_size );
4992 
4993  ds >> string;
4994  }
4995 
4996  if ( emrtext.offDx ) {
4997  ibuffer.reset( new INT[ emrtext.nChars ] );
4998 
4999  INTARRAY dx_is( ibuffer.get(), emrtext.nChars );
5000 
5001  ds >> dx_is;
5002  }
5003 
5004  string_a = cbuffer.release();
5005  dx_i = ibuffer.release();
5006  }
5012  {
5013  if ( string_a ) delete[] string_a;
5014  if ( dx_i ) delete[] dx_i;
5015  }
5019  bool serialize ( DATASTREAM ds )
5020  {
5021  ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
5022  << emrtext << WCHARSTR( string_a, string_size );
5023  if ( dx_i )
5024  ds << INTARRAY( dx_i, emrtext.nChars );
5025  return true;
5026  }
5030  int size ( void ) const { return emr.nSize; }
5036  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5037  {
5038  EMF_UNUSED(source);
5039  RECT rect;
5040  rect.left = emrtext.rcl.left;
5041  rect.top = emrtext.rcl.top;
5042  rect.right = emrtext.rcl.right;
5043  rect.bottom = emrtext.rcl.bottom;
5044 
5045  ExtTextOutW( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
5046  emrtext.fOptions, &rect, string_a, emrtext.nChars,
5047  dx_i );
5048  }
5049 #ifdef ENABLE_EDITING
5053  void edit ( void ) const
5054  {
5055 #if defined(__LP64__)
5056  const char* FMT0 = "unknown(%d)\n";
5057  const char* FMT1 = "\tptlReference\t: (%d,%d)\n";
5058  const char* FMT2 = "\tnChars\t\t: %d\n";
5059  const char* FMT3 = "\toffString\t: %d\n";
5060  const char* FMT4 = "\toffDx\t\t: %d\n";
5061 #else
5062  const char* FMT0 = "unknown(%ld)\n";
5063  const char* FMT1 = "\tptlReference\t: (%ld,%ld)\n";
5064  const char* FMT2 = "\tnChars\t\t: %ld\n";
5065  const char* FMT3 = "\toffString\t: %ld\n";
5066  const char* FMT4 = "\toffDx\t\t: %ld\n";
5067 #endif /* __x86_64__ */
5068  printf( "*EXTTEXTOUTW*\n" );
5069  edit_rectl( "rclBounds", rclBounds );
5070  printf( "\tiGraphicsMode\t: " );
5071  switch ( iGraphicsMode ) {
5072  case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
5073  case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
5074  default: printf( FMT0, iGraphicsMode );
5075  }
5076  printf( "\texScale\t\t: %f\n", exScale );
5077  printf( "\teyScale\t\t: %f\n", eyScale );
5078  printf( FMT1, emrtext.ptlReference.x, emrtext.ptlReference.y );
5079  printf( FMT2, emrtext.nChars );
5080  printf( FMT3, emrtext.offString );
5081  printf( "\tfOptions\t: " );
5082  if ( emrtext.fOptions == 0 )
5083  printf( "None" );
5084  else {
5085  if ( emrtext.fOptions & ETO_GRAYED ) {
5086  printf( "ETO_GRAYED" );
5087  if ( emrtext.fOptions & ~ETO_GRAYED )
5088  printf( " | " );
5089  }
5090  if ( emrtext.fOptions & ETO_OPAQUE ) {
5091  printf( "ETO_OPAQUE" );
5092  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
5093  printf( " | " );
5094  }
5095  if ( emrtext.fOptions & ETO_CLIPPED ) {
5096  printf( "ETO_CLIPPED" );
5097  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
5098  printf( " | " );
5099  }
5100  if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
5101  printf( "ETO_GLYPH_INDEX" );
5102  if ( emrtext.fOptions &
5103  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
5104  printf( " | " );
5105  }
5106  if ( emrtext.fOptions & ETO_RTLREADING ) {
5107  printf( "ETO_RTLREADING" );
5108  if ( emrtext.fOptions &
5109  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
5110  ETO_RTLREADING) )
5111  printf( " | " );
5112  }
5113  if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
5114  printf( "ETO_IGNORELANGUAGE" );
5115  }
5116  printf( "\n" );
5117  edit_rectl( "rcl\t", emrtext.rcl );
5118  printf( FMT4, emrtext.offDx );
5119 
5120  if ( emrtext.nChars > 0 ) {
5121  // iconv_open arguments are TO, FROM (not the other way around).
5122  iconv_t cvt = iconv_open( "UTF-8", "UTF-16LE" );
5123  std::vector<char> utf8_buffer( emrtext.nChars );
5124  // Cannot predict the space necessary to hold the converted
5125  // string. So, we loop until conversion is complete.
5126  size_t size = emrtext.nChars;
5127  size_t in_bytes_left = emrtext.nChars * sizeof(*string_a);
5128  size_t converted = 0;
5129  char* in_buffer = (char*)string_a;
5130  while ( 1 ) {
5131  char* out_buffer = &utf8_buffer[converted];
5132  size_t out_bytes_left = size - converted;
5133 
5134  size_t n = iconv( cvt, &in_buffer, &in_bytes_left,
5135  &out_buffer, &out_bytes_left );
5136 
5137  converted = size - out_bytes_left;
5138 
5139  if ( n == (size_t)-1 ) {
5140  if ( errno == E2BIG ) {
5141  size_t new_size = 2 * utf8_buffer.size();
5142  utf8_buffer.resize( new_size );
5143  size = utf8_buffer.size();
5144  }
5145  else {
5146  // Real conversion error.
5147  break;
5148  }
5149  }
5150  else {
5151  break;
5152  }
5153  }
5154 
5155  iconv_close( cvt );
5156 
5157  if ( converted == utf8_buffer.size() )
5158  utf8_buffer.push_back( '\0' );
5159  else
5160  utf8_buffer[converted] = '\0';
5161 
5162  printf( "\tString:\n\t\t%s\n", utf8_buffer.data() );
5163  }
5164  else {
5165  puts( "\tString:\n\t\t<empty>\n" );
5166  }
5167 
5168  if ( emrtext.offDx != 0 and emrtext.nChars > 0 ) {
5169  printf( "\tOffsets:\n\t\t" );
5170  for ( unsigned int i = 0; i < emrtext.nChars; i++ )
5171  printf( "%d ", dx_i[i] );
5172  printf( "\n" );
5173  }
5174  }
5175 #endif /* ENABLE_EDITING */
5176  };
5177 
5179 
5183  public:
5189  EMRSETPIXELV ( INT x, INT y, COLORREF color )
5190  {
5191  emr.iType = EMR_SETPIXELV;
5192  emr.nSize = sizeof( ::EMRSETPIXELV );
5193  ptlPixel.x = x;
5194  ptlPixel.y = y;
5195  crColor = color;
5196  }
5202  {
5203  ds >> emr >> ptlPixel >> crColor;
5204  }
5208  bool serialize ( DATASTREAM ds )
5209  {
5210  ds << emr << ptlPixel << crColor;
5211  return true;
5212  }
5216  int size ( void ) const { return emr.nSize; }
5222  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5223  {
5224  EMF_UNUSED(source);
5225  SetPixel( dc, ptlPixel.x, ptlPixel.y, crColor );
5226  }
5227 #ifdef ENABLE_EDITING
5231  void edit ( void ) const
5232  {
5233  printf( "*SETPIXELV*\n" );
5234  edit_pointl( "ptlPixel", ptlPixel );
5235  edit_color( "crColor\t", crColor );
5236  }
5237 #endif /* ENABLE_EDITING */
5238  };
5239 
5240  class PEN;
5241  class EXTPEN;
5242  class BRUSH;
5243  class FONT;
5244  class PALETTE;
5245 
5247 
5250  class EMRCREATEPEN : public METARECORD, public ::EMRCREATEPEN
5251  {
5252  public:
5257  EMRCREATEPEN ( PEN* pen, HGDIOBJ handle );
5262  EMRCREATEPEN ( DATASTREAM& ds );
5266  bool serialize ( DATASTREAM ds )
5267  {
5268  ds << emr << ihPen << lopn;
5269  return true;
5270  }
5274  int size ( void ) const { return emr.nSize; }
5280  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5281 #ifdef ENABLE_EDITING
5285  void edit ( void ) const
5286  {
5287 #if defined(__LP64__)
5288  const char* FMT0 = "\tihPen\t\t: 0x%x\n";
5289  const char* FMT1 = "\tlopn.lopnWidth\t: %d, %d\n";
5290 #else
5291  const char* FMT0 = "\tihPen\t\t: 0x%lx\n";
5292  const char* FMT1 = "\tlopn.lopnWidth\t: %ld, %ld\n";
5293 #endif /* __x86_64__ */
5294  printf( "*CREATEPEN*\n" );
5295  printf( FMT0, ihPen );
5296  edit_pen_style( "lopn.lopnStyle", lopn.lopnStyle );
5297  printf( FMT1, lopn.lopnWidth.x, lopn.lopnWidth.y );
5298  edit_color( "lopn.lopnColor", lopn.lopnColor );
5299  }
5300 #endif /* ENABLE_EDITING */
5301  };
5302 
5304 
5309  {
5310  public:
5315  EMREXTCREATEPEN ( EXTPEN* pen, HGDIOBJ handle );
5320  EMREXTCREATEPEN ( DATASTREAM& ds );
5324  bool serialize ( DATASTREAM ds )
5325  {
5326  ds << emr << ihPen << offBmi << cbBmi << offBits << cbBits << elp;
5327  return true;
5328  }
5332  int size ( void ) const { return emr.nSize; }
5338  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5339 #ifdef ENABLE_EDITING
5343  void edit ( void ) const
5344  {
5345 #if defined(__LP64__)
5346  const char* FMT0 = "\tihPen\t\t\t: 0x%x\n";
5347  const char* FMT1 = "\toffBmi\t\t\t: %d\n";
5348  const char* FMT2 = "\tcbBmi\t\t\t: %d\n";
5349  const char* FMT3 = "\toffBits\t\t\t: %d\n";
5350  const char* FMT4 = "\tcbBits\t\t\t: %d\n";
5351  const char* FMT5 = "\telp.elpWidth\t\t: %d\n";
5352  const char* FMT6 = "\telp.elpNumEntries\t: %d\n";
5353 #else
5354  const char* FMT0 = "\tihPen\t\t\t: 0x%lx\n";
5355  const char* FMT1 = "\toffBmi\t\t\t: %ld\n";
5356  const char* FMT2 = "\tcbBmi\t\t\t: %ld\n";
5357  const char* FMT3 = "\toffBits\t\t\t: %ld\n";
5358  const char* FMT4 = "\tcbBits\t\t\t: %ld\n";
5359  const char* FMT5 = "\telp.elpWidth\t\t: %ld\n";
5360  const char* FMT6 = "\telp.elpNumEntries\t: %ld\n";
5361 #endif /* __x86_64__ */
5362  printf( "*EXTCREATEPEN*\n" );
5363  printf( FMT0, ihPen );
5364  printf( FMT1, offBmi );
5365  printf( FMT2, cbBmi );
5366  printf( FMT3, offBits );
5367  printf( FMT4, cbBits );
5368  edit_pen_style( "elp.elpPenStyle\t", elp.elpPenStyle );
5369  printf( FMT5, elp.elpWidth );
5370  edit_brush_style( "elp.elpBrushStyle", elp.elpBrushStyle );
5371  edit_color( "elp.elpColor\t", elp.elpColor );
5372  edit_brush_hatch( "elp.elpHatch\t", elp.elpHatch );
5373  printf( FMT6, elp.elpNumEntries );
5374  }
5375 #endif /* ENABLE_EDITING */
5376  };
5377 
5379 
5383  {
5384  public:
5389  EMRCREATEBRUSHINDIRECT ( BRUSH* brush, HGDIOBJ handle );
5398  bool serialize ( DATASTREAM ds )
5399  {
5400  ds << emr << ihBrush << lb;
5401  return true;
5402  }
5406  int size ( void ) const { return emr.nSize; }
5412  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5413 #ifdef ENABLE_EDITING
5417  void edit ( void ) const
5418  {
5419 #if defined(__LP64__)
5420  const char* FMT = "\tihBrush\t\t: 0x%x\n";
5421 #else
5422  const char* FMT = "\tihBrush\t\t: 0x%lx\n";
5423 #endif /* __x86_64__ */
5424  printf( "*CREATEBRUSHINDIRECT*\n" );
5425  printf( FMT, ihBrush );
5426  edit_brush_style( "lb.lbStyle", lb.lbStyle );
5427  edit_color( "lb.lbColor", lb.lbColor );
5428  edit_brush_hatch( "lb.lbHatch", lb.lbHatch );
5429  }
5430 #endif /* ENABLE_EDITING */
5431  };
5432 
5434 
5438  {
5439  public:
5444  EMREXTCREATEFONTINDIRECTW ( FONT* font, HGDIOBJ handle );
5453  bool serialize ( DATASTREAM ds )
5454  {
5455  // Since EMF records have to be multiples of 4 bytes, this
5456  // should perhaps be a general thing, but we know it's currently
5457  // only a problem for this structure.
5458 
5459  ds << emr << ihFont << elfw << PADDING( 2 );
5460 
5461  return true;
5462  }
5466  int size ( void ) const { return emr.nSize; }
5472  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5473 #ifdef ENABLE_EDITING
5477  void edit ( void ) const
5478  {
5479 #if defined(__LP64__)
5480  const char* FMT0 = "\tihFont\t\t\t: %d\n";
5481  const char* FMT1 = "\tlfHeight\t\t: %d\n";
5482  const char* FMT2 = "\tlfWidth\t\t\t: %d\n";
5483  const char* FMT3 = "\tlfEscapement\t\t: %d\n";
5484  const char* FMT4 = "\tlfOrientation\t\t: %d\n";
5485  const char* FMT5 = "\telfVersion\t\t: %d\n";
5486  const char* FMT6 = "\telfStyleSize\t\t: %d\n";
5487  const char* FMT7 = "\telfMatch\t\t: %d\n";
5488  const char* FMT8 = "\telfCulture\t\t: %d\n";
5489 #else
5490  const char* FMT0 = "\tihFont\t\t\t: %ld\n";
5491  const char* FMT1 = "\tlfHeight\t\t: %ld\n";
5492  const char* FMT2 = "\tlfWidth\t\t\t: %ld\n";
5493  const char* FMT3 = "\tlfEscapement\t\t: %ld\n";
5494  const char* FMT4 = "\tlfOrientation\t\t: %ld\n";
5495  const char* FMT5 = "\telfVersion\t\t: %ld\n";
5496  const char* FMT6 = "\telfStyleSize\t\t: %ld\n";
5497  const char* FMT7 = "\telfMatch\t\t: %ld\n";
5498  const char* FMT8 = "\telfCulture\t\t: %ld\n";
5499 #endif /* __x86_64__ */
5500  printf( "*EXTCREATEFONTINDIRECTW*\n" );
5501  printf( FMT0, ihFont );
5502  printf( FMT1, elfw.elfLogFont.lfHeight );
5503  printf( FMT2, elfw.elfLogFont.lfWidth );
5504  printf( FMT3, elfw.elfLogFont.lfEscapement );
5505  printf( FMT4, elfw.elfLogFont.lfOrientation );
5506  printf( "\tlfWeight\t\t: " );
5507  switch ( elfw.elfLogFont.lfWeight ) {
5508  case FW_DONTCARE: printf( "FW_DONTCARE\n" ); break;
5509  case FW_THIN: printf( "FW_THIN\n" ); break;
5510  case FW_EXTRALIGHT: printf( "FW_EXTRALIGHT\n" ); break;
5511  case FW_LIGHT: printf( "FW_LIGHT\n" ); break;
5512  case FW_NORMAL: printf( "FW_NORMAL\n" ); break;
5513  case FW_MEDIUM: printf( "FW_MEDIUM\n" ); break;
5514  case FW_SEMIBOLD: printf( "FW_SEMIBOLD\n" ); break;
5515  case FW_BOLD: printf( "FW_BOLD\n" ); break;
5516  case FW_EXTRABOLD: printf( "FW_EXTRABOLD\n" ); break;
5517  case FW_BLACK: printf( "FW_BLACK\n" ); break;
5518  }
5519  printf( "\tlfItalic\t\t: %d\n", elfw.elfLogFont.lfItalic );
5520  printf( "\tlfUnderline\t\t: %d\n", elfw.elfLogFont.lfUnderline );
5521  printf( "\tlfStrikeOut\t\t: %d\n", elfw.elfLogFont.lfStrikeOut );
5522  printf( "\tlfCharSet\t\t: %d\n", elfw.elfLogFont.lfCharSet );
5523  printf( "\tlfOutPrecision\t\t: %d\n", elfw.elfLogFont.lfOutPrecision );
5524  printf( "\tlfClipPrecision\t\t: %d\n", elfw.elfLogFont.lfClipPrecision );
5525  printf( "\tlfQuality\t\t: %d\n", elfw.elfLogFont.lfQuality );
5526  printf( "\tlfPitchAndFamily\t: %d\n", elfw.elfLogFont.lfPitchAndFamily );
5527  int i = 0;
5528  printf( "\tlfFaceName\t\t: '" );
5529  while ( elfw.elfLogFont.lfFaceName[i] != 0 && i < LF_FACESIZE ) {
5530  putchar( elfw.elfLogFont.lfFaceName[i] );
5531  i++;
5532  }
5533  puts( "'" );
5534 
5535  i = 0;
5536  printf( "\telfFullName\t\t: '" );
5537  while ( elfw.elfFullName[i] != 0 && i < LF_FULLFACESIZE ) {
5538  putchar( elfw.elfFullName[i] );
5539  i++;
5540  }
5541  puts( "'" );
5542 
5543  i = 0;
5544  printf( "\telfStyle\t\t: '" );
5545  while ( elfw.elfStyle[i] != 0 && i < LF_FACESIZE ) {
5546  putchar( elfw.elfStyle[i] );
5547  i++;
5548  }
5549  puts( "'" );
5550 
5551  printf( FMT5, elfw.elfVersion );
5552  printf( FMT6, elfw.elfStyleSize );
5553  printf( FMT7, elfw.elfMatch );
5554  printf( "\telfVendorId\t\t: '%s'\n", elfw.elfVendorId );
5555  printf( FMT8, elfw.elfCulture );
5556  printf( "\telfPanose\t\t:\n" );
5557  printf( "\t\tbFamilyType\t\t: %d\n", elfw.elfPanose.bFamilyType );
5558  printf( "\t\tbSerifStyle\t\t: %d\n", elfw.elfPanose.bSerifStyle );
5559  printf( "\t\tbWeight\t\t\t: %d\n", elfw.elfPanose.bWeight );
5560  printf( "\t\tbProportion\t\t: %d\n", elfw.elfPanose.bProportion );
5561  printf( "\t\tbContrast\t\t: %d\n", elfw.elfPanose.bContrast );
5562  printf( "\t\tbStrokeVariation\t: %d\n", elfw.elfPanose.bStrokeVariation );
5563  printf( "\t\tbArmStyle\t\t: %d\n", elfw.elfPanose.bArmStyle );
5564  printf( "\t\tbLetterform\t\t: %d\n", elfw.elfPanose.bLetterform );
5565  printf( "\t\tbMidline\t\t: %d\n", elfw.elfPanose.bMidline );
5566  printf( "\t\tbXHeight\t\t: %d\n", elfw.elfPanose.bXHeight );
5567  }
5568 #endif /* ENABLE_EDITING */
5569  };
5570 
5572 
5576  {
5577  public:
5582  EMRCREATEPALETTE ( PALETTE* palette, HGDIOBJ handle );
5591  bool serialize ( DATASTREAM ds )
5592  {
5593  ds << emr << ihPal << lgpl;
5594  return true;
5595  }
5599  int size ( void ) const { return emr.nSize; }
5605  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5606 #ifdef ENABLE_EDITING
5610  void edit ( void ) const
5611  {
5612  printf( "*CREATEPALETTE* (not really handled by libEMF)\n" );
5613  }
5614 #endif /* ENABLE_EDITING */
5615  };
5616 
5618 
5622  public:
5626  EMRFILLPATH ( const RECTL* bounds )
5627  {
5628  emr.iType = EMR_FILLPATH;
5629  emr.nSize = sizeof( ::EMRFILLPATH );
5630  rclBounds = *bounds;
5631  }
5637  {
5638  ds >> emr >> rclBounds;
5639  }
5643  bool serialize ( DATASTREAM ds )
5644  {
5645  ds << emr << rclBounds;
5646  return true;
5647  }
5651  int size ( void ) const { return emr.nSize; }
5657  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5658  {
5659  EMF_UNUSED(source);
5660  FillPath( dc );
5661  }
5662 #ifdef ENABLE_EDITING
5666  void edit ( void ) const
5667  {
5668  printf( "*FILLPATH*\n" );
5669  edit_rectl( "rclBounds", rclBounds );
5670  }
5671 #endif /* ENABLE_EDITING */
5672  };
5674 
5678  public:
5682  EMRSTROKEPATH ( const RECTL* bounds )
5683  {
5684  emr.iType = EMR_STROKEPATH;
5685  emr.nSize = sizeof( ::EMRSTROKEPATH );
5686  rclBounds = *bounds;
5687  }
5693  {
5694  ds >> emr >> rclBounds;
5695  }
5699  bool serialize ( DATASTREAM ds )
5700  {
5701  ds << emr << rclBounds;
5702  return true;
5703  }
5707  int size ( void ) const { return emr.nSize; }
5713  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5714  {
5715  EMF_UNUSED(source);
5716  StrokePath( dc );
5717  }
5718 #ifdef ENABLE_EDITING
5722  void edit ( void ) const
5723  {
5724  printf( "*STROKEPATH*\n" );
5725  edit_rectl( "rclBounds", rclBounds );
5726  }
5727 #endif /* ENABLE_EDITING */
5728  };
5730 
5734  public:
5738  EMRSTROKEANDFILLPATH ( const RECTL* bounds )
5739  {
5740  emr.iType = EMR_STROKEANDFILLPATH;
5741  emr.nSize = sizeof( ::EMRSTROKEANDFILLPATH );
5742  rclBounds = *bounds;
5743  }
5749  {
5750  ds >> emr >> rclBounds;
5751  }
5755  bool serialize ( DATASTREAM ds )
5756  {
5757  ds << emr << rclBounds;
5758  return true;
5759  }
5763  int size ( void ) const { return emr.nSize; }
5769  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5770  {
5771  EMF_UNUSED(source);
5772  StrokeAndFillPath( dc );
5773  }
5774 #ifdef ENABLE_EDITING
5778  void edit ( void ) const
5779  {
5780  printf( "*STROKEANDFILLPATH*\n" );
5781  edit_rectl( "rclBounds", rclBounds );
5782  }
5783 #endif /* ENABLE_EDITING */
5784  };
5786 
5790  public:
5794  EMRBEGINPATH ( void )
5795  {
5796  emr.iType = EMR_BEGINPATH;
5797  emr.nSize = sizeof( ::EMRBEGINPATH );
5798  }
5804  {
5805  ds >> emr;
5806  }
5810  bool serialize ( DATASTREAM ds )
5811  {
5812  ds << emr;
5813  return true;
5814  }
5818  int size ( void ) const { return emr.nSize; }
5824  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5825  {
5826  EMF_UNUSED(source);
5827  BeginPath( dc );
5828  }
5829 #ifdef ENABLE_EDITING
5833  void edit ( void ) const
5834  {
5835  printf( "*BEGINPATH*\n" );
5836  }
5837 #endif /* ENABLE_EDITING */
5838  };
5840 
5844  public:
5848  EMRENDPATH ( void )
5849  {
5850  emr.iType = EMR_ENDPATH;
5851  emr.nSize = sizeof( ::EMRENDPATH );
5852  }
5858  {
5859  ds >> emr;
5860  }
5864  bool serialize ( DATASTREAM ds )
5865  {
5866  ds << emr;
5867  return true;
5868  }
5872  int size ( void ) const { return emr.nSize; }
5878  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5879  {
5880  EMF_UNUSED(source);
5881  EndPath( dc );
5882  }
5883 #ifdef ENABLE_EDITING
5887  void edit ( void ) const
5888  {
5889  printf( "*ENDPATH*\n" );
5890  }
5891 #endif /* ENABLE_EDITING */
5892  };
5894 
5898  public:
5903  {
5904  emr.iType = EMR_CLOSEFIGURE;
5905  emr.nSize = sizeof( ::EMRCLOSEFIGURE );
5906  }
5912  {
5913  ds >> emr;
5914  }
5918  bool serialize ( DATASTREAM ds )
5919  {
5920  ds << emr;
5921  return true;
5922  }
5926  int size ( void ) const { return emr.nSize; }
5932  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5933  {
5934  EMF_UNUSED(source);
5935  CloseFigure( dc );
5936  }
5937 #ifdef ENABLE_EDITING
5941  void edit ( void ) const
5942  {
5943  printf( "*CLOSEFIGURE*\n" );
5944  }
5945 #endif /* ENABLE_EDITING */
5946  };
5948 
5953  public:
5957  EMRSAVEDC ( void )
5958  {
5959  emr.iType = EMR_SAVEDC;
5960  emr.nSize = sizeof( ::EMRSAVEDC );
5961  }
5967  {
5968  ds >> emr;
5969  }
5973  bool serialize ( DATASTREAM ds )
5974  {
5975  ds << emr;
5976  return true;
5977  }
5981  int size ( void ) const { return emr.nSize; }
5987  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5988  {
5989  EMF_UNUSED(source);
5990  SaveDC( dc );
5991  }
5992 #ifdef ENABLE_EDITING
5996  void edit ( void ) const
5997  {
5998  printf( "*SAVEDC*\n" );
5999  }
6000 #endif /* ENABLE_EDITING */
6001  };
6003 
6007  public:
6011  EMRRESTOREDC ( INT n )
6012  {
6013  emr.iType = EMR_RESTOREDC;
6014  emr.nSize = sizeof( ::EMRRESTOREDC );
6015  iRelative = n;
6016  }
6022  {
6023  ds >> emr >> iRelative;
6024  }
6028  bool serialize ( DATASTREAM ds )
6029  {
6030  ds << emr << iRelative;
6031  return true;
6032  }
6036  int size ( void ) const { return emr.nSize; }
6042  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
6043  {
6044  EMF_UNUSED(source);
6045  RestoreDC( dc, iRelative );
6046  }
6047 #ifdef ENABLE_EDITING
6051  void edit ( void ) const
6052  {
6053 #if defined(__LP64__)
6054  const char* FMT = "\tiRelative: %d\n";
6055 #else
6056  const char* FMT = "\tiRelative: %ld\n";
6057 #endif /* __x86_64__ */
6058  printf( "*RESTOREDC*\n" );
6059  printf( FMT, iRelative );
6060  }
6061 #endif /* ENABLE_EDITING */
6062  };
6064 
6068  public:
6072  EMRSETMETARGN ( void )
6073  {
6074  emr.iType = EMR_SETMETARGN;
6075  emr.nSize = sizeof( ::EMRSETMETARGN );
6076  }
6082  {
6083  ds >> emr;
6084  }
6088  bool serialize ( DATASTREAM ds )
6089  {
6090  ds << emr;
6091  return true;
6092  }
6096  int size ( void ) const { return emr.nSize; }
6102  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
6103  {
6104  EMF_UNUSED(source);
6105  SetMetaRgn( dc );
6106  }
6107 #ifdef ENABLE_EDITING
6111  void edit ( void ) const
6112  {
6113  printf( "*SETMETARGN*\n" );
6114  }
6115 #endif /* ENABLE_EDITING */
6116  };
6117 
6119 
6122  class PEN : public GRAPHICSOBJECT, public LOGPEN {
6123  public:
6127  PEN ( const LOGPEN* lpen )
6128  {
6129  lopnStyle = lpen->lopnStyle;
6130  lopnWidth = lpen->lopnWidth;
6131  lopnColor = lpen->lopnColor;
6132  }
6136  OBJECTTYPE getType ( void ) const { return O_PEN; }
6143  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6144  {
6145  contexts[dc] = emf_handle;
6146  return new EMRCREATEPEN( this, emf_handle );
6147  }
6148  };
6149 
6151 
6154  class EXTPEN : public GRAPHICSOBJECT, public EXTLOGPEN {
6155  public:
6159  EXTPEN ( const EXTLOGPEN* lpen )
6160  {
6161  elpPenStyle = lpen->elpPenStyle;
6162  elpWidth = lpen->elpWidth;
6163  elpBrushStyle = lpen->elpBrushStyle;
6164  elpColor = lpen->elpColor;
6165  elpHatch = lpen->elpHatch;
6166  elpNumEntries = 0;
6167  elpStyleEntry[0] = 0;
6168  }
6172  OBJECTTYPE getType ( void ) const { return O_EXTPEN; }
6179  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6180  {
6181  contexts[dc] = emf_handle;
6182  return new EMREXTCREATEPEN( this, emf_handle );
6183  }
6184  };
6185 
6187 
6190  class BRUSH : public GRAPHICSOBJECT, public LOGBRUSH {
6191  public:
6195  BRUSH ( const LOGBRUSH* lbrush )
6196  {
6197  lbStyle = lbrush->lbStyle;
6198  lbColor = lbrush->lbColor;
6199  lbHatch = lbrush->lbHatch;
6200  }
6204  OBJECTTYPE getType ( void ) const { return O_BRUSH; }
6211  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6212  {
6213  contexts[dc] = emf_handle;
6214  return new EMRCREATEBRUSHINDIRECT( this, emf_handle );
6215  }
6216  };
6217 
6219 
6222  class FONT : public GRAPHICSOBJECT, public EXTLOGFONTW {
6223  public:
6227  FONT ( const LOGFONTW* lfont )
6228  {
6229  this->elfLogFont = *lfont;
6230  // There are a lot more entries in the EXTLOGFONTW structure than
6231  // the API has values for, so we invent them here
6232  memset( &elfFullName, 0, sizeof elfFullName );
6233  memset( &elfStyle, 0, sizeof elfStyle );
6234  elfVersion = ELF_VERSION;
6235  elfStyleSize = 0;
6236  elfMatch = 0;
6237  elfReserved = 0;
6238  memset( &elfVendorId, 0, sizeof elfVendorId );
6239  elfCulture = ELF_CULTURE_LATIN;
6240  memset( &elfPanose, 1, sizeof(PANOSE) );
6241  }
6245  OBJECTTYPE getType ( void ) const { return O_FONT; }
6252  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6253  {
6254  contexts[dc] = emf_handle;
6255  return new EMREXTCREATEFONTINDIRECTW( this, emf_handle );
6256  }
6257  };
6258 
6260 
6263  class PALETTE : public GRAPHICSOBJECT, public LOGPALETTE {
6264  public:
6268  PALETTE ( const LOGPALETTE* lpalette )
6269  {
6270  EMF_UNUSED(lpalette);
6271  palVersion = 0;
6272  palNumEntries = 0;
6273  PALETTEENTRY zero_entry = { 0, 0, 0, 0 };
6274  palPalEntry[0] = zero_entry;
6275  }
6279  OBJECTTYPE getType ( void ) const { return O_PALETTE; }
6286  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6287  {
6288  contexts[dc] = emf_handle;
6289  return new EMRCREATEPALETTE( this, emf_handle );
6290  }
6291  };
6292 
6294 
6298  public:
6302  EMRSETMITERLIMIT ( FLOAT limit )
6303  {
6304  emr.iType = EMR_SETMITERLIMIT;
6305  emr.nSize = sizeof( ::EMRSETMITERLIMIT );
6306  eMiterLimit = limit;
6307  }
6313  {
6314  int miter_limit;
6315  ds >> emr >> miter_limit;
6316  eMiterLimit = float(miter_limit);
6317  }
6321  bool serialize ( DATASTREAM ds )
6322  {
6323  ds << emr << (int)eMiterLimit;
6324  return true;
6325  }
6329  int size ( void ) const { return emr.nSize; }
6335  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
6336  {
6337  EMF_UNUSED(source);
6338  SetMiterLimit( dc, eMiterLimit, 0 );
6339  }
6340 #ifdef ENABLE_EDITING
6344  void edit ( void ) const
6345  {
6346  printf( "*SETMITERLIMIT*\n" );
6347  printf( "\teMiterLimit\t: %f\n", eMiterLimit );
6348  }
6349 #endif /* ENABLE_EDITING */
6350  };
6351 
6353 
6367  void init ( const RECT* size, LPCWSTR description_w ) {
6368 
6369  // Evidently, metafile handles are numbered from 1, so don't
6370  // ever use 0.
6371 
6372  handles.push_back( true );
6373 
6374  // Keep some of our graphics state in a header record
6375 
6376  header = new ENHMETAHEADER ( description_w );
6377  records.push_back( header );
6378 
6379  // Compute the size and position of the metafile on the "page"
6380 
6381  if ( size ) {
6382  update_frame = false;
6383 
6384  header->rclFrame.left = size->left;
6385  header->rclFrame.top = size->top;
6386  header->rclFrame.right = size->right;
6387  header->rclFrame.bottom = size->bottom;
6388 
6389  header->rclBounds.left =
6390  size->left * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
6391  header->rclBounds.top =
6392  size->top * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
6393  header->rclBounds.right =
6394  size->right * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
6395  header->rclBounds.bottom =
6396  size->bottom * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
6397  }
6398  else {
6399  update_frame = true;
6400 
6401  header->rclBounds.left = -10;
6402  header->rclBounds.top = -10;
6403  header->rclBounds.right = 10;
6404  header->rclBounds.bottom = 10;
6405 
6406  header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
6407  header->szlMillimeters.cx * 100 / header->szlDevice.cx );
6408  header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
6409  header->szlMillimeters.cy * 100 / header->szlDevice.cy );
6410  header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
6411  header->szlMillimeters.cx * 100 / header->szlDevice.cx );
6412  header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
6413  header->szlMillimeters.cy * 100 / header->szlDevice.cy );
6414  }
6415 
6416  // Some default graphics state (are they really, though?)
6417 
6418  SIZEL default_resolution = { RESOLUTION, RESOLUTION };
6419  resolution = default_resolution;
6420  SIZEL default_viewport_ext = { 1, 1 };
6421  viewport_ext = default_viewport_ext;
6422  POINT default_viewport_org = { 0, 0 };
6423  viewport_org = default_viewport_org;
6424  SIZEL default_window_ext = { 1, 1 };
6425  window_ext = default_window_ext;
6426  POINT default_window_org = { 0, 0 };
6427  window_org = default_window_org;
6428 
6431 
6432  pen = (PEN*)globalObjects.find( BLACK_PEN | ENHMETA_STOCK_OBJECT );
6433  brush = (BRUSH*)globalObjects.find( BLACK_BRUSH | ENHMETA_STOCK_OBJECT );
6434  font = (FONT*)globalObjects.find( DEVICE_DEFAULT_FONT | ENHMETA_STOCK_OBJECT);
6435  palette = (PALETTE*)globalObjects.find( DEFAULT_PALETTE|ENHMETA_STOCK_OBJECT);
6436 
6437  text_alignment = TA_BASELINE;
6438  text_color = RGB(0,0,0);
6439  bk_color = RGB(0xff,0xff,0xff);
6440  bk_mode = OPAQUE;
6441  polyfill_mode = ALTERNATE;
6442  map_mode = MM_TEXT;
6443  miter_limit = 10.f;
6444 
6445  handle = globalObjects.add( this );
6446  }
6447 
6448  public:
6452  ::FILE* fp;
6465  std::vector< EMF::METARECORD* > records;
6466 
6467  // Keep a small set of graphics state information
6468  SIZEL resolution;
6471  SIZEL window_ext;
6472  POINT window_org;
6476  POINT point;
6482  COLORREF text_color;
6483  COLORREF bk_color;
6484  INT bk_mode;
6486  INT map_mode;
6487  FLOAT miter_limit;
6488 
6494  std::vector< bool > handles;
6495 
6501  std::map< HGDIOBJ, HGDIOBJ > emf_handles;
6502 
6513  METAFILEDEVICECONTEXT ( FILE* fp_, const RECT* size,
6514  LPCWSTR description_w )
6515  : fp(fp_), ds( fp_ )
6516  {
6517  init( size, description_w );
6518  }
6524  {
6525  // Purge all the metarecords (if there are any) {this include the
6526  // header record, too}
6527  if ( records.size() > 0 )
6528  deleteMetafile();
6529  }
6533  OBJECTTYPE getType ( void ) const { return O_METAFILEDEVICECONTEXT; }
6538  DWORD nextHandle ( void )
6539  {
6540  for ( unsigned int i = 1; i < handles.size(); i++ ) {
6541  if ( !handles[i] ) {
6542  handles[i] = true;
6543  return i;
6544  }
6545  }
6546  handles.push_back( true );
6547  // Well, it appears that even StockObject handles count for something.
6548  // Not sure what the right value here is, then.
6549  header->nHandles = handles.size();
6550  return handles.size()-1;
6551  }
6555  void clearHandle ( DWORD handle )
6556  {
6557  if ( handle < handles.size() ) {
6558  handles[handle] = false;
6559  }
6560  }
6566  void appendRecord ( METARECORD* record )
6567  {
6568  records.push_back( record );
6569 
6570  header->nBytes += record->size();
6571  header->nRecords++;
6572  }
6578  void appendHandle ( METARECORD* record )
6579  {
6580  records.push_back( record );
6581 
6582  header->nBytes += record->size();
6583  header->nRecords++;
6584  }
6589  void deleteMetafile ( void )
6590  {
6591  for ( auto r = records.begin(); r != records.end(); r++ ) {
6592  delete *r;
6593  }
6594  records.clear();
6595  }
6600  void mergePoint ( const LONG& x, const LONG& y )
6601  {
6602  POINT p;
6603  p.x = x;
6604  p.y = y;
6605  mergePoint( p );
6606  }
6611  void mergePoint( const POINT& p )
6612  {
6613  POINT device_point;
6614 
6615  // *** Note, it's possible for the global transformation matrix to
6616  // affect this too. ***
6617 
6618  int window_width = window_ext.cx <= 0 ? 1 : window_ext.cx;
6619  int window_height = window_ext.cy <= 0 ? 1 : window_ext.cy;
6620 
6621  device_point.x = (LONG)( (float)( p.x - window_org.x ) / window_width *
6622  viewport_ext.cx + viewport_org.x );
6623 
6624  device_point.y = (LONG)( (float)( p.y - window_org.y ) / window_height *
6625  viewport_ext.cy + viewport_org.y );
6626 
6627  // If the user didn't specify a bounding rectangle in the constructor,
6628  // compute one from this data, too.
6629  if ( device_point.x < min_device_point.x ) {
6630  min_device_point.x = device_point.x;
6631  if ( update_frame ) {
6632  header->rclBounds.left = min_device_point.x - 10;
6633  int device_width = header->szlDevice.cx <= 0 ? 1 : header->szlDevice.cx;
6634  header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
6635  header->szlMillimeters.cx * 100 / device_width );
6636  }
6637  }
6638  else if ( device_point.x > max_device_point.x ) {
6639  max_device_point.x = device_point.x;
6640  if ( update_frame ) {
6641  header->rclBounds.right = max_device_point.x + 10;
6642  int device_width = header->szlDevice.cx <= 0 ? 1 : header->szlDevice.cx;
6643  header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
6644  header->szlMillimeters.cx * 100 / device_width );
6645  }
6646  }
6647 
6648  if ( device_point.y < min_device_point.y ) {
6649  min_device_point.y = device_point.y;
6650  if ( update_frame ) {
6651  header->rclBounds.top = min_device_point.y - 10;
6652  int device_height = header->szlDevice.cy <= 0 ? 1 : header->szlDevice.cy;
6653  header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
6654  header->szlMillimeters.cy * 100 / device_height );
6655  }
6656  }
6657  else if ( device_point.y > max_device_point.y ) {
6658  max_device_point.y = device_point.y;
6659  if ( update_frame ) {
6660  header->rclBounds.bottom = max_device_point.y + 10;
6661  int device_height = header->szlDevice.cy <= 0 ? 1 : header->szlDevice.cy;
6662  header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
6663  header->szlMillimeters.cy * 100 / device_height );
6664  }
6665  }
6666  }
6667  };
6668 
6669 } // close EMF namespace
6670 
6671 #undef EMF_UNUSED
6672 #endif /* _LIBEMF_H */
Graphics Brush.
Definition: libemf.h:6190
OBJECTTYPE getType(void) const
Definition: libemf.h:6204
BRUSH(const LOGBRUSH *lbrush)
Definition: libemf.h:6195
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6211
Support different endian modes when reading and writing the metafile.
Definition: libemf.h:224
DATASTREAM & operator>>(BYTE &byte)
Definition: libemf.h:252
void setStream(::FILE *fp)
Definition: libemf.h:238
DATASTREAM & operator<<(const BYTE &byte)
Definition: libemf.h:243
DATASTREAM(::FILE *fp=0)
Definition: libemf.h:233
EMF Arc To.
Definition: libemf.h:2995
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3047
bool serialize(DATASTREAM ds)
Definition: libemf.h:3033
EMRARCTO(INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: libemf.h:3008
EMRARCTO(DATASTREAM &ds)
Definition: libemf.h:3026
int size(void) const
Definition: libemf.h:3041
EMF Arc.
Definition: libemf.h:2919
EMRARC(INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: libemf.h:2932
bool serialize(DATASTREAM ds)
Definition: libemf.h:2957
EMRARC(DATASTREAM &ds)
Definition: libemf.h:2950
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2971
int size(void) const
Definition: libemf.h:2965
EMF Begin Path.
Definition: libemf.h:5789
EMRBEGINPATH(DATASTREAM &ds)
Definition: libemf.h:5803
EMRBEGINPATH(void)
Definition: libemf.h:5794
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5824
int size(void) const
Definition: libemf.h:5818
bool serialize(DATASTREAM ds)
Definition: libemf.h:5810
EMF Close Figure.
Definition: libemf.h:5897
int size(void) const
Definition: libemf.h:5926
EMRCLOSEFIGURE(DATASTREAM &ds)
Definition: libemf.h:5911
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5932
EMRCLOSEFIGURE(void)
Definition: libemf.h:5902
bool serialize(DATASTREAM ds)
Definition: libemf.h:5918
EMF Brush.
Definition: libemf.h:5383
int size(void) const
Definition: libemf.h:5406
bool serialize(DATASTREAM ds)
Definition: libemf.h:5398
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:639
EMRCREATEBRUSHINDIRECT(BRUSH *brush, HGDIOBJ handle)
Definition: libemf.cpp:631
EMF Palette.
Definition: libemf.h:5576
EMRCREATEPALETTE(PALETTE *palette, HGDIOBJ handle)
Definition: libemf.cpp:686
int size(void) const
Definition: libemf.h:5599
bool serialize(DATASTREAM ds)
Definition: libemf.h:5591
EMRCREATEPALETTE(DATASTREAM &ds)
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:694
EMF Pen.
Definition: libemf.h:5251
EMRCREATEPEN(PEN *pen, HGDIOBJ handle)
Definition: libemf.cpp:538
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:581
bool serialize(DATASTREAM ds)
Definition: libemf.h:5266
int size(void) const
Definition: libemf.h:5274
EMF Delete Object.
Definition: libemf.h:2743
bool serialize(DATASTREAM ds)
Definition: libemf.h:2765
EMRDELETEOBJECT(DATASTREAM &ds)
Definition: libemf.h:2758
EMRDELETEOBJECT(HGDIOBJ object)
Definition: libemf.h:2748
int size(void) const
Definition: libemf.h:2773
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:561
EMF Ellipse.
Definition: libemf.h:3134
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3177
bool serialize(DATASTREAM ds)
Definition: libemf.h:3163
EMRELLIPSE(INT left, INT top, INT right, INT bottom)
Definition: libemf.h:3143
int size(void) const
Definition: libemf.h:3171
EMRELLIPSE(DATASTREAM &ds)
Definition: libemf.h:3156
EMF End Path.
Definition: libemf.h:5843
bool serialize(DATASTREAM ds)
Definition: libemf.h:5864
int size(void) const
Definition: libemf.h:5872
EMRENDPATH(void)
Definition: libemf.h:5848
EMRENDPATH(DATASTREAM &ds)
Definition: libemf.h:5857
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5878
EMF End of File Record.
Definition: libemf.h:1676
int size(void) const
Definition: libemf.h:1710
bool serialize(DATASTREAM ds)
Definition: libemf.h:1702
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1716
EMREOF(DATASTREAM &ds)
Definition: libemf.h:1694
EMREOF(void)
Definition: libemf.h:1681
EMF Font.
Definition: libemf.h:5438
bool serialize(DATASTREAM ds)
Definition: libemf.h:5453
int size(void) const
Definition: libemf.h:5466
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:672
EMREXTCREATEFONTINDIRECTW(FONT *font, HGDIOBJ handle)
Definition: libemf.cpp:658
EMF Extended Pen.
Definition: libemf.h:5309
int size(void) const
Definition: libemf.h:5332
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:606
EMREXTCREATEPEN(EXTPEN *pen, HGDIOBJ handle)
Definition: libemf.cpp:594
bool serialize(DATASTREAM ds)
Definition: libemf.h:5324
EMF Extended Text Output ASCII.
Definition: libemf.h:4648
EMREXTTEXTOUTA(DATASTREAM &ds)
Definition: libemf.h:4721
bool serialize(DATASTREAM ds)
Definition: libemf.h:4771
~EMREXTTEXTOUTA()
Definition: libemf.h:4763
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4788
int size(void) const
Definition: libemf.h:4782
EMREXTTEXTOUTA(const RECTL *bounds, DWORD graphicsMode, FLOAT xScale, FLOAT yScale, const PEMRTEXT text, LPCSTR string, const INT *dx)
Definition: libemf.h:4663
EMF Extended Text Output Wide character.
Definition: libemf.h:4896
bool serialize(DATASTREAM ds)
Definition: libemf.h:5019
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5036
~EMREXTTEXTOUTW()
Definition: libemf.h:5011
EMREXTTEXTOUTW(const RECTL *bounds, DWORD graphicsMode, FLOAT xScale, FLOAT yScale, const PEMRTEXT text, LPCWSTR string, const INT *dx)
Definition: libemf.h:4911
int size(void) const
Definition: libemf.h:5030
EMREXTTEXTOUTW(DATASTREAM &ds)
Definition: libemf.h:4969
EMF Fill path.
Definition: libemf.h:5621
EMRFILLPATH(DATASTREAM &ds)
Definition: libemf.h:5636
bool serialize(DATASTREAM ds)
Definition: libemf.h:5643
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5657
int size(void) const
Definition: libemf.h:5651
EMRFILLPATH(const RECTL *bounds)
Definition: libemf.h:5626
EMF Line To.
Definition: libemf.h:2860
bool serialize(DATASTREAM ds)
Definition: libemf.h:2884
EMRLINETO(DATASTREAM &ds)
Definition: libemf.h:2877
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2898
EMRLINETO(INT x, INT y)
Definition: libemf.h:2866
int size(void) const
Definition: libemf.h:2892
EMF Modify World Transform.
Definition: libemf.h:2144
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2183
bool serialize(DATASTREAM ds)
Definition: libemf.h:2169
EMRMODIFYWORLDTRANSFORM(DATASTREAM &ds)
Definition: libemf.h:2162
int size(void) const
Definition: libemf.h:2177
EMRMODIFYWORLDTRANSFORM(const XFORM *transform, DWORD mode)
Definition: libemf.h:2151
EMF MoveTo (ex)
Definition: libemf.h:2801
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2839
EMRMOVETOEX(INT x, INT y)
Definition: libemf.h:2807
int size(void) const
Definition: libemf.h:2833
EMRMOVETOEX(DATASTREAM &ds)
Definition: libemf.h:2818
bool serialize(DATASTREAM ds)
Definition: libemf.h:2825
EMF Polybezier16.
Definition: libemf.h:4096
int size(void) const
Definition: libemf.h:4187
EMRPOLYBEZIER16(DATASTREAM &ds)
Definition: libemf.h:4152
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4193
~EMRPOLYBEZIER16()
Definition: libemf.h:4172
EMRPOLYBEZIER16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4129
bool serialize(DATASTREAM ds)
Definition: libemf.h:4179
EMRPOLYBEZIER16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:4104
EMF PolyBezierTo16.
Definition: libemf.h:4311
EMRPOLYBEZIERTO16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4344
bool serialize(DATASTREAM ds)
Definition: libemf.h:4394
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4408
EMRPOLYBEZIERTO16(DATASTREAM &ds)
Definition: libemf.h:4367
int size(void) const
Definition: libemf.h:4402
EMRPOLYBEZIERTO16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:4319
~EMRPOLYBEZIERTO16()
Definition: libemf.h:4387
EMF PolyBezierTo.
Definition: libemf.h:4216
~EMRPOLYBEZIERTO()
Definition: libemf.h:4267
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4288
int size(void) const
Definition: libemf.h:4282
bool serialize(DATASTREAM ds)
Definition: libemf.h:4274
EMRPOLYBEZIERTO(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4224
EMRPOLYBEZIERTO(DATASTREAM &ds)
Definition: libemf.h:4247
EMF Polybezier.
Definition: libemf.h:4001
EMRPOLYBEZIER(DATASTREAM &ds)
Definition: libemf.h:4032
int size(void) const
Definition: libemf.h:4067
~EMRPOLYBEZIER()
Definition: libemf.h:4052
bool serialize(DATASTREAM ds)
Definition: libemf.h:4059
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4073
EMRPOLYBEZIER(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4009
EMF Filled Polygon16.
Definition: libemf.h:3507
~EMRPOLYGON16()
Definition: libemf.h:3583
EMRPOLYGON16(const RECTL *bounds, const POINT16 *points, INT16 n)
Definition: libemf.h:3540
bool serialize(DATASTREAM ds)
Definition: libemf.h:3590
int size(void) const
Definition: libemf.h:3598
EMRPOLYGON16(DATASTREAM &ds)
Definition: libemf.h:3563
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3604
EMRPOLYGON16(const RECTL *bounds, const POINT *points, INT16 n)
Definition: libemf.h:3515
EMF Filled Polygon.
Definition: libemf.h:3412
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3484
int size(void) const
Definition: libemf.h:3478
EMRPOLYGON(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:3420
bool serialize(DATASTREAM ds)
Definition: libemf.h:3470
EMRPOLYGON(DATASTREAM &ds)
Definition: libemf.h:3443
~EMRPOLYGON()
Definition: libemf.h:3463
EMF Polyline16.
Definition: libemf.h:3292
bool serialize(DATASTREAM ds)
Definition: libemf.h:3375
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3389
EMRPOLYLINE16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:3300
EMRPOLYLINE16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:3325
EMRPOLYLINE16(DATASTREAM &ds)
Definition: libemf.h:3355
int size(void) const
Definition: libemf.h:3383
~EMRPOLYLINE16()
Definition: libemf.h:3347
EMF PolylineTo16.
Definition: libemf.h:4526
EMRPOLYLINETO16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4559
EMRPOLYLINETO16(DATASTREAM &ds)
Definition: libemf.h:4582
bool serialize(DATASTREAM ds)
Definition: libemf.h:4609
~EMRPOLYLINETO16()
Definition: libemf.h:4602
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4623
EMRPOLYLINETO16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:4534
int size(void) const
Definition: libemf.h:4617
EMF PolylineTo.
Definition: libemf.h:4431
EMRPOLYLINETO(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4439
~EMRPOLYLINETO()
Definition: libemf.h:4482
EMRPOLYLINETO(DATASTREAM &ds)
Definition: libemf.h:4462
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4503
bool serialize(DATASTREAM ds)
Definition: libemf.h:4489
int size(void) const
Definition: libemf.h:4497
EMF Polyline.
Definition: libemf.h:3198
int size(void) const
Definition: libemf.h:3263
bool serialize(DATASTREAM ds)
Definition: libemf.h:3255
EMRPOLYLINE(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:3206
~EMRPOLYLINE()
Definition: libemf.h:3228
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3269
EMRPOLYLINE(DATASTREAM &ds)
Definition: libemf.h:3236
EMF Poly Polygon16.
Definition: libemf.h:3796
int size(void) const
Definition: libemf.h:3943
bool serialize(DATASTREAM ds)
Definition: libemf.h:3934
EMRPOLYPOLYGON16(const RECTL *bounds, const POINT16 *points, const INT *counts, UINT16 polygons)
Definition: libemf.h:3847
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3949
EMRPOLYPOLYGON16(DATASTREAM &ds)
Definition: libemf.h:3893
EMRPOLYPOLYGON16(const RECTL *bounds, const POINT *points, const INT *counts, UINT polygons)
Definition: libemf.h:3806
~EMRPOLYPOLYGON16()
Definition: libemf.h:3884
EMF Poly Polygon.
Definition: libemf.h:3627
EMRPOLYPOLYGON(DATASTREAM &ds)
Definition: libemf.h:3683
EMRPOLYPOLYGON(const RECTL *bounds, const POINT *points, const INT *counts, UINT polygons)
Definition: libemf.h:3637
bool serialize(DATASTREAM ds)
Definition: libemf.h:3725
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3740
int size(void) const
Definition: libemf.h:3734
~EMRPOLYPOLYGON()
Definition: libemf.h:3674
EMF Rectangle.
Definition: libemf.h:3071
EMRRECTANGLE(DATASTREAM &ds)
Definition: libemf.h:3092
bool serialize(DATASTREAM ds)
Definition: libemf.h:3099
int size(void) const
Definition: libemf.h:3107
EMRRECTANGLE(INT left, INT top, INT right, INT bottom)
Definition: libemf.h:3079
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3113
EMF Restore DC.
Definition: libemf.h:6006
EMRRESTOREDC(INT n)
Definition: libemf.h:6011
EMRRESTOREDC(DATASTREAM &ds)
Definition: libemf.h:6021
int size(void) const
Definition: libemf.h:6036
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:6042
bool serialize(DATASTREAM ds)
Definition: libemf.h:6028
EMF Save DC.
Definition: libemf.h:5952
EMRSAVEDC(DATASTREAM &ds)
Definition: libemf.h:5966
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5987
int size(void) const
Definition: libemf.h:5981
EMRSAVEDC(void)
Definition: libemf.h:5957
bool serialize(DATASTREAM ds)
Definition: libemf.h:5973
EMF Scale Viewport Extents (ex)
Definition: libemf.h:1924
EMRSCALEVIEWPORTEXTEX(DATASTREAM &ds)
Definition: libemf.h:1945
int size(void) const
Definition: libemf.h:1960
EMRSCALEVIEWPORTEXTEX(LONG x_num, LONG x_den, LONG y_num, LONG y_den)
Definition: libemf.h:1932
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1966
bool serialize(DATASTREAM ds)
Definition: libemf.h:1952
EMF Scale Window Extents (ex)
Definition: libemf.h:2064
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2106
bool serialize(DATASTREAM ds)
Definition: libemf.h:2092
int size(void) const
Definition: libemf.h:2100
EMRSCALEWINDOWEXTEX(DATASTREAM &ds)
Definition: libemf.h:2085
EMRSCALEWINDOWEXTEX(LONG x_num, LONG x_den, LONG y_num, LONG y_den)
Definition: libemf.h:2072
EMF Select Object.
Definition: libemf.h:2685
EMRSELECTOBJECT(HGDIOBJ object)
Definition: libemf.h:2690
bool serialize(DATASTREAM ds)
Definition: libemf.h:2707
EMRSELECTOBJECT(DATASTREAM &ds)
Definition: libemf.h:2700
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:546
int size(void) const
Definition: libemf.h:2715
EMF Set Background Color.
Definition: libemf.h:2419
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2455
int size(void) const
Definition: libemf.h:2449
EMRSETBKCOLOR(COLORREF color)
Definition: libemf.h:2424
EMRSETBKCOLOR(DATASTREAM &ds)
Definition: libemf.h:2434
bool serialize(DATASTREAM ds)
Definition: libemf.h:2441
EMF Set Background Mode.
Definition: libemf.h:2477
EMRSETBKMODE(DWORD mode)
Definition: libemf.h:2482
int size(void) const
Definition: libemf.h:2507
bool serialize(DATASTREAM ds)
Definition: libemf.h:2499
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2513
EMRSETBKMODE(DATASTREAM &ds)
Definition: libemf.h:2492
EMF Set Mapping Mode.
Definition: libemf.h:2612
EMRSETMAPMODE(DWORD mode)
Definition: libemf.h:2617
EMRSETMAPMODE(DATASTREAM &ds)
Definition: libemf.h:2627
int size(void) const
Definition: libemf.h:2642
bool serialize(DATASTREAM ds)
Definition: libemf.h:2634
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2648
EMF Set Meta Region.
Definition: libemf.h:6067
EMRSETMETARGN(DATASTREAM &ds)
Definition: libemf.h:6081
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:6102
EMRSETMETARGN(void)
Definition: libemf.h:6072
bool serialize(DATASTREAM ds)
Definition: libemf.h:6088
int size(void) const
Definition: libemf.h:6096
EMF SetMiterLimit.
Definition: libemf.h:6297
bool serialize(DATASTREAM ds)
Definition: libemf.h:6321
EMRSETMITERLIMIT(FLOAT limit)
Definition: libemf.h:6302
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:6335
int size(void) const
Definition: libemf.h:6329
EMRSETMITERLIMIT(DATASTREAM &ds)
Definition: libemf.h:6312
EMF Set Pixel.
Definition: libemf.h:5182
EMRSETPIXELV(DATASTREAM &ds)
Definition: libemf.h:5201
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5222
bool serialize(DATASTREAM ds)
Definition: libemf.h:5208
EMRSETPIXELV(INT x, INT y, COLORREF color)
Definition: libemf.h:5189
int size(void) const
Definition: libemf.h:5216
EMF Set the Polygon Fill Mode.
Definition: libemf.h:2544
bool serialize(DATASTREAM ds)
Definition: libemf.h:2566
EMRSETPOLYFILLMODE(DATASTREAM &ds)
Definition: libemf.h:2559
int size(void) const
Definition: libemf.h:2574
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2580
EMRSETPOLYFILLMODE(DWORD mode)
Definition: libemf.h:2549
EMF Set Text Alignment.
Definition: libemf.h:2276
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2312
bool serialize(DATASTREAM ds)
Definition: libemf.h:2298
int size(void) const
Definition: libemf.h:2306
EMRSETTEXTALIGN(DATASTREAM &ds)
Definition: libemf.h:2291
EMRSETTEXTALIGN(UINT mode)
Definition: libemf.h:2281
EMF Set Text Color.
Definition: libemf.h:2362
EMRSETTEXTCOLOR(DATASTREAM &ds)
Definition: libemf.h:2377
EMRSETTEXTCOLOR(COLORREF color)
Definition: libemf.h:2367
bool serialize(DATASTREAM ds)
Definition: libemf.h:2384
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2398
int size(void) const
Definition: libemf.h:2392
EMF Set Viewport Extents (ex)
Definition: libemf.h:1863
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1901
int size(void) const
Definition: libemf.h:1895
EMRSETVIEWPORTEXTEX(INT cx, INT cy)
Definition: libemf.h:1869
bool serialize(DATASTREAM ds)
Definition: libemf.h:1887
EMRSETVIEWPORTEXTEX(DATASTREAM &ds)
Definition: libemf.h:1880
EMF Set Viewport Origin (ex)
Definition: libemf.h:1739
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1777
EMRSETVIEWPORTORGEX(INT x, INT y)
Definition: libemf.h:1745
bool serialize(DATASTREAM ds)
Definition: libemf.h:1763
EMRSETVIEWPORTORGEX(DATASTREAM &ds)
Definition: libemf.h:1756
int size(void) const
Definition: libemf.h:1771
EMF Set Window Extent (ex)
Definition: libemf.h:2003
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2041
bool serialize(DATASTREAM ds)
Definition: libemf.h:2027
EMRSETWINDOWEXTEX(DATASTREAM &ds)
Definition: libemf.h:2020
EMRSETWINDOWEXTEX(INT cx, INT cy)
Definition: libemf.h:2009
int size(void) const
Definition: libemf.h:2035
EMF Set Window Origin (ex)
Definition: libemf.h:1802
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1840
bool serialize(DATASTREAM ds)
Definition: libemf.h:1826
int size(void) const
Definition: libemf.h:1834
EMRSETWINDOWORGEX(INT x, INT y)
Definition: libemf.h:1808
EMRSETWINDOWORGEX(DATASTREAM &ds)
Definition: libemf.h:1819
EMF Set World Transform.
Definition: libemf.h:2219
bool serialize(DATASTREAM ds)
Definition: libemf.h:2241
EMRSETWORLDTRANSFORM(DATASTREAM &ds)
Definition: libemf.h:2234
int size(void) const
Definition: libemf.h:2249
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2255
EMRSETWORLDTRANSFORM(const XFORM *transform)
Definition: libemf.h:2224
EMF Stroke and Fill path.
Definition: libemf.h:5733
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5769
EMRSTROKEANDFILLPATH(DATASTREAM &ds)
Definition: libemf.h:5748
EMRSTROKEANDFILLPATH(const RECTL *bounds)
Definition: libemf.h:5738
bool serialize(DATASTREAM ds)
Definition: libemf.h:5755
int size(void) const
Definition: libemf.h:5763
EMF Stroke path.
Definition: libemf.h:5677
EMRSTROKEPATH(const RECTL *bounds)
Definition: libemf.h:5682
int size(void) const
Definition: libemf.h:5707
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5713
EMRSTROKEPATH(DATASTREAM &ds)
Definition: libemf.h:5692
bool serialize(DATASTREAM ds)
Definition: libemf.h:5699
Enhanced Metafile Header Record.
Definition: libemf.h:1423
bool serialize(DATASTREAM ds)
Definition: libemf.h:1511
int size(void) const
Definition: libemf.h:1571
ENHMETAHEADER(LPCWSTR description=0)
Definition: libemf.h:1435
bool unserialize(DATASTREAM ds)
Definition: libemf.h:1526
~ENHMETAHEADER()
Definition: libemf.h:1503
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1577
Extended Graphics Pen.
Definition: libemf.h:6154
EXTPEN(const EXTLOGPEN *lpen)
Definition: libemf.h:6159
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6179
OBJECTTYPE getType(void) const
Definition: libemf.h:6172
Graphics Font.
Definition: libemf.h:6222
FONT(const LOGFONTW *lfont)
Definition: libemf.h:6227
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6252
OBJECTTYPE getType(void) const
Definition: libemf.h:6245
Definition: libemf.h:1275
static EMF::METARECORD * new_extcreatefontindirectw(DATASTREAM &ds)
Create a new EXTCREATEFONTINDIRECTW record.
Definition: libemf.cpp:483
static EMF::METARECORD * new_exttextoutw(DATASTREAM &ds)
Create a new EXTTEXTOUTW record.
Definition: libemf.cpp:458
static EMF::METARECORD * new_arc(DATASTREAM &ds)
Create a new ARC record.
Definition: libemf.cpp:373
static EMF::METARECORD * new_polypolygon16(DATASTREAM &ds)
Create a new POLYPOLYGON16 record.
Definition: libemf.cpp:418
static EMF::METARECORD * new_modifyworldtransform(DATASTREAM &ds)
Create a new MODIFYWORLDTRANSFORM record.
Definition: libemf.cpp:313
static EMF::METARECORD * new_createbrushindirect(DATASTREAM &ds)
Create a new CREATEBRUSHINDIRECT record.
Definition: libemf.cpp:478
static EMF::METARECORD * new_ellipse(DATASTREAM &ds)
Create a new ELLIPSE record.
Definition: libemf.cpp:388
static EMF::METARECORD * new_savedc(DATASTREAM &ds)
Create a new SAVEDC record.
Definition: libemf.cpp:518
static EMF::METARECORD * new_polybezierto(DATASTREAM &ds)
Create a new POLYBEZIERTO record.
Definition: libemf.cpp:433
static EMF::METARECORD * new_createpen(DATASTREAM &ds)
Create a new CREATEPEN record.
Definition: libemf.cpp:468
static EMF::METARECORD * new_exttextouta(DATASTREAM &ds)
Create a new EXTTEXTOUTA record.
Definition: libemf.cpp:453
static EMF::METARECORD * new_scaleviewportextex(DATASTREAM &ds)
Create a new SCALEVIEWPORTEXTEX record.
Definition: libemf.cpp:303
static EMF::METARECORD * new_extcreatepen(DATASTREAM &ds)
Create a new EXTCREATEPEN record.
Definition: libemf.cpp:473
static EMF::METARECORD * new_setviewportorgex(DATASTREAM &ds)
Create a new EMRSETVIEWPORTORGEX record.
Definition: libemf.cpp:283
static EMF::METARECORD * new_setmiterlimit(DATASTREAM &ds)
Create a new SETMITERLIMIT record.
Definition: libemf.cpp:533
auto end(void) const
Definition: libemf.h:1304
static EMF::METARECORD * new_setbkmode(DATASTREAM &ds)
Create a new SETBKMODE record.
Definition: libemf.cpp:338
METARECORDCTOR newRecord(DWORD iType) const
Definition: libemf.cpp:268
static EMF::METARECORD * new_polyline(DATASTREAM &ds)
Create a new POLYLINE record.
Definition: libemf.cpp:393
static EMF::METARECORD * new_setviewportextex(DATASTREAM &ds)
Create a new EMRSETVIEWPORTEXTEX record.
Definition: libemf.cpp:293
static EMF::METARECORD * new_deleteobject(DATASTREAM &ds)
Create a new DELETEOBJECT record.
Definition: libemf.cpp:358
static EMF::METARECORD * new_polylineto(DATASTREAM &ds)
Create a new POLYLINETO record.
Definition: libemf.cpp:443
static EMF::METARECORD * new_polylineto16(DATASTREAM &ds)
Create a new POLYLINETO16 record.
Definition: libemf.cpp:448
static EMF::METARECORD * new_settextalign(DATASTREAM &ds)
Create a new SETTEXTALIGN record.
Definition: libemf.cpp:323
void remove(const OBJECT *object)
Definition: libemf.cpp:254
static EMF::METARECORD * new_polybezier16(DATASTREAM &ds)
Create a new POLYBEZIER16 record.
Definition: libemf.cpp:428
auto begin(void) const
Definition: libemf.h:1299
static EMF::METARECORD * new_polypolygon(DATASTREAM &ds)
Create a new POLYPOLYGON record.
Definition: libemf.cpp:413
static EMF::METARECORD * new_setwindowextex(DATASTREAM &ds)
Create a new EMRSETWINDOWEXTEX record.
Definition: libemf.cpp:298
static EMF::METARECORD * new_polyline16(DATASTREAM &ds)
Create a new POLYLINE16 record.
Definition: libemf.cpp:398
static EMF::METARECORD * new_endpath(DATASTREAM &ds)
Create a new ENDPATH record.
Definition: libemf.cpp:508
static EMF::METARECORD * new_setpixelv(DATASTREAM &ds)
Create a new SETPIXELV record.
Definition: libemf.cpp:463
static EMF::METARECORD * new_restoredc(DATASTREAM &ds)
Create a new RESTOREDC record.
Definition: libemf.cpp:523
static EMF::METARECORD * new_beginpath(DATASTREAM &ds)
Create a new BEGINPATH record.
Definition: libemf.cpp:503
static EMF::METARECORD * new_scalewindowextex(DATASTREAM &ds)
Create a new SCALEWINDOWEXTEX record.
Definition: libemf.cpp:308
static EMF::METARECORD * new_setmapmode(DATASTREAM &ds)
Create a new SETMAPMODE record.
Definition: libemf.cpp:348
static EMF::METARECORD * new_polybezierto16(DATASTREAM &ds)
Create a new POLYBEZIERTO16 record.
Definition: libemf.cpp:438
static EMF::METARECORD * new_eof(DATASTREAM &ds)
Create a new EMREOF record.
Definition: libemf.cpp:278
static EMF::METARECORD * new_setbkcolor(DATASTREAM &ds)
Create a new SETBKCOLOR record.
Definition: libemf.cpp:333
static EMF::METARECORD * new_setworldtransform(DATASTREAM &ds)
Create a new SETWORLDTRANSFORM record.
Definition: libemf.cpp:318
static EMF::METARECORD * new_setwindoworgex(DATASTREAM &ds)
Create a new EMRSETWINDOWORGEX record.
Definition: libemf.cpp:288
static EMF::METARECORD * new_strokeandfillpath(DATASTREAM &ds)
Create a new STROKEANDFILLPATH record.
Definition: libemf.cpp:498
HGDIOBJ add(OBJECT *object)
Definition: libemf.cpp:199
static EMF::METARECORD * new_polygon(DATASTREAM &ds)
Create a new POLYGON record.
Definition: libemf.cpp:403
static EMF::METARECORD * new_strokepath(DATASTREAM &ds)
Create a new STROKEPATH record.
Definition: libemf.cpp:493
static EMF::METARECORD * new_polygon16(DATASTREAM &ds)
Create a new POLYGON16 record.
Definition: libemf.cpp:408
static EMF::METARECORD * new_fillpath(DATASTREAM &ds)
Create a new FILLPATH record.
Definition: libemf.cpp:488
static EMF::METARECORD * new_arcto(DATASTREAM &ds)
Create a new ARCTO record.
Definition: libemf.cpp:378
static EMF::METARECORD * new_lineto(DATASTREAM &ds)
Create a new LINETO record.
Definition: libemf.cpp:368
static EMF::METARECORD * new_setpolyfillmode(DATASTREAM &ds)
Create a new SETPOLYFILLMODE record.
Definition: libemf.cpp:343
static EMF::METARECORD * new_settextcolor(DATASTREAM &ds)
Create a new SETTEXTCOLOR record.
Definition: libemf.cpp:328
static EMF::METARECORD * new_rectangle(DATASTREAM &ds)
Create a new RECTANGLE record.
Definition: libemf.cpp:383
static EMF::METARECORD * new_movetoex(DATASTREAM &ds)
Create a new MOVETOEX record.
Definition: libemf.cpp:363
static EMF::METARECORD * new_closefigure(DATASTREAM &ds)
Create a new CLOSEFIGURE record.
Definition: libemf.cpp:513
static EMF::METARECORD * new_polybezier(DATASTREAM &ds)
Create a new POLYBEZIER record.
Definition: libemf.cpp:423
static EMF::METARECORD * new_selectobject(DATASTREAM &ds)
Create a new SELECTOBJECT record.
Definition: libemf.cpp:353
static EMF::METARECORD * new_setmetargn(DATASTREAM &ds)
Create a new SETMETARGN record.
Definition: libemf.cpp:528
OBJECT * find(const HGDIOBJ handle)
Definition: libemf.cpp:231
A global graphics object.
Definition: libemf.h:1252
virtual METARECORD * newEMR(HDC dc, HGDIOBJ handle)=0
std::map< HDC, HGDIOBJ > contexts
Definition: libemf.h:1260
virtual ~GRAPHICSOBJECT()
GRAPHICSOBJECTs has a virtual destructor.
Definition: libemf.h:1255
Graphics Device Context.
Definition: libemf.h:6359
void clearHandle(DWORD handle)
Definition: libemf.h:6555
OBJECTTYPE getType(void) const
Definition: libemf.h:6533
void appendHandle(METARECORD *record)
Definition: libemf.h:6578
ENHMETAHEADER * header
Definition: libemf.h:6461
INT polyfill_mode
The current polygon fill mode.
Definition: libemf.h:6485
POINT window_org
The origin of the window.
Definition: libemf.h:6472
void deleteMetafile(void)
Definition: libemf.h:6589
::FILE * fp
Definition: libemf.h:6452
PEN * pen
The current pen.
Definition: libemf.h:6477
FONT * font
The current font.
Definition: libemf.h:6479
BRUSH * brush
The current brush.
Definition: libemf.h:6478
SIZEL viewport_ext
The extent of the viewport.
Definition: libemf.h:6469
bool update_frame
Update the frame automatically?
Definition: libemf.h:6473
SIZEL resolution
The resolution in DPI of the reference DC.
Definition: libemf.h:6468
UINT text_alignment
The current text alignment.
Definition: libemf.h:6481
virtual ~METAFILEDEVICECONTEXT()
Definition: libemf.h:6523
void appendRecord(METARECORD *record)
Definition: libemf.h:6566
FLOAT miter_limit
The current miter length limit.
Definition: libemf.h:6487
POINT min_device_point
The lft/top-most painted point in device units.
Definition: libemf.h:6474
void mergePoint(const LONG &x, const LONG &y)
Definition: libemf.h:6600
POINT point
The current point.
Definition: libemf.h:6476
INT map_mode
The current mapping mode.
Definition: libemf.h:6486
COLORREF bk_color
The current background color.
Definition: libemf.h:6483
DATASTREAM ds
Definition: libemf.h:6457
std::vector< bool > handles
Definition: libemf.h:6494
POINT max_device_point
The rgt/btm-most painted point in device units.
Definition: libemf.h:6475
METAFILEDEVICECONTEXT(FILE *fp_, const RECT *size, LPCWSTR description_w)
Definition: libemf.h:6513
COLORREF text_color
The current text foreground color.
Definition: libemf.h:6482
PALETTE * palette
The current palette.
Definition: libemf.h:6480
POINT viewport_org
The origin of the viewport.
Definition: libemf.h:6470
SIZEL window_ext
The extent of the window.
Definition: libemf.h:6471
INT bk_mode
The current background mode.
Definition: libemf.h:6484
std::vector< EMF::METARECORD * > records
Definition: libemf.h:6465
void mergePoint(const POINT &p)
Definition: libemf.h:6611
std::map< HGDIOBJ, HGDIOBJ > emf_handles
Definition: libemf.h:6501
DWORD nextHandle(void)
Definition: libemf.h:6538
The base class of all metafile records.
Definition: libemf.h:988
virtual int size(void) const =0
virtual ~METARECORD()
Definition: libemf.h:1015
virtual void execute(METAFILEDEVICECONTEXT *source, HDC dc) const =0
virtual bool serialize(DATASTREAM ds)=0
Global GDI object.
Definition: libemf.h:1230
OBJECT(void)
Definition: libemf.h:1239
virtual OBJECTTYPE getType(void) const =0
HGDIOBJ handle
Definition: libemf.h:1232
virtual ~OBJECT()
OBJECTs have a virtual destructor.
Definition: libemf.h:1234
Graphics Palette.
Definition: libemf.h:6263
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6286
OBJECTTYPE getType(void) const
Definition: libemf.h:6279
PALETTE(const LOGPALETTE *lpalette)
Definition: libemf.h:6268
Graphics Pen.
Definition: libemf.h:6122
PEN(const LOGPEN *lpen)
Definition: libemf.h:6127
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6143
OBJECTTYPE getType(void) const
Definition: libemf.h:6136
Represent a byte array in a simple way.
Definition: libemf.h:126
const int n_
Number of bytes in array.
Definition: libemf.h:128
BYTE *const array_
Array of unsigned bytes.
Definition: libemf.h:127
BYTEARRAY(BYTE *const array, const int n)
Definition: libemf.h:134
Represent an ASCII character string in a simple way.
Definition: libemf.h:109
const int length_
Number of single byte characters in array.
Definition: libemf.h:111
CHARSTR(CHAR *const string, const int length)
Definition: libemf.h:117
CHAR *const string_
Array of single byte characters.
Definition: libemf.h:110
Represent an array of double word integers in a simple way.
Definition: libemf.h:190
DWORD *const dwords_
Array of double words.
Definition: libemf.h:191
const DWORD n_
Number of double words in array.
Definition: libemf.h:192
DWORDARRAY(DWORD *const dwords, const DWORD n)
Definition: libemf.h:198
Represent an array of integers in a simple way.
Definition: libemf.h:174
INT *const ints_
Array of ints.
Definition: libemf.h:175
const DWORD n_
Number of ints in array.
Definition: libemf.h:176
INTARRAY(INT *const ints, const DWORD n)
Definition: libemf.h:182
All metafile records must be padded out to a multiple of 4 bytes.
Definition: libemf.h:206
static const char padding_[4]
Pad with '\0's.
Definition: libemf.h:207
PADDING(const int size)
Definition: libemf.h:213
const int size_
Number of bytes of padding.
Definition: libemf.h:208
Represent an array of 16-bit point in a simple way.
Definition: libemf.h:158
POINT16 *const points_
Array of POINT16s.
Definition: libemf.h:159
const DWORD n_
Number of POINT16s in array.
Definition: libemf.h:160
POINT16ARRAY(POINT16 *const points, const DWORD n)
Definition: libemf.h:166
Represent an array of points in a simple way.
Definition: libemf.h:142
const DWORD n_
Number of POINTLs in array.
Definition: libemf.h:144
POINTL *const points_
Array of POINTLs.
Definition: libemf.h:143
POINTLARRAY(POINTL *const points, const DWORD n)
Definition: libemf.h:150
Represent a wide (UNICODE) character string in a simple way.
Definition: libemf.h:91
const int length_
Number of WCHARs in string.
Definition: libemf.h:93
WCHARSTR(WCHAR *const string, const int length)
Definition: libemf.h:99
WCHAR *const string_
String of WCHARs.
Definition: libemf.h:92