libemf  1.0.9
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 94 2020-04-25 18:46:06Z 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 <functional>
28 #include <algorithm>
29 #include <stdexcept>
30 #include <memory>
31 
32 #include <config.h>
33 #include <libEMF/emf.h>
34 
35 #include <libEMF/wine/w16.h>
36 
37 #ifdef ENABLE_EDITING
38 #include <iconv.h>
39 #include <errno.h>
40 #endif
41 
42 #define EMF_UNUSED(x) (void)x;
43 
44 namespace EMF {
49 #if 1
50  const int XMAX_PIXELS = 1024; /*(INT_MAX)*/
51 #else
52  const int XMAX_PIXELS = 1280; /*(INT_MAX)*/
53 #endif
58 #if 1
59  const int YMAX_PIXELS = 768; /*(INT_MAX)*/
60 #else
61  const int YMAX_PIXELS = 1024; /*(INT_MAX)*/
62 #endif
68  const int XMAX_MM = 320;
74  const int YMAX_MM = 240;
78  const int RESOLUTION = 96;
82  static inline DWORD ROUND_TO_LONG ( DWORD n ) { return ((n+3)/4)*4; }
83 
84  static bool bigEndian ( void );
85 
87 
92  struct WCHARSTR {
93  WCHAR *const string_;
94  const int length_;
100  WCHARSTR ( WCHAR *const string, const int length )
101  : string_( string ), length_( length ) {}
102  };
103 
105 
110  struct CHARSTR {
111  CHAR *const string_;
112  const int length_;
118  CHARSTR ( CHAR *const string, const int length )
119  : string_( string ), length_( length ) {}
120  };
121 
123 
127  struct BYTEARRAY {
128  BYTE *const array_;
129  const int n_;
135  BYTEARRAY ( BYTE *const array, const int n )
136  : array_( array ), n_( n ) {}
137  };
138 
140 
143  struct POINTLARRAY {
144  POINTL *const points_;
145  const DWORD n_;
151  POINTLARRAY ( POINTL *const points, const DWORD n )
152  : points_( points ), n_( n ) {}
153  };
154 
156 
159  struct POINT16ARRAY {
160  POINT16 *const points_;
161  const DWORD n_;
167  POINT16ARRAY ( POINT16 *const points, const DWORD n )
168  : points_( points ), n_( n ) {}
169  };
170 
172 
175  struct INTARRAY {
176  INT *const ints_;
177  const DWORD n_;
183  INTARRAY ( INT *const ints, const DWORD n )
184  : ints_( ints ), n_( n ) {}
185  };
186 
188 
191  struct DWORDARRAY {
192  DWORD *const dwords_;
193  const DWORD n_;
199  DWORDARRAY ( DWORD *const dwords, const DWORD n )
200  : dwords_( dwords ), n_( n ) {}
201  };
202 
204 
207  struct PADDING {
208  static const char padding_[4];
209  const int size_;
214  PADDING ( const int size ) : size_( size ) {}
215  };
216 
218 
225  class DATASTREAM {
226  bool swap_;
227  ::FILE* fp_;
228  public:
234  DATASTREAM ( ::FILE* fp = 0 ) : swap_( bigEndian() ), fp_( fp ) {}
239  void setStream ( ::FILE* fp ) { fp_ = fp; }
244  DATASTREAM& operator<< ( const BYTE& byte )
245  {
246  fwrite( &byte, sizeof(BYTE), 1, fp_ );
247  return *this;
248  }
253  DATASTREAM& operator>> ( BYTE& byte )
254  {
255  fread( &byte, sizeof(BYTE), 1, fp_ );
256  return *this;
257  }
262  DATASTREAM& operator<< ( const WORD& word )
263  {
264  if ( swap_ ) {
265  unsigned char const * p = (unsigned char const*)&word;
266  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
267  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
268  }
269  else
270  fwrite( &word, sizeof(WORD), 1, fp_ );
271  return *this;
272  }
277  DATASTREAM& operator>> ( WORD& word )
278  {
279  if ( swap_ ) {
280  unsigned char* p = (unsigned char*)&word;
281  fread( &p[1], sizeof(unsigned char), 1, fp_ );
282  fread( &p[0], sizeof(unsigned char), 1, fp_ );
283  }
284  else
285  fread( &word, sizeof(WORD), 1, fp_ );
286  return *this;
287  }
292  DATASTREAM& operator<< ( const INT16& word )
293  {
294  if ( swap_ ) {
295  unsigned char const * p = (unsigned char const*)&word;
296  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
297  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
298  }
299  else
300  fwrite( &word, sizeof(INT16), 1, fp_ );
301  return *this;
302  }
307  DATASTREAM& operator>> ( INT16& word )
308  {
309  if ( swap_ ) {
310  unsigned char* p = (unsigned char*)&word;
311  fread( &p[1], sizeof(unsigned char), 1, fp_ );
312  fread( &p[0], sizeof(unsigned char), 1, fp_ );
313  }
314  else
315  fread( &word, sizeof(INT16), 1, fp_ );
316  return *this;
317  }
322  DATASTREAM& operator<< ( const DWORD& dword )
323  {
324  if ( swap_ ) {
325  unsigned char const* p = (unsigned char const*)&dword;
326  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
327  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
328  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
329  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
330  }
331  else
332  fwrite( &dword, sizeof(DWORD), 1, fp_ );
333  return *this;
334  }
339  DATASTREAM& operator>> ( DWORD& dword )
340  {
341  if ( swap_ ) {
342  unsigned char* p = (unsigned char*)&dword;
343  fread( &p[3], sizeof(unsigned char), 1, fp_ );
344  fread( &p[2], sizeof(unsigned char), 1, fp_ );
345  fread( &p[1], sizeof(unsigned char), 1, fp_ );
346  fread( &p[0], sizeof(unsigned char), 1, fp_ );
347  }
348  else
349  fread( &dword, sizeof(DWORD), 1, fp_ );
350  return *this;
351  }
352 #if !defined( __LP64__ )
357  DATASTREAM& operator<< ( const LONG& long_ )
358  {
359  if ( swap_ ) {
360  unsigned char const* p = (unsigned char const*)&long_;
361  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
362  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
363  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
364  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
365  }
366  else
367  fwrite( &long_, sizeof(LONG), 1, fp_ );
368  return *this;
369  }
374  DATASTREAM& operator>> ( LONG& long_ )
375  {
376  if ( swap_ ) {
377  unsigned char* p = (unsigned char*)&long_;
378  fread( &p[3], sizeof(unsigned char), 1, fp_ );
379  fread( &p[2], sizeof(unsigned char), 1, fp_ );
380  fread( &p[1], sizeof(unsigned char), 1, fp_ );
381  fread( &p[0], sizeof(unsigned char), 1, fp_ );
382  }
383  else
384  fread( &long_, sizeof(LONG), 1, fp_ );
385  return *this;
386  }
387 #endif /* __x86_64__ */
392  DATASTREAM& operator<< ( const INT& int_ )
393  {
394  if ( swap_ ) {
395  unsigned char const* p = (unsigned char const*)&int_;
396  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
397  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
398  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
399  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
400  }
401  else
402  fwrite( &int_, sizeof(INT), 1, fp_ );
403  return *this;
404  }
409  DATASTREAM& operator>> ( INT& int_ )
410  {
411  if ( swap_ ) {
412  unsigned char* p = (unsigned char*)&int_;
413  fread( &p[3], sizeof(unsigned char), 1, fp_ );
414  fread( &p[2], sizeof(unsigned char), 1, fp_ );
415  fread( &p[1], sizeof(unsigned char), 1, fp_ );
416  fread( &p[0], sizeof(unsigned char), 1, fp_ );
417  }
418  else
419  fread( &int_, sizeof(INT), 1, fp_ );
420  return *this;
421  }
422 #if !defined(__LP64__)
427  DATASTREAM& operator<< ( const UINT& uint )
428  {
429  if ( swap_ ) {
430  unsigned char const* p = (unsigned char const*)&uint;
431  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
432  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
433  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
434  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
435  }
436  else
437  fwrite( &uint, sizeof(UINT), 1, fp_ );
438  return *this;
439  }
444  DATASTREAM& operator>> ( UINT& uint )
445  {
446  if ( swap_ ) {
447  unsigned char* p = (unsigned char*)&uint;
448  fread( &p[3], sizeof(unsigned char), 1, fp_ );
449  fread( &p[2], sizeof(unsigned char), 1, fp_ );
450  fread( &p[1], sizeof(unsigned char), 1, fp_ );
451  fread( &p[0], sizeof(unsigned char), 1, fp_ );
452  }
453  else
454  fread( &uint, sizeof(UINT), 1, fp_ );
455  return *this;
456  }
457 #endif /* !__x86_64__ */
462  DATASTREAM& operator<< ( const FLOAT& float_ )
463  {
464  if ( swap_ ) {
465  unsigned char const* p = (unsigned char const*)&float_;
466  fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
467  fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
468  fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
469  fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
470  }
471  else
472  fwrite( &float_, sizeof(FLOAT), 1, fp_ );
473  return *this;
474  }
479  DATASTREAM& operator>> ( FLOAT& float_ )
480  {
481  if ( swap_ ) {
482  unsigned char* p = (unsigned char*)&float_;
483  fread( &p[3], sizeof(unsigned char), 1, fp_ );
484  fread( &p[2], sizeof(unsigned char), 1, fp_ );
485  fread( &p[1], sizeof(unsigned char), 1, fp_ );
486  fread( &p[0], sizeof(unsigned char), 1, fp_ );
487  }
488  else
489  fread( &float_, sizeof(FLOAT), 1, fp_ );
490  return *this;
491  }
496  DATASTREAM& operator<< ( const PADDING& padding )
497  {
498  if ( padding.size_ != 0 )
499  fwrite( &padding.padding_, sizeof(CHAR), padding.size_, fp_ );
500  return *this;
501  }
506  DATASTREAM& operator<< ( const RECTL& rectl )
507  {
508  *this << rectl.left << rectl.top << rectl.right << rectl.bottom;
509  return *this;
510  }
515  DATASTREAM& operator>> ( RECTL& rectl )
516  {
517  *this >> rectl.left >> rectl.top >> rectl.right >> rectl.bottom;
518  return *this;
519  }
524  DATASTREAM& operator<< ( const SIZEL& sizel )
525  {
526  *this << sizel.cx << sizel.cy;
527  return *this;
528  }
533  DATASTREAM& operator>> ( SIZEL& sizel )
534  {
535  *this >> sizel.cx >> sizel.cy;
536  return *this;
537  }
542  DATASTREAM& operator<< ( const WCHARSTR& wcharstr )
543  {
544  for ( int i = 0; i < wcharstr.length_; i++ )
545  *this << wcharstr.string_[i];
546  return *this;
547  }
553  {
554  for ( int i = 0; i < wcharstr.length_; i++ )
555  *this >> wcharstr.string_[i];
556  return *this;
557  }
562  DATASTREAM& operator<< ( const CHARSTR& charstr )
563  {
564  fwrite( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
565  return *this;
566  }
572  {
573  fread( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
574  return *this;
575  }
580  DATASTREAM& operator<< ( const ::EMR& emr )
581  {
582  *this << emr.iType << emr.nSize;
583  return *this;
584  }
589  DATASTREAM& operator>> ( ::EMR& emr )
590  {
591  *this >> emr.iType >> emr.nSize;
592  return *this;
593  }
598  DATASTREAM& operator<< ( const POINT& point )
599  {
600  *this << point.x << point.y;
601  return *this;
602  }
607  DATASTREAM& operator>> ( POINT& point )
608  {
609  *this >> point.x >> point.y;
610  return *this;
611  }
616  DATASTREAM& operator<< ( const POINTL& pointl )
617  {
618  *this << pointl.x << pointl.y;
619  return *this;
620  }
625  DATASTREAM& operator>> ( POINTL& pointl )
626  {
627  *this >> pointl.x >> pointl.y;
628  return *this;
629  }
634  DATASTREAM& operator<< ( const POINT16& point )
635  {
636  *this << point.x << point.y;
637  return *this;
638  }
643  DATASTREAM& operator>> ( POINT16& point )
644  {
645  *this >> point.x >> point.y;
646  return *this;
647  }
652  DATASTREAM& operator<< ( const XFORM& xform )
653  {
654  *this << xform.eM11 << xform.eM12 << xform.eM21 << xform.eM22
655  << xform.eDx << xform.eDy;
656  return *this;
657  }
662  DATASTREAM& operator>> ( XFORM& xform )
663  {
664  *this >> xform.eM11 >> xform.eM12 >> xform.eM21 >> xform.eM22
665  >> xform.eDx >> xform.eDy;
666  return *this;
667  }
673  {
674  fwrite( array.array_, sizeof(BYTE), array.n_, fp_ );
675  return *this;
676  }
682  {
683  fread( array.array_, sizeof(BYTE), array.n_, fp_ );
684  return *this;
685  }
691  {
692  for ( unsigned int i = 0; i < array.n_; i++ )
693  *this << array.points_[i];
694  return *this;
695  }
701  {
702  for ( unsigned int i = 0; i < array.n_; i++ )
703  *this >> array.points_[i];
704  return *this;
705  }
711  {
712  for ( unsigned int i = 0; i < array.n_; i++ )
713  *this << array.points_[i];
714  return *this;
715  }
721  {
722  for ( unsigned int i = 0; i < array.n_; i++ )
723  *this >> array.points_[i];
724  return *this;
725  }
730  DATASTREAM& operator<< ( const INTARRAY& array )
731  {
732  for ( unsigned int i = 0; i < array.n_; i++ )
733  *this << array.ints_[i];
734  return *this;
735  }
741  {
742  for ( unsigned int i = 0; i < array.n_; i++ )
743  *this >> array.ints_[i];
744  return *this;
745  }
751  {
752  for ( unsigned int i = 0; i < array.n_; i++ )
753  *this << array.dwords_[i];
754  return *this;
755  }
761  {
762  for ( unsigned int i = 0; i < array.n_; i++ )
763  *this >> array.dwords_[i];
764  return *this;
765  }
770  DATASTREAM& operator<< ( const ::EMRTEXT& text )
771  {
772  *this << text.ptlReference << text.nChars << text.offString << text.fOptions
773  << text.rcl << text.offDx;
774  return *this;
775  }
780  DATASTREAM& operator>> ( ::EMRTEXT& text )
781  {
782  *this >> text.ptlReference >> text.nChars >> text.offString >> text.fOptions
783  >> text.rcl >> text.offDx;
784  return *this;
785  }
790  DATASTREAM& operator<< ( const LOGPEN& pen )
791  {
792  *this << pen.lopnStyle << pen.lopnWidth << pen.lopnColor;
793  return *this;
794  }
799  DATASTREAM& operator>> ( LOGPEN& pen )
800  {
801  *this >> pen.lopnStyle >> pen.lopnWidth >> pen.lopnColor;
802  return *this;
803  }
808  DATASTREAM& operator<< ( const EXTLOGPEN& pen )
809  {
810  // *** How big is this structure if there are no style entries? ***
811  *this << pen.elpPenStyle << pen.elpWidth << pen.elpBrushStyle << pen.elpColor
812  << pen.elpHatch << pen.elpNumEntries;
813  return *this;
814  }
819  DATASTREAM& operator>> ( EXTLOGPEN& pen )
820  {
821  // *** How big is this structure if there are no style entries? ***
822  *this >> pen.elpPenStyle >> pen.elpWidth >> pen.elpBrushStyle >> pen.elpColor
823  >> pen.elpHatch >> pen.elpNumEntries;
824  return *this;
825  }
830  DATASTREAM& operator<< ( const LOGBRUSH& brush )
831  {
832  *this << brush.lbStyle << brush.lbColor << brush.lbHatch;
833  return *this;
834  }
839  DATASTREAM& operator>> ( LOGBRUSH& brush )
840  {
841  *this >> brush.lbStyle >> brush.lbColor >> brush.lbHatch;
842  return *this;
843  }
848  DATASTREAM& operator<< ( const LOGFONTW& font )
849  {
850  *this << font.lfHeight << font.lfWidth << font.lfEscapement
851  << font.lfOrientation << font.lfWeight << font.lfItalic
852  << font.lfUnderline << font.lfStrikeOut << font.lfCharSet
853  << font.lfOutPrecision << font.lfClipPrecision << font.lfQuality
854  << font.lfPitchAndFamily
855  << WCHARSTR( const_cast<WCHAR*>(font.lfFaceName), LF_FACESIZE );
856  return *this;
857  }
862  DATASTREAM& operator>> ( LOGFONTW& font )
863  {
864  WCHARSTR wFaceName( font.lfFaceName, LF_FACESIZE );
865 
866  *this >> font.lfHeight >> font.lfWidth >> font.lfEscapement
867  >> font.lfOrientation >> font.lfWeight >> font.lfItalic
868  >> font.lfUnderline >> font.lfStrikeOut >> font.lfCharSet
869  >> font.lfOutPrecision >> font.lfClipPrecision >> font.lfQuality
870  >> font.lfPitchAndFamily
871  >> wFaceName;
872  return *this;
873  }
878  DATASTREAM& operator<< ( const PANOSE& panose )
879  {
880  fwrite( &panose, sizeof(PANOSE), 1, fp_ );
881  return *this;
882  }
887  DATASTREAM& operator>> ( PANOSE& panose )
888  {
889  fread( &panose, sizeof(PANOSE), 1, fp_ );
890  return *this;
891  }
896  DATASTREAM& operator<< ( const EXTLOGFONTW& font )
897  {
898  *this << font.elfLogFont
899  << WCHARSTR( const_cast<WCHAR*>(font.elfFullName),
900  LF_FULLFACESIZE )
901  << WCHARSTR( const_cast<WCHAR*>(font.elfStyle), LF_FACESIZE )
902  << font.elfVersion << font.elfStyleSize << font.elfMatch
903  << font.elfReserved
904  << BYTEARRAY( const_cast<BYTE*>(font.elfVendorId),
905  ELF_VENDOR_SIZE )
906  << font.elfCulture << font.elfPanose;
907  return *this;
908  }
913  DATASTREAM& operator>> ( EXTLOGFONTW& font )
914  {
915  WCHARSTR wFullName( font.elfFullName, LF_FULLFACESIZE );
916  WCHARSTR wStyle( font.elfStyle, LF_FACESIZE );
917  BYTEARRAY bVendorId( font.elfVendorId, ELF_VENDOR_SIZE );
918  *this >> font.elfLogFont
919  >> wFullName >> wStyle
920  >> font.elfVersion >> font.elfStyleSize >> font.elfMatch
921  >> font.elfReserved >> bVendorId
922  >> font.elfCulture >> font.elfPanose;
923  return *this;
924  }
929  DATASTREAM& operator<< ( const LOGPALETTE& palette )
930  {
931  // *** How big is this structure if the palette is empty? ***
932  *this << palette.palVersion << palette.palNumEntries;
933  return *this;
934  }
939  DATASTREAM& operator>> ( LOGPALETTE& palette )
940  {
941  // *** How big is this structure if the palette is empty? ***
942  *this >> palette.palVersion >> palette.palNumEntries;
943  return *this;
944  }
945  private:
955  void fread ( void* ptr, size_t size, size_t nmemb, FILE* stream )
956  {
957  size_t res = ::fread( ptr, size, nmemb, stream );
958  if ( res < nmemb ) {
959  throw std::runtime_error( "Premature EOF on EMF stream" );
960  }
961  }
971  void fwrite ( const void* ptr, size_t size, size_t nmemb, FILE* stream )
972  {
973  size_t res = ::fwrite( ptr, size, nmemb, stream );
974  if ( res < nmemb ) {
975  throw std::runtime_error( "error writing EMF stream" );
976  }
977  }
978  };
979 
980  class METAFILEDEVICECONTEXT;
981 
983 
989  class METARECORD {
990  public:
997  virtual void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const = 0;
1004  virtual bool serialize ( DATASTREAM ds ) = 0;
1010  virtual int size ( void ) const = 0;
1016  virtual ~METARECORD( ) { }
1017 #ifdef ENABLE_EDITING
1022  virtual void edit ( void ) const {}
1023 #endif
1024  };
1025 
1026 #ifdef ENABLE_EDITING
1027  /* Miscellaneous editing routines */
1028  inline void edit_rectl ( const char* tag, const RECTL& rectl )
1029  {
1030 #if defined(__LP64__)
1031  const char* FMT = "\t%s\t: (%d, %d) - (%d, %d)\n";
1032 #else
1033  const char* FMT = "\t%s\t: (%ld, %ld) - (%ld, %ld)\n";
1034 #endif /* __x86_64__ */
1035  printf( FMT, tag, rectl.left, rectl.top, rectl.right, rectl.bottom );
1036  }
1037 
1038  inline void edit_xform ( const char* tag, const XFORM& xform )
1039  {
1040  printf( "\t%s.eM11\t: %f\n", tag, xform.eM11 );
1041  printf( "\t%s.eM12\t: %f\n", tag, xform.eM12 );
1042  printf( "\t%s.eM21\t: %f\n", tag, xform.eM21 );
1043  printf( "\t%s.eM22\t: %f\n", tag, xform.eM22 );
1044  printf( "\t%s.eDx\t: %f\n", tag, xform.eDx );
1045  printf( "\t%s.eDy\t: %f\n", tag, xform.eDy );
1046  }
1047 
1048  inline void edit_color ( const char* tag, const COLORREF& color )
1049  {
1050 #if defined(__LP64__)
1051  const char* FMT = "\t%s\t: R(0x%02x) G(0x%02x) B(0x%02x)\n";
1052 #else
1053  const char* FMT = "\t%s\t: R(0x%02lx) G(0x%02lx) B(0x%02lx)\n";
1054 #endif /* __x86_64__ */
1055  printf( FMT, tag,
1056  GetRValue( color ), GetGValue( color ), GetBValue( color ) );
1057  }
1058 
1059  inline void edit_sizel ( const char* tag, const SIZEL& size )
1060  {
1061 #if defined(__LP64__)
1062  const char* FMT = "\t%s\t: (%d, %d)\n";
1063 #else
1064  const char* FMT = "\t%s\t: (%ld, %ld)\n";
1065 #endif /* __x86_64__ */
1066  printf( FMT, tag, size.cx, size.cy );
1067  }
1068 
1069  inline void edit_pointl ( const char* tag, const POINTL& point )
1070  {
1071 #if defined(__LP64__)
1072  const char* FMT = "\t%s\t: (%d, %d)\n";
1073 #else
1074  const char* FMT = "\t%s\t: (%ld, %ld)\n";
1075 #endif /* __x86_64__ */
1076  printf( FMT, tag, point.x, point.y );
1077  }
1078 
1079  inline void edit_pointlarray ( const char* tag, const DWORD cptl,
1080  const POINTL* points )
1081  {
1082 #if defined(__LP64__)
1083  const char* FMT0 = "\tcptl%s\t: %d\n";
1084  const char* FMT1 = "%d, %d\n";
1085  const char* FMT2 = "\t\t%s %d, %d\n";
1086 #else
1087  const char* FMT0 = "\tcptl%s\t: %ld\n";
1088  const char* FMT1 = "%ld, %ld\n";
1089  const char* FMT2 = "\t\t%s %ld, %ld\n";
1090 #endif /* __x86_64__ */
1091  printf( FMT0, tag, cptl );
1092  printf( "\taptl%s\t: ", tag );
1093  if ( cptl > 0 )
1094  printf( FMT1, points[0].x, points[0].y );
1095  else
1096  puts( "" );
1097  for ( DWORD i = 1; i < cptl; i++ )
1098  printf( FMT2, tag, points[i].x, points[i].y );
1099  }
1100 
1101  inline void edit_point16array ( const char* tag, const unsigned int cpts,
1102  const POINT16* points )
1103  {
1104  printf( "\tcpts%s\t: %d\n", tag, cpts );
1105  printf( "\tapts%s\t: ", tag );
1106  if ( cpts > 0 )
1107  printf( "%d, %d\n", points[0].x, points[0].y );
1108  else
1109  puts( "" );
1110  for ( unsigned int i = 1; i < cpts; i++ )
1111  printf( "\t\t%s %d, %d\n", tag, points[i].x, points[i].y );
1112  }
1113 
1114  inline void edit_pen_style ( const char* tag, DWORD style )
1115  {
1116  printf( "\t%s\t: ", tag );
1117  switch ( style & PS_STYLE_MASK ) {
1118  case PS_SOLID: printf( "PS_SOLID" ); break;
1119  case PS_DASH: printf( "PS_DASH" ); break;
1120  case PS_DOT: printf( "PS_DOT" ); break;
1121  case PS_DASHDOT: printf( "PS_DASHDOT" ); break;
1122  case PS_DASHDOTDOT: printf( "PS_DASHDOTDOT" ); break;
1123  case PS_NULL: printf( "PS_NULL" ); break;
1124  case PS_INSIDEFRAME: printf( "PS_INSIDEFRAME" ); break;
1125  case PS_USERSTYLE: printf( "PS_USERSTYLE" ); break;
1126  case PS_ALTERNATE: printf( "PS_ALTERNATE" ); break;
1127  }
1128  switch ( style & PS_ENDCAP_MASK ) {
1129  case PS_ENDCAP_ROUND: printf( " | PS_ENDCAP_ROUND" ); break;
1130  case PS_ENDCAP_SQUARE: printf( " | PS_ENDCAP_SQUARE" ); break;
1131  case PS_ENDCAP_FLAT: printf( " | PS_ENDCAP_FLAT" ); break;
1132  }
1133  switch ( style & PS_JOIN_MASK ) {
1134  case PS_JOIN_ROUND: printf( " | PS_JOIN_ROUND" ); break;
1135  case PS_JOIN_BEVEL: printf( " | PS_JOIN_BEVEL" ); break;
1136  case PS_JOIN_MITER: printf( " | PS_JOIN_MITER" ); break;
1137  }
1138  switch ( style & PS_TYPE_MASK ) {
1139  case PS_COSMETIC: printf( " | PS_COSMETIC" ); break;
1140  case PS_GEOMETRIC: printf( " | PS_GEOMETRIC" ); break;
1141  }
1142  printf( "\n" );
1143  }
1144 
1145  inline void edit_brush_style ( const char* tag, DWORD style )
1146  {
1147 #if defined(__LP64__)
1148  const char* FMT = "unknown(%d)";
1149 #else
1150  const char* FMT = "unknown(%ld)";
1151 #endif /* __x86_64__ */
1152  printf( "\t%s\t: ", tag );
1153  switch ( style ) {
1154  case BS_SOLID: printf( "BS_SOLID" ); break;
1155  case BS_NULL: printf( "BS_NULL" ); break;
1156  case BS_HATCHED: printf( "BS_HATCHED" ); break;
1157  case BS_PATTERN: printf( "BS_PATTERN" ); break;
1158  case BS_INDEXED: printf( "BS_INDEXED" ); break;
1159  case BS_DIBPATTERN: printf( "BS_DIBPATTERN" ); break;
1160  case BS_DIBPATTERNPT: printf( "BS_DIBPATTERNPT" ); break;
1161  case BS_PATTERN8X8: printf( "BS_PATTERN8X8" ); break;
1162  case BS_DIBPATTERN8X8: printf( "BS_DIBPATTERN8X8" ); break;
1163  case BS_MONOPATTERN: printf( "BS_DIBPATTERN8X8" ); break;
1164  default: printf( FMT, style );
1165  }
1166  printf( "\n" );
1167  }
1168 
1169  inline void edit_brush_hatch ( const char* tag, DWORD hatch )
1170  {
1171 #if defined(__LP64__)
1172  const char* FMT = "unknown(%d)";
1173 #else
1174  const char* FMT = "unknown(%ld)";
1175 #endif /* __x86_64__ */
1176  printf( "\t%s\t: ", tag );
1177  switch ( hatch ) {
1178  case HS_HORIZONTAL: printf( "HS_HORIZONTAL" ); break;
1179  case HS_VERTICAL: printf( "HS_VERTICAL" ); break;
1180  case HS_FDIAGONAL: printf( "HS_FDIAGONAL" ); break;
1181  case HS_BDIAGONAL: printf( "HS_BDIAGONAL" ); break;
1182  case HS_CROSS: printf( "HS_CROSS" ); break;
1183  case HS_DIAGCROSS: printf( "HS_DIAGCROSS" ); break;
1184  default: printf( FMT, hatch );
1185  }
1186  printf( "\n" );
1187  }
1188 #endif
1196  enum OBJECTTYPE { O_METAFILEDEVICECONTEXT = OBJ_METADC,
1197  O_FONT = OBJ_FONT,
1198  O_PEN = OBJ_PEN,
1199  O_EXTPEN = OBJ_EXTPEN,
1200  O_BRUSH = OBJ_BRUSH,
1201  O_PALETTE = OBJ_PAL };
1202 #if 0
1206  static char* typStr ( OBJECTTYPE type )
1207  {
1208  switch (type) {
1209  case O_METAFILEDEVICECONTEXT:
1210  return "metafile device context";
1211  case O_FONT:
1212  return "font";
1213  case O_PEN:
1214  return "pen";
1215  case O_EXTPEN:
1216  return "extended pen";
1217  case O_BRUSH:
1218  return "brush";
1219  case O_PALETTE:
1220  return "palette";
1221  }
1222  return "unknown object";
1223  }
1224 #endif
1226 
1231  class OBJECT {
1232  public:
1233  HGDIOBJ handle;
1235  virtual ~OBJECT () {}
1240  OBJECT ( void ) : handle( 0 ) {}
1244  virtual OBJECTTYPE getType ( void ) const = 0;
1245  };
1246 
1248 
1253  class GRAPHICSOBJECT : public OBJECT {
1254  public:
1256  virtual ~GRAPHICSOBJECT () {}
1261  std::map< HDC, HGDIOBJ > contexts;
1268  virtual METARECORD* newEMR ( HDC dc, HGDIOBJ handle ) = 0;
1269  };
1270 
1271  typedef METARECORD*(*METARECORDCTOR)(DATASTREAM&);
1272 
1280  std::vector<OBJECT*> objects;
1281 
1288  std::map< DWORD, METARECORDCTOR > new_records;
1289 
1290  public:
1291  GLOBALOBJECTS ( void );
1292  ~GLOBALOBJECTS ( void );
1293  HGDIOBJ add ( OBJECT* object );
1294  OBJECT* find ( const HGDIOBJ handle );
1295  void remove ( const OBJECT* object );
1296 
1300  auto begin ( void ) const { return objects.begin(); }
1301 
1305  auto end ( void ) const { return objects.end(); }
1306 
1307  METARECORDCTOR newRecord ( DWORD iType ) const;
1308 
1310  static EMF::METARECORD* new_eof ( DATASTREAM& ds );
1332  static EMF::METARECORD* new_setbkcolor ( DATASTREAM& ds );
1334  static EMF::METARECORD* new_setbkmode ( DATASTREAM& ds );
1338  static EMF::METARECORD* new_setmapmode ( DATASTREAM& ds );
1344  static EMF::METARECORD* new_movetoex ( DATASTREAM& ds );
1346  static EMF::METARECORD* new_lineto ( DATASTREAM& ds );
1348  static EMF::METARECORD* new_arc ( DATASTREAM& ds );
1350  static EMF::METARECORD* new_arcto ( DATASTREAM& ds );
1352  static EMF::METARECORD* new_rectangle ( DATASTREAM& ds );
1354  static EMF::METARECORD* new_ellipse ( DATASTREAM& ds );
1356  static EMF::METARECORD* new_polyline ( DATASTREAM& ds );
1358  static EMF::METARECORD* new_polyline16 ( DATASTREAM& ds );
1360  static EMF::METARECORD* new_polygon ( DATASTREAM& ds );
1362  static EMF::METARECORD* new_polygon16 ( DATASTREAM& ds );
1364  static EMF::METARECORD* new_polypolygon ( DATASTREAM& ds );
1368  static EMF::METARECORD* new_polybezier ( DATASTREAM& ds );
1376  static EMF::METARECORD* new_polylineto ( DATASTREAM& ds );
1380  static EMF::METARECORD* new_exttextouta ( DATASTREAM& ds );
1382  static EMF::METARECORD* new_exttextoutw ( DATASTREAM& ds );
1384  static EMF::METARECORD* new_setpixelv ( DATASTREAM& ds );
1386  static EMF::METARECORD* new_createpen ( DATASTREAM& ds );
1394  static EMF::METARECORD* new_fillpath ( DATASTREAM& ds );
1396  static EMF::METARECORD* new_strokepath ( DATASTREAM& ds );
1400  static EMF::METARECORD* new_beginpath ( DATASTREAM& ds );
1402  static EMF::METARECORD* new_endpath ( DATASTREAM& ds );
1404  static EMF::METARECORD* new_closefigure ( DATASTREAM& ds );
1406  static EMF::METARECORD* new_savedc ( DATASTREAM& ds );
1408  static EMF::METARECORD* new_restoredc ( DATASTREAM& ds );
1410  static EMF::METARECORD* new_setmetargn ( DATASTREAM& ds );
1413  };
1414 
1415  extern GLOBALOBJECTS globalObjects;
1416 
1418 
1424  class ENHMETAHEADER : public METARECORD, public ::ENHMETAHEADER {
1425 
1426  LPWSTR description_w{ nullptr };
1427  int description_size{ 0 };
1428 
1429  public:
1436  ENHMETAHEADER ( LPCWSTR description = 0 )
1437  : description_w( 0 ), description_size( 0 )
1438  {
1439  iType = EMR_HEADER;
1440  nSize = sizeof( ::ENHMETAHEADER );
1441 
1442  // Compute the bounds
1443  RECTL default_bounds = { 0, 0, 0, 0 };
1444  rclBounds = default_bounds;
1445  RECTL default_frame = { 0, 0, 0, 0 };
1446  rclFrame = default_frame;
1447  dSignature = ENHMETA_SIGNATURE;
1448  nVersion = 0x10000;
1449  nBytes = nSize;
1450  nRecords = 1;
1451  nHandles = 0;
1452  sReserved = 0;
1453  nDescription = 0;
1454  offDescription = 0;
1455  nPalEntries = 0;
1456  szlDevice.cx = XMAX_PIXELS;
1457  szlDevice.cy = YMAX_PIXELS;
1458  szlMillimeters.cx = XMAX_MM;
1459  szlMillimeters.cy = YMAX_MM;
1460  //
1461  cbPixelFormat = 0;
1462  offPixelFormat = 0;
1463  bOpenGL = FALSE;
1464  //
1465 #if 1
1466  szlMicrometers.cx = 1000 * szlMillimeters.cx;
1467  szlMicrometers.cy = 1000 * szlMillimeters.cy;
1468 #endif
1469  if ( description ) {
1470  // Count the number of characters in the description
1471  int description_count = 0, nulls = 0;
1472  LPCWSTR description_p = description;
1473  while ( nulls < 3 ) {
1474  description_count++;
1475  if ( (*description_p++) == 0 ) nulls++;
1476  }
1477 
1478  // Make sure that the TOTAL record length will be a multiple of 4
1479 
1480  int record_size = ROUND_TO_LONG( sizeof( ::ENHMETAHEADER ) +
1481  sizeof( WCHAR ) * description_count );
1482  description_size =
1483  (record_size - sizeof( ::ENHMETAHEADER )) / sizeof( WCHAR );
1484 
1485  std::unique_ptr<WCHAR[]>
1486  description_tmp( new WCHAR[ description_size ] );
1487 
1488  description_w = description_tmp.release();
1489 
1490  memset( description_w, 0, sizeof(WCHAR) * description_size );
1491 
1492  for ( int i=0; i<description_count; i++ )
1493  description_w[i] = *description++;
1494 
1495  nSize = nBytes = record_size;
1496  nDescription = description_count;
1497  offDescription = sizeof( ::ENHMETAHEADER );
1498  }
1499  }
1500 
1505  {
1506  if ( description_w ) delete[] description_w;
1507  }
1512  bool serialize ( DATASTREAM ds )
1513  {
1514  ds << iType << nSize
1515  << rclBounds << rclFrame
1516  << dSignature << nVersion << nBytes << nRecords << nHandles << sReserved
1517  << nDescription << offDescription << nPalEntries
1518  << szlDevice << szlMillimeters
1519  << cbPixelFormat << offPixelFormat << bOpenGL
1520  << szlMicrometers
1521  << WCHARSTR( description_w, description_size );
1522  return true;
1523  }
1528  {
1529  ds >> iType >> nSize
1530  >> rclBounds >> rclFrame
1531  >> dSignature >> nVersion >> nBytes >> nRecords >> nHandles >> sReserved
1532  >> nDescription >> offDescription >> nPalEntries
1533  >> szlDevice >> szlMillimeters;
1534 
1535  // Some elements of the metafile header were added at later dates
1536 
1537 #define OffsetOf( a, b ) ((unsigned int)(((char*)&(((::ENHMETAHEADER*)a)->b)) - \
1538 (char*)((::ENHMETAHEADER*)a)))
1539  if ( OffsetOf( this, szlMicrometers ) <= offDescription )
1540  ds >> cbPixelFormat >> offPixelFormat >> bOpenGL;
1541 #undef OffsetOf
1542  if ( sizeof(::ENHMETAHEADER) <= offDescription )
1543  ds >> szlMicrometers;
1544 
1545  // Should now probably check that the offset is correct...
1546 
1547  int description_size_to_read = ( nSize - offDescription ) / sizeof(WCHAR);
1548 
1549  if ( description_size_to_read < (int)nDescription ) {
1550  throw std::runtime_error( "record size inconsistent with description size" );
1551  }
1552 
1553  description_size = max( 2, description_size_to_read );
1554 
1555  std::unique_ptr<WCHAR[]> buffer( new WCHAR[description_size] );
1556 
1557  WCHARSTR description( buffer.get(), description_size_to_read );
1558 
1559  ds >> description;
1560 
1561  description_w = buffer.release();
1562 
1563  // Make sure it's terminated properly.
1564  description_w[description_size-1] = 0;
1565  description_w[description_size-2] = 0;
1566 
1567  return true;
1568  }
1572  int size ( void ) const { return nSize; }
1578  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1579  {
1580  // Actually handled by the destination device context.
1581  EMF_UNUSED(source);
1582  EMF_UNUSED(dc);
1583  }
1584 #ifdef ENABLE_EDITING
1588  void edit ( void ) const
1589  {
1590 #if defined(__LP64__)
1591  const char* FMT0 = "\tiType\t\t\t: %d\n";
1592  const char* FMT1 = "\tnSize\t\t\t: %d\n";
1593  const char* FMT2 = "\tnBytes\t\t\t: %d\n";
1594  const char* FMT3 = "\tnRecords\t\t: %d\n";
1595  const char* FMT4 = "\tnDescription\t\t: %d\n";
1596  const char* FMT5 = "\toffDescription\t\t: %d\n";
1597  const char* FMT6 = "\tnPalEntries\t\t: %d\n";
1598  const char* FMT7 = "\tcbPixelFormat\t\t: %d\n";
1599  const char* FMT8 = "\toffPixelFormat\t\t: %d\n";
1600  const char* FMT9 = "\tbOpenGL\t\t\t: %d\n";
1601 #else
1602  const char* FMT0 = "\tiType\t\t\t: %ld\n";
1603  const char* FMT1 = "\tnSize\t\t\t: %ld\n";
1604  const char* FMT2 = "\tnBytes\t\t\t: %ld\n";
1605  const char* FMT3 = "\tnRecords\t\t: %ld\n";
1606  const char* FMT4 = "\tnDescription\t\t: %ld\n";
1607  const char* FMT5 = "\toffDescription\t\t: %ld\n";
1608  const char* FMT6 = "\tnPalEntries\t\t: %ld\n";
1609  const char* FMT7 = "\tcbPixelFormat\t\t: %ld\n";
1610  const char* FMT8 = "\toffPixelFormat\t\t: %ld\n";
1611  const char* FMT9 = "\tbOpenGL\t\t\t: %ld\n";
1612 #endif
1613  printf( "*HEADER*\n" );
1614  printf( FMT0, iType );
1615  printf( FMT1, nSize );
1616  edit_rectl( "rclBounds\t", rclBounds );
1617  edit_rectl( "rclFrame\t", rclFrame );
1618  printf( "\tdSignature\t\t: %.4s\n", (const char*)&dSignature );
1619  printf( "\tnVersion\t\t: 0x%x\n", (unsigned int)nVersion );
1620  printf( FMT2, nBytes );
1621  printf( FMT3, nRecords );
1622  printf( "\tnHandles\t\t: %d\n", nHandles );
1623  printf( FMT4, nDescription );
1624  printf( FMT5, offDescription );
1625  printf( FMT6, nPalEntries );
1626  edit_sizel( "szlDevice\t", szlDevice );
1627  edit_sizel( "szlMillimeters\t", szlMillimeters );
1628 
1629  /* Make a crude guess as to the age of this file */
1630 #define OffsetOf( a, b ) ((unsigned int)(((const char*)&(((const ::ENHMETAHEADER*)a)->b)) - \
1631 (const char*)((const ::ENHMETAHEADER*)a)))
1632 
1633  if ( OffsetOf( this, cbPixelFormat ) <= offDescription ) {
1634  printf( FMT7, cbPixelFormat );
1635  printf( FMT8, offPixelFormat );
1636  printf( FMT9, bOpenGL );
1637 #if 1
1638  if ( sizeof(::ENHMETAHEADER) <= offDescription ) {
1639  edit_sizel( "szlMicrometers\t", szlMicrometers );
1640  }
1641 #endif
1642  }
1643 
1644 #undef OffsetOf
1645 
1646  if ( nDescription != 0 ) {
1647 
1648  wchar_t last_w = 0;
1649  WCHAR* description = description_w;
1650 
1651  printf( "\tDescription:" );
1652 
1653  for ( DWORD i = 0; i < nDescription; i++ ) {
1654 
1655  wchar_t w = *description++; /* This is not true, really. UNICODE is not
1656  * glibc's wide character representation */
1657 
1658  if ( w != 0 ) {
1659  if ( last_w == 0 ) printf( "\n\t\t" );
1660  putchar( w );
1661  }
1662 
1663  last_w = w;
1664  }
1665  printf( "\n" );
1666  }
1667  }
1668 #endif /* ENABLE_EDITING */
1669  };
1670 
1672 
1677  class EMREOF : public METARECORD, ::EMREOF {
1678  public:
1682  EMREOF ( void )
1683  {
1684  emr.iType = EMR_EOF;
1685  emr.nSize = sizeof( ::EMREOF );
1686  nPalEntries = 0;
1687  offPalEntries = 0;
1688  nSizeLast = 0;
1689  }
1690 
1696  {
1697  ds >> emr >> nPalEntries >> offPalEntries >> nSizeLast;
1698  }
1699 
1703  bool serialize ( DATASTREAM ds )
1704  {
1705  ds << emr << nPalEntries << offPalEntries << nSizeLast;
1706  return true;
1707  }
1711  int size ( void ) const { return emr.nSize; }
1717  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1718  {
1719  // Actually handled by the destination device context.
1720  EMF_UNUSED(source);
1721  EMF_UNUSED(dc);
1722  }
1723 #ifdef ENABLE_EDITING
1727  void edit ( void ) const
1728  {
1729  printf( "*EOF*\n" );
1730  }
1731 #endif /* ENABLE_EDITING */
1732  };
1733 
1735 
1741  public:
1746  EMRSETVIEWPORTORGEX ( INT x, INT y )
1747  {
1748  emr.iType = EMR_SETVIEWPORTORGEX;
1749  emr.nSize = sizeof( ::EMRSETVIEWPORTORGEX );
1750  ptlOrigin.x = x;
1751  ptlOrigin.y = y;
1752  }
1758  {
1759  ds >> emr >> ptlOrigin;
1760  }
1764  bool serialize ( DATASTREAM ds )
1765  {
1766  ds << emr << ptlOrigin;
1767  return true;
1768  }
1772  int size ( void ) const { return emr.nSize; }
1778  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1779  {
1780  EMF_UNUSED(source);
1781  SetViewportOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
1782  }
1783 #ifdef ENABLE_EDITING
1787  void edit ( void ) const
1788  {
1789  printf( "*SETVIEWPORTORGEX*\n" );
1790  edit_pointl( "ptlOrigin", ptlOrigin );
1791  }
1792 #endif /* ENABLE_EDITING */
1793  };
1794 
1796 
1804  public:
1809  EMRSETWINDOWORGEX ( INT x, INT y )
1810  {
1811  emr.iType = EMR_SETWINDOWORGEX;
1812  emr.nSize = sizeof( ::EMRSETWINDOWORGEX );
1813  ptlOrigin.x = x;
1814  ptlOrigin.y = y;
1815  }
1821  {
1822  ds >> emr >> ptlOrigin;
1823  }
1827  bool serialize ( DATASTREAM ds )
1828  {
1829  ds << emr << ptlOrigin;
1830  return true;
1831  }
1835  int size ( void ) const { return emr.nSize; }
1841  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1842  {
1843  EMF_UNUSED(source);
1844  SetWindowOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
1845  }
1846 #ifdef ENABLE_EDITING
1850  void edit ( void ) const
1851  {
1852  printf( "*SETWINDOWORGEX*\n" );
1853  edit_pointl( "ptlOrigin", ptlOrigin );
1854  }
1855 #endif /* ENABLE_EDITING */
1856  };
1857 
1859 
1865  public:
1870  EMRSETVIEWPORTEXTEX ( INT cx, INT cy )
1871  {
1872  emr.iType = EMR_SETVIEWPORTEXTEX;
1873  emr.nSize = sizeof( ::EMRSETVIEWPORTEXTEX );
1874  szlExtent.cx = cx;
1875  szlExtent.cy = cy;
1876  }
1882  {
1883  ds >> emr >> szlExtent;
1884  }
1888  bool serialize ( DATASTREAM ds )
1889  {
1890  ds << emr << szlExtent;
1891  return true;
1892  }
1896  int size ( void ) const { return emr.nSize; }
1902  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1903  {
1904  EMF_UNUSED(source);
1905  SetViewportExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
1906  }
1907 #ifdef ENABLE_EDITING
1911  void edit ( void ) const
1912  {
1913  printf( "*SETVIEWPORTEXTEX*\n" );
1914  edit_sizel( "szlExtent", szlExtent );
1915  }
1916 #endif /* ENABLE_EDITING */
1917  };
1918 
1920 
1926  public:
1933  EMRSCALEVIEWPORTEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
1934  {
1935  emr.iType = EMR_SCALEVIEWPORTEXTEX;
1936  emr.nSize = sizeof( ::EMRSCALEVIEWPORTEXTEX );
1937  xNum = x_num;
1938  xDenom = x_den;
1939  yNum = y_num;
1940  yDenom = y_den;
1941  }
1947  {
1948  ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
1949  }
1953  bool serialize ( DATASTREAM ds )
1954  {
1955  ds << emr << xNum << xDenom << yNum << yDenom;
1956  return true;
1957  }
1961  int size ( void ) const { return emr.nSize; }
1967  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
1968  {
1969  EMF_UNUSED(source);
1970  ScaleViewportExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
1971  }
1972 #ifdef ENABLE_EDITING
1976  void edit ( void ) const
1977  {
1978 #if defined(__LP64__)
1979  const char* FMT0 = "\txNum\t: %d\n";
1980  const char* FMT1 = "\txDenom\t: %d\n";
1981  const char* FMT2 = "\tyNum\t: %d\n";
1982  const char* FMT3 = "\tyDenom\t: %d\n";
1983 #else
1984  const char* FMT0 = "\txNum\t: %ld\n";
1985  const char* FMT1 = "\txDenom\t: %ld\n";
1986  const char* FMT2 = "\tyNum\t: %ld\n";
1987  const char* FMT3 = "\tyDenom\t: %ld\n";
1988 #endif
1989  printf( "*SCALEVIEWPORTEXTEX*\n" );
1990  printf( FMT0, xNum );
1991  printf( FMT1, xDenom );
1992  printf( FMT2, yNum );
1993  printf( FMT3, yDenom );
1994  }
1995 #endif /* ENABLE_EDITING */
1996  };
1997 
1999 
2005  public:
2010  EMRSETWINDOWEXTEX ( INT cx, INT cy )
2011  {
2012  emr.iType = EMR_SETWINDOWEXTEX;
2013  emr.nSize = sizeof( ::EMRSETWINDOWEXTEX );
2014  szlExtent.cx = cx;
2015  szlExtent.cy = cy;
2016  }
2022  {
2023  ds >> emr >> szlExtent;
2024  }
2028  bool serialize ( DATASTREAM ds )
2029  {
2030  ds << emr << szlExtent;
2031  return true;
2032  }
2036  int size ( void ) const { return emr.nSize; }
2042  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2043  {
2044  EMF_UNUSED(source);
2045  SetWindowExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
2046  }
2047 #ifdef ENABLE_EDITING
2051  void edit ( void ) const
2052  {
2053  printf( "*SETWINDOWEXTEX*\n" );
2054  edit_sizel( "szlExtent", szlExtent );
2055  }
2056 #endif /* ENABLE_EDITING */
2057  };
2058 
2060 
2066  public:
2073  EMRSCALEWINDOWEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
2074  {
2075  emr.iType = EMR_SCALEWINDOWEXTEX;
2076  emr.nSize = sizeof( ::EMRSCALEWINDOWEXTEX );
2077  xNum = x_num;
2078  xDenom = x_den;
2079  yNum = y_num;
2080  yDenom = y_den;
2081  }
2087  {
2088  ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
2089  }
2093  bool serialize ( DATASTREAM ds )
2094  {
2095  ds << emr << xNum << xDenom << yNum << yDenom;
2096  return true;
2097  }
2101  int size ( void ) const { return emr.nSize; }
2107  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2108  {
2109  EMF_UNUSED(source);
2110  ScaleWindowExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
2111  }
2112 #ifdef ENABLE_EDITING
2116  void edit ( void ) const
2117  {
2118 #if defined(__LP64__)
2119  const char* FMT0 = "\txNum\t: %d\n";
2120  const char* FMT1 = "\txDenom\t: %d\n";
2121  const char* FMT2 = "\tyNum\t: %d\n";
2122  const char* FMT3 = "\tyDenom\t: %d\n";
2123 #else
2124  const char* FMT0 = "\txNum\t: %ld\n";
2125  const char* FMT1 = "\txDenom\t: %ld\n";
2126  const char* FMT2 = "\tyNum\t: %ld\n";
2127  const char* FMT3 = "\tyDenom\t: %ld\n";
2128 #endif
2129  printf( "*SCALEWINDOWEXTEX*\n" );
2130  printf( FMT0, xNum );
2131  printf( FMT1, xDenom );
2132  printf( FMT2, yNum );
2133  printf( FMT3, yDenom );
2134  }
2135 #endif /* ENABLE_EDITING */
2136  };
2137 
2139 
2146  public:
2152  EMRMODIFYWORLDTRANSFORM ( const XFORM* transform, DWORD mode )
2153  {
2154  emr.iType = EMR_MODIFYWORLDTRANSFORM;
2155  emr.nSize = sizeof( ::EMRMODIFYWORLDTRANSFORM );
2156  xform = *transform;
2157  iMode = mode;
2158  }
2164  {
2165  ds >> emr >> xform >> iMode;
2166  }
2170  bool serialize ( DATASTREAM ds )
2171  {
2172  ds << emr << xform << iMode;
2173  return true;
2174  }
2178  int size ( void ) const { return emr.nSize; }
2184  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2185  {
2186  EMF_UNUSED(source);
2187  ModifyWorldTransform( dc, &xform, iMode );
2188  }
2189 #ifdef ENABLE_EDITING
2193  void edit ( void ) const
2194  {
2195 #if defined(__LP64__)
2196  const char* FMT = "unknown(%d)\n";
2197 #else
2198  const char* FMT = "unknown(%ld)\n";
2199 #endif /* __x86_64__ */
2200  printf( "*MODIFYWORLDTRANSFORM*\n" );
2201  edit_xform( "xform", xform );
2202  printf( "\tiMode\t\t: " );
2203  switch ( iMode ) {
2204  case MWT_IDENTITY: printf( "MWT_IDENTITY\n" ); break;
2205  case MWT_LEFTMULTIPLY: printf( "MWT_LEFTMULTIPLY\n" ); break;
2206  case MWT_RIGHTMULTIPLY: printf( "MWT_RIGHTMULTIPLY\n" ); break;
2207  default: printf( FMT, iMode );
2208  }
2209  }
2210 #endif /* ENABLE_EDITING */
2211  };
2212 
2214 
2221  public:
2225  EMRSETWORLDTRANSFORM ( const XFORM* transform )
2226  {
2227  emr.iType = EMR_SETWORLDTRANSFORM;
2228  emr.nSize = sizeof( ::EMRSETWORLDTRANSFORM );
2229  xform = *transform;
2230  }
2236  {
2237  ds >> emr >> xform;
2238  }
2242  bool serialize ( DATASTREAM ds )
2243  {
2244  ds << emr << xform;
2245  return true;
2246  }
2250  int size ( void ) const { return emr.nSize; }
2256  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2257  {
2258  EMF_UNUSED(source);
2259  SetWorldTransform( dc, &xform );
2260  }
2261 #ifdef ENABLE_EDITING
2265  void edit ( void ) const
2266  {
2267  printf( "*SETWORLDTRANSFORM*\n" );
2268  edit_xform( "xform", xform );
2269  }
2270 #endif /* ENABLE_EDITING */
2271  };
2272 
2274 
2278  public:
2282  EMRSETTEXTALIGN ( UINT mode )
2283  {
2284  emr.iType = EMR_SETTEXTALIGN;
2285  emr.nSize = sizeof( ::EMRSETTEXTALIGN );
2286  iMode = mode;
2287  }
2293  {
2294  ds >> emr >> iMode;
2295  }
2299  bool serialize ( DATASTREAM ds )
2300  {
2301  ds << emr << iMode;
2302  return true;
2303  }
2307  int size ( void ) const { return emr.nSize; }
2313  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2314  {
2315  EMF_UNUSED(source);
2316  SetTextAlign( dc, iMode );
2317  }
2318 #ifdef ENABLE_EDITING
2322  void edit ( void ) const
2323  {
2324 #if defined(__LP64__)
2325  const char* FMT = "| unknown bits(0x%x)";
2326 #else
2327  const char* FMT = "| unknown bits(0x%lx)";
2328 #endif /* __x86_64__ */
2329  unsigned int known_bits = TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING;
2330  unsigned int unknown_bits = ~known_bits;
2331 
2332  printf( "*SETTEXTALIGN*\n" );
2333  printf( "\tiMode\t: " );
2334  if ( iMode & TA_UPDATECP )
2335  printf( "TA_UPDATECP" );
2336  else
2337  printf( "TA_NOUPDATECP" );
2338  if ( iMode & TA_CENTER )
2339  printf( " | TA_CENTER" );
2340  else if ( iMode & TA_RIGHT )
2341  printf( " | TA_RIGHT" );
2342  else
2343  printf( " | TA_LEFT" );
2344  if ( iMode & TA_BASELINE )
2345  printf( " | TA_BASELINE" );
2346  else if ( iMode & TA_BOTTOM )
2347  printf( " | TA_BOTTOM" );
2348  else
2349  printf( " | TA_TOP" );
2350  if ( iMode & TA_RTLREADING )
2351  printf( " | TA_RTLREADING" );
2352  if ( iMode & unknown_bits )
2353  printf( FMT, iMode & unknown_bits );
2354  printf( "\n" );
2355  }
2356 #endif /* ENABLE_EDITING */
2357  };
2358 
2360 
2364  public:
2368  EMRSETTEXTCOLOR ( COLORREF color )
2369  {
2370  emr.iType = EMR_SETTEXTCOLOR;
2371  emr.nSize = sizeof( ::EMRSETTEXTCOLOR );
2372  crColor = color;
2373  }
2379  {
2380  ds >> emr >> crColor;
2381  }
2385  bool serialize ( DATASTREAM ds )
2386  {
2387  ds << emr << crColor;
2388  return true;
2389  }
2393  int size ( void ) const { return emr.nSize; }
2399  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2400  {
2401  EMF_UNUSED(source);
2402  SetTextColor( dc, crColor );
2403  }
2404 #ifdef ENABLE_EDITING
2408  void edit ( void ) const
2409  {
2410  printf( "*SETTEXTCOLOR*\n" );
2411  edit_color( "crColor", crColor );
2412  }
2413 #endif /* ENABLE_EDITING */
2414  };
2415 
2417 
2421  public:
2425  EMRSETBKCOLOR ( COLORREF color )
2426  {
2427  emr.iType = EMR_SETBKCOLOR;
2428  emr.nSize = sizeof( ::EMRSETBKCOLOR );
2429  crColor = color;
2430  }
2436  {
2437  ds >> emr >> crColor;
2438  }
2442  bool serialize ( DATASTREAM ds )
2443  {
2444  ds << emr << crColor;
2445  return true;
2446  }
2450  int size ( void ) const { return emr.nSize; }
2456  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2457  {
2458  EMF_UNUSED(source);
2459  SetBkColor( dc, crColor );
2460  }
2461 #ifdef ENABLE_EDITING
2465  void edit ( void ) const
2466  {
2467  printf( "*SETBKCOLOR*\n" );
2468  edit_color( "crColor", crColor );
2469  }
2470 #endif /* ENABLE_EDITING */
2471  };
2472 
2474 
2479  public:
2483  EMRSETBKMODE ( DWORD mode )
2484  {
2485  emr.iType = EMR_SETBKMODE;
2486  emr.nSize = sizeof( ::EMRSETBKMODE );
2487  iMode = mode;
2488  }
2494  {
2495  ds >> emr >> iMode;
2496  }
2500  bool serialize ( DATASTREAM ds )
2501  {
2502  ds << emr << iMode;
2503  return true;
2504  }
2508  int size ( void ) const { return emr.nSize; }
2514  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2515  {
2516  EMF_UNUSED(source);
2517  SetBkMode( dc, iMode );
2518  }
2519 #ifdef ENABLE_EDITING
2523  void edit ( void ) const
2524  {
2525 #if defined(__LP64__)
2526  const char* FMT = "unknown(%d)\n";
2527 #else
2528  const char* FMT = "unknown(%ld)\n";
2529 #endif /* __x86_64__ */
2530  printf( "*SETBKMODE*\n" );
2531  printf( "\tiMode\t: " );
2532  switch ( iMode ) {
2533  case TRANSPARENT: printf( "TRANSPARENT\n" ); break;
2534  case OPAQUE: printf( "OPAQUE\n" ); break;
2535  default: printf( FMT, iMode );
2536  }
2537  }
2538 #endif /* ENABLE_EDITING */
2539  };
2540 
2542 
2546  public:
2550  EMRSETPOLYFILLMODE ( DWORD mode )
2551  {
2552  emr.iType = EMR_SETPOLYFILLMODE;
2553  emr.nSize = sizeof( ::EMRSETPOLYFILLMODE );
2554  iMode = mode;
2555  }
2561  {
2562  ds >> emr >> iMode;
2563  }
2567  bool serialize ( DATASTREAM ds )
2568  {
2569  ds << emr << iMode;
2570  return true;
2571  }
2575  int size ( void ) const { return emr.nSize; }
2581  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2582  {
2583  EMF_UNUSED(source);
2584  SetPolyFillMode( dc, iMode );
2585  }
2586 #ifdef ENABLE_EDITING
2590  void edit ( void ) const
2591  {
2592 #if defined(__LP64__)
2593  const char* FMT = "unknown(%d)\n";
2594 #else
2595  const char* FMT = "unknown(%ld)\n";
2596 #endif /* __x86_64__ */
2597  printf( "*SETPOLYFILLMODE*\n" );
2598  printf( "\tiMode: " );
2599  switch ( iMode ) {
2600  case ALTERNATE: printf( "ALTERNATE\n" ); break;
2601  case WINDING: printf( "WINDING\n" ); break;
2602  default: printf( FMT, iMode );
2603  }
2604  }
2605 #endif /* ENABLE_EDITING */
2606  };
2607 
2609 
2614  public:
2618  EMRSETMAPMODE ( DWORD mode )
2619  {
2620  emr.iType = EMR_SETMAPMODE;
2621  emr.nSize = sizeof( ::EMRSETMAPMODE );
2622  iMode = mode;
2623  }
2629  {
2630  ds >> emr >> iMode;
2631  }
2635  bool serialize ( DATASTREAM ds )
2636  {
2637  ds << emr << iMode;
2638  return true;
2639  }
2643  int size ( void ) const { return emr.nSize; }
2649  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2650  {
2651  EMF_UNUSED(source);
2652  SetMapMode( dc, iMode );
2653  }
2654 #ifdef ENABLE_EDITING
2658  void edit ( void ) const
2659  {
2660 #if defined(__LP64__)
2661  const char* FMT = "unknown(%d)\n";
2662 #else
2663  const char* FMT = "unknown(%ld)\n";
2664 #endif /* __x86_64__ */
2665  printf( "*SETMAPMODE*\n" );
2666  printf( "\tiMode\t: " );
2667  switch ( iMode ) {
2668  case MM_TEXT: printf( "MM_TEXT\n" ); break;
2669  case MM_LOMETRIC: printf( "MM_LOMETRIC\n" ); break;
2670  case MM_HIMETRIC: printf( "MM_HIMETRIC\n" ); break;
2671  case MM_LOENGLISH: printf( "MM_LOENGLISH\n" ); break;
2672  case MM_HIENGLISH: printf( "MM_HIENGLISH\n" ); break;
2673  case MM_TWIPS: printf( "MM_TWIPS\n" ); break;
2674  case MM_ISOTROPIC: printf( "MM_ISOTROPIC\n" ); break;
2675  case MM_ANISOTROPIC: printf( "MM_ANISOTROPIC\n" ); break;
2676  default: printf( FMT, iMode );
2677  }
2678  }
2679 #endif /* ENABLE_EDITING */
2680  };
2681 
2683 
2687  public:
2691  EMRSELECTOBJECT ( HGDIOBJ object )
2692  {
2693  emr.iType = EMR_SELECTOBJECT;
2694  emr.nSize = sizeof( ::EMRSELECTOBJECT );
2695  ihObject = object;
2696  }
2702  {
2703  ds >> emr >> ihObject;
2704  }
2708  bool serialize ( DATASTREAM ds )
2709  {
2710  ds << emr << ihObject;
2711  return true;
2712  }
2716  int size ( void ) const { return emr.nSize; }
2722  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
2723 #ifdef ENABLE_EDITING
2727  void edit ( void ) const
2728  {
2729 #if defined(__LP64__)
2730  const char* FMT = "\tihObject\t: 0x%x\n";
2731 #else
2732  const char* FMT = "\tihObject\t: 0x%lx\n";
2733 #endif /* __x86_64__ */
2734  printf( "*SELECTOBJECT*\n" );
2735  printf( FMT, ihObject );
2736  }
2737 #endif /* ENABLE_EDITING */
2738  };
2739 
2741 
2745  public:
2749  EMRDELETEOBJECT ( HGDIOBJ object )
2750  {
2751  emr.iType = EMR_DELETEOBJECT;
2752  emr.nSize = sizeof( ::EMRDELETEOBJECT );
2753  ihObject = object;
2754  }
2760  {
2761  ds >> emr >> ihObject;
2762  }
2766  bool serialize ( DATASTREAM ds )
2767  {
2768  ds << emr << ihObject;
2769  return true;
2770  }
2774  int size ( void ) const { return emr.nSize; }
2780  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
2781 #ifdef ENABLE_EDITING
2785  void edit ( void ) const
2786  {
2787 #if defined(__LP64__)
2788  const char* FMT = "\tihObject\t: 0x%x\n";
2789 #else
2790  const char* FMT = "\tihObject\t: 0x%lx\n";
2791 #endif /* __x86_64__ */
2792  printf( "*DELETEOBJECT*\n" );
2793  printf( FMT, ihObject );
2794  }
2795 #endif /* ENABLE_EDITING */
2796  };
2797 
2799 
2803  public:
2808  EMRMOVETOEX ( INT x, INT y )
2809  {
2810  emr.iType = EMR_MOVETOEX;
2811  emr.nSize = sizeof( ::EMRMOVETOEX );
2812  ptl.x = x;
2813  ptl.y = y;
2814  }
2820  {
2821  ds >> emr >> ptl;
2822  }
2826  bool serialize ( DATASTREAM ds )
2827  {
2828  ds << emr << ptl;
2829  return true;
2830  }
2834  int size ( void ) const { return emr.nSize; }
2840  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2841  {
2842  EMF_UNUSED(source);
2843  MoveToEx( dc, ptl.x, ptl.y, 0 );
2844  }
2845 #ifdef ENABLE_EDITING
2849  void edit ( void ) const
2850  {
2851  printf( "*MOVETOEX*\n" );
2852  edit_pointl( "ptl", ptl );
2853  }
2854 #endif /* ENABLE_EDITING */
2855  };
2856 
2858 
2862  public:
2867  EMRLINETO ( INT x, INT y )
2868  {
2869  emr.iType = EMR_LINETO;
2870  emr.nSize = sizeof( ::EMRLINETO );
2871  ptl.x = x;
2872  ptl.y = y;
2873  }
2879  {
2880  ds >> emr >> ptl;
2881  }
2885  bool serialize ( DATASTREAM ds )
2886  {
2887  ds << emr << ptl;
2888  return true;
2889  }
2893  int size ( void ) const { return emr.nSize; }
2899  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2900  {
2901  EMF_UNUSED(source);
2902  LineTo( dc, ptl.x, ptl.y );
2903  }
2904 #ifdef ENABLE_EDITING
2908  void edit ( void ) const
2909  {
2910  printf( "*LINETO*\n" );
2911  edit_pointl( "ptl", ptl );
2912  }
2913 #endif /* ENABLE_EDITING */
2914  };
2915 
2917 
2920  class EMRARC : public METARECORD, ::EMRARC {
2921  public:
2933  EMRARC ( INT left, INT top, INT right, INT bottom, INT xstart,
2934  INT ystart, INT xend, INT yend )
2935  {
2936  emr.iType = EMR_ARC;
2937  emr.nSize = sizeof( ::EMRARC );
2938  rclBox.left = left;
2939  rclBox.right = right;
2940  rclBox.bottom = bottom;
2941  rclBox.top = top;
2942  ptlStart.x = xstart;
2943  ptlStart.y = ystart;
2944  ptlEnd.x = xend;
2945  ptlEnd.y = yend;
2946  }
2952  {
2953  ds >> emr >> rclBox >> ptlStart >> ptlEnd;
2954  }
2958  bool serialize ( DATASTREAM ds )
2959  {
2960  ds << emr << rclBox << ptlStart << ptlEnd;
2961  return true;
2962  }
2966  int size ( void ) const { return emr.nSize; }
2972  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
2973  {
2974  EMF_UNUSED(source);
2975  Arc( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
2976  ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
2977  }
2978 #ifdef ENABLE_EDITING
2982  void edit ( void ) const
2983  {
2984  printf( "*ARC*\n" );
2985  edit_rectl( "rclBox\t", rclBox );
2986  edit_pointl( "ptlStart", ptlStart );
2987  edit_pointl( "ptlEnd\t", ptlEnd );
2988  }
2989 #endif /* ENABLE_EDITING */
2990  };
2991 
2993 
2996  class EMRARCTO : public METARECORD, ::EMRARCTO {
2997  public:
3009  EMRARCTO ( INT left, INT top, INT right, INT bottom, INT xstart,
3010  INT ystart, INT xend, INT yend )
3011  {
3012  emr.iType = EMR_ARCTO;
3013  emr.nSize = sizeof( ::EMRARCTO );
3014  rclBox.left = left;
3015  rclBox.right = right;
3016  rclBox.bottom = bottom;
3017  rclBox.top = top;
3018  ptlStart.x = xstart;
3019  ptlStart.y = ystart;
3020  ptlEnd.x = xend;
3021  ptlEnd.y = yend;
3022  }
3028  {
3029  ds >> emr >> rclBox >> ptlStart >> ptlEnd;
3030  }
3034  bool serialize ( DATASTREAM ds )
3035  {
3036  ds << emr << rclBox << ptlStart << ptlEnd;
3037  return true;
3038  }
3042  int size ( void ) const { return emr.nSize; }
3048  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3049  {
3050  EMF_UNUSED(source);
3051  ArcTo( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
3052  ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
3053  }
3054 #ifdef ENABLE_EDITING
3058  void edit ( void ) const
3059  {
3060  printf( "*ARCTO*\n" );
3061  edit_rectl( "rclBox\t", rclBox );
3062  edit_pointl( "ptlStart", ptlStart );
3063  edit_pointl( "ptlEnd\t", ptlEnd );
3064  }
3065 #endif /* ENABLE_EDITING */
3066  };
3067 
3069 
3073  public:
3080  EMRRECTANGLE ( INT left, INT top, INT right, INT bottom )
3081  {
3082  emr.iType = EMR_RECTANGLE;
3083  emr.nSize = sizeof( ::EMRRECTANGLE );
3084  rclBox.left = left;
3085  rclBox.right = right;
3086  rclBox.bottom = bottom;
3087  rclBox.top = top;
3088  }
3094  {
3095  ds >> emr >> rclBox;
3096  }
3100  bool serialize ( DATASTREAM ds )
3101  {
3102  ds << emr << rclBox;
3103  return true;
3104  }
3108  int size ( void ) const { return emr.nSize; }
3114  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3115  {
3116  EMF_UNUSED(source);
3117  Rectangle( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
3118  }
3119 #ifdef ENABLE_EDITING
3123  void edit ( void ) const
3124  {
3125  printf( "*RECTANGLE*\n" );
3126  edit_rectl( "rclBox", rclBox );
3127  }
3128 #endif /* ENABLE_EDITING */
3129  };
3130 
3132 
3136  public:
3144  EMRELLIPSE ( INT left, INT top, INT right, INT bottom )
3145  {
3146  emr.iType = EMR_ELLIPSE;
3147  emr.nSize = sizeof( ::EMRELLIPSE );
3148  rclBox.left = left;
3149  rclBox.right = right;
3150  rclBox.bottom = bottom;
3151  rclBox.top = top;
3152  }
3158  {
3159  ds >> emr >> rclBox;
3160  }
3164  bool serialize ( DATASTREAM ds )
3165  {
3166  ds << emr << rclBox;
3167  return true;
3168  }
3172  int size ( void ) const { return emr.nSize; }
3178  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3179  {
3180  EMF_UNUSED(source);
3181  Ellipse( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
3182  }
3183 #ifdef ENABLE_EDITING
3187  void edit ( void ) const
3188  {
3189  printf( "*ELLIPSE*\n" );
3190  edit_rectl( "rclBox", rclBox );
3191  }
3192 #endif /* ENABLE_EDITING */
3193  };
3194 
3196 
3200  POINTL* lpoints{nullptr};
3201  public:
3207  EMRPOLYLINE ( const RECTL* bounds, const POINT* points, INT n )
3208  {
3209  cptl = n;
3210  aptl[0].x = 0; // Really unused
3211  aptl[0].y = 0;
3212 
3213  emr.iType = EMR_POLYLINE;
3214  // The (cptl - 1) below is to account for aptl, which isn't written out
3215  emr.nSize = sizeof( ::EMRPOLYLINE ) + sizeof( POINTL ) * ( cptl - 1);
3216 
3217  lpoints = new POINTL[cptl];
3218 
3219  for (int i=0; i<n; i++) {
3220  lpoints[i].x = points[i].x;
3221  lpoints[i].y = points[i].y;
3222  }
3223 
3224  rclBounds = *bounds;
3225  }
3230  {
3231  if ( lpoints ) delete[] lpoints;
3232  }
3238  {
3239  ds >> emr >> rclBounds >> cptl;
3240 
3241  if ( emr.nSize - (sizeof(::EMRPOLYLINE)-sizeof(POINTL) ) <
3242  sizeof(POINTL) * cptl ) {
3243  throw std::runtime_error( "Invalid record size" );
3244  }
3245 
3246  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
3247  POINTLARRAY points( buffer.get(), cptl );
3248 
3249  ds >> points;
3250 
3251  lpoints = buffer.release();
3252  }
3256  bool serialize ( DATASTREAM ds )
3257  {
3258  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
3259  return true;
3260  }
3264  int size ( void ) const { return emr.nSize; }
3270  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3271  {
3272  EMF_UNUSED(source);
3273  // According to the wine windef.h header, POINT and POINTL are equivalent
3274  Polyline( dc, (POINT*)lpoints, cptl );
3275  }
3276 #ifdef ENABLE_EDITING
3280  void edit ( void ) const
3281  {
3282  printf( "*POLYLINE*\n" );
3283  edit_rectl( "rclBounds", rclBounds );
3284  edit_pointlarray( "\t", cptl, lpoints );
3285  }
3286 #endif /* ENABLE_EDITING */
3287  };
3288 
3290 
3294  POINT16* lpoints{ nullptr };
3295  public:
3301  EMRPOLYLINE16 ( const RECTL* bounds, const POINT16* points, INT n )
3302  {
3303  cpts = n;
3304  apts[0].x = 0; // Really unused
3305  apts[0].y = 0;
3306 
3307  emr.iType = EMR_POLYLINE16;
3308  // The (cptl - 1) below is to account for aptl, which isn't written out
3309  emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
3310 
3311  lpoints = new POINT16[cpts];
3312 
3313  for (int i=0; i<n; i++) {
3314  lpoints[i].x = points[i].x;
3315  lpoints[i].y = points[i].y;
3316  }
3317 
3318  rclBounds = *bounds;
3319  }
3326  EMRPOLYLINE16 ( const RECTL* bounds, const POINT* points, INT n )
3327  {
3328  cpts = n;
3329  apts[0].x = 0; // Really unused
3330  apts[0].y = 0;
3331 
3332  emr.iType = EMR_POLYLINE16;
3333  // The (cptl - 1) below is to account for aptl, which isn't written out
3334  emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
3335 
3336  lpoints = new POINT16[cpts];
3337 
3338  for (int i=0; i<n; i++) {
3339  lpoints[i].x = points[i].x;
3340  lpoints[i].y = points[i].y;
3341  }
3342 
3343  rclBounds = *bounds;
3344  }
3349  {
3350  if ( lpoints ) delete[] lpoints;
3351  }
3357  {
3358  ds >> emr >> rclBounds >> cpts;
3359 
3360  if ( emr.nSize - (sizeof(::EMRPOLYLINE16)-sizeof(POINT16) ) <
3361  sizeof(POINT16) * cpts ) {
3362  throw std::runtime_error( "Invalid record size" );
3363  }
3364 
3365  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
3366 
3367  POINT16ARRAY points( buffer.get(), cpts );
3368 
3369  ds >> points;
3370 
3371  lpoints = buffer.release();
3372  }
3376  bool serialize ( DATASTREAM ds )
3377  {
3378  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
3379  return true;
3380  }
3384  int size ( void ) const { return emr.nSize; }
3390  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3391  {
3392  EMF_UNUSED(source);
3393  // According to the wine windef.h header, POINT and POINTL are equivalent
3394  Polyline16( dc, lpoints, cpts );
3395  }
3396 #ifdef ENABLE_EDITING
3400  void edit ( void ) const
3401  {
3402  printf( "*POLYLINE16*\n" );
3403  edit_rectl( "rclBounds", rclBounds );
3404  edit_point16array( "\t", cpts, lpoints );
3405  }
3406 #endif /* ENABLE_EDITING */
3407  };
3408 
3410 
3414  POINTL* lpoints{ nullptr };
3415  public:
3421  EMRPOLYGON ( const RECTL* bounds, const POINT* points, INT n )
3422  {
3423  cptl = n;
3424  aptl[0].x = 0; // Really unused
3425  aptl[0].y = 0;
3426 
3427  emr.iType = EMR_POLYGON;
3428  // The (cptl-1) below is to account for aptl, which isn't written out
3429  emr.nSize = sizeof( ::EMRPOLYGON ) + sizeof( POINTL ) * (cptl-1);
3430 
3431  lpoints = new POINTL[cptl];
3432 
3433  for (int i=0; i<n; i++) {
3434  lpoints[i].x = points[i].x;
3435  lpoints[i].y = points[i].y;
3436  }
3437 
3438  rclBounds = *bounds;
3439  }
3445  {
3446  ds >> emr >> rclBounds >> cptl;
3447 
3448  if ( emr.nSize - (sizeof(::EMRPOLYGON) - sizeof(POINTL)) <
3449  cptl * sizeof(POINTL) ) {
3450  throw std::runtime_error( "Invalid record size" );
3451  }
3452 
3453  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
3454 
3455  POINTLARRAY points( buffer.get(), cptl );
3456 
3457  ds >> points;
3458 
3459  lpoints = buffer.release();
3460  }
3465  {
3466  if ( lpoints ) delete[] lpoints;
3467  }
3471  bool serialize ( DATASTREAM ds )
3472  {
3473  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
3474  return true;
3475  }
3479  int size ( void ) const { return emr.nSize; }
3485  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3486  {
3487  EMF_UNUSED(source);
3488  // According to the wine windef.h header, POINT and POINTL are equivalent
3489  Polygon( dc, (POINT*)lpoints, cptl );
3490  }
3491 #ifdef ENABLE_EDITING
3495  void edit ( void ) const
3496  {
3497  printf( "*POLYGON*\n" );
3498  edit_rectl( "rclBounds", rclBounds );
3499  edit_pointlarray( "\t", cptl, lpoints );
3500  }
3501 #endif /* ENABLE_EDITING */
3502  };
3503 
3505 
3509  POINT16* lpoints{ nullptr };
3510  public:
3516  EMRPOLYGON16 ( const RECTL* bounds, const POINT* points, INT16 n )
3517  {
3518  cpts = n;
3519  apts[0].x = 0; // Really unused
3520  apts[0].y = 0;
3521 
3522  emr.iType = EMR_POLYGON16;
3523  // The (cptl-1) below is to account for aptl, which isn't written out
3524  emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
3525 
3526  lpoints = new POINT16[cpts];
3527 
3528  for (int i=0; i<n; i++) {
3529  lpoints[i].x = points[i].x;
3530  lpoints[i].y = points[i].y;
3531  }
3532 
3533  rclBounds = *bounds;
3534  }
3541  EMRPOLYGON16 ( const RECTL* bounds, const POINT16* points, INT16 n )
3542  {
3543  cpts = n;
3544  apts[0].x = 0; // Really unused
3545  apts[0].y = 0;
3546 
3547  emr.iType = EMR_POLYGON16;
3548  // The (cptl-1) below is to account for aptl, which isn't written out
3549  emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
3550 
3551  lpoints = new POINT16[cpts];
3552 
3553  for (int i=0; i<n; i++) {
3554  lpoints[i].x = points[i].x;
3555  lpoints[i].y = points[i].y;
3556  }
3557 
3558  rclBounds = *bounds;
3559  }
3565  {
3566  ds >> emr >> rclBounds >> cpts;
3567 
3568  if ( emr.nSize - (sizeof(::EMRPOLYGON16) - sizeof(POINT16)) <
3569  cpts * sizeof(POINT16) ) {
3570  throw std::runtime_error( "Invalid record size" );
3571  }
3572 
3573  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
3574 
3575  POINT16ARRAY points( buffer.get(), cpts );
3576 
3577  ds >> points;
3578 
3579  lpoints = buffer.release();
3580  }
3585  {
3586  if ( lpoints ) delete[] lpoints;
3587  }
3591  bool serialize ( DATASTREAM ds )
3592  {
3593  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
3594  return true;
3595  }
3599  int size ( void ) const { return emr.nSize; }
3605  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3606  {
3607  EMF_UNUSED(source);
3608  // According to the wine windef.h header, POINT and POINTL are equivalent
3609  Polygon16( dc, lpoints, cpts );
3610  }
3611 #ifdef ENABLE_EDITING
3615  void edit ( void ) const
3616  {
3617  printf( "*POLYGON16*\n" );
3618  edit_rectl( "rclBounds", rclBounds );
3619  edit_point16array( "\t", cpts, lpoints );
3620  }
3621 #endif /* ENABLE_EDITING */
3622  };
3623 
3625 
3629  DWORD* lcounts{ nullptr };
3630  POINTL* lpoints{ nullptr };
3631  public:
3638  EMRPOLYPOLYGON ( const RECTL* bounds, const POINT* points, const INT* counts,
3639  UINT polygons )
3640  {
3641  nPolys = polygons;
3642  // Count the number of points in points
3643  int n = 0;
3644  for ( unsigned int i = 0; i < nPolys; i++ )
3645  n += counts[i];
3646 
3647  cptl = n;
3648  aPolyCounts[0] = 0; // Really unused
3649  aptl[0].x = 0;
3650  aptl[0].y = 0;
3651 
3652  emr.iType = EMR_POLYPOLYGON;
3653  // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
3654  // aren't directly written out
3655  emr.nSize = sizeof( ::EMRPOLYPOLYGON ) + sizeof( POINTL ) * (cptl-1)
3656  + sizeof( DWORD ) * (nPolys-1);
3657 
3658  lcounts = new DWORD[nPolys];
3659 
3660  for ( unsigned int i = 0; i < nPolys; i++ )
3661  lcounts[i] = counts[i];
3662 
3663  lpoints = new POINTL[cptl];
3664 
3665  for (int i=0; i<n; i++) {
3666  lpoints[i].x = points[i].x;
3667  lpoints[i].y = points[i].y;
3668  }
3669 
3670  rclBounds = *bounds;
3671  }
3676  {
3677  if ( lcounts ) delete[] lcounts;
3678  if ( lpoints ) delete[] lpoints;
3679  }
3685  {
3686  ds >> emr >> rclBounds >> nPolys >> cptl;
3687 
3688  if ( emr.nSize - ( sizeof( ::EMRPOLYPOLYGON ) - sizeof(POINTL) - sizeof(DWORD) ) <
3689  sizeof( POINTL ) * cptl + sizeof( DWORD ) * nPolys ) {
3690  throw std::runtime_error( "Invalid record size" );
3691  }
3692 
3693  std::unique_ptr<DWORD[]> cbuffer( new DWORD[nPolys] );
3694 
3695  DWORDARRAY counts( cbuffer.get(), nPolys );
3696 
3697  ds >> counts;
3698 
3699  // Counts have to add up to less than the number of points
3700  // we have. DWORD is unsigned so we most care about overflow.
3701  DWORD n{0}, n_old{0};
3702  for ( DWORD c{0}; c < nPolys; ++c ) {
3703  n_old = n;
3704  n += cbuffer[c];
3705  if ( n < n_old ) {
3706  throw std::runtime_error( "Unsigned overflow" );
3707  }
3708  }
3709  if ( n > cptl ) {
3710  throw std::runtime_error( "Too few points" );
3711  }
3712 
3713  std::unique_ptr<POINTL[]> pbuffer( new POINTL[cptl] );
3714 
3715  POINTLARRAY points( pbuffer.get(), cptl );
3716 
3717  ds >> points;
3718 
3719  // Don't do this until we won't have any more exceptions.
3720  lcounts = cbuffer.release();
3721  lpoints = pbuffer.release();
3722  }
3726  bool serialize ( DATASTREAM ds )
3727  {
3728  ds << emr << rclBounds << nPolys << cptl << DWORDARRAY( lcounts, nPolys )
3729  << POINTLARRAY( lpoints, cptl );
3730  return true;
3731  }
3735  int size ( void ) const { return emr.nSize; }
3741  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3742  {
3743  EMF_UNUSED(source);
3744  // According to the wine windef.h header, POINT and POINTL are equivalent
3745  // (but DWORD and INT are not)
3746  std::vector<INT> countsv( lcounts, lcounts + nPolys );
3747 
3748  PolyPolygon( dc, (POINT*)lpoints, countsv.data(), nPolys );
3749  }
3750 #ifdef ENABLE_EDITING
3754  void edit ( void ) const
3755  {
3756 #if defined(__LP64__)
3757  const char* FMT0 = "\tnPolys\t\t: %d\n";
3758  const char* FMT1 = "\tcptl\t\t: %d\n";
3759  const char* FMT2 = "%d\n";
3760  const char* FMT3 = "\t\t\t %d\n";
3761  const char* FMT4 = "%d, %d\n";
3762  const char* FMT5 = "\t\t\t %d, %d\n";
3763 #else
3764  const char* FMT0 = "\tnPolys\t\t: %ld\n";
3765  const char* FMT1 = "\tcptl\t\t: %ld\n";
3766  const char* FMT2 = "%ld\n";
3767  const char* FMT3 = "\t\t\t %ld\n";
3768  const char* FMT4 = "%ld, %ld\n";
3769  const char* FMT5 = "\t\t\t %ld, %ld\n";
3770 #endif /* __x86_64__ */
3771  printf( "*POLYPOLYGON*\n" );
3772  edit_rectl( "rclBounds", rclBounds );
3773  printf( FMT0, nPolys );
3774  printf( FMT1, cptl );
3775  printf( "\taPolyCounts\t: " );
3776  if ( nPolys > 0 )
3777  printf( FMT2, lcounts[0] );
3778  else
3779  puts( "" );
3780  for ( unsigned int i = 1; i < nPolys; i++ )
3781  printf( FMT3, lcounts[i] );
3782  printf( "\tapts\t\t: " );
3783  if ( cptl > 0 )
3784  printf( FMT4, lpoints[0].x, lpoints[0].y );
3785  else
3786  puts( "" );
3787  for ( unsigned int i = 1; i < cptl; i++ )
3788  printf( FMT5, lpoints[i].x, lpoints[i].y );
3789  }
3790 #endif /* ENABLE_EDITING */
3791  };
3792 
3794 
3798  DWORD* lcounts{ nullptr };
3799  POINT16* lpoints{ nullptr };
3800  public:
3807  EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT* points,
3808  const INT* counts, UINT polygons )
3809  {
3810  nPolys = polygons;
3811  // Count the number of points in points
3812  int n = 0;
3813  for ( unsigned int i = 0; i < nPolys; i++ )
3814  n += counts[i];
3815 
3816  cpts = n;
3817  aPolyCounts[0] = 0; // Really unused
3818  apts[0].x = 0;
3819  apts[0].y = 0;
3820 
3821  emr.iType = EMR_POLYPOLYGON16;
3822  // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
3823  // aren't directly written out
3824  emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
3825  + sizeof( DWORD ) * (nPolys-1);
3826 
3827  lcounts = new DWORD[nPolys];
3828 
3829  for ( unsigned int i = 0; i < nPolys; i++ )
3830  lcounts[i] = counts[i];
3831 
3832  lpoints = new POINT16[cpts];
3833 
3834  for (int i=0; i<n; i++) {
3835  lpoints[i].x = points[i].x;
3836  lpoints[i].y = points[i].y;
3837  }
3838 
3839  rclBounds = *bounds;
3840  }
3848  EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT16* points,
3849  const INT* counts, UINT16 polygons )
3850  {
3851  nPolys = polygons;
3852  // Count the number of points in points
3853  int n = 0;
3854  for ( unsigned int i = 0; i < nPolys; i++ )
3855  n += counts[i];
3856 
3857  cpts = n;
3858  aPolyCounts[0] = 0; // Really unused
3859  apts[0].x = 0;
3860  apts[0].y = 0;
3861 
3862  emr.iType = EMR_POLYPOLYGON16;
3863  // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
3864  // aren't directly written out
3865  emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
3866  + sizeof( DWORD ) * (nPolys-1);
3867 
3868  lcounts = new DWORD[nPolys];
3869 
3870  for ( unsigned int i = 0; i < nPolys; i++ )
3871  lcounts[i] = counts[i];
3872 
3873  lpoints = new POINT16[cpts];
3874 
3875  for (int i=0; i<n; i++) {
3876  lpoints[i].x = points[i].x;
3877  lpoints[i].y = points[i].y;
3878  }
3879 
3880  rclBounds = *bounds;
3881  }
3886  {
3887  if ( lcounts ) delete[] lcounts;
3888  if ( lpoints ) delete[] lpoints;
3889  }
3895  {
3896  ds >> emr >> rclBounds >> nPolys >> cpts;
3897 
3898  if ( emr.nSize - ( sizeof( ::EMRPOLYPOLYGON16 ) - sizeof(POINT16) - sizeof(DWORD) ) <
3899  sizeof( POINT16 ) * cpts + sizeof( DWORD ) * nPolys ) {
3900  throw std::runtime_error( "Invalid record size" );
3901  }
3902 
3903  std::unique_ptr<DWORD[]> cbuffer( new DWORD[nPolys] );
3904 
3905  DWORDARRAY counts( cbuffer.get(), nPolys );
3906 
3907  ds >> counts;
3908 
3909  // Counts have to add up to less than the number of points
3910  // we have. DWORD is unsigned so we most care about overflow.
3911  DWORD n{0}, n_old{0};
3912  for ( DWORD c{0}; c < nPolys; ++c ) {
3913  n_old = n;
3914  n += cbuffer[c];
3915  if ( n < n_old ) {
3916  throw std::runtime_error( "Unsigned overflow" );
3917  }
3918  }
3919  if ( n > cpts ) {
3920  throw std::runtime_error( "Too few points" );
3921  }
3922 
3923  std::unique_ptr<POINT16[]> pbuffer( new POINT16[cpts] );
3924 
3925  POINT16ARRAY points( pbuffer.get(), cpts );
3926 
3927  ds >> points;
3928 
3929  lcounts = cbuffer.release();
3930  lpoints = pbuffer.release();
3931  }
3935  bool serialize ( DATASTREAM ds )
3936  {
3937  ds << emr << rclBounds << nPolys << cpts << DWORDARRAY( lcounts, nPolys )
3938  << POINT16ARRAY( lpoints, cpts );
3939  return true;
3940  }
3944  int size ( void ) const { return emr.nSize; }
3950  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
3951  {
3952  EMF_UNUSED(source);
3953  // According to the wine windef.h header, POINT and POINTL are equivalent
3954  // (but DWORD and INT are not)
3955  std::vector<INT> counts( lcounts, lcounts + nPolys );
3956 
3957  PolyPolygon16( dc, lpoints, counts.data(), nPolys );
3958  }
3959 #ifdef ENABLE_EDITING
3963  void edit ( void ) const
3964  {
3965 #if defined(__LP64__)
3966  const char* FMT0 = "\tnPolys\t\t: %d\n";
3967  const char* FMT1 = "\tcptl\t\t: %d\n";
3968  const char* FMT2 = "%d\n";
3969  const char* FMT3 = "\t\t\t %d\n";
3970 #else
3971  const char* FMT0 = "\tnPolys\t\t: %ld\n";
3972  const char* FMT1 = "\tcptl\t\t: %ld\n";
3973  const char* FMT2 = "%ld\n";
3974  const char* FMT3 = "\t\t\t %ld\n";
3975 #endif /* __x86_64__ */
3976  printf( "*POLYPOLYGON16*\n" );
3977  edit_rectl( "rclBounds", rclBounds );
3978  printf( FMT0, nPolys );
3979  printf( FMT1, cpts );
3980  printf( "\taPolyCounts\t: " );
3981  if ( nPolys > 0 )
3982  printf( FMT2, lcounts[0] );
3983  else
3984  puts( "" );
3985  for ( unsigned int i = 1; i < nPolys; i++ )
3986  printf( FMT3, lcounts[i] );
3987  printf( "\tapts\t\t: " );
3988  if ( cpts > 0 )
3989  printf( "%d, %d\n", lpoints[0].x, lpoints[0].y );
3990  else
3991  puts( "" );
3992  for ( unsigned int i = 1; i < cpts; i++ )
3993  printf( "\t\t\t %d, %d\n", lpoints[i].x, lpoints[i].y );
3994  }
3995 #endif /* ENABLE_EDITING */
3996  };
3997 
3999 
4003  POINTL* lpoints{ nullptr };
4004  public:
4010  EMRPOLYBEZIER ( const RECTL* bounds, const POINT* points, INT n )
4011  {
4012  cptl = n;
4013  aptl[0].x = 0; // Really unused
4014  aptl[0].y = 0;
4015 
4016  emr.iType = EMR_POLYBEZIER;
4017  // The (cptl-1) below is to account for aptl, which isn't written out
4018  emr.nSize = sizeof( ::EMRPOLYBEZIER ) + sizeof( POINTL ) * (cptl-1);
4019 
4020  lpoints = new POINTL[cptl];
4021 
4022  for (int i=0; i<n; i++) {
4023  lpoints[i].x = points[i].x;
4024  lpoints[i].y = points[i].y;
4025  }
4026 
4027  rclBounds = *bounds;
4028  }
4034  {
4035  ds >> emr >> rclBounds >> cptl;
4036 
4037  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIER ) - sizeof(POINTL)) <
4038  sizeof( POINTL ) * cptl ) {
4039  throw std::runtime_error( "Invalid record size" );
4040  }
4041 
4042  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
4043 
4044  POINTLARRAY points( buffer.get(), cptl );
4045 
4046  ds >> points;
4047 
4048  lpoints = buffer.release();
4049  }
4054  {
4055  if ( lpoints ) delete[] lpoints;
4056  }
4060  bool serialize ( DATASTREAM ds )
4061  {
4062  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
4063  return true;
4064  }
4068  int size ( void ) const { return emr.nSize; }
4074  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4075  {
4076  EMF_UNUSED(source);
4077  // According to the wine windef.h header, POINT and POINTL are equivalent
4078  PolyBezier( dc, (POINT*)lpoints, cptl );
4079  }
4080 #ifdef ENABLE_EDITING
4084  void edit ( void ) const
4085  {
4086  printf( "*POLYBEZIER*\n" );
4087  edit_rectl( "rclBounds", rclBounds );
4088  edit_pointlarray( "\t", cptl, lpoints );
4089  }
4090 #endif /* ENABLE_EDITING */
4091  };
4092 
4094 
4098  POINT16* lpoints{ nullptr };
4099  public:
4105  EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT16* points, INT n )
4106  {
4107  cpts = n;
4108  apts[0].x = 0; // Really unused
4109  apts[0].y = 0;
4110 
4111  emr.iType = EMR_POLYBEZIER16;
4112  // The (cptl-1) below is to account for aptl, which isn't written out
4113  emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
4114 
4115  lpoints = new POINT16[cpts];
4116 
4117  for (int i=0; i<n; i++) {
4118  lpoints[i].x = points[i].x;
4119  lpoints[i].y = points[i].y;
4120  }
4121 
4122  rclBounds = *bounds;
4123  }
4130  EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT* points, INT n )
4131  {
4132  cpts = n;
4133  apts[0].x = 0; // Really unused
4134  apts[0].y = 0;
4135 
4136  emr.iType = EMR_POLYBEZIER16;
4137  // The (cptl-1) below is to account for aptl, which isn't written out
4138  emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
4139 
4140  lpoints = new POINT16[cpts];
4141 
4142  for (int i=0; i<n; i++) {
4143  lpoints[i].x = points[i].x;
4144  lpoints[i].y = points[i].y;
4145  }
4146 
4147  rclBounds = *bounds;
4148  }
4154  {
4155  ds >> emr >> rclBounds >> cpts;
4156 
4157  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIER16 ) - sizeof(POINT16)) <
4158  sizeof( POINT16 ) * cpts ) {
4159  throw std::runtime_error( "Invalid record size" );
4160  }
4161 
4162  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
4163 
4164  POINT16ARRAY points( buffer.get(), cpts );
4165 
4166  ds >> points;
4167 
4168  lpoints = buffer.release();
4169  }
4174  {
4175  if ( lpoints ) delete[] lpoints;
4176  }
4180  bool serialize ( DATASTREAM ds )
4181  {
4182  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
4183  return true;
4184  }
4188  int size ( void ) const { return emr.nSize; }
4194  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4195  {
4196  EMF_UNUSED(source);
4197  // According to the wine windef.h header, POINT and POINTL are equivalent
4198  PolyBezier16( dc, lpoints, cpts );
4199  }
4200 #ifdef ENABLE_EDITING
4204  void edit ( void ) const
4205  {
4206  printf( "*POLYBEZIER16*\n" );
4207  edit_rectl( "rclBounds", rclBounds );
4208  edit_point16array( "\t", cpts, lpoints );
4209  }
4210 #endif /* ENABLE_EDITING */
4211  };
4212 
4214 
4218  POINTL* lpoints{ nullptr };
4219  public:
4225  EMRPOLYBEZIERTO ( const RECTL* bounds, const POINT* points, INT n )
4226  {
4227  cptl = n;
4228  aptl[0].x = 0; // Really unused
4229  aptl[0].y = 0;
4230 
4231  emr.iType = EMR_POLYBEZIERTO;
4232  // The (cptl-1) below is to account for aptl, which isn't written out
4233  emr.nSize = sizeof( ::EMRPOLYBEZIERTO ) + sizeof( POINTL ) * (cptl-1);
4234 
4235  lpoints = new POINTL[cptl];
4236 
4237  for (int i=0; i<n; i++) {
4238  lpoints[i].x = points[i].x;
4239  lpoints[i].y = points[i].y;
4240  }
4241 
4242  rclBounds = *bounds;
4243  }
4249  {
4250  ds >> emr >> rclBounds >> cptl;
4251 
4252  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIERTO ) - sizeof(POINTL)) <
4253  sizeof( POINTL ) * cptl ) {
4254  throw std::runtime_error( "Invalid record size" );
4255  }
4256 
4257  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
4258 
4259  POINTLARRAY points( buffer.get(), cptl );
4260 
4261  ds >> points;
4262 
4263  lpoints = buffer.release();
4264  }
4269  {
4270  if ( lpoints ) delete[] lpoints;
4271  }
4275  bool serialize ( DATASTREAM ds )
4276  {
4277  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
4278  return true;
4279  }
4283  int size ( void ) const { return emr.nSize; }
4289  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4290  {
4291  EMF_UNUSED(source);
4292  // According to the wine windef.h header, POINT and POINTL are equivalent
4293  PolyBezierTo( dc, (POINT*)lpoints, cptl );
4294  }
4295 #ifdef ENABLE_EDITING
4299  void edit ( void ) const
4300  {
4301  printf( "*POLYBEZIERTO*\n" );
4302  edit_rectl( "rclBounds", rclBounds );
4303  edit_pointlarray( "\t", cptl, lpoints );
4304  }
4305 #endif /* ENABLE_EDITING */
4306  };
4307 
4309 
4313  POINT16* lpoints{ nullptr };
4314  public:
4320  EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT16* points, INT n )
4321  {
4322  cpts = n;
4323  apts[0].x = 0; // Really unused
4324  apts[0].y = 0;
4325 
4326  emr.iType = EMR_POLYBEZIERTO16;
4327  // The (cptl-1) below is to account for aptl, which isn't written out
4328  emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
4329 
4330  lpoints = new POINT16[cpts];
4331 
4332  for (int i=0; i<n; i++) {
4333  lpoints[i].x = points[i].x;
4334  lpoints[i].y = points[i].y;
4335  }
4336 
4337  rclBounds = *bounds;
4338  }
4345  EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT* points, INT n )
4346  {
4347  cpts = n;
4348  apts[0].x = 0; // Really unused
4349  apts[0].y = 0;
4350 
4351  emr.iType = EMR_POLYBEZIERTO16;
4352  // The (cptl-1) below is to account for aptl, which isn't written out
4353  emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
4354 
4355  lpoints = new POINT16[cpts];
4356 
4357  for (int i=0; i<n; i++) {
4358  lpoints[i].x = points[i].x;
4359  lpoints[i].y = points[i].y;
4360  }
4361 
4362  rclBounds = *bounds;
4363  }
4369  {
4370  ds >> emr >> rclBounds >> cpts;
4371 
4372  if ( emr.nSize - (sizeof( ::EMRPOLYBEZIERTO16 ) - sizeof(POINT16)) <
4373  sizeof( POINT16 ) * cpts ) {
4374  throw std::runtime_error( "Invalid record size" );
4375  }
4376 
4377  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
4378 
4379  POINT16ARRAY points( buffer.get(), cpts );
4380 
4381  ds >> points;
4382 
4383  lpoints = buffer.release();
4384  }
4389  {
4390  if ( lpoints ) delete[] lpoints;
4391  }
4395  bool serialize ( DATASTREAM ds )
4396  {
4397  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
4398  return true;
4399  }
4403  int size ( void ) const { return emr.nSize; }
4409  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4410  {
4411  EMF_UNUSED(source);
4412  // According to the wine windef.h header, POINT and POINTL are equivalent
4413  PolyBezierTo16( dc, lpoints, cpts );
4414  }
4415 #ifdef ENABLE_EDITING
4419  void edit ( void ) const
4420  {
4421  printf( "*POLYBEZIERTO16*\n" );
4422  edit_rectl( "rclBounds", rclBounds );
4423  edit_point16array( "\t", cpts, lpoints );
4424  }
4425 #endif /* ENABLE_EDITING */
4426  };
4427 
4429 
4433  POINTL* lpoints{ nullptr };
4434  public:
4440  EMRPOLYLINETO ( const RECTL* bounds, const POINT* points, INT n )
4441  {
4442  cptl = n;
4443  aptl[0].x = 0;
4444  aptl[0].y = 0;
4445 
4446  emr.iType = EMR_POLYLINETO;
4447  // The (cptl-1) below is to account for aptl, which isn't written out
4448  emr.nSize = sizeof( ::EMRPOLYLINETO ) + sizeof( POINTL ) * (cptl-1);
4449 
4450  lpoints = new POINTL[cptl];
4451 
4452  for (int i=0; i<n; i++) {
4453  lpoints[i].x = points[i].x;
4454  lpoints[i].y = points[i].y;
4455  }
4456 
4457  rclBounds = *bounds;
4458  }
4464  {
4465  ds >> emr >> rclBounds >> cptl;
4466 
4467  if ( emr.nSize - (sizeof( ::EMRPOLYLINETO ) - sizeof(POINTL)) <
4468  sizeof( POINTL ) * cptl ) {
4469  throw std::runtime_error( "Invalid record size" );
4470  }
4471 
4472  std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
4473 
4474  POINTLARRAY points( buffer.get(), cptl );
4475 
4476  ds >> points;
4477 
4478  lpoints = buffer.release();
4479  }
4484  {
4485  if ( lpoints ) delete[] lpoints;
4486  }
4490  bool serialize ( DATASTREAM ds )
4491  {
4492  ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
4493  return true;
4494  }
4498  int size ( void ) const { return emr.nSize; }
4504  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4505  {
4506  EMF_UNUSED(source);
4507  // According to the wine windef.h header, POINT and POINTL are equivalent
4508  PolylineTo( dc, (POINT*)lpoints, cptl );
4509  }
4510 #ifdef ENABLE_EDITING
4514  void edit ( void ) const
4515  {
4516  printf( "*POLYLINETO*\n" );
4517  edit_rectl( "rclBounds", rclBounds );
4518  edit_pointlarray( "\t", cptl, lpoints );
4519  }
4520 #endif /* ENABLE_EDITING */
4521  };
4522 
4524 
4528  POINT16* lpoints{ nullptr };
4529  public:
4535  EMRPOLYLINETO16 ( const RECTL* bounds, const POINT16* points, INT n )
4536  {
4537  cpts = n;
4538  apts[0].x = 0;
4539  apts[0].y = 0;
4540 
4541  emr.iType = EMR_POLYLINETO16;
4542  // The (cptl-1) below is to account for aptl, which isn't written out
4543  emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
4544 
4545  lpoints = new POINT16[cpts];
4546 
4547  for (int i=0; i<n; i++) {
4548  lpoints[i].x = points[i].x;
4549  lpoints[i].y = points[i].y;
4550  }
4551 
4552  rclBounds = *bounds;
4553  }
4560  EMRPOLYLINETO16 ( const RECTL* bounds, const POINT* points, INT n )
4561  {
4562  cpts = n;
4563  apts[0].x = 0;
4564  apts[0].y = 0;
4565 
4566  emr.iType = EMR_POLYLINETO16;
4567  // The (cptl-1) below is to account for aptl, which isn't written out
4568  emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
4569 
4570  lpoints = new POINT16[cpts];
4571 
4572  for (int i=0; i<n; i++) {
4573  lpoints[i].x = points[i].x;
4574  lpoints[i].y = points[i].y;
4575  }
4576 
4577  rclBounds = *bounds;
4578  }
4584  {
4585  ds >> emr >> rclBounds >> cpts;
4586 
4587  if ( emr.nSize - (sizeof( ::EMRPOLYLINETO16 ) - sizeof(POINT16)) <
4588  sizeof( POINT16 ) * cpts ) {
4589  throw std::runtime_error( "Invalid record size" );
4590  }
4591 
4592  std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
4593 
4594  POINT16ARRAY points( buffer.get(), cpts );
4595 
4596  ds >> points;
4597 
4598  lpoints = buffer.release();
4599  }
4604  {
4605  if ( lpoints ) delete[] lpoints;
4606  }
4610  bool serialize ( DATASTREAM ds )
4611  {
4612  ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
4613  return true;
4614  }
4618  int size ( void ) const { return emr.nSize; }
4624  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4625  {
4626  EMF_UNUSED(source);
4627  // According to the wine windef.h header, POINT and POINTL are equivalent
4628  PolylineTo16( dc, lpoints, cpts );
4629  }
4630 #ifdef ENABLE_EDITING
4634  void edit ( void ) const
4635  {
4636  printf( "*POLYLINETO16*\n" );
4637  edit_rectl( "rclBounds", rclBounds );
4638  edit_point16array( "\t", cpts, lpoints );
4639  }
4640 #endif /* ENABLE_EDITING */
4641  };
4642 
4644 
4650  PSTR string_a{ nullptr };
4651  int string_size;
4652 
4653  INT* dx_i{ nullptr };
4654  public:
4664  EMREXTTEXTOUTA ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
4665  FLOAT yScale, const PEMRTEXT text, LPCSTR string,
4666  const INT* dx )
4667  {
4668  emr.iType = EMR_EXTTEXTOUTA;
4669  emr.nSize = sizeof( ::EMREXTTEXTOUTA );
4670 
4671  rclBounds = *bounds;
4672 
4673  iGraphicsMode = graphicsMode;
4674  exScale = xScale;
4675  eyScale = yScale;
4676 
4677  emrtext = *text;
4678 
4679  string_size = ROUND_TO_LONG( emrtext.nChars );
4680 
4681  string_a = new CHAR[ string_size ];
4682 
4683  memset( string_a, 0, sizeof(CHAR) * string_size );
4684 
4685  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4686  string_a[i] = *string++;
4687 
4688  emrtext.offString = emr.nSize;
4689  emr.nSize += string_size * sizeof(CHAR);
4690 #if 0
4691 /*
4692 Test only - Problem: Windows requires this dx to be set - at least from 2K on
4693 but to calculate real dx values is hard
4694 For pstoedit - this is "fixed" now by estimating dx in pstoedit
4695 */
4696  if ( !dx ) {
4697  int * dxn = new int [string_size];
4698  for (unsigned int i=0; i < string_size; i++) dxn[i] = 10;
4699  dx = dxn;
4700  }
4701 #endif
4702 
4703  if ( dx ) {
4704 
4705  dx_i = new INT[ emrtext.nChars ];
4706 
4707  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4708  dx_i[i] = *dx++;
4709 
4710  emrtext.offDx = emr.nSize;
4711  emr.nSize += emrtext.nChars * sizeof(INT);
4712  }
4713  else {
4714  emrtext.offDx = 0;
4715  dx_i = 0;
4716  }
4717  }
4723  {
4724  ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
4725 
4726  if ( emrtext.nChars > 0 and emrtext.offString == 0 ) {
4727  throw std::runtime_error( "Invalid text specification" );
4728  }
4729 
4730  if ( emrtext.nChars > emr.nSize - emrtext.offString ) {
4731  throw std::runtime_error( "Invalid text specification" );
4732  }
4733 
4734  std::unique_ptr<char[]> cbuffer;
4735  std::unique_ptr<INT[]> ibuffer;
4736 
4737  if ( emrtext.offString != 0 ) {
4738  string_size = ROUND_TO_LONG( emrtext.nChars );
4739 
4740  cbuffer.reset( new char[string_size] );
4741 
4742  memset( cbuffer.get(), 0, sizeof(CHAR) * string_size );
4743 
4744  CHARSTR string( cbuffer.get(), string_size );
4745 
4746  ds >> string;
4747  }
4748 
4749  if ( emrtext.offDx ) {
4750  ibuffer.reset( new INT[emrtext.nChars] );
4751 
4752  INTARRAY dx_is( ibuffer.get(), emrtext.nChars );
4753 
4754  ds >> dx_is;
4755  }
4756 
4757  string_a = cbuffer.release();
4758  dx_i = ibuffer.release();
4759  }
4765  {
4766  if ( string_a ) delete[] string_a;
4767  if ( dx_i ) delete[] dx_i;
4768  }
4772  bool serialize ( DATASTREAM ds )
4773  {
4774  ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
4775  << emrtext << CHARSTR( string_a, string_size );
4776  if ( dx_i )
4777  ds << INTARRAY( dx_i, emrtext.nChars );
4778  return true;
4779  }
4783  int size ( void ) const { return emr.nSize; }
4789  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
4790  {
4791  EMF_UNUSED(source);
4792  RECT rect;
4793  rect.left = emrtext.rcl.left;
4794  rect.top = emrtext.rcl.top;
4795  rect.right = emrtext.rcl.right;
4796  rect.bottom = emrtext.rcl.bottom;
4797 
4798  ExtTextOutA( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
4799  emrtext.fOptions, &rect, string_a, emrtext.nChars,
4800  dx_i );
4801  }
4802 #ifdef ENABLE_EDITING
4806  void edit ( void ) const
4807  {
4808 #if defined(__LP64__)
4809  const char* FMT0 = "unknown(%d)\n";
4810  const char* FMT1 = "\tptlReference\t: (%d,%d)\n";
4811  const char* FMT2 = "\tnChars\t\t: %d\n";
4812  const char* FMT3 = "\toffString\t: %d\n";
4813  const char* FMT4 = "\toffDx\t\t: %d\n";
4814 #else
4815  const char* FMT0 = "unknown(%ld)\n";
4816  const char* FMT1 = "\tptlReference\t: (%ld,%ld)\n";
4817  const char* FMT2 = "\tnChars\t\t: %ld\n";
4818  const char* FMT3 = "\toffString\t: %ld\n";
4819  const char* FMT4 = "\toffDx\t\t: %ld\n";
4820 #endif /* __x86_64__ */
4821  printf( "*EXTTEXTOUTA*\n" );
4822  edit_rectl( "rclBounds", rclBounds );
4823  printf( "\tiGraphicsMode\t: " );
4824  switch ( iGraphicsMode ) {
4825  case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
4826  case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
4827  default: printf( FMT0, iGraphicsMode );
4828  }
4829  printf( "\texScale\t\t: %f\n", exScale );
4830  printf( "\teyScale\t\t: %f\n", eyScale );
4831  printf( FMT1, emrtext.ptlReference.x, emrtext.ptlReference.y );
4832  printf( FMT2, emrtext.nChars );
4833  printf( FMT3, emrtext.offString );
4834  printf( "\tfOptions\t: " );
4835  if ( emrtext.fOptions == 0 )
4836  printf( "None" );
4837  else {
4838  if ( emrtext.fOptions & ETO_GRAYED ) {
4839  printf( "ETO_GRAYED" );
4840  if ( emrtext.fOptions & ~ETO_GRAYED )
4841  printf( " | " );
4842  }
4843  if ( emrtext.fOptions & ETO_OPAQUE ) {
4844  printf( "ETO_OPAQUE" );
4845  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
4846  printf( " | " );
4847  }
4848  if ( emrtext.fOptions & ETO_CLIPPED ) {
4849  printf( "ETO_CLIPPED" );
4850  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
4851  printf( " | " );
4852  }
4853  if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
4854  printf( "ETO_GLYPH_INDEX" );
4855  if ( emrtext.fOptions &
4856  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
4857  printf( " | " );
4858  }
4859  if ( emrtext.fOptions & ETO_RTLREADING ) {
4860  printf( "ETO_RTLREADING" );
4861  if ( emrtext.fOptions &
4862  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
4863  ETO_RTLREADING) )
4864  printf( " | " );
4865  }
4866  if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
4867  printf( "ETO_IGNORELANGUAGE" );
4868  }
4869  printf( "\n" );
4870  edit_rectl( "rcl\t", emrtext.rcl );
4871  printf( FMT4, emrtext.offDx );
4872  printf( "\tString:\n\t\t" );
4873  if ( emrtext.nChars > 0 ) {
4874  for ( DWORD i = 0; i < emrtext.nChars; ++i ) {
4875  putchar( string_a[i] );
4876  }
4877  }
4878  else {
4879  printf( "<empty>" );
4880  }
4881  putchar( '\n' );
4882  if ( emrtext.offDx != 0 ) {
4883  printf( "\tOffsets:\n\t\t" );
4884  for ( unsigned int i = 0; i < emrtext.nChars; i++ )
4885  printf( "%d ", dx_i[i] );
4886  printf( "\n" );
4887  }
4888  }
4889 #endif /* ENABLE_EDITING */
4890  };
4892 
4898  PWSTR string_a{ nullptr };
4899  int string_size;
4900 
4901  INT* dx_i{ nullptr };
4902  public:
4912  EMREXTTEXTOUTW ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
4913  FLOAT yScale, const PEMRTEXT text, LPCWSTR string,
4914  const INT* dx )
4915  {
4916  emr.iType = EMR_EXTTEXTOUTW;
4917  emr.nSize = sizeof( ::EMREXTTEXTOUTW );
4918 
4919  rclBounds = *bounds;
4920 
4921  iGraphicsMode = graphicsMode;
4922  exScale = xScale;
4923  eyScale = yScale;
4924 
4925  emrtext = *text;
4926 
4927  string_size = ROUND_TO_LONG( emrtext.nChars );
4928 
4929  string_a = new WCHAR[ string_size ];
4930 
4931  memset( string_a, 0, sizeof(WCHAR) * string_size );
4932 
4933  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4934  string_a[i] = *string++;
4935 
4936  emrtext.offString = emr.nSize;
4937  emr.nSize += string_size * sizeof(WCHAR);
4938 #if 0
4939 /*
4940 Test only - Problem: Windows requires this dx to be set - at least from 2K on
4941 but to calculate real dx values is hard
4942 For pstoedit - this is "fixed" now by estimating dx in pstoedit
4943 */
4944  if ( !dx ) {
4945  int * dxn = new int [string_size];
4946  for (unsigned int i=0; i < string_size; i++) dxn[i] = 10;
4947  dx = dxn;
4948  }
4949 #endif
4950 
4951  if ( dx ) {
4952 
4953  dx_i = new INT[ emrtext.nChars ];
4954 
4955  for ( unsigned int i=0; i<emrtext.nChars; i++ )
4956  dx_i[i] = *dx++;
4957 
4958  emrtext.offDx = emr.nSize;
4959  emr.nSize += emrtext.nChars * sizeof(INT);
4960  }
4961  else {
4962  emrtext.offDx = 0;
4963  dx_i = 0;
4964  }
4965  }
4971  {
4972  ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
4973 
4974  if ( emrtext.nChars > 0 and emrtext.offString == 0 ) {
4975  throw std::runtime_error( "Invalid text specification" );
4976  }
4977 
4978  if ( emrtext.nChars > emr.nSize - emrtext.offString ) {
4979  throw std::runtime_error( "Invalid text specification" );
4980  }
4981 
4982  std::unique_ptr<WCHAR[]> cbuffer;
4983  std::unique_ptr<INT[]> ibuffer;
4984 
4985  if ( emrtext.offString != 0 ) { // So, what is the point of this check?
4986  string_size = ROUND_TO_LONG( emrtext.nChars );
4987 
4988  cbuffer.reset( new WCHAR[string_size] );
4989 
4990  memset( cbuffer.get(), 0, sizeof(WCHAR) * string_size );
4991 
4992  WCHARSTR string( cbuffer.get(), string_size );
4993 
4994  ds >> string;
4995  }
4996 
4997  if ( emrtext.offDx ) {
4998  ibuffer.reset( new INT[ emrtext.nChars ] );
4999 
5000  INTARRAY dx_is( ibuffer.get(), emrtext.nChars );
5001 
5002  ds >> dx_is;
5003  }
5004 
5005  string_a = cbuffer.release();
5006  dx_i = ibuffer.release();
5007  }
5013  {
5014  if ( string_a ) delete[] string_a;
5015  if ( dx_i ) delete[] dx_i;
5016  }
5020  bool serialize ( DATASTREAM ds )
5021  {
5022  ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
5023  << emrtext << WCHARSTR( string_a, string_size );
5024  if ( dx_i )
5025  ds << INTARRAY( dx_i, emrtext.nChars );
5026  return true;
5027  }
5031  int size ( void ) const { return emr.nSize; }
5037  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5038  {
5039  EMF_UNUSED(source);
5040  RECT rect;
5041  rect.left = emrtext.rcl.left;
5042  rect.top = emrtext.rcl.top;
5043  rect.right = emrtext.rcl.right;
5044  rect.bottom = emrtext.rcl.bottom;
5045 
5046  ExtTextOutW( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
5047  emrtext.fOptions, &rect, string_a, emrtext.nChars,
5048  dx_i );
5049  }
5050 #ifdef ENABLE_EDITING
5054  void edit ( void ) const
5055  {
5056 #if defined(__LP64__)
5057  const char* FMT0 = "unknown(%d)\n";
5058  const char* FMT1 = "\tptlReference\t: (%d,%d)\n";
5059  const char* FMT2 = "\tnChars\t\t: %d\n";
5060  const char* FMT3 = "\toffString\t: %d\n";
5061  const char* FMT4 = "\toffDx\t\t: %d\n";
5062 #else
5063  const char* FMT0 = "unknown(%ld)\n";
5064  const char* FMT1 = "\tptlReference\t: (%ld,%ld)\n";
5065  const char* FMT2 = "\tnChars\t\t: %ld\n";
5066  const char* FMT3 = "\toffString\t: %ld\n";
5067  const char* FMT4 = "\toffDx\t\t: %ld\n";
5068 #endif /* __x86_64__ */
5069  printf( "*EXTTEXTOUTW*\n" );
5070  edit_rectl( "rclBounds", rclBounds );
5071  printf( "\tiGraphicsMode\t: " );
5072  switch ( iGraphicsMode ) {
5073  case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
5074  case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
5075  default: printf( FMT0, iGraphicsMode );
5076  }
5077  printf( "\texScale\t\t: %f\n", exScale );
5078  printf( "\teyScale\t\t: %f\n", eyScale );
5079  printf( FMT1, emrtext.ptlReference.x, emrtext.ptlReference.y );
5080  printf( FMT2, emrtext.nChars );
5081  printf( FMT3, emrtext.offString );
5082  printf( "\tfOptions\t: " );
5083  if ( emrtext.fOptions == 0 )
5084  printf( "None" );
5085  else {
5086  if ( emrtext.fOptions & ETO_GRAYED ) {
5087  printf( "ETO_GRAYED" );
5088  if ( emrtext.fOptions & ~ETO_GRAYED )
5089  printf( " | " );
5090  }
5091  if ( emrtext.fOptions & ETO_OPAQUE ) {
5092  printf( "ETO_OPAQUE" );
5093  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
5094  printf( " | " );
5095  }
5096  if ( emrtext.fOptions & ETO_CLIPPED ) {
5097  printf( "ETO_CLIPPED" );
5098  if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
5099  printf( " | " );
5100  }
5101  if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
5102  printf( "ETO_GLYPH_INDEX" );
5103  if ( emrtext.fOptions &
5104  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
5105  printf( " | " );
5106  }
5107  if ( emrtext.fOptions & ETO_RTLREADING ) {
5108  printf( "ETO_RTLREADING" );
5109  if ( emrtext.fOptions &
5110  ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
5111  ETO_RTLREADING) )
5112  printf( " | " );
5113  }
5114  if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
5115  printf( "ETO_IGNORELANGUAGE" );
5116  }
5117  printf( "\n" );
5118  edit_rectl( "rcl\t", emrtext.rcl );
5119  printf( FMT4, emrtext.offDx );
5120 
5121  if ( emrtext.nChars > 0 ) {
5122  // iconv_open arguments are TO, FROM (not the other way around).
5123  iconv_t cvt = iconv_open( "UTF-8", "UTF-16LE" );
5124  std::vector<char> utf8_buffer( emrtext.nChars );
5125  // Cannot predict the space necessary to hold the converted
5126  // string. So, we loop until conversion is complete.
5127  size_t size = emrtext.nChars;
5128  size_t in_bytes_left = emrtext.nChars * sizeof(*string_a);
5129  size_t converted = 0;
5130  char* in_buffer = (char*)string_a;
5131  while ( 1 ) {
5132  char* out_buffer = &utf8_buffer[converted];
5133  size_t out_bytes_left = size - converted;
5134 
5135  size_t n = iconv( cvt, &in_buffer, &in_bytes_left,
5136  &out_buffer, &out_bytes_left );
5137 
5138  converted = size - out_bytes_left;
5139 
5140  if ( n == (size_t)-1 ) {
5141  if ( errno == E2BIG ) {
5142  size_t new_size = 2 * utf8_buffer.size();
5143  utf8_buffer.resize( new_size );
5144  size = utf8_buffer.size();
5145  }
5146  else {
5147  // Real conversion error.
5148  break;
5149  }
5150  }
5151  else {
5152  break;
5153  }
5154  }
5155 
5156  iconv_close( cvt );
5157 
5158  if ( converted == utf8_buffer.size() )
5159  utf8_buffer.push_back( '\0' );
5160  else
5161  utf8_buffer[converted] = '\0';
5162 
5163  printf( "\tString:\n\t\t%s\n", utf8_buffer.data() );
5164  }
5165  else {
5166  puts( "\tString:\n\t\t<empty>\n" );
5167  }
5168 
5169  if ( emrtext.offDx != 0 and emrtext.nChars > 0 ) {
5170  printf( "\tOffsets:\n\t\t" );
5171  for ( unsigned int i = 0; i < emrtext.nChars; i++ )
5172  printf( "%d ", dx_i[i] );
5173  printf( "\n" );
5174  }
5175  }
5176 #endif /* ENABLE_EDITING */
5177  };
5178 
5180 
5184  public:
5190  EMRSETPIXELV ( INT x, INT y, COLORREF color )
5191  {
5192  emr.iType = EMR_SETPIXELV;
5193  emr.nSize = sizeof( ::EMRSETPIXELV );
5194  ptlPixel.x = x;
5195  ptlPixel.y = y;
5196  crColor = color;
5197  }
5203  {
5204  ds >> emr >> ptlPixel >> crColor;
5205  }
5209  bool serialize ( DATASTREAM ds )
5210  {
5211  ds << emr << ptlPixel << crColor;
5212  return true;
5213  }
5217  int size ( void ) const { return emr.nSize; }
5223  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5224  {
5225  EMF_UNUSED(source);
5226  SetPixel( dc, ptlPixel.x, ptlPixel.y, crColor );
5227  }
5228 #ifdef ENABLE_EDITING
5232  void edit ( void ) const
5233  {
5234  printf( "*SETPIXELV*\n" );
5235  edit_pointl( "ptlPixel", ptlPixel );
5236  edit_color( "crColor\t", crColor );
5237  }
5238 #endif /* ENABLE_EDITING */
5239  };
5240 
5241  class PEN;
5242  class EXTPEN;
5243  class BRUSH;
5244  class FONT;
5245  class PALETTE;
5246 
5248 
5251  class EMRCREATEPEN : public METARECORD, public ::EMRCREATEPEN
5252  {
5253  public:
5258  EMRCREATEPEN ( PEN* pen, HGDIOBJ handle );
5263  EMRCREATEPEN ( DATASTREAM& ds );
5267  bool serialize ( DATASTREAM ds )
5268  {
5269  ds << emr << ihPen << lopn;
5270  return true;
5271  }
5275  int size ( void ) const { return emr.nSize; }
5281  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5282 #ifdef ENABLE_EDITING
5286  void edit ( void ) const
5287  {
5288 #if defined(__LP64__)
5289  const char* FMT0 = "\tihPen\t\t: 0x%x\n";
5290  const char* FMT1 = "\tlopn.lopnWidth\t: %d, %d\n";
5291 #else
5292  const char* FMT0 = "\tihPen\t\t: 0x%lx\n";
5293  const char* FMT1 = "\tlopn.lopnWidth\t: %ld, %ld\n";
5294 #endif /* __x86_64__ */
5295  printf( "*CREATEPEN*\n" );
5296  printf( FMT0, ihPen );
5297  edit_pen_style( "lopn.lopnStyle", lopn.lopnStyle );
5298  printf( FMT1, lopn.lopnWidth.x, lopn.lopnWidth.y );
5299  edit_color( "lopn.lopnColor", lopn.lopnColor );
5300  }
5301 #endif /* ENABLE_EDITING */
5302  };
5303 
5305 
5310  {
5311  public:
5316  EMREXTCREATEPEN ( EXTPEN* pen, HGDIOBJ handle );
5321  EMREXTCREATEPEN ( DATASTREAM& ds );
5325  bool serialize ( DATASTREAM ds )
5326  {
5327  ds << emr << ihPen << offBmi << cbBmi << offBits << cbBits << elp;
5328  return true;
5329  }
5333  int size ( void ) const { return emr.nSize; }
5339  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5340 #ifdef ENABLE_EDITING
5344  void edit ( void ) const
5345  {
5346 #if defined(__LP64__)
5347  const char* FMT0 = "\tihPen\t\t\t: 0x%x\n";
5348  const char* FMT1 = "\toffBmi\t\t\t: %d\n";
5349  const char* FMT2 = "\tcbBmi\t\t\t: %d\n";
5350  const char* FMT3 = "\toffBits\t\t\t: %d\n";
5351  const char* FMT4 = "\tcbBits\t\t\t: %d\n";
5352  const char* FMT5 = "\telp.elpWidth\t\t: %d\n";
5353  const char* FMT6 = "\telp.elpNumEntries\t: %d\n";
5354 #else
5355  const char* FMT0 = "\tihPen\t\t\t: 0x%lx\n";
5356  const char* FMT1 = "\toffBmi\t\t\t: %ld\n";
5357  const char* FMT2 = "\tcbBmi\t\t\t: %ld\n";
5358  const char* FMT3 = "\toffBits\t\t\t: %ld\n";
5359  const char* FMT4 = "\tcbBits\t\t\t: %ld\n";
5360  const char* FMT5 = "\telp.elpWidth\t\t: %ld\n";
5361  const char* FMT6 = "\telp.elpNumEntries\t: %ld\n";
5362 #endif /* __x86_64__ */
5363  printf( "*EXTCREATEPEN*\n" );
5364  printf( FMT0, ihPen );
5365  printf( FMT1, offBmi );
5366  printf( FMT2, cbBmi );
5367  printf( FMT3, offBits );
5368  printf( FMT4, cbBits );
5369  edit_pen_style( "elp.elpPenStyle\t", elp.elpPenStyle );
5370  printf( FMT5, elp.elpWidth );
5371  edit_brush_style( "elp.elpBrushStyle", elp.elpBrushStyle );
5372  edit_color( "elp.elpColor\t", elp.elpColor );
5373  edit_brush_hatch( "elp.elpHatch\t", elp.elpHatch );
5374  printf( FMT6, elp.elpNumEntries );
5375  }
5376 #endif /* ENABLE_EDITING */
5377  };
5378 
5380 
5384  {
5385  public:
5390  EMRCREATEBRUSHINDIRECT ( BRUSH* brush, HGDIOBJ handle );
5399  bool serialize ( DATASTREAM ds )
5400  {
5401  ds << emr << ihBrush << lb;
5402  return true;
5403  }
5407  int size ( void ) const { return emr.nSize; }
5413  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5414 #ifdef ENABLE_EDITING
5418  void edit ( void ) const
5419  {
5420 #if defined(__LP64__)
5421  const char* FMT = "\tihBrush\t\t: 0x%x\n";
5422 #else
5423  const char* FMT = "\tihBrush\t\t: 0x%lx\n";
5424 #endif /* __x86_64__ */
5425  printf( "*CREATEBRUSHINDIRECT*\n" );
5426  printf( FMT, ihBrush );
5427  edit_brush_style( "lb.lbStyle", lb.lbStyle );
5428  edit_color( "lb.lbColor", lb.lbColor );
5429  edit_brush_hatch( "lb.lbHatch", lb.lbHatch );
5430  }
5431 #endif /* ENABLE_EDITING */
5432  };
5433 
5435 
5439  {
5440  public:
5445  EMREXTCREATEFONTINDIRECTW ( FONT* font, HGDIOBJ handle );
5454  bool serialize ( DATASTREAM ds )
5455  {
5456  // Since EMF records have to be multiples of 4 bytes, this
5457  // should perhaps be a general thing, but we know it's currently
5458  // only a problem for this structure.
5459 
5460  ds << emr << ihFont << elfw << PADDING( 2 );
5461 
5462  return true;
5463  }
5467  int size ( void ) const { return emr.nSize; }
5473  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5474 #ifdef ENABLE_EDITING
5478  void edit ( void ) const
5479  {
5480 #if defined(__LP64__)
5481  const char* FMT0 = "\tihFont\t\t\t: %d\n";
5482  const char* FMT1 = "\tlfHeight\t\t: %d\n";
5483  const char* FMT2 = "\tlfWidth\t\t\t: %d\n";
5484  const char* FMT3 = "\tlfEscapement\t\t: %d\n";
5485  const char* FMT4 = "\tlfOrientation\t\t: %d\n";
5486  const char* FMT5 = "\telfVersion\t\t: %d\n";
5487  const char* FMT6 = "\telfStyleSize\t\t: %d\n";
5488  const char* FMT7 = "\telfMatch\t\t: %d\n";
5489  const char* FMT8 = "\telfCulture\t\t: %d\n";
5490 #else
5491  const char* FMT0 = "\tihFont\t\t\t: %ld\n";
5492  const char* FMT1 = "\tlfHeight\t\t: %ld\n";
5493  const char* FMT2 = "\tlfWidth\t\t\t: %ld\n";
5494  const char* FMT3 = "\tlfEscapement\t\t: %ld\n";
5495  const char* FMT4 = "\tlfOrientation\t\t: %ld\n";
5496  const char* FMT5 = "\telfVersion\t\t: %ld\n";
5497  const char* FMT6 = "\telfStyleSize\t\t: %ld\n";
5498  const char* FMT7 = "\telfMatch\t\t: %ld\n";
5499  const char* FMT8 = "\telfCulture\t\t: %ld\n";
5500 #endif /* __x86_64__ */
5501  printf( "*EXTCREATEFONTINDIRECTW*\n" );
5502  printf( FMT0, ihFont );
5503  printf( FMT1, elfw.elfLogFont.lfHeight );
5504  printf( FMT2, elfw.elfLogFont.lfWidth );
5505  printf( FMT3, elfw.elfLogFont.lfEscapement );
5506  printf( FMT4, elfw.elfLogFont.lfOrientation );
5507  printf( "\tlfWeight\t\t: " );
5508  switch ( elfw.elfLogFont.lfWeight ) {
5509  case FW_DONTCARE: printf( "FW_DONTCARE\n" ); break;
5510  case FW_THIN: printf( "FW_THIN\n" ); break;
5511  case FW_EXTRALIGHT: printf( "FW_EXTRALIGHT\n" ); break;
5512  case FW_LIGHT: printf( "FW_LIGHT\n" ); break;
5513  case FW_NORMAL: printf( "FW_NORMAL\n" ); break;
5514  case FW_MEDIUM: printf( "FW_MEDIUM\n" ); break;
5515  case FW_SEMIBOLD: printf( "FW_SEMIBOLD\n" ); break;
5516  case FW_BOLD: printf( "FW_BOLD\n" ); break;
5517  case FW_EXTRABOLD: printf( "FW_EXTRABOLD\n" ); break;
5518  case FW_BLACK: printf( "FW_BLACK\n" ); break;
5519  }
5520  printf( "\tlfItalic\t\t: %d\n", elfw.elfLogFont.lfItalic );
5521  printf( "\tlfUnderline\t\t: %d\n", elfw.elfLogFont.lfUnderline );
5522  printf( "\tlfStrikeOut\t\t: %d\n", elfw.elfLogFont.lfStrikeOut );
5523  printf( "\tlfCharSet\t\t: %d\n", elfw.elfLogFont.lfCharSet );
5524  printf( "\tlfOutPrecision\t\t: %d\n", elfw.elfLogFont.lfOutPrecision );
5525  printf( "\tlfClipPrecision\t\t: %d\n", elfw.elfLogFont.lfClipPrecision );
5526  printf( "\tlfQuality\t\t: %d\n", elfw.elfLogFont.lfQuality );
5527  printf( "\tlfPitchAndFamily\t: %d\n", elfw.elfLogFont.lfPitchAndFamily );
5528  int i = 0;
5529  printf( "\tlfFaceName\t\t: '" );
5530  while ( elfw.elfLogFont.lfFaceName[i] != 0 && i < LF_FACESIZE ) {
5531  putchar( elfw.elfLogFont.lfFaceName[i] );
5532  i++;
5533  }
5534  puts( "'" );
5535 
5536  i = 0;
5537  printf( "\telfFullName\t\t: '" );
5538  while ( elfw.elfFullName[i] != 0 && i < LF_FULLFACESIZE ) {
5539  putchar( elfw.elfFullName[i] );
5540  i++;
5541  }
5542  puts( "'" );
5543 
5544  i = 0;
5545  printf( "\telfStyle\t\t: '" );
5546  while ( elfw.elfStyle[i] != 0 && i < LF_FACESIZE ) {
5547  putchar( elfw.elfStyle[i] );
5548  i++;
5549  }
5550  puts( "'" );
5551 
5552  printf( FMT5, elfw.elfVersion );
5553  printf( FMT6, elfw.elfStyleSize );
5554  printf( FMT7, elfw.elfMatch );
5555  printf( "\telfVendorId\t\t: '%s'\n", elfw.elfVendorId );
5556  printf( FMT8, elfw.elfCulture );
5557  printf( "\telfPanose\t\t:\n" );
5558  printf( "\t\tbFamilyType\t\t: %d\n", elfw.elfPanose.bFamilyType );
5559  printf( "\t\tbSerifStyle\t\t: %d\n", elfw.elfPanose.bSerifStyle );
5560  printf( "\t\tbWeight\t\t\t: %d\n", elfw.elfPanose.bWeight );
5561  printf( "\t\tbProportion\t\t: %d\n", elfw.elfPanose.bProportion );
5562  printf( "\t\tbContrast\t\t: %d\n", elfw.elfPanose.bContrast );
5563  printf( "\t\tbStrokeVariation\t: %d\n", elfw.elfPanose.bStrokeVariation );
5564  printf( "\t\tbArmStyle\t\t: %d\n", elfw.elfPanose.bArmStyle );
5565  printf( "\t\tbLetterform\t\t: %d\n", elfw.elfPanose.bLetterform );
5566  printf( "\t\tbMidline\t\t: %d\n", elfw.elfPanose.bMidline );
5567  printf( "\t\tbXHeight\t\t: %d\n", elfw.elfPanose.bXHeight );
5568  }
5569 #endif /* ENABLE_EDITING */
5570  };
5571 
5573 
5577  {
5578  public:
5583  EMRCREATEPALETTE ( PALETTE* palette, HGDIOBJ handle );
5592  bool serialize ( DATASTREAM ds )
5593  {
5594  ds << emr << ihPal << lgpl;
5595  return true;
5596  }
5600  int size ( void ) const { return emr.nSize; }
5606  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
5607 #ifdef ENABLE_EDITING
5611  void edit ( void ) const
5612  {
5613  printf( "*CREATEPALETTE* (not really handled by libEMF)\n" );
5614  }
5615 #endif /* ENABLE_EDITING */
5616  };
5617 
5619 
5623  public:
5627  EMRFILLPATH ( const RECTL* bounds )
5628  {
5629  emr.iType = EMR_FILLPATH;
5630  emr.nSize = sizeof( ::EMRFILLPATH );
5631  rclBounds = *bounds;
5632  }
5638  {
5639  ds >> emr >> rclBounds;
5640  }
5644  bool serialize ( DATASTREAM ds )
5645  {
5646  ds << emr << rclBounds;
5647  return true;
5648  }
5652  int size ( void ) const { return emr.nSize; }
5658  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5659  {
5660  EMF_UNUSED(source);
5661  FillPath( dc );
5662  }
5663 #ifdef ENABLE_EDITING
5667  void edit ( void ) const
5668  {
5669  printf( "*FILLPATH*\n" );
5670  edit_rectl( "rclBounds", rclBounds );
5671  }
5672 #endif /* ENABLE_EDITING */
5673  };
5675 
5679  public:
5683  EMRSTROKEPATH ( const RECTL* bounds )
5684  {
5685  emr.iType = EMR_STROKEPATH;
5686  emr.nSize = sizeof( ::EMRSTROKEPATH );
5687  rclBounds = *bounds;
5688  }
5694  {
5695  ds >> emr >> rclBounds;
5696  }
5700  bool serialize ( DATASTREAM ds )
5701  {
5702  ds << emr << rclBounds;
5703  return true;
5704  }
5708  int size ( void ) const { return emr.nSize; }
5714  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5715  {
5716  EMF_UNUSED(source);
5717  StrokePath( dc );
5718  }
5719 #ifdef ENABLE_EDITING
5723  void edit ( void ) const
5724  {
5725  printf( "*STROKEPATH*\n" );
5726  edit_rectl( "rclBounds", rclBounds );
5727  }
5728 #endif /* ENABLE_EDITING */
5729  };
5731 
5735  public:
5739  EMRSTROKEANDFILLPATH ( const RECTL* bounds )
5740  {
5741  emr.iType = EMR_STROKEANDFILLPATH;
5742  emr.nSize = sizeof( ::EMRSTROKEANDFILLPATH );
5743  rclBounds = *bounds;
5744  }
5750  {
5751  ds >> emr >> rclBounds;
5752  }
5756  bool serialize ( DATASTREAM ds )
5757  {
5758  ds << emr << rclBounds;
5759  return true;
5760  }
5764  int size ( void ) const { return emr.nSize; }
5770  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5771  {
5772  EMF_UNUSED(source);
5773  StrokeAndFillPath( dc );
5774  }
5775 #ifdef ENABLE_EDITING
5779  void edit ( void ) const
5780  {
5781  printf( "*STROKEANDFILLPATH*\n" );
5782  edit_rectl( "rclBounds", rclBounds );
5783  }
5784 #endif /* ENABLE_EDITING */
5785  };
5787 
5791  public:
5795  EMRBEGINPATH ( void )
5796  {
5797  emr.iType = EMR_BEGINPATH;
5798  emr.nSize = sizeof( ::EMRBEGINPATH );
5799  }
5805  {
5806  ds >> emr;
5807  }
5811  bool serialize ( DATASTREAM ds )
5812  {
5813  ds << emr;
5814  return true;
5815  }
5819  int size ( void ) const { return emr.nSize; }
5825  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5826  {
5827  EMF_UNUSED(source);
5828  BeginPath( dc );
5829  }
5830 #ifdef ENABLE_EDITING
5834  void edit ( void ) const
5835  {
5836  printf( "*BEGINPATH*\n" );
5837  }
5838 #endif /* ENABLE_EDITING */
5839  };
5841 
5845  public:
5849  EMRENDPATH ( void )
5850  {
5851  emr.iType = EMR_ENDPATH;
5852  emr.nSize = sizeof( ::EMRENDPATH );
5853  }
5859  {
5860  ds >> emr;
5861  }
5865  bool serialize ( DATASTREAM ds )
5866  {
5867  ds << emr;
5868  return true;
5869  }
5873  int size ( void ) const { return emr.nSize; }
5879  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5880  {
5881  EMF_UNUSED(source);
5882  EndPath( dc );
5883  }
5884 #ifdef ENABLE_EDITING
5888  void edit ( void ) const
5889  {
5890  printf( "*ENDPATH*\n" );
5891  }
5892 #endif /* ENABLE_EDITING */
5893  };
5895 
5899  public:
5904  {
5905  emr.iType = EMR_CLOSEFIGURE;
5906  emr.nSize = sizeof( ::EMRCLOSEFIGURE );
5907  }
5913  {
5914  ds >> emr;
5915  }
5919  bool serialize ( DATASTREAM ds )
5920  {
5921  ds << emr;
5922  return true;
5923  }
5927  int size ( void ) const { return emr.nSize; }
5933  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5934  {
5935  EMF_UNUSED(source);
5936  CloseFigure( dc );
5937  }
5938 #ifdef ENABLE_EDITING
5942  void edit ( void ) const
5943  {
5944  printf( "*CLOSEFIGURE*\n" );
5945  }
5946 #endif /* ENABLE_EDITING */
5947  };
5949 
5954  public:
5958  EMRSAVEDC ( void )
5959  {
5960  emr.iType = EMR_SAVEDC;
5961  emr.nSize = sizeof( ::EMRSAVEDC );
5962  }
5968  {
5969  ds >> emr;
5970  }
5974  bool serialize ( DATASTREAM ds )
5975  {
5976  ds << emr;
5977  return true;
5978  }
5982  int size ( void ) const { return emr.nSize; }
5988  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
5989  {
5990  EMF_UNUSED(source);
5991  SaveDC( dc );
5992  }
5993 #ifdef ENABLE_EDITING
5997  void edit ( void ) const
5998  {
5999  printf( "*SAVEDC*\n" );
6000  }
6001 #endif /* ENABLE_EDITING */
6002  };
6004 
6008  public:
6012  EMRRESTOREDC ( INT n )
6013  {
6014  emr.iType = EMR_RESTOREDC;
6015  emr.nSize = sizeof( ::EMRRESTOREDC );
6016  iRelative = n;
6017  }
6023  {
6024  ds >> emr >> iRelative;
6025  }
6029  bool serialize ( DATASTREAM ds )
6030  {
6031  ds << emr << iRelative;
6032  return true;
6033  }
6037  int size ( void ) const { return emr.nSize; }
6043  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
6044  {
6045  EMF_UNUSED(source);
6046  RestoreDC( dc, iRelative );
6047  }
6048 #ifdef ENABLE_EDITING
6052  void edit ( void ) const
6053  {
6054 #if defined(__LP64__)
6055  const char* FMT = "\tiRelative: %d\n";
6056 #else
6057  const char* FMT = "\tiRelative: %ld\n";
6058 #endif /* __x86_64__ */
6059  printf( "*RESTOREDC*\n" );
6060  printf( FMT, iRelative );
6061  }
6062 #endif /* ENABLE_EDITING */
6063  };
6065 
6069  public:
6073  EMRSETMETARGN ( void )
6074  {
6075  emr.iType = EMR_SETMETARGN;
6076  emr.nSize = sizeof( ::EMRSETMETARGN );
6077  }
6083  {
6084  ds >> emr;
6085  }
6089  bool serialize ( DATASTREAM ds )
6090  {
6091  ds << emr;
6092  return true;
6093  }
6097  int size ( void ) const { return emr.nSize; }
6103  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
6104  {
6105  EMF_UNUSED(source);
6106  SetMetaRgn( dc );
6107  }
6108 #ifdef ENABLE_EDITING
6112  void edit ( void ) const
6113  {
6114  printf( "*SETMETARGN*\n" );
6115  }
6116 #endif /* ENABLE_EDITING */
6117  };
6118 
6120 
6123  class PEN : public GRAPHICSOBJECT, public LOGPEN {
6124  public:
6128  PEN ( const LOGPEN* lpen )
6129  {
6130  lopnStyle = lpen->lopnStyle;
6131  lopnWidth = lpen->lopnWidth;
6132  lopnColor = lpen->lopnColor;
6133  }
6137  OBJECTTYPE getType ( void ) const { return O_PEN; }
6144  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6145  {
6146  contexts[dc] = emf_handle;
6147  return new EMRCREATEPEN( this, emf_handle );
6148  }
6149  };
6150 
6152 
6155  class EXTPEN : public GRAPHICSOBJECT, public EXTLOGPEN {
6156  public:
6160  EXTPEN ( const EXTLOGPEN* lpen )
6161  {
6162  elpPenStyle = lpen->elpPenStyle;
6163  elpWidth = lpen->elpWidth;
6164  elpBrushStyle = lpen->elpBrushStyle;
6165  elpColor = lpen->elpColor;
6166  elpHatch = lpen->elpHatch;
6167  elpNumEntries = 0;
6168  elpStyleEntry[0] = 0;
6169  }
6173  OBJECTTYPE getType ( void ) const { return O_EXTPEN; }
6180  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6181  {
6182  contexts[dc] = emf_handle;
6183  return new EMREXTCREATEPEN( this, emf_handle );
6184  }
6185  };
6186 
6188 
6191  class BRUSH : public GRAPHICSOBJECT, public LOGBRUSH {
6192  public:
6196  BRUSH ( const LOGBRUSH* lbrush )
6197  {
6198  lbStyle = lbrush->lbStyle;
6199  lbColor = lbrush->lbColor;
6200  lbHatch = lbrush->lbHatch;
6201  }
6205  OBJECTTYPE getType ( void ) const { return O_BRUSH; }
6212  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6213  {
6214  contexts[dc] = emf_handle;
6215  return new EMRCREATEBRUSHINDIRECT( this, emf_handle );
6216  }
6217  };
6218 
6220 
6223  class FONT : public GRAPHICSOBJECT, public EXTLOGFONTW {
6224  public:
6228  FONT ( const LOGFONTW* lfont )
6229  {
6230  this->elfLogFont = *lfont;
6231  // There are a lot more entries in the EXTLOGFONTW structure than
6232  // the API has values for, so we invent them here
6233  memset( &elfFullName, 0, sizeof elfFullName );
6234  memset( &elfStyle, 0, sizeof elfStyle );
6235  elfVersion = ELF_VERSION;
6236  elfStyleSize = 0;
6237  elfMatch = 0;
6238  elfReserved = 0;
6239  memset( &elfVendorId, 0, sizeof elfVendorId );
6240  elfCulture = ELF_CULTURE_LATIN;
6241  memset( &elfPanose, 1, sizeof(PANOSE) );
6242  }
6246  OBJECTTYPE getType ( void ) const { return O_FONT; }
6253  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6254  {
6255  contexts[dc] = emf_handle;
6256  return new EMREXTCREATEFONTINDIRECTW( this, emf_handle );
6257  }
6258  };
6259 
6261 
6264  class PALETTE : public GRAPHICSOBJECT, public LOGPALETTE {
6265  public:
6269  PALETTE ( const LOGPALETTE* lpalette )
6270  {
6271  EMF_UNUSED(lpalette);
6272  palVersion = 0;
6273  palNumEntries = 0;
6274  PALETTEENTRY zero_entry = { 0, 0, 0, 0 };
6275  palPalEntry[0] = zero_entry;
6276  }
6280  OBJECTTYPE getType ( void ) const { return O_PALETTE; }
6287  METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
6288  {
6289  contexts[dc] = emf_handle;
6290  return new EMRCREATEPALETTE( this, emf_handle );
6291  }
6292  };
6293 
6295 
6299  public:
6303  EMRSETMITERLIMIT ( FLOAT limit )
6304  {
6305  emr.iType = EMR_SETMITERLIMIT;
6306  emr.nSize = sizeof( ::EMRSETMITERLIMIT );
6307  eMiterLimit = limit;
6308  }
6314  {
6315  int miter_limit;
6316  ds >> emr >> miter_limit;
6317  eMiterLimit = float(miter_limit);
6318  }
6322  bool serialize ( DATASTREAM ds )
6323  {
6324  ds << emr << (int)eMiterLimit;
6325  return true;
6326  }
6330  int size ( void ) const { return emr.nSize; }
6336  void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
6337  {
6338  EMF_UNUSED(source);
6339  SetMiterLimit( dc, eMiterLimit, 0 );
6340  }
6341 #ifdef ENABLE_EDITING
6345  void edit ( void ) const
6346  {
6347  printf( "*SETMITERLIMIT*\n" );
6348  printf( "\teMiterLimit\t: %f\n", eMiterLimit );
6349  }
6350 #endif /* ENABLE_EDITING */
6351  };
6352 
6354 
6368  void init ( const RECT* size, LPCWSTR description_w ) {
6369 
6370  // Evidently, metafile handles are numbered from 1, so don't
6371  // ever use 0.
6372 
6373  handles.push_back( true );
6374 
6375  // Keep some of our graphics state in a header record
6376 
6377  header = new ENHMETAHEADER ( description_w );
6378  records.push_back( header );
6379 
6380  // Compute the size and position of the metafile on the "page"
6381 
6382  if ( size ) {
6383  update_frame = false;
6384 
6385  header->rclFrame.left = size->left;
6386  header->rclFrame.top = size->top;
6387  header->rclFrame.right = size->right;
6388  header->rclFrame.bottom = size->bottom;
6389 
6390  header->rclBounds.left =
6391  size->left * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
6392  header->rclBounds.top =
6393  size->top * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
6394  header->rclBounds.right =
6395  size->right * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
6396  header->rclBounds.bottom =
6397  size->bottom * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
6398  }
6399  else {
6400  update_frame = true;
6401 
6402  header->rclBounds.left = -10;
6403  header->rclBounds.top = -10;
6404  header->rclBounds.right = 10;
6405  header->rclBounds.bottom = 10;
6406 
6407  header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
6408  header->szlMillimeters.cx * 100 / header->szlDevice.cx );
6409  header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
6410  header->szlMillimeters.cy * 100 / header->szlDevice.cy );
6411  header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
6412  header->szlMillimeters.cx * 100 / header->szlDevice.cx );
6413  header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
6414  header->szlMillimeters.cy * 100 / header->szlDevice.cy );
6415  }
6416 
6417  // Some default graphics state (are they really, though?)
6418 
6419  SIZEL default_resolution = { RESOLUTION, RESOLUTION };
6420  resolution = default_resolution;
6421  SIZEL default_viewport_ext = { 1, 1 };
6422  viewport_ext = default_viewport_ext;
6423  POINT default_viewport_org = { 0, 0 };
6424  viewport_org = default_viewport_org;
6425  SIZEL default_window_ext = { 1, 1 };
6426  window_ext = default_window_ext;
6427  POINT default_window_org = { 0, 0 };
6428  window_org = default_window_org;
6429 
6432 
6433  pen = (PEN*)globalObjects.find( BLACK_PEN | ENHMETA_STOCK_OBJECT );
6434  brush = (BRUSH*)globalObjects.find( BLACK_BRUSH | ENHMETA_STOCK_OBJECT );
6435  font = (FONT*)globalObjects.find( DEVICE_DEFAULT_FONT | ENHMETA_STOCK_OBJECT);
6436  palette = (PALETTE*)globalObjects.find( DEFAULT_PALETTE|ENHMETA_STOCK_OBJECT);
6437 
6438  text_alignment = TA_BASELINE;
6439  text_color = RGB(0,0,0);
6440  bk_color = RGB(0xff,0xff,0xff);
6441  bk_mode = OPAQUE;
6442  polyfill_mode = ALTERNATE;
6443  map_mode = MM_TEXT;
6444  miter_limit = 10.f;
6445 
6446  handle = globalObjects.add( this );
6447  }
6448 
6449  public:
6453  ::FILE* fp;
6466  std::vector< EMF::METARECORD* > records;
6467 
6468  // Keep a small set of graphics state information
6469  SIZEL resolution;
6472  SIZEL window_ext;
6473  POINT window_org;
6477  POINT point;
6483  COLORREF text_color;
6484  COLORREF bk_color;
6485  INT bk_mode;
6487  INT map_mode;
6488  FLOAT miter_limit;
6489 
6495  std::vector< bool > handles;
6496 
6502  std::map< HGDIOBJ, HGDIOBJ > emf_handles;
6503 
6514  METAFILEDEVICECONTEXT ( FILE* fp_, const RECT* size,
6515  LPCWSTR description_w )
6516  : fp(fp_), ds( fp_ )
6517  {
6518  init( size, description_w );
6519  }
6525  {
6526  // Purge all the metarecords (if there are any) {this include the
6527  // header record, too}
6528  if ( records.size() > 0 )
6529  deleteMetafile();
6530  }
6534  OBJECTTYPE getType ( void ) const { return O_METAFILEDEVICECONTEXT; }
6539  DWORD nextHandle ( void )
6540  {
6541  for ( unsigned int i = 1; i < handles.size(); i++ ) {
6542  if ( !handles[i] ) {
6543  handles[i] = true;
6544  return i;
6545  }
6546  }
6547  handles.push_back( true );
6548  // Well, it appears that even StockObject handles count for something.
6549  // Not sure what the right value here is, then.
6550  header->nHandles = handles.size();
6551  return handles.size()-1;
6552  }
6556  void clearHandle ( DWORD handle )
6557  {
6558  if ( handle < handles.size() ) {
6559  handles[handle] = false;
6560  }
6561  }
6567  void appendRecord ( METARECORD* record )
6568  {
6569  records.push_back( record );
6570 
6571  header->nBytes += record->size();
6572  header->nRecords++;
6573  }
6579  void appendHandle ( METARECORD* record )
6580  {
6581  records.push_back( record );
6582 
6583  header->nBytes += record->size();
6584  header->nRecords++;
6585  }
6590  void deleteMetafile ( void )
6591  {
6592  for ( auto r = records.begin(); r != records.end(); r++ ) {
6593  delete *r;
6594  }
6595  records.clear();
6596  }
6601  void mergePoint ( const LONG& x, const LONG& y )
6602  {
6603  POINT p;
6604  p.x = x;
6605  p.y = y;
6606  mergePoint( p );
6607  }
6612  void mergePoint( const POINT& p )
6613  {
6614  POINT device_point;
6615 
6616  // *** Note, it's possible for the global transformation matrix to
6617  // affect this too. ***
6618 
6619  int window_width = window_ext.cx <= 0 ? 1 : window_ext.cx;
6620  int window_height = window_ext.cy <= 0 ? 1 : window_ext.cy;
6621 
6622  device_point.x = (LONG)( (float)( p.x - window_org.x ) / window_width *
6623  viewport_ext.cx + viewport_org.x );
6624 
6625  device_point.y = (LONG)( (float)( p.y - window_org.y ) / window_height *
6626  viewport_ext.cy + viewport_org.y );
6627 
6628  // If the user didn't specify a bounding rectangle in the constructor,
6629  // compute one from this data, too.
6630  if ( device_point.x < min_device_point.x ) {
6631  min_device_point.x = device_point.x;
6632  if ( update_frame ) {
6633  header->rclBounds.left = min_device_point.x - 10;
6634  int device_width = header->szlDevice.cx <= 0 ? 1 : header->szlDevice.cx;
6635  header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
6636  header->szlMillimeters.cx * 100 / device_width );
6637  }
6638  }
6639  else if ( device_point.x > max_device_point.x ) {
6640  max_device_point.x = device_point.x;
6641  if ( update_frame ) {
6642  header->rclBounds.right = max_device_point.x + 10;
6643  int device_width = header->szlDevice.cx <= 0 ? 1 : header->szlDevice.cx;
6644  header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
6645  header->szlMillimeters.cx * 100 / device_width );
6646  }
6647  }
6648 
6649  if ( device_point.y < min_device_point.y ) {
6650  min_device_point.y = device_point.y;
6651  if ( update_frame ) {
6652  header->rclBounds.top = min_device_point.y - 10;
6653  int device_height = header->szlDevice.cy <= 0 ? 1 : header->szlDevice.cy;
6654  header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
6655  header->szlMillimeters.cy * 100 / device_height );
6656  }
6657  }
6658  else if ( device_point.y > max_device_point.y ) {
6659  max_device_point.y = device_point.y;
6660  if ( update_frame ) {
6661  header->rclBounds.bottom = max_device_point.y + 10;
6662  int device_height = header->szlDevice.cy <= 0 ? 1 : header->szlDevice.cy;
6663  header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
6664  header->szlMillimeters.cy * 100 / device_height );
6665  }
6666  }
6667  }
6668  };
6669 
6670 } // close EMF namespace
6671 
6672 #undef EMF_UNUSED
6673 #endif /* _LIBEMF_H */
Graphics Brush.
Definition: libemf.h:6191
OBJECTTYPE getType(void) const
Definition: libemf.h:6205
BRUSH(const LOGBRUSH *lbrush)
Definition: libemf.h:6196
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6212
Support different endian modes when reading and writing the metafile.
Definition: libemf.h:225
DATASTREAM & operator>>(BYTE &byte)
Definition: libemf.h:253
void setStream(::FILE *fp)
Definition: libemf.h:239
DATASTREAM & operator<<(const BYTE &byte)
Definition: libemf.h:244
DATASTREAM(::FILE *fp=0)
Definition: libemf.h:234
EMF Arc To.
Definition: libemf.h:2996
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3048
bool serialize(DATASTREAM ds)
Definition: libemf.h:3034
EMRARCTO(INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: libemf.h:3009
EMRARCTO(DATASTREAM &ds)
Definition: libemf.h:3027
int size(void) const
Definition: libemf.h:3042
EMF Arc.
Definition: libemf.h:2920
EMRARC(INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition: libemf.h:2933
bool serialize(DATASTREAM ds)
Definition: libemf.h:2958
EMRARC(DATASTREAM &ds)
Definition: libemf.h:2951
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2972
int size(void) const
Definition: libemf.h:2966
EMF Begin Path.
Definition: libemf.h:5790
EMRBEGINPATH(DATASTREAM &ds)
Definition: libemf.h:5804
EMRBEGINPATH(void)
Definition: libemf.h:5795
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5825
int size(void) const
Definition: libemf.h:5819
bool serialize(DATASTREAM ds)
Definition: libemf.h:5811
EMF Close Figure.
Definition: libemf.h:5898
int size(void) const
Definition: libemf.h:5927
EMRCLOSEFIGURE(DATASTREAM &ds)
Definition: libemf.h:5912
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5933
EMRCLOSEFIGURE(void)
Definition: libemf.h:5903
bool serialize(DATASTREAM ds)
Definition: libemf.h:5919
EMF Brush.
Definition: libemf.h:5384
int size(void) const
Definition: libemf.h:5407
bool serialize(DATASTREAM ds)
Definition: libemf.h:5399
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:633
EMRCREATEBRUSHINDIRECT(BRUSH *brush, HGDIOBJ handle)
Definition: libemf.cpp:625
EMF Palette.
Definition: libemf.h:5577
EMRCREATEPALETTE(PALETTE *palette, HGDIOBJ handle)
Definition: libemf.cpp:680
int size(void) const
Definition: libemf.h:5600
bool serialize(DATASTREAM ds)
Definition: libemf.h:5592
EMRCREATEPALETTE(DATASTREAM &ds)
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:688
EMF Pen.
Definition: libemf.h:5252
EMRCREATEPEN(PEN *pen, HGDIOBJ handle)
Definition: libemf.cpp:532
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:575
bool serialize(DATASTREAM ds)
Definition: libemf.h:5267
int size(void) const
Definition: libemf.h:5275
EMF Delete Object.
Definition: libemf.h:2744
bool serialize(DATASTREAM ds)
Definition: libemf.h:2766
EMRDELETEOBJECT(DATASTREAM &ds)
Definition: libemf.h:2759
EMRDELETEOBJECT(HGDIOBJ object)
Definition: libemf.h:2749
int size(void) const
Definition: libemf.h:2774
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:555
EMF Ellipse.
Definition: libemf.h:3135
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3178
bool serialize(DATASTREAM ds)
Definition: libemf.h:3164
EMRELLIPSE(INT left, INT top, INT right, INT bottom)
Definition: libemf.h:3144
int size(void) const
Definition: libemf.h:3172
EMRELLIPSE(DATASTREAM &ds)
Definition: libemf.h:3157
EMF End Path.
Definition: libemf.h:5844
bool serialize(DATASTREAM ds)
Definition: libemf.h:5865
int size(void) const
Definition: libemf.h:5873
EMRENDPATH(void)
Definition: libemf.h:5849
EMRENDPATH(DATASTREAM &ds)
Definition: libemf.h:5858
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5879
EMF End of File Record.
Definition: libemf.h:1677
int size(void) const
Definition: libemf.h:1711
bool serialize(DATASTREAM ds)
Definition: libemf.h:1703
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1717
EMREOF(DATASTREAM &ds)
Definition: libemf.h:1695
EMREOF(void)
Definition: libemf.h:1682
EMF Font.
Definition: libemf.h:5439
bool serialize(DATASTREAM ds)
Definition: libemf.h:5454
int size(void) const
Definition: libemf.h:5467
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:666
EMREXTCREATEFONTINDIRECTW(FONT *font, HGDIOBJ handle)
Definition: libemf.cpp:652
EMF Extended Pen.
Definition: libemf.h:5310
int size(void) const
Definition: libemf.h:5333
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:600
EMREXTCREATEPEN(EXTPEN *pen, HGDIOBJ handle)
Definition: libemf.cpp:588
bool serialize(DATASTREAM ds)
Definition: libemf.h:5325
EMF Extended Text Output ASCII.
Definition: libemf.h:4649
EMREXTTEXTOUTA(DATASTREAM &ds)
Definition: libemf.h:4722
bool serialize(DATASTREAM ds)
Definition: libemf.h:4772
~EMREXTTEXTOUTA()
Definition: libemf.h:4764
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4789
int size(void) const
Definition: libemf.h:4783
EMREXTTEXTOUTA(const RECTL *bounds, DWORD graphicsMode, FLOAT xScale, FLOAT yScale, const PEMRTEXT text, LPCSTR string, const INT *dx)
Definition: libemf.h:4664
EMF Extended Text Output Wide character.
Definition: libemf.h:4897
bool serialize(DATASTREAM ds)
Definition: libemf.h:5020
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5037
~EMREXTTEXTOUTW()
Definition: libemf.h:5012
EMREXTTEXTOUTW(const RECTL *bounds, DWORD graphicsMode, FLOAT xScale, FLOAT yScale, const PEMRTEXT text, LPCWSTR string, const INT *dx)
Definition: libemf.h:4912
int size(void) const
Definition: libemf.h:5031
EMREXTTEXTOUTW(DATASTREAM &ds)
Definition: libemf.h:4970
EMF Fill path.
Definition: libemf.h:5622
EMRFILLPATH(DATASTREAM &ds)
Definition: libemf.h:5637
bool serialize(DATASTREAM ds)
Definition: libemf.h:5644
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5658
int size(void) const
Definition: libemf.h:5652
EMRFILLPATH(const RECTL *bounds)
Definition: libemf.h:5627
EMF Line To.
Definition: libemf.h:2861
bool serialize(DATASTREAM ds)
Definition: libemf.h:2885
EMRLINETO(DATASTREAM &ds)
Definition: libemf.h:2878
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2899
EMRLINETO(INT x, INT y)
Definition: libemf.h:2867
int size(void) const
Definition: libemf.h:2893
EMF Modify World Transform.
Definition: libemf.h:2145
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2184
bool serialize(DATASTREAM ds)
Definition: libemf.h:2170
EMRMODIFYWORLDTRANSFORM(DATASTREAM &ds)
Definition: libemf.h:2163
int size(void) const
Definition: libemf.h:2178
EMRMODIFYWORLDTRANSFORM(const XFORM *transform, DWORD mode)
Definition: libemf.h:2152
EMF MoveTo (ex)
Definition: libemf.h:2802
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2840
EMRMOVETOEX(INT x, INT y)
Definition: libemf.h:2808
int size(void) const
Definition: libemf.h:2834
EMRMOVETOEX(DATASTREAM &ds)
Definition: libemf.h:2819
bool serialize(DATASTREAM ds)
Definition: libemf.h:2826
EMF Polybezier16.
Definition: libemf.h:4097
int size(void) const
Definition: libemf.h:4188
EMRPOLYBEZIER16(DATASTREAM &ds)
Definition: libemf.h:4153
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4194
~EMRPOLYBEZIER16()
Definition: libemf.h:4173
EMRPOLYBEZIER16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4130
bool serialize(DATASTREAM ds)
Definition: libemf.h:4180
EMRPOLYBEZIER16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:4105
EMF PolyBezierTo16.
Definition: libemf.h:4312
EMRPOLYBEZIERTO16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4345
bool serialize(DATASTREAM ds)
Definition: libemf.h:4395
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4409
EMRPOLYBEZIERTO16(DATASTREAM &ds)
Definition: libemf.h:4368
int size(void) const
Definition: libemf.h:4403
EMRPOLYBEZIERTO16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:4320
~EMRPOLYBEZIERTO16()
Definition: libemf.h:4388
EMF PolyBezierTo.
Definition: libemf.h:4217
~EMRPOLYBEZIERTO()
Definition: libemf.h:4268
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4289
int size(void) const
Definition: libemf.h:4283
bool serialize(DATASTREAM ds)
Definition: libemf.h:4275
EMRPOLYBEZIERTO(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4225
EMRPOLYBEZIERTO(DATASTREAM &ds)
Definition: libemf.h:4248
EMF Polybezier.
Definition: libemf.h:4002
EMRPOLYBEZIER(DATASTREAM &ds)
Definition: libemf.h:4033
int size(void) const
Definition: libemf.h:4068
~EMRPOLYBEZIER()
Definition: libemf.h:4053
bool serialize(DATASTREAM ds)
Definition: libemf.h:4060
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4074
EMRPOLYBEZIER(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4010
EMF Filled Polygon16.
Definition: libemf.h:3508
~EMRPOLYGON16()
Definition: libemf.h:3584
EMRPOLYGON16(const RECTL *bounds, const POINT16 *points, INT16 n)
Definition: libemf.h:3541
bool serialize(DATASTREAM ds)
Definition: libemf.h:3591
int size(void) const
Definition: libemf.h:3599
EMRPOLYGON16(DATASTREAM &ds)
Definition: libemf.h:3564
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3605
EMRPOLYGON16(const RECTL *bounds, const POINT *points, INT16 n)
Definition: libemf.h:3516
EMF Filled Polygon.
Definition: libemf.h:3413
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3485
int size(void) const
Definition: libemf.h:3479
EMRPOLYGON(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:3421
bool serialize(DATASTREAM ds)
Definition: libemf.h:3471
EMRPOLYGON(DATASTREAM &ds)
Definition: libemf.h:3444
~EMRPOLYGON()
Definition: libemf.h:3464
EMF Polyline16.
Definition: libemf.h:3293
bool serialize(DATASTREAM ds)
Definition: libemf.h:3376
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3390
EMRPOLYLINE16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:3301
EMRPOLYLINE16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:3326
EMRPOLYLINE16(DATASTREAM &ds)
Definition: libemf.h:3356
int size(void) const
Definition: libemf.h:3384
~EMRPOLYLINE16()
Definition: libemf.h:3348
EMF PolylineTo16.
Definition: libemf.h:4527
EMRPOLYLINETO16(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4560
EMRPOLYLINETO16(DATASTREAM &ds)
Definition: libemf.h:4583
bool serialize(DATASTREAM ds)
Definition: libemf.h:4610
~EMRPOLYLINETO16()
Definition: libemf.h:4603
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4624
EMRPOLYLINETO16(const RECTL *bounds, const POINT16 *points, INT n)
Definition: libemf.h:4535
int size(void) const
Definition: libemf.h:4618
EMF PolylineTo.
Definition: libemf.h:4432
EMRPOLYLINETO(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:4440
~EMRPOLYLINETO()
Definition: libemf.h:4483
EMRPOLYLINETO(DATASTREAM &ds)
Definition: libemf.h:4463
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:4504
bool serialize(DATASTREAM ds)
Definition: libemf.h:4490
int size(void) const
Definition: libemf.h:4498
EMF Polyline.
Definition: libemf.h:3199
int size(void) const
Definition: libemf.h:3264
bool serialize(DATASTREAM ds)
Definition: libemf.h:3256
EMRPOLYLINE(const RECTL *bounds, const POINT *points, INT n)
Definition: libemf.h:3207
~EMRPOLYLINE()
Definition: libemf.h:3229
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3270
EMRPOLYLINE(DATASTREAM &ds)
Definition: libemf.h:3237
EMF Poly Polygon16.
Definition: libemf.h:3797
int size(void) const
Definition: libemf.h:3944
bool serialize(DATASTREAM ds)
Definition: libemf.h:3935
EMRPOLYPOLYGON16(const RECTL *bounds, const POINT16 *points, const INT *counts, UINT16 polygons)
Definition: libemf.h:3848
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3950
EMRPOLYPOLYGON16(DATASTREAM &ds)
Definition: libemf.h:3894
EMRPOLYPOLYGON16(const RECTL *bounds, const POINT *points, const INT *counts, UINT polygons)
Definition: libemf.h:3807
~EMRPOLYPOLYGON16()
Definition: libemf.h:3885
EMF Poly Polygon.
Definition: libemf.h:3628
EMRPOLYPOLYGON(DATASTREAM &ds)
Definition: libemf.h:3684
EMRPOLYPOLYGON(const RECTL *bounds, const POINT *points, const INT *counts, UINT polygons)
Definition: libemf.h:3638
bool serialize(DATASTREAM ds)
Definition: libemf.h:3726
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3741
int size(void) const
Definition: libemf.h:3735
~EMRPOLYPOLYGON()
Definition: libemf.h:3675
EMF Rectangle.
Definition: libemf.h:3072
EMRRECTANGLE(DATASTREAM &ds)
Definition: libemf.h:3093
bool serialize(DATASTREAM ds)
Definition: libemf.h:3100
int size(void) const
Definition: libemf.h:3108
EMRRECTANGLE(INT left, INT top, INT right, INT bottom)
Definition: libemf.h:3080
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:3114
EMF Restore DC.
Definition: libemf.h:6007
EMRRESTOREDC(INT n)
Definition: libemf.h:6012
EMRRESTOREDC(DATASTREAM &ds)
Definition: libemf.h:6022
int size(void) const
Definition: libemf.h:6037
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:6043
bool serialize(DATASTREAM ds)
Definition: libemf.h:6029
EMF Save DC.
Definition: libemf.h:5953
EMRSAVEDC(DATASTREAM &ds)
Definition: libemf.h:5967
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5988
int size(void) const
Definition: libemf.h:5982
EMRSAVEDC(void)
Definition: libemf.h:5958
bool serialize(DATASTREAM ds)
Definition: libemf.h:5974
EMF Scale Viewport Extents (ex)
Definition: libemf.h:1925
EMRSCALEVIEWPORTEXTEX(DATASTREAM &ds)
Definition: libemf.h:1946
int size(void) const
Definition: libemf.h:1961
EMRSCALEVIEWPORTEXTEX(LONG x_num, LONG x_den, LONG y_num, LONG y_den)
Definition: libemf.h:1933
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1967
bool serialize(DATASTREAM ds)
Definition: libemf.h:1953
EMF Scale Window Extents (ex)
Definition: libemf.h:2065
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2107
bool serialize(DATASTREAM ds)
Definition: libemf.h:2093
int size(void) const
Definition: libemf.h:2101
EMRSCALEWINDOWEXTEX(DATASTREAM &ds)
Definition: libemf.h:2086
EMRSCALEWINDOWEXTEX(LONG x_num, LONG x_den, LONG y_num, LONG y_den)
Definition: libemf.h:2073
EMF Select Object.
Definition: libemf.h:2686
EMRSELECTOBJECT(HGDIOBJ object)
Definition: libemf.h:2691
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.cpp:540
bool serialize(DATASTREAM ds)
Definition: libemf.h:2708
EMRSELECTOBJECT(DATASTREAM &ds)
Definition: libemf.h:2701
int size(void) const
Definition: libemf.h:2716
EMF Set Background Color.
Definition: libemf.h:2420
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2456
int size(void) const
Definition: libemf.h:2450
EMRSETBKCOLOR(COLORREF color)
Definition: libemf.h:2425
EMRSETBKCOLOR(DATASTREAM &ds)
Definition: libemf.h:2435
bool serialize(DATASTREAM ds)
Definition: libemf.h:2442
EMF Set Background Mode.
Definition: libemf.h:2478
EMRSETBKMODE(DWORD mode)
Definition: libemf.h:2483
int size(void) const
Definition: libemf.h:2508
bool serialize(DATASTREAM ds)
Definition: libemf.h:2500
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2514
EMRSETBKMODE(DATASTREAM &ds)
Definition: libemf.h:2493
EMF Set Mapping Mode.
Definition: libemf.h:2613
EMRSETMAPMODE(DWORD mode)
Definition: libemf.h:2618
EMRSETMAPMODE(DATASTREAM &ds)
Definition: libemf.h:2628
int size(void) const
Definition: libemf.h:2643
bool serialize(DATASTREAM ds)
Definition: libemf.h:2635
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2649
EMF Set Meta Region.
Definition: libemf.h:6068
EMRSETMETARGN(DATASTREAM &ds)
Definition: libemf.h:6082
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:6103
EMRSETMETARGN(void)
Definition: libemf.h:6073
bool serialize(DATASTREAM ds)
Definition: libemf.h:6089
int size(void) const
Definition: libemf.h:6097
EMF SetMiterLimit.
Definition: libemf.h:6298
bool serialize(DATASTREAM ds)
Definition: libemf.h:6322
EMRSETMITERLIMIT(FLOAT limit)
Definition: libemf.h:6303
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:6336
int size(void) const
Definition: libemf.h:6330
EMRSETMITERLIMIT(DATASTREAM &ds)
Definition: libemf.h:6313
EMF Set Pixel.
Definition: libemf.h:5183
EMRSETPIXELV(DATASTREAM &ds)
Definition: libemf.h:5202
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5223
bool serialize(DATASTREAM ds)
Definition: libemf.h:5209
EMRSETPIXELV(INT x, INT y, COLORREF color)
Definition: libemf.h:5190
int size(void) const
Definition: libemf.h:5217
EMF Set the Polygon Fill Mode.
Definition: libemf.h:2545
bool serialize(DATASTREAM ds)
Definition: libemf.h:2567
EMRSETPOLYFILLMODE(DATASTREAM &ds)
Definition: libemf.h:2560
int size(void) const
Definition: libemf.h:2575
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2581
EMRSETPOLYFILLMODE(DWORD mode)
Definition: libemf.h:2550
EMF Set Text Alignment.
Definition: libemf.h:2277
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2313
bool serialize(DATASTREAM ds)
Definition: libemf.h:2299
int size(void) const
Definition: libemf.h:2307
EMRSETTEXTALIGN(DATASTREAM &ds)
Definition: libemf.h:2292
EMRSETTEXTALIGN(UINT mode)
Definition: libemf.h:2282
EMF Set Text Color.
Definition: libemf.h:2363
EMRSETTEXTCOLOR(DATASTREAM &ds)
Definition: libemf.h:2378
EMRSETTEXTCOLOR(COLORREF color)
Definition: libemf.h:2368
bool serialize(DATASTREAM ds)
Definition: libemf.h:2385
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2399
int size(void) const
Definition: libemf.h:2393
EMF Set Viewport Extents (ex)
Definition: libemf.h:1864
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1902
int size(void) const
Definition: libemf.h:1896
EMRSETVIEWPORTEXTEX(INT cx, INT cy)
Definition: libemf.h:1870
bool serialize(DATASTREAM ds)
Definition: libemf.h:1888
EMRSETVIEWPORTEXTEX(DATASTREAM &ds)
Definition: libemf.h:1881
EMF Set Viewport Origin (ex)
Definition: libemf.h:1740
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1778
EMRSETVIEWPORTORGEX(INT x, INT y)
Definition: libemf.h:1746
bool serialize(DATASTREAM ds)
Definition: libemf.h:1764
EMRSETVIEWPORTORGEX(DATASTREAM &ds)
Definition: libemf.h:1757
int size(void) const
Definition: libemf.h:1772
EMF Set Window Extent (ex)
Definition: libemf.h:2004
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2042
bool serialize(DATASTREAM ds)
Definition: libemf.h:2028
EMRSETWINDOWEXTEX(DATASTREAM &ds)
Definition: libemf.h:2021
EMRSETWINDOWEXTEX(INT cx, INT cy)
Definition: libemf.h:2010
int size(void) const
Definition: libemf.h:2036
EMF Set Window Origin (ex)
Definition: libemf.h:1803
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1841
bool serialize(DATASTREAM ds)
Definition: libemf.h:1827
int size(void) const
Definition: libemf.h:1835
EMRSETWINDOWORGEX(INT x, INT y)
Definition: libemf.h:1809
EMRSETWINDOWORGEX(DATASTREAM &ds)
Definition: libemf.h:1820
EMF Set World Transform.
Definition: libemf.h:2220
bool serialize(DATASTREAM ds)
Definition: libemf.h:2242
EMRSETWORLDTRANSFORM(DATASTREAM &ds)
Definition: libemf.h:2235
int size(void) const
Definition: libemf.h:2250
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:2256
EMRSETWORLDTRANSFORM(const XFORM *transform)
Definition: libemf.h:2225
EMF Stroke and Fill path.
Definition: libemf.h:5734
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5770
EMRSTROKEANDFILLPATH(DATASTREAM &ds)
Definition: libemf.h:5749
EMRSTROKEANDFILLPATH(const RECTL *bounds)
Definition: libemf.h:5739
bool serialize(DATASTREAM ds)
Definition: libemf.h:5756
int size(void) const
Definition: libemf.h:5764
EMF Stroke path.
Definition: libemf.h:5678
EMRSTROKEPATH(const RECTL *bounds)
Definition: libemf.h:5683
int size(void) const
Definition: libemf.h:5708
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:5714
EMRSTROKEPATH(DATASTREAM &ds)
Definition: libemf.h:5693
bool serialize(DATASTREAM ds)
Definition: libemf.h:5700
Enhanced Metafile Header Record.
Definition: libemf.h:1424
bool serialize(DATASTREAM ds)
Definition: libemf.h:1512
int size(void) const
Definition: libemf.h:1572
ENHMETAHEADER(LPCWSTR description=0)
Definition: libemf.h:1436
bool unserialize(DATASTREAM ds)
Definition: libemf.h:1527
~ENHMETAHEADER()
Definition: libemf.h:1504
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition: libemf.h:1578
Extended Graphics Pen.
Definition: libemf.h:6155
EXTPEN(const EXTLOGPEN *lpen)
Definition: libemf.h:6160
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6180
OBJECTTYPE getType(void) const
Definition: libemf.h:6173
Graphics Font.
Definition: libemf.h:6223
FONT(const LOGFONTW *lfont)
Definition: libemf.h:6228
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6253
OBJECTTYPE getType(void) const
Definition: libemf.h:6246
Definition: libemf.h:1276
static EMF::METARECORD * new_extcreatefontindirectw(DATASTREAM &ds)
Create a new EXTCREATEFONTINDIRECTW record.
Definition: libemf.cpp:477
static EMF::METARECORD * new_exttextoutw(DATASTREAM &ds)
Create a new EXTTEXTOUTW record.
Definition: libemf.cpp:452
static EMF::METARECORD * new_arc(DATASTREAM &ds)
Create a new ARC record.
Definition: libemf.cpp:367
static EMF::METARECORD * new_polypolygon16(DATASTREAM &ds)
Create a new POLYPOLYGON16 record.
Definition: libemf.cpp:412
static EMF::METARECORD * new_modifyworldtransform(DATASTREAM &ds)
Create a new MODIFYWORLDTRANSFORM record.
Definition: libemf.cpp:307
static EMF::METARECORD * new_createbrushindirect(DATASTREAM &ds)
Create a new CREATEBRUSHINDIRECT record.
Definition: libemf.cpp:472
static EMF::METARECORD * new_ellipse(DATASTREAM &ds)
Create a new ELLIPSE record.
Definition: libemf.cpp:382
static EMF::METARECORD * new_savedc(DATASTREAM &ds)
Create a new SAVEDC record.
Definition: libemf.cpp:512
static EMF::METARECORD * new_polybezierto(DATASTREAM &ds)
Create a new POLYBEZIERTO record.
Definition: libemf.cpp:427
static EMF::METARECORD * new_createpen(DATASTREAM &ds)
Create a new CREATEPEN record.
Definition: libemf.cpp:462
static EMF::METARECORD * new_exttextouta(DATASTREAM &ds)
Create a new EXTTEXTOUTA record.
Definition: libemf.cpp:447
static EMF::METARECORD * new_scaleviewportextex(DATASTREAM &ds)
Create a new SCALEVIEWPORTEXTEX record.
Definition: libemf.cpp:297
static EMF::METARECORD * new_extcreatepen(DATASTREAM &ds)
Create a new EXTCREATEPEN record.
Definition: libemf.cpp:467
static EMF::METARECORD * new_setviewportorgex(DATASTREAM &ds)
Create a new EMRSETVIEWPORTORGEX record.
Definition: libemf.cpp:277
static EMF::METARECORD * new_setmiterlimit(DATASTREAM &ds)
Create a new SETMITERLIMIT record.
Definition: libemf.cpp:527
auto end(void) const
Definition: libemf.h:1305
static EMF::METARECORD * new_setbkmode(DATASTREAM &ds)
Create a new SETBKMODE record.
Definition: libemf.cpp:332
METARECORDCTOR newRecord(DWORD iType) const
Definition: libemf.cpp:262
static EMF::METARECORD * new_polyline(DATASTREAM &ds)
Create a new POLYLINE record.
Definition: libemf.cpp:387
static EMF::METARECORD * new_setviewportextex(DATASTREAM &ds)
Create a new EMRSETVIEWPORTEXTEX record.
Definition: libemf.cpp:287
static EMF::METARECORD * new_deleteobject(DATASTREAM &ds)
Create a new DELETEOBJECT record.
Definition: libemf.cpp:352
static EMF::METARECORD * new_polylineto(DATASTREAM &ds)
Create a new POLYLINETO record.
Definition: libemf.cpp:437
static EMF::METARECORD * new_polylineto16(DATASTREAM &ds)
Create a new POLYLINETO16 record.
Definition: libemf.cpp:442
static EMF::METARECORD * new_settextalign(DATASTREAM &ds)
Create a new SETTEXTALIGN record.
Definition: libemf.cpp:317
void remove(const OBJECT *object)
Definition: libemf.cpp:248
static EMF::METARECORD * new_polybezier16(DATASTREAM &ds)
Create a new POLYBEZIER16 record.
Definition: libemf.cpp:422
auto begin(void) const
Definition: libemf.h:1300
static EMF::METARECORD * new_polypolygon(DATASTREAM &ds)
Create a new POLYPOLYGON record.
Definition: libemf.cpp:407
static EMF::METARECORD * new_setwindowextex(DATASTREAM &ds)
Create a new EMRSETWINDOWEXTEX record.
Definition: libemf.cpp:292
static EMF::METARECORD * new_polyline16(DATASTREAM &ds)
Create a new POLYLINE16 record.
Definition: libemf.cpp:392
static EMF::METARECORD * new_endpath(DATASTREAM &ds)
Create a new ENDPATH record.
Definition: libemf.cpp:502
static EMF::METARECORD * new_setpixelv(DATASTREAM &ds)
Create a new SETPIXELV record.
Definition: libemf.cpp:457
static EMF::METARECORD * new_restoredc(DATASTREAM &ds)
Create a new RESTOREDC record.
Definition: libemf.cpp:517
static EMF::METARECORD * new_beginpath(DATASTREAM &ds)
Create a new BEGINPATH record.
Definition: libemf.cpp:497
static EMF::METARECORD * new_scalewindowextex(DATASTREAM &ds)
Create a new SCALEWINDOWEXTEX record.
Definition: libemf.cpp:302
static EMF::METARECORD * new_setmapmode(DATASTREAM &ds)
Create a new SETMAPMODE record.
Definition: libemf.cpp:342
static EMF::METARECORD * new_polybezierto16(DATASTREAM &ds)
Create a new POLYBEZIERTO16 record.
Definition: libemf.cpp:432
static EMF::METARECORD * new_eof(DATASTREAM &ds)
Create a new EMREOF record.
Definition: libemf.cpp:272
static EMF::METARECORD * new_setbkcolor(DATASTREAM &ds)
Create a new SETBKCOLOR record.
Definition: libemf.cpp:327
static EMF::METARECORD * new_setworldtransform(DATASTREAM &ds)
Create a new SETWORLDTRANSFORM record.
Definition: libemf.cpp:312
static EMF::METARECORD * new_setwindoworgex(DATASTREAM &ds)
Create a new EMRSETWINDOWORGEX record.
Definition: libemf.cpp:282
static EMF::METARECORD * new_strokeandfillpath(DATASTREAM &ds)
Create a new STROKEANDFILLPATH record.
Definition: libemf.cpp:492
HGDIOBJ add(OBJECT *object)
Definition: libemf.cpp:193
static EMF::METARECORD * new_polygon(DATASTREAM &ds)
Create a new POLYGON record.
Definition: libemf.cpp:397
static EMF::METARECORD * new_strokepath(DATASTREAM &ds)
Create a new STROKEPATH record.
Definition: libemf.cpp:487
static EMF::METARECORD * new_polygon16(DATASTREAM &ds)
Create a new POLYGON16 record.
Definition: libemf.cpp:402
static EMF::METARECORD * new_fillpath(DATASTREAM &ds)
Create a new FILLPATH record.
Definition: libemf.cpp:482
static EMF::METARECORD * new_arcto(DATASTREAM &ds)
Create a new ARCTO record.
Definition: libemf.cpp:372
static EMF::METARECORD * new_lineto(DATASTREAM &ds)
Create a new LINETO record.
Definition: libemf.cpp:362
static EMF::METARECORD * new_setpolyfillmode(DATASTREAM &ds)
Create a new SETPOLYFILLMODE record.
Definition: libemf.cpp:337
static EMF::METARECORD * new_settextcolor(DATASTREAM &ds)
Create a new SETTEXTCOLOR record.
Definition: libemf.cpp:322
static EMF::METARECORD * new_rectangle(DATASTREAM &ds)
Create a new RECTANGLE record.
Definition: libemf.cpp:377
static EMF::METARECORD * new_movetoex(DATASTREAM &ds)
Create a new MOVETOEX record.
Definition: libemf.cpp:357
static EMF::METARECORD * new_closefigure(DATASTREAM &ds)
Create a new CLOSEFIGURE record.
Definition: libemf.cpp:507
static EMF::METARECORD * new_polybezier(DATASTREAM &ds)
Create a new POLYBEZIER record.
Definition: libemf.cpp:417
static EMF::METARECORD * new_selectobject(DATASTREAM &ds)
Create a new SELECTOBJECT record.
Definition: libemf.cpp:347
static EMF::METARECORD * new_setmetargn(DATASTREAM &ds)
Create a new SETMETARGN record.
Definition: libemf.cpp:522
OBJECT * find(const HGDIOBJ handle)
Definition: libemf.cpp:225
A global graphics object.
Definition: libemf.h:1253
virtual METARECORD * newEMR(HDC dc, HGDIOBJ handle)=0
std::map< HDC, HGDIOBJ > contexts
Definition: libemf.h:1261
virtual ~GRAPHICSOBJECT()
GRAPHICSOBJECTs has a virtual destructor.
Definition: libemf.h:1256
Graphics Device Context.
Definition: libemf.h:6360
void clearHandle(DWORD handle)
Definition: libemf.h:6556
OBJECTTYPE getType(void) const
Definition: libemf.h:6534
void appendHandle(METARECORD *record)
Definition: libemf.h:6579
ENHMETAHEADER * header
Definition: libemf.h:6462
INT polyfill_mode
The current polygon fill mode.
Definition: libemf.h:6486
POINT window_org
The origin of the window.
Definition: libemf.h:6473
void deleteMetafile(void)
Definition: libemf.h:6590
::FILE * fp
Definition: libemf.h:6453
PEN * pen
The current pen.
Definition: libemf.h:6478
FONT * font
The current font.
Definition: libemf.h:6480
BRUSH * brush
The current brush.
Definition: libemf.h:6479
SIZEL viewport_ext
The extent of the viewport.
Definition: libemf.h:6470
bool update_frame
Update the frame automatically?
Definition: libemf.h:6474
SIZEL resolution
The resolution in DPI of the reference DC.
Definition: libemf.h:6469
UINT text_alignment
The current text alignment.
Definition: libemf.h:6482
virtual ~METAFILEDEVICECONTEXT()
Definition: libemf.h:6524
void appendRecord(METARECORD *record)
Definition: libemf.h:6567
FLOAT miter_limit
The current miter length limit.
Definition: libemf.h:6488
POINT min_device_point
The lft/top-most painted point in device units.
Definition: libemf.h:6475
void mergePoint(const LONG &x, const LONG &y)
Definition: libemf.h:6601
POINT point
The current point.
Definition: libemf.h:6477
INT map_mode
The current mapping mode.
Definition: libemf.h:6487
COLORREF bk_color
The current background color.
Definition: libemf.h:6484
DATASTREAM ds
Definition: libemf.h:6458
std::vector< bool > handles
Definition: libemf.h:6495
POINT max_device_point
The rgt/btm-most painted point in device units.
Definition: libemf.h:6476
METAFILEDEVICECONTEXT(FILE *fp_, const RECT *size, LPCWSTR description_w)
Definition: libemf.h:6514
COLORREF text_color
The current text foreground color.
Definition: libemf.h:6483
PALETTE * palette
The current palette.
Definition: libemf.h:6481
POINT viewport_org
The origin of the viewport.
Definition: libemf.h:6471
SIZEL window_ext
The extent of the window.
Definition: libemf.h:6472
INT bk_mode
The current background mode.
Definition: libemf.h:6485
std::vector< EMF::METARECORD * > records
Definition: libemf.h:6466
void mergePoint(const POINT &p)
Definition: libemf.h:6612
std::map< HGDIOBJ, HGDIOBJ > emf_handles
Definition: libemf.h:6502
DWORD nextHandle(void)
Definition: libemf.h:6539
The base class of all metafile records.
Definition: libemf.h:989
virtual int size(void) const =0
virtual ~METARECORD()
Definition: libemf.h:1016
virtual void execute(METAFILEDEVICECONTEXT *source, HDC dc) const =0
virtual bool serialize(DATASTREAM ds)=0
Global GDI object.
Definition: libemf.h:1231
OBJECT(void)
Definition: libemf.h:1240
virtual OBJECTTYPE getType(void) const =0
HGDIOBJ handle
Definition: libemf.h:1233
virtual ~OBJECT()
OBJECTs have a virtual destructor.
Definition: libemf.h:1235
Graphics Palette.
Definition: libemf.h:6264
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6287
OBJECTTYPE getType(void) const
Definition: libemf.h:6280
PALETTE(const LOGPALETTE *lpalette)
Definition: libemf.h:6269
Graphics Pen.
Definition: libemf.h:6123
PEN(const LOGPEN *lpen)
Definition: libemf.h:6128
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition: libemf.h:6144
OBJECTTYPE getType(void) const
Definition: libemf.h:6137
Represent a byte array in a simple way.
Definition: libemf.h:127
const int n_
Number of bytes in array.
Definition: libemf.h:129
BYTE *const array_
Array of unsigned bytes.
Definition: libemf.h:128
BYTEARRAY(BYTE *const array, const int n)
Definition: libemf.h:135
Represent an ASCII character string in a simple way.
Definition: libemf.h:110
const int length_
Number of single byte characters in array.
Definition: libemf.h:112
CHARSTR(CHAR *const string, const int length)
Definition: libemf.h:118
CHAR *const string_
Array of single byte characters.
Definition: libemf.h:111
Represent an array of double word integers in a simple way.
Definition: libemf.h:191
DWORD *const dwords_
Array of double words.
Definition: libemf.h:192
const DWORD n_
Number of double words in array.
Definition: libemf.h:193
DWORDARRAY(DWORD *const dwords, const DWORD n)
Definition: libemf.h:199
Represent an array of integers in a simple way.
Definition: libemf.h:175
INT *const ints_
Array of ints.
Definition: libemf.h:176
const DWORD n_
Number of ints in array.
Definition: libemf.h:177
INTARRAY(INT *const ints, const DWORD n)
Definition: libemf.h:183
All metafile records must be padded out to a multiple of 4 bytes.
Definition: libemf.h:207
static const char padding_[4]
Pad with '\0's.
Definition: libemf.h:208
PADDING(const int size)
Definition: libemf.h:214
const int size_
Number of bytes of padding.
Definition: libemf.h:209
Represent an array of 16-bit point in a simple way.
Definition: libemf.h:159
POINT16 *const points_
Array of POINT16s.
Definition: libemf.h:160
const DWORD n_
Number of POINT16s in array.
Definition: libemf.h:161
POINT16ARRAY(POINT16 *const points, const DWORD n)
Definition: libemf.h:167
Represent an array of points in a simple way.
Definition: libemf.h:143
const DWORD n_
Number of POINTLs in array.
Definition: libemf.h:145
POINTL *const points_
Array of POINTLs.
Definition: libemf.h:144
POINTLARRAY(POINTL *const points, const DWORD n)
Definition: libemf.h:151
Represent a wide (UNICODE) character string in a simple way.
Definition: libemf.h:92
const int length_
Number of WCHARs in string.
Definition: libemf.h:94
WCHARSTR(WCHAR *const string, const int length)
Definition: libemf.h:100
WCHAR *const string_
String of WCHARs.
Definition: libemf.h:93