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