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