00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _LIBEMF_H
00022 #define _LIBEMF_H 1
00023
00024 #include <cmath>
00025 #include <vector>
00026 #include <map>
00027 #include <functional>
00028 #include <algorithm>
00029
00030 #include <config.h>
00031 #include <libEMF/emf.h>
00032
00033 #include <libEMF/wine/w16.h>
00034
00035 namespace EMF {
00040 #if 1
00041 const int XMAX_PIXELS = 1024;
00042 #else
00043 const int XMAX_PIXELS = 1280;
00044 #endif
00045
00049 #if 1
00050 const int YMAX_PIXELS = 768;
00051 #else
00052 const int YMAX_PIXELS = 1024;
00053 #endif
00054
00059 const int XMAX_MM = 320;
00065 const int YMAX_MM = 240;
00069 const int RESOLUTION = 96;
00073 static inline int ROUND_TO_LONG ( int n ) { return ((n+3)/4)*4; }
00074
00076
00081 struct WCHARSTR {
00082 WCHAR *const string_;
00083 const int length_;
00084
00089 WCHARSTR ( WCHAR *const string, const int length )
00090 : string_( string ), length_( length ) {}
00091 };
00092
00094
00099 struct CHARSTR {
00100 CHAR *const string_;
00101 const int length_;
00102
00107 CHARSTR ( CHAR *const string, const int length )
00108 : string_( string ), length_( length ) {}
00109 };
00110
00112
00116 struct BYTEARRAY {
00117 BYTE *const array_;
00118 const int n_;
00119
00124 BYTEARRAY ( BYTE *const array, const int n )
00125 : array_( array ), n_( n ) {}
00126 };
00127
00129
00132 struct POINTLARRAY {
00133 POINTL *const points_;
00134 const DWORD n_;
00135
00140 POINTLARRAY ( POINTL *const points, const DWORD n )
00141 : points_( points ), n_( n ) {}
00142 };
00143
00145
00148 struct POINT16ARRAY {
00149 POINT16 *const points_;
00150 const DWORD n_;
00151
00156 POINT16ARRAY ( POINT16 *const points, const DWORD n )
00157 : points_( points ), n_( n ) {}
00158 };
00159
00161
00164 struct INTARRAY {
00165 INT *const ints_;
00166 const DWORD n_;
00167
00172 INTARRAY ( INT *const ints, const DWORD n )
00173 : ints_( ints ), n_( n ) {}
00174 };
00175
00177
00180 struct DWORDARRAY {
00181 DWORD *const dwords_;
00182 const DWORD n_;
00183
00188 DWORDARRAY ( DWORD *const dwords, const DWORD n )
00189 : dwords_( dwords ), n_( n ) {}
00190 };
00191
00193
00196 struct PADDING {
00197 static const char padding_[4];
00198 const int size_;
00199
00203 PADDING ( const int size ) : size_( size ) {}
00204 };
00205
00207
00214 class DATASTREAM {
00215 bool swap_;
00216 ::FILE* fp_;
00217
00218 static bool bigEndian ( void );
00219 public:
00225 DATASTREAM ( ::FILE* fp = 0 ) : swap_( bigEndian() ), fp_( fp ) {}
00230 void setStream ( ::FILE* fp ) { fp_ = fp; }
00235 DATASTREAM& operator<< ( const BYTE& byte )
00236 {
00237 fwrite( &byte, sizeof(BYTE), 1, fp_ );
00238 return *this;
00239 }
00244 DATASTREAM& operator>> ( BYTE& byte )
00245 {
00246 fread( &byte, sizeof(BYTE), 1, fp_ );
00247 return *this;
00248 }
00253 DATASTREAM& operator<< ( const WORD& word )
00254 {
00255 if ( swap_ ) {
00256 unsigned char const * p = (unsigned char const*)&word;
00257 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00258 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00259 }
00260 else
00261 fwrite( &word, sizeof(WORD), 1, fp_ );
00262 return *this;
00263 }
00268 DATASTREAM& operator>> ( WORD& word )
00269 {
00270 if ( swap_ ) {
00271 unsigned char* p = (unsigned char*)&word;
00272 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00273 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00274 }
00275 else
00276 fread( &word, sizeof(WORD), 1, fp_ );
00277 return *this;
00278 }
00283 DATASTREAM& operator<< ( const INT16& word )
00284 {
00285 if ( swap_ ) {
00286 unsigned char const * p = (unsigned char const*)&word;
00287 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00288 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00289 }
00290 else
00291 fwrite( &word, sizeof(INT16), 1, fp_ );
00292 return *this;
00293 }
00298 DATASTREAM& operator>> ( INT16& word )
00299 {
00300 if ( swap_ ) {
00301 unsigned char* p = (unsigned char*)&word;
00302 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00303 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00304 }
00305 else
00306 fread( &word, sizeof(INT16), 1, fp_ );
00307 return *this;
00308 }
00313 DATASTREAM& operator<< ( const DWORD& dword )
00314 {
00315 if ( swap_ ) {
00316 unsigned char const* p = (unsigned char const*)&dword;
00317 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00318 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00319 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00320 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00321 }
00322 else
00323 fwrite( &dword, sizeof(DWORD), 1, fp_ );
00324 return *this;
00325 }
00330 DATASTREAM& operator>> ( DWORD& dword )
00331 {
00332 if ( swap_ ) {
00333 unsigned char* p = (unsigned char*)&dword;
00334 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00335 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00336 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00337 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00338 }
00339 else
00340 fread( &dword, sizeof(DWORD), 1, fp_ );
00341 return *this;
00342 }
00347 DATASTREAM& operator<< ( const LONG& long_ )
00348 {
00349 if ( swap_ ) {
00350 unsigned char const* p = (unsigned char const*)&long_;
00351 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00352 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00353 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00354 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00355 }
00356 else
00357 fwrite( &long_, sizeof(LONG), 1, fp_ );
00358 return *this;
00359 }
00364 DATASTREAM& operator>> ( LONG& long_ )
00365 {
00366 if ( swap_ ) {
00367 unsigned char* p = (unsigned char*)&long_;
00368 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00369 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00370 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00371 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00372 }
00373 else
00374 fread( &long_, sizeof(LONG), 1, fp_ );
00375 return *this;
00376 }
00381 DATASTREAM& operator<< ( const INT& int_ )
00382 {
00383 if ( swap_ ) {
00384 unsigned char const* p = (unsigned char const*)&int_;
00385 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00386 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00387 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00388 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00389 }
00390 else
00391 fwrite( &int_, sizeof(INT), 1, fp_ );
00392 return *this;
00393 }
00398 DATASTREAM& operator>> ( INT& int_ )
00399 {
00400 if ( swap_ ) {
00401 unsigned char* p = (unsigned char*)&int_;
00402 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00403 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00404 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00405 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00406 }
00407 else
00408 fread( &int_, sizeof(INT), 1, fp_ );
00409 return *this;
00410 }
00415 DATASTREAM& operator<< ( const UINT& uint )
00416 {
00417 if ( swap_ ) {
00418 unsigned char const* p = (unsigned char const*)&uint;
00419 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00420 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00421 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00422 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00423 }
00424 else
00425 fwrite( &uint, sizeof(UINT), 1, fp_ );
00426 return *this;
00427 }
00432 DATASTREAM& operator>> ( UINT& uint )
00433 {
00434 if ( swap_ ) {
00435 unsigned char* p = (unsigned char*)&uint;
00436 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00437 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00438 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00439 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00440 }
00441 else
00442 fread( &uint, sizeof(UINT), 1, fp_ );
00443 return *this;
00444 }
00449 DATASTREAM& operator<< ( const FLOAT& float_ )
00450 {
00451 if ( swap_ ) {
00452 unsigned char const* p = (unsigned char const*)&float_;
00453 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00454 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00455 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00456 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00457 }
00458 else
00459 fwrite( &float_, sizeof(FLOAT), 1, fp_ );
00460 return *this;
00461 }
00466 DATASTREAM& operator>> ( FLOAT& float_ )
00467 {
00468 if ( swap_ ) {
00469 unsigned char* p = (unsigned char*)&float_;
00470 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00471 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00472 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00473 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00474 }
00475 else
00476 fread( &float_, sizeof(FLOAT), 1, fp_ );
00477 return *this;
00478 }
00483 DATASTREAM& operator<< ( const PADDING& padding )
00484 {
00485 if ( padding.size_ != 0 )
00486 fwrite( &padding.padding_, sizeof(CHAR), padding.size_, fp_ );
00487 return *this;
00488 }
00493 DATASTREAM& operator<< ( const RECTL& rectl )
00494 {
00495 *this << rectl.left << rectl.top << rectl.right << rectl.bottom;
00496 return *this;
00497 }
00502 DATASTREAM& operator>> ( RECTL& rectl )
00503 {
00504 *this >> rectl.left >> rectl.top >> rectl.right >> rectl.bottom;
00505 return *this;
00506 }
00511 DATASTREAM& operator<< ( const SIZEL& sizel )
00512 {
00513 *this << sizel.cx << sizel.cy;
00514 return *this;
00515 }
00520 DATASTREAM& operator>> ( SIZEL& sizel )
00521 {
00522 *this >> sizel.cx >> sizel.cy;
00523 return *this;
00524 }
00529 DATASTREAM& operator<< ( const WCHARSTR& wcharstr )
00530 {
00531 for ( int i = 0; i < wcharstr.length_; i++ )
00532 *this << wcharstr.string_[i];
00533 return *this;
00534 }
00539 DATASTREAM& operator>> ( WCHARSTR& wcharstr )
00540 {
00541 for ( int i = 0; i < wcharstr.length_; i++ )
00542 *this >> wcharstr.string_[i];
00543 return *this;
00544 }
00549 DATASTREAM& operator<< ( const CHARSTR& charstr )
00550 {
00551 fwrite( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
00552 return *this;
00553 }
00558 DATASTREAM& operator>> ( CHARSTR& charstr )
00559 {
00560 fread( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
00561 return *this;
00562 }
00567 DATASTREAM& operator<< ( const ::EMR& emr )
00568 {
00569 *this << emr.iType << emr.nSize;
00570 return *this;
00571 }
00576 DATASTREAM& operator>> ( ::EMR& emr )
00577 {
00578 *this >> emr.iType >> emr.nSize;
00579 return *this;
00580 }
00585 DATASTREAM& operator<< ( const POINT& point )
00586 {
00587 *this << point.x << point.y;
00588 return *this;
00589 }
00594 DATASTREAM& operator>> ( POINT& point )
00595 {
00596 *this >> point.x >> point.y;
00597 return *this;
00598 }
00603 DATASTREAM& operator<< ( const POINTL& pointl )
00604 {
00605 *this << pointl.x << pointl.y;
00606 return *this;
00607 }
00612 DATASTREAM& operator>> ( POINTL& pointl )
00613 {
00614 *this >> pointl.x >> pointl.y;
00615 return *this;
00616 }
00621 DATASTREAM& operator<< ( const POINT16& point )
00622 {
00623 *this << point.x << point.y;
00624 return *this;
00625 }
00630 DATASTREAM& operator>> ( POINT16& point )
00631 {
00632 *this >> point.x >> point.y;
00633 return *this;
00634 }
00639 DATASTREAM& operator<< ( const XFORM& xform )
00640 {
00641 *this << xform.eM11 << xform.eM12 << xform.eM21 << xform.eM22
00642 << xform.eDx << xform.eDy;
00643 return *this;
00644 }
00649 DATASTREAM& operator>> ( XFORM& xform )
00650 {
00651 *this >> xform.eM11 >> xform.eM12 >> xform.eM21 >> xform.eM22
00652 >> xform.eDx >> xform.eDy;
00653 return *this;
00654 }
00659 DATASTREAM& operator<< ( const BYTEARRAY& array )
00660 {
00661 fwrite( array.array_, sizeof(BYTE), array.n_, fp_ );
00662 return *this;
00663 }
00668 DATASTREAM& operator>> ( BYTEARRAY& array )
00669 {
00670 fread( array.array_, sizeof(BYTE), array.n_, fp_ );
00671 return *this;
00672 }
00677 DATASTREAM& operator<< ( const POINTLARRAY& array )
00678 {
00679 for ( unsigned int i = 0; i < array.n_; i++ )
00680 *this << array.points_[i];
00681 return *this;
00682 }
00687 DATASTREAM& operator>> ( POINTLARRAY& array )
00688 {
00689 for ( unsigned int i = 0; i < array.n_; i++ )
00690 *this >> array.points_[i];
00691 return *this;
00692 }
00697 DATASTREAM& operator<< ( const POINT16ARRAY& array )
00698 {
00699 for ( unsigned int i = 0; i < array.n_; i++ )
00700 *this << array.points_[i];
00701 return *this;
00702 }
00707 DATASTREAM& operator>> ( POINT16ARRAY& array )
00708 {
00709 for ( unsigned int i = 0; i < array.n_; i++ )
00710 *this >> array.points_[i];
00711 return *this;
00712 }
00717 DATASTREAM& operator<< ( const INTARRAY& array )
00718 {
00719 for ( unsigned int i = 0; i < array.n_; i++ )
00720 *this << array.ints_[i];
00721 return *this;
00722 }
00727 DATASTREAM& operator>> ( INTARRAY& array )
00728 {
00729 for ( unsigned int i = 0; i < array.n_; i++ )
00730 *this >> array.ints_[i];
00731 return *this;
00732 }
00737 DATASTREAM& operator<< ( const DWORDARRAY& array )
00738 {
00739 for ( unsigned int i = 0; i < array.n_; i++ )
00740 *this << array.dwords_[i];
00741 return *this;
00742 }
00747 DATASTREAM& operator>> ( DWORDARRAY& array )
00748 {
00749 for ( unsigned int i = 0; i < array.n_; i++ )
00750 *this >> array.dwords_[i];
00751 return *this;
00752 }
00757 DATASTREAM& operator<< ( const ::EMRTEXT& text )
00758 {
00759 *this << text.ptlReference << text.nChars << text.offString << text.fOptions
00760 << text.rcl << text.offDx;
00761 return *this;
00762 }
00767 DATASTREAM& operator>> ( ::EMRTEXT& text )
00768 {
00769 *this >> text.ptlReference >> text.nChars >> text.offString >> text.fOptions
00770 >> text.rcl >> text.offDx;
00771 return *this;
00772 }
00777 DATASTREAM& operator<< ( const LOGPEN& pen )
00778 {
00779 *this << pen.lopnStyle << pen.lopnWidth << pen.lopnColor;
00780 return *this;
00781 }
00786 DATASTREAM& operator>> ( LOGPEN& pen )
00787 {
00788 *this >> pen.lopnStyle >> pen.lopnWidth >> pen.lopnColor;
00789 return *this;
00790 }
00795 DATASTREAM& operator<< ( const EXTLOGPEN& pen )
00796 {
00797
00798 *this << pen.elpPenStyle << pen.elpWidth << pen.elpBrushStyle << pen.elpColor
00799 << pen.elpHatch << pen.elpNumEntries;
00800 return *this;
00801 }
00806 DATASTREAM& operator>> ( EXTLOGPEN& pen )
00807 {
00808
00809 *this >> pen.elpPenStyle >> pen.elpWidth >> pen.elpBrushStyle >> pen.elpColor
00810 >> pen.elpHatch >> pen.elpNumEntries;
00811 return *this;
00812 }
00817 DATASTREAM& operator<< ( const LOGBRUSH& brush )
00818 {
00819 *this << brush.lbStyle << brush.lbColor << brush.lbHatch;
00820 return *this;
00821 }
00826 DATASTREAM& operator>> ( LOGBRUSH& brush )
00827 {
00828 *this >> brush.lbStyle >> brush.lbColor >> brush.lbHatch;
00829 return *this;
00830 }
00835 DATASTREAM& operator<< ( const LOGFONTW& font )
00836 {
00837 *this << font.lfHeight << font.lfWidth << font.lfEscapement
00838 << font.lfOrientation << font.lfWeight << font.lfItalic
00839 << font.lfUnderline << font.lfStrikeOut << font.lfCharSet
00840 << font.lfOutPrecision << font.lfClipPrecision << font.lfQuality
00841 << font.lfPitchAndFamily
00842 << WCHARSTR( const_cast<WCHAR*const>(font.lfFaceName), LF_FACESIZE );
00843 return *this;
00844 }
00849 DATASTREAM& operator>> ( LOGFONTW& font )
00850 {
00851 WCHARSTR wFaceName( font.lfFaceName, LF_FACESIZE );
00852
00853 *this >> font.lfHeight >> font.lfWidth >> font.lfEscapement
00854 >> font.lfOrientation >> font.lfWeight >> font.lfItalic
00855 >> font.lfUnderline >> font.lfStrikeOut >> font.lfCharSet
00856 >> font.lfOutPrecision >> font.lfClipPrecision >> font.lfQuality
00857 >> font.lfPitchAndFamily
00858 >> wFaceName;
00859 return *this;
00860 }
00865 DATASTREAM& operator<< ( const PANOSE& panose )
00866 {
00867 fwrite( &panose, sizeof(PANOSE), 1, fp_ );
00868 return *this;
00869 }
00874 DATASTREAM& operator>> ( PANOSE& panose )
00875 {
00876 fread( &panose, sizeof(PANOSE), 1, fp_ );
00877 return *this;
00878 }
00883 DATASTREAM& operator<< ( const EXTLOGFONTW& font )
00884 {
00885 *this << font.elfLogFont
00886 << WCHARSTR( const_cast<WCHAR*const>(font.elfFullName),
00887 LF_FULLFACESIZE )
00888 << WCHARSTR( const_cast<WCHAR*const>(font.elfStyle), LF_FACESIZE )
00889 << font.elfVersion << font.elfStyleSize << font.elfMatch
00890 << font.elfReserved
00891 << BYTEARRAY( const_cast<BYTE*const>(font.elfVendorId),
00892 ELF_VENDOR_SIZE )
00893 << font.elfCulture << font.elfPanose;
00894 return *this;
00895 }
00900 DATASTREAM& operator>> ( EXTLOGFONTW& font )
00901 {
00902 WCHARSTR wFullName( font.elfFullName, LF_FULLFACESIZE );
00903 WCHARSTR wStyle( font.elfStyle, LF_FACESIZE );
00904 BYTEARRAY bVendorId( font.elfVendorId, ELF_VENDOR_SIZE );
00905 *this >> font.elfLogFont
00906 >> wFullName >> wStyle
00907 >> font.elfVersion >> font.elfStyleSize >> font.elfMatch
00908 >> font.elfReserved >> bVendorId
00909 >> font.elfCulture >> font.elfPanose;
00910 return *this;
00911 }
00916 DATASTREAM& operator<< ( const LOGPALETTE& palette )
00917 {
00918
00919 *this << palette.palVersion << palette.palNumEntries;
00920 return *this;
00921 }
00926 DATASTREAM& operator>> ( LOGPALETTE& palette )
00927 {
00928
00929 *this >> palette.palVersion >> palette.palNumEntries;
00930 return *this;
00931 }
00932 };
00933
00934 class METAFILEDEVICECONTEXT;
00935
00937
00943 class METARECORD {
00944 public:
00951 virtual void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const = 0;
00958 virtual bool serialize ( DATASTREAM ds ) = 0;
00964 virtual int size ( void ) const = 0;
00970 virtual ~METARECORD( ) { }
00971 #ifdef ENABLE_EDITING
00972
00976 virtual void edit ( void ) const {}
00977 #endif
00978 };
00979
00980 #ifdef ENABLE_EDITING
00981
00982 inline void edit_rectl ( const char* tag, const RECTL& rectl )
00983 {
00984 printf( "\t%s\t: (%ld, %ld) - (%ld, %ld)\n", tag, rectl.left, rectl.top,
00985 rectl.right, rectl.bottom );
00986 }
00987
00988 inline void edit_xform ( const char* tag, const XFORM& xform )
00989 {
00990 printf( "\t%s.eM11\t: %f\n", tag, xform.eM11 );
00991 printf( "\t%s.eM12\t: %f\n", tag, xform.eM12 );
00992 printf( "\t%s.eM21\t: %f\n", tag, xform.eM21 );
00993 printf( "\t%s.eM22\t: %f\n", tag, xform.eM22 );
00994 printf( "\t%s.eDx\t: %f\n", tag, xform.eDx );
00995 printf( "\t%s.eDy\t: %f\n", tag, xform.eDy );
00996 }
00997
00998 inline void edit_color ( const char* tag, const COLORREF& color )
00999 {
01000 printf( "\t%s\t: R(0x%02lx) G(0x%02lx) B(0x%02lx)\n", tag,
01001 GetRValue( color ), GetGValue( color ), GetBValue( color ) );
01002 }
01003
01004 inline void edit_sizel ( const char* tag, const SIZEL& size )
01005 {
01006 printf( "\t%s\t: (%ld, %ld)\n", tag, size.cx, size.cy );
01007 }
01008
01009 inline void edit_pointl ( const char* tag, const POINTL& point )
01010 {
01011 printf( "\t%s\t: (%ld, %ld)\n", tag, point.x, point.y );
01012 }
01013
01014 inline void edit_pointlarray ( const char* tag, const DWORD cptl,
01015 const POINTL* points )
01016 {
01017 printf( "\tcptl%s\t: %ld\n", tag, cptl );
01018 printf( "\taptl%s\t: ", tag );
01019 if ( cptl > 0 )
01020 printf( "%ld, %ld\n", points[0].x, points[0].y );
01021 else
01022 puts( "" );
01023 for ( DWORD i = 1; i < cptl; i++ )
01024 printf( "\t\t%s %ld, %ld\n", tag, points[i].x, points[i].y );
01025 }
01026
01027 inline void edit_point16array ( const char* tag, const unsigned int cpts,
01028 const POINT16* points )
01029 {
01030 printf( "\tcpts%s\t: %d\n", tag, cpts );
01031 printf( "\tapts%s\t: ", tag );
01032 if ( cpts > 0 )
01033 printf( "%d, %d\n", points[0].x, points[0].y );
01034 else
01035 puts( "" );
01036 for ( unsigned int i = 1; i < cpts; i++ )
01037 printf( "\t\t%s %d, %d\n", tag, points[i].x, points[i].y );
01038 }
01039
01040 inline void edit_pen_style ( const char* tag, DWORD style )
01041 {
01042 printf( "\t%s\t: ", tag );
01043 switch ( style & PS_STYLE_MASK ) {
01044 case PS_SOLID: printf( "PS_SOLID" ); break;
01045 case PS_DASH: printf( "PS_DASH" ); break;
01046 case PS_DOT: printf( "PS_DOT" ); break;
01047 case PS_DASHDOT: printf( "PS_DASHDOT" ); break;
01048 case PS_DASHDOTDOT: printf( "PS_DASHDOTDOT" ); break;
01049 case PS_NULL: printf( "PS_NULL" ); break;
01050 case PS_INSIDEFRAME: printf( "PS_INSIDEFRAME" ); break;
01051 case PS_USERSTYLE: printf( "PS_USERSTYLE" ); break;
01052 case PS_ALTERNATE: printf( "PS_ALTERNATE" ); break;
01053 }
01054 switch ( style & PS_ENDCAP_MASK ) {
01055 case PS_ENDCAP_ROUND: printf( " | PS_ENDCAP_ROUND" ); break;
01056 case PS_ENDCAP_SQUARE: printf( " | PS_ENDCAP_SQUARE" ); break;
01057 case PS_ENDCAP_FLAT: printf( " | PS_ENDCAP_FLAT" ); break;
01058 }
01059 switch ( style & PS_JOIN_MASK ) {
01060 case PS_JOIN_ROUND: printf( " | PS_JOIN_ROUND" ); break;
01061 case PS_JOIN_BEVEL: printf( " | PS_JOIN_BEVEL" ); break;
01062 case PS_JOIN_MITER: printf( " | PS_JOIN_MITER" ); break;
01063 }
01064 switch ( style & PS_TYPE_MASK ) {
01065 case PS_COSMETIC: printf( " | PS_COSMETIC" ); break;
01066 case PS_GEOMETRIC: printf( " | PS_GEOMETRIC" ); break;
01067 }
01068 printf( "\n" );
01069 }
01070
01071 inline void edit_brush_style ( const char* tag, DWORD style )
01072 {
01073 printf( "\t%s\t: ", tag );
01074 switch ( style ) {
01075 case BS_SOLID: printf( "BS_SOLID" ); break;
01076 case BS_NULL: printf( "BS_NULL" ); break;
01077 case BS_HATCHED: printf( "BS_HATCHED" ); break;
01078 case BS_PATTERN: printf( "BS_PATTERN" ); break;
01079 case BS_INDEXED: printf( "BS_INDEXED" ); break;
01080 case BS_DIBPATTERN: printf( "BS_DIBPATTERN" ); break;
01081 case BS_DIBPATTERNPT: printf( "BS_DIBPATTERNPT" ); break;
01082 case BS_PATTERN8X8: printf( "BS_PATTERN8X8" ); break;
01083 case BS_DIBPATTERN8X8: printf( "BS_DIBPATTERN8X8" ); break;
01084 case BS_MONOPATTERN: printf( "BS_DIBPATTERN8X8" ); break;
01085 default: printf( "unknown(%ld)", style );
01086 }
01087 printf( "\n" );
01088 }
01089
01090 inline void edit_brush_hatch ( const char* tag, DWORD hatch )
01091 {
01092 printf( "\t%s\t: ", tag );
01093 switch ( hatch ) {
01094 case HS_HORIZONTAL: printf( "HS_HORIZONTAL" ); break;
01095 case HS_VERTICAL: printf( "HS_VERTICAL" ); break;
01096 case HS_FDIAGONAL: printf( "HS_FDIAGONAL" ); break;
01097 case HS_BDIAGONAL: printf( "HS_BDIAGONAL" ); break;
01098 case HS_CROSS: printf( "HS_CROSS" ); break;
01099 case HS_DIAGCROSS: printf( "HS_DIAGCROSS" ); break;
01100 default: printf( "unknown(%ld)", hatch );
01101 }
01102 printf( "\n" );
01103 }
01104 #endif
01105
01112 enum OBJECTTYPE { O_METAFILEDEVICECONTEXT = OBJ_METADC,
01113 O_FONT = OBJ_FONT,
01114 O_PEN = OBJ_PEN,
01115 O_EXTPEN = OBJ_EXTPEN,
01116 O_BRUSH = OBJ_BRUSH,
01117 O_PALETTE = OBJ_PAL };
01118 #if 0
01119
01122 static char* typStr ( OBJECTTYPE type )
01123 {
01124 switch (type) {
01125 case O_METAFILEDEVICECONTEXT:
01126 return "metafile device context";
01127 case O_FONT:
01128 return "font";
01129 case O_PEN:
01130 return "pen";
01131 case O_EXTPEN:
01132 return "extended pen";
01133 case O_BRUSH:
01134 return "brush";
01135 case O_PALETTE:
01136 return "palette";
01137 }
01138 return "unknown object";
01139 }
01140 #endif
01141
01142
01147 class OBJECT {
01148 public:
01149 HGDIOBJ handle;
01150
01151 virtual ~OBJECT () {}
01156 OBJECT ( void ) : handle( 0 ) {}
01160 virtual OBJECTTYPE getType ( void ) const = 0;
01161 };
01162
01164
01169 class GRAPHICSOBJECT : public OBJECT {
01170 public:
01172 virtual ~GRAPHICSOBJECT () {}
01177 std::map< HDC, HGDIOBJ > contexts;
01183 virtual METARECORD* newEMR ( HDC dc, HGDIOBJ handle ) = 0;
01184 };
01185
01186 typedef METARECORD*(*METARECORDCTOR)(DATASTREAM&);
01187
01188 class GLOBALOBJECTS {
01192 std::vector<OBJECT*> objects;
01193
01200 std::map< DWORD, METARECORDCTOR > new_records;
01201
01202 public:
01203 GLOBALOBJECTS ( void );
01204 ~GLOBALOBJECTS ( void );
01205 HGDIOBJ add ( OBJECT* object );
01206 OBJECT* find ( const HGDIOBJ handle );
01207 void remove ( const OBJECT* object );
01208
01209 std::vector<EMF::OBJECT*>::const_iterator begin ( void ) const
01210 { return objects.begin(); }
01211 std::vector<EMF::OBJECT*>::const_iterator end ( void ) const
01212 { return objects.end(); }
01213
01214 METARECORDCTOR newRecord ( DWORD iType ) const;
01215
01216 static EMF::METARECORD* new_eof ( DATASTREAM& ds );
01217 static EMF::METARECORD* new_setviewportorgex ( DATASTREAM& ds );
01218 static EMF::METARECORD* new_setwindoworgex ( DATASTREAM& ds );
01219 static EMF::METARECORD* new_setviewportextex ( DATASTREAM& ds );
01220 static EMF::METARECORD* new_setwindowextex ( DATASTREAM& ds );
01221 static EMF::METARECORD* new_scaleviewportextex ( DATASTREAM& ds );
01222 static EMF::METARECORD* new_scalewindowextex ( DATASTREAM& ds );
01223 static EMF::METARECORD* new_modifyworldtransform ( DATASTREAM& ds );
01224 static EMF::METARECORD* new_setworldtransform ( DATASTREAM& ds );
01225 static EMF::METARECORD* new_settextalign ( DATASTREAM& ds );
01226 static EMF::METARECORD* new_settextcolor ( DATASTREAM& ds );
01227 static EMF::METARECORD* new_setbkcolor ( DATASTREAM& ds );
01228 static EMF::METARECORD* new_setbkmode ( DATASTREAM& ds );
01229 static EMF::METARECORD* new_setpolyfillmode ( DATASTREAM& ds );
01230 static EMF::METARECORD* new_setmapmode ( DATASTREAM& ds );
01231 static EMF::METARECORD* new_selectobject ( DATASTREAM& ds );
01232 static EMF::METARECORD* new_deleteobject ( DATASTREAM& ds );
01233 static EMF::METARECORD* new_movetoex ( DATASTREAM& ds );
01234 static EMF::METARECORD* new_lineto ( DATASTREAM& ds );
01235 static EMF::METARECORD* new_arc ( DATASTREAM& ds );
01236 static EMF::METARECORD* new_arcto ( DATASTREAM& ds );
01237 static EMF::METARECORD* new_rectangle ( DATASTREAM& ds );
01238 static EMF::METARECORD* new_ellipse ( DATASTREAM& ds );
01239 static EMF::METARECORD* new_polyline ( DATASTREAM& ds );
01240 static EMF::METARECORD* new_polyline16 ( DATASTREAM& ds );
01241 static EMF::METARECORD* new_polygon ( DATASTREAM& ds );
01242 static EMF::METARECORD* new_polygon16 ( DATASTREAM& ds );
01243 static EMF::METARECORD* new_polypolygon ( DATASTREAM& ds );
01244 static EMF::METARECORD* new_polypolygon16 ( DATASTREAM& ds );
01245 static EMF::METARECORD* new_polybezier ( DATASTREAM& ds );
01246 static EMF::METARECORD* new_polybezier16 ( DATASTREAM& ds );
01247 static EMF::METARECORD* new_polybezierto ( DATASTREAM& ds );
01248 static EMF::METARECORD* new_polybezierto16 ( DATASTREAM& ds );
01249 static EMF::METARECORD* new_polylineto ( DATASTREAM& ds );
01250 static EMF::METARECORD* new_polylineto16 ( DATASTREAM& ds );
01251 static EMF::METARECORD* new_exttextouta ( DATASTREAM& ds );
01252 static EMF::METARECORD* new_setpixelv ( DATASTREAM& ds );
01253 static EMF::METARECORD* new_createpen ( DATASTREAM& ds );
01254 static EMF::METARECORD* new_extcreatepen ( DATASTREAM& ds );
01255 static EMF::METARECORD* new_createbrushindirect ( DATASTREAM& ds );
01256 static EMF::METARECORD* new_extcreatefontindirectw ( DATASTREAM& ds );
01257 static EMF::METARECORD* new_fillpath ( DATASTREAM& ds );
01258 static EMF::METARECORD* new_strokepath ( DATASTREAM& ds );
01259 static EMF::METARECORD* new_strokeandfillpath ( DATASTREAM& ds );
01260 static EMF::METARECORD* new_beginpath ( DATASTREAM& ds );
01261 static EMF::METARECORD* new_endpath ( DATASTREAM& ds );
01262 static EMF::METARECORD* new_closefigure ( DATASTREAM& ds );
01263 static EMF::METARECORD* new_savedc ( DATASTREAM& ds );
01264 static EMF::METARECORD* new_restoredc ( DATASTREAM& ds );
01265 static EMF::METARECORD* new_setmetargn ( DATASTREAM& ds );
01266 };
01267
01268 extern GLOBALOBJECTS globalObjects;
01269
01271
01277 class ENHMETAHEADER : public METARECORD, public ::ENHMETAHEADER {
01278
01279 LPWSTR description_w;
01280 int description_size;
01281
01282 public:
01289 ENHMETAHEADER ( LPCWSTR description = 0 )
01290 : description_w( 0 ), description_size( 0 )
01291 {
01292 iType = EMR_HEADER;
01293 nSize = sizeof( ::ENHMETAHEADER );
01294
01295
01296 RECTL default_bounds = { 0, 0, 0, 0 };
01297 rclBounds = default_bounds;
01298 RECTL default_frame = { 0, 0, 0, 0 };
01299 rclFrame = default_frame;
01300 dSignature = ENHMETA_SIGNATURE;
01301 nVersion = 0x10000;
01302 nBytes = nSize;
01303 nRecords = 1;
01304 nHandles = 0;
01305 sReserved = 0;
01306 nDescription = 0;
01307 offDescription = 0;
01308 nPalEntries = 0;
01309 szlDevice.cx = XMAX_PIXELS;
01310 szlDevice.cy = YMAX_PIXELS;
01311 szlMillimeters.cx = XMAX_MM;
01312 szlMillimeters.cy = YMAX_MM;
01313
01314 cbPixelFormat = 0;
01315 offPixelFormat = 0;
01316 bOpenGL = FALSE;
01317
01318 #if 1
01319 szlMicrometers.cx = 1000 * szlMillimeters.cx;
01320 szlMicrometers.cy = 1000 * szlMillimeters.cy;
01321 #endif
01322 if ( description ) {
01323
01324 int description_count = 0, nulls = 0;
01325 LPCWSTR description_p = description;
01326 while ( nulls < 3 ) {
01327 description_count++;
01328 if ( (*description_p++) == 0 ) nulls++;
01329 }
01330
01331
01332
01333 int record_size = ROUND_TO_LONG( sizeof( ::ENHMETAHEADER ) +
01334 sizeof( WCHAR ) * description_count );
01335 description_size =
01336 (record_size - sizeof( ::ENHMETAHEADER )) / sizeof( WCHAR );
01337
01338 description_w = new WCHAR[ description_size ];
01339
01340 memset( description_w, 0, sizeof(WCHAR) * description_size );
01341
01342 for ( int i=0; i<description_count; i++ )
01343 description_w[i] = *description++;
01344
01345 nSize = nBytes = record_size;
01346 nDescription = description_count;
01347 offDescription = sizeof( ::ENHMETAHEADER );
01348 }
01349 }
01350
01354 ~ENHMETAHEADER ( )
01355 {
01356 if ( description_w ) delete[] description_w;
01357 }
01362 bool serialize ( DATASTREAM ds )
01363 {
01364 ds << iType << nSize
01365 << rclBounds << rclFrame
01366 << dSignature << nVersion << nBytes << nRecords << nHandles << sReserved
01367 << nDescription << offDescription << nPalEntries
01368 << szlDevice << szlMillimeters
01369 << cbPixelFormat << offPixelFormat << bOpenGL
01370 #if 1
01371 << szlMicrometers
01372 #endif
01373 << WCHARSTR( description_w, description_size );
01374 return true;
01375 }
01379 bool unserialize ( DATASTREAM ds )
01380 {
01381 ds >> iType >> nSize
01382 >> rclBounds >> rclFrame
01383 >> dSignature >> nVersion >> nBytes >> nRecords >> nHandles >> sReserved
01384 >> nDescription >> offDescription >> nPalEntries
01385 >> szlDevice >> szlMillimeters;
01386
01387
01388
01389 #define OffsetOf( a, b ) ((unsigned int)(((char*)&(((::ENHMETAHEADER*)a)->b)) - \
01390 (char*)((::ENHMETAHEADER*)a)))
01391 #if 1
01392 if ( OffsetOf( this, szlMicrometers ) <= offDescription )
01393 ds >> cbPixelFormat >> offPixelFormat >> bOpenGL;
01394 #else
01395 if ( sizeof(::ENHMETAHEADER) <= offDescription )
01396 ds >> cbPixelFormat >> offPixelFormat >> bOpenGL;
01397 #endif
01398 #undef OffsetOf
01399 #if 1
01400 if ( sizeof(::ENHMETAHEADER) <= offDescription )
01401 ds >> szlMicrometers;
01402 #endif
01403
01404
01405 description_size = ( nSize - offDescription ) / sizeof(WCHAR);
01406 description_w = new WCHAR[ description_size ];
01407
01408 WCHARSTR description( description_w, description_size );
01409
01410 ds >> description;
01411
01412 return true;
01413 }
01417 int size ( void ) const { return nSize; }
01423 void execute ( METAFILEDEVICECONTEXT* , HDC ) const
01424 {
01425
01426 }
01427 #ifdef ENABLE_EDITING
01428
01431 void edit ( void ) const
01432 {
01433 printf( "*HEADER*\n" );
01434 printf( "\tiType\t\t\t: %ld\n", iType );
01435 printf( "\tnSize\t\t\t: %ld\n", nSize );
01436 edit_rectl( "rclBounds\t", rclBounds );
01437 edit_rectl( "rclFrame\t", rclFrame );
01438 printf( "\tdSignature\t\t: %.4s\n", (const char*)&dSignature );
01439 printf( "\tnVersion\t\t: 0x%x\n", (unsigned int)nVersion );
01440 printf( "\tnBytes\t\t\t: %ld\n", nBytes );
01441 printf( "\tnRecords\t\t: %ld\n", nRecords );
01442 printf( "\tnHandles\t\t: %d\n", nHandles );
01443 printf( "\tnDescription\t\t: %ld\n", nDescription );
01444 printf( "\toffDescription\t\t: %ld\n", offDescription );
01445 printf( "\tnPalEntries\t\t: %ld\n", nPalEntries );
01446 edit_sizel( "szlDevice\t", szlDevice );
01447 edit_sizel( "szlMillimeters\t", szlMillimeters );
01448
01449
01450 #define OffsetOf( a, b ) ((unsigned int)(((const char*)&(((const ::ENHMETAHEADER*)a)->b)) - \
01451 (const char*)((const ::ENHMETAHEADER*)a)))
01452
01453 if ( OffsetOf( this, cbPixelFormat ) <= offDescription ) {
01454 printf( "\tcbPixelFormat\t\t: %ld\n", cbPixelFormat );
01455 printf( "\toffPixelFormat\t\t: %ld\n", offPixelFormat );
01456 printf( "\tbOpenGL\t\t\t: %ld\n", bOpenGL );
01457 #if 1
01458 if ( sizeof(::ENHMETAHEADER) <= offDescription ) {
01459 edit_sizel( "szlMicrometers\t", szlMicrometers );
01460 }
01461 #endif
01462 }
01463
01464 #undef OffsetOf
01465
01466 if ( nDescription != 0 ) {
01467
01468 wchar_t last_w = 0;
01469 WCHAR* description = description_w;
01470
01471 printf( "\tDescription:" );
01472
01473 for ( DWORD i = 0; i < nDescription; i++ ) {
01474
01475 wchar_t w = *description++;
01476
01477
01478 if ( w != 0 ) {
01479 if ( last_w == 0 ) printf( "\n\t\t" );
01480 putchar( w );
01481 }
01482
01483 last_w = w;
01484 }
01485 printf( "\n" );
01486 }
01487 }
01488 #endif
01489 };
01490
01492
01497 class EMREOF : public METARECORD, ::EMREOF {
01498 public:
01502 EMREOF ( void )
01503 {
01504 emr.iType = EMR_EOF;
01505 emr.nSize = sizeof( ::EMREOF );
01506 nPalEntries = 0;
01507 offPalEntries = 0;
01508 nSizeLast = 0;
01509 }
01510
01515 EMREOF ( DATASTREAM& ds )
01516 {
01517 ds >> emr >> nPalEntries >> offPalEntries >> nSizeLast;
01518 }
01519
01523 bool serialize ( DATASTREAM ds )
01524 {
01525 ds << emr << nPalEntries << offPalEntries << nSizeLast;
01526 return true;
01527 }
01531 int size ( void ) const { return emr.nSize; }
01537 void execute ( METAFILEDEVICECONTEXT* , HDC ) const
01538 {
01539
01540 }
01541 #ifdef ENABLE_EDITING
01542
01545 void edit ( void ) const
01546 {
01547 printf( "*EOF*\n" );
01548 }
01549 #endif
01550 };
01551
01553
01558 class EMRSETVIEWPORTORGEX : public METARECORD, ::EMRSETVIEWPORTORGEX {
01559 public:
01564 EMRSETVIEWPORTORGEX ( INT x, INT y )
01565 {
01566 emr.iType = EMR_SETVIEWPORTORGEX;
01567 emr.nSize = sizeof( ::EMRSETVIEWPORTORGEX );
01568 ptlOrigin.x = x;
01569 ptlOrigin.y = y;
01570 }
01575 EMRSETVIEWPORTORGEX ( DATASTREAM& ds )
01576 {
01577 ds >> emr >> ptlOrigin;
01578 }
01582 bool serialize ( DATASTREAM ds )
01583 {
01584 ds << emr << ptlOrigin;
01585 return true;
01586 }
01590 int size ( void ) const { return emr.nSize; }
01596 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01597 {
01598 SetViewportOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
01599 }
01600 #ifdef ENABLE_EDITING
01601
01604 void edit ( void ) const
01605 {
01606 printf( "*SETVIEWPORTORGEX*\n" );
01607 edit_pointl( "ptlOrigin", ptlOrigin );
01608 }
01609 #endif
01610 };
01611
01613
01620 class EMRSETWINDOWORGEX : public METARECORD, ::EMRSETWINDOWORGEX {
01621 public:
01626 EMRSETWINDOWORGEX ( INT x, INT y )
01627 {
01628 emr.iType = EMR_SETWINDOWORGEX;
01629 emr.nSize = sizeof( ::EMRSETWINDOWORGEX );
01630 ptlOrigin.x = x;
01631 ptlOrigin.y = y;
01632 }
01637 EMRSETWINDOWORGEX ( DATASTREAM& ds )
01638 {
01639 ds >> emr >> ptlOrigin;
01640 }
01644 bool serialize ( DATASTREAM ds )
01645 {
01646 ds << emr << ptlOrigin;
01647 return true;
01648 }
01652 int size ( void ) const { return emr.nSize; }
01658 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01659 {
01660 SetWindowOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
01661 }
01662 #ifdef ENABLE_EDITING
01663
01666 void edit ( void ) const
01667 {
01668 printf( "*SETWINDOWORGEX*\n" );
01669 edit_pointl( "ptlOrigin", ptlOrigin );
01670 }
01671 #endif
01672 };
01673
01675
01680 class EMRSETVIEWPORTEXTEX : public METARECORD, ::EMRSETVIEWPORTEXTEX {
01681 public:
01686 EMRSETVIEWPORTEXTEX ( INT cx, INT cy )
01687 {
01688 emr.iType = EMR_SETVIEWPORTEXTEX;
01689 emr.nSize = sizeof( ::EMRSETVIEWPORTEXTEX );
01690 szlExtent.cx = cx;
01691 szlExtent.cy = cy;
01692 }
01697 EMRSETVIEWPORTEXTEX ( DATASTREAM& ds )
01698 {
01699 ds >> emr >> szlExtent;
01700 }
01704 bool serialize ( DATASTREAM ds )
01705 {
01706 ds << emr << szlExtent;
01707 return true;
01708 }
01712 int size ( void ) const { return emr.nSize; }
01718 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01719 {
01720 SetViewportExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
01721 }
01722 #ifdef ENABLE_EDITING
01723
01726 void edit ( void ) const
01727 {
01728 printf( "*SETVIEWPORTEXTEX*\n" );
01729 edit_sizel( "szlExtent", szlExtent );
01730 }
01731 #endif
01732 };
01733
01735
01740 class EMRSCALEVIEWPORTEXTEX : public METARECORD, ::EMRSCALEVIEWPORTEXTEX {
01741 public:
01748 EMRSCALEVIEWPORTEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
01749 {
01750 emr.iType = EMR_SCALEVIEWPORTEXTEX;
01751 emr.nSize = sizeof( ::EMRSCALEVIEWPORTEXTEX );
01752 xNum = x_num;
01753 xDenom = x_den;
01754 yNum = y_num;
01755 yDenom = y_den;
01756 }
01761 EMRSCALEVIEWPORTEXTEX ( DATASTREAM& ds )
01762 {
01763 ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
01764 }
01768 bool serialize ( DATASTREAM ds )
01769 {
01770 ds << emr << xNum << xDenom << yNum << yDenom;
01771 return true;
01772 }
01776 int size ( void ) const { return emr.nSize; }
01782 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01783 {
01784 ScaleViewportExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
01785 }
01786 #ifdef ENABLE_EDITING
01787
01790 void edit ( void ) const
01791 {
01792 printf( "*SCALEVIEWPORTEXTEX*\n" );
01793 printf( "\txNum\t: %ld\n", xNum );
01794 printf( "\txDenom\t: %ld\n", xDenom );
01795 printf( "\tyNum\t: %ld\n", yNum );
01796 printf( "\tyDenom\t: %ld\n", yDenom );
01797 }
01798 #endif
01799 };
01800
01802
01807 class EMRSETWINDOWEXTEX : public METARECORD, ::EMRSETWINDOWEXTEX {
01808 public:
01813 EMRSETWINDOWEXTEX ( INT cx, INT cy )
01814 {
01815 emr.iType = EMR_SETWINDOWEXTEX;
01816 emr.nSize = sizeof( ::EMRSETWINDOWEXTEX );
01817 szlExtent.cx = cx;
01818 szlExtent.cy = cy;
01819 }
01824 EMRSETWINDOWEXTEX ( DATASTREAM& ds )
01825 {
01826 ds >> emr >> szlExtent;
01827 }
01831 bool serialize ( DATASTREAM ds )
01832 {
01833 ds << emr << szlExtent;
01834 return true;
01835 }
01839 int size ( void ) const { return emr.nSize; }
01845 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01846 {
01847 SetWindowExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
01848 }
01849 #ifdef ENABLE_EDITING
01850
01853 void edit ( void ) const
01854 {
01855 printf( "*SETWINDOWEXTEX*\n" );
01856 edit_sizel( "szlExtent", szlExtent );
01857 }
01858 #endif
01859 };
01860
01862
01867 class EMRSCALEWINDOWEXTEX : public METARECORD, ::EMRSCALEWINDOWEXTEX {
01868 public:
01875 EMRSCALEWINDOWEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
01876 {
01877 emr.iType = EMR_SCALEWINDOWEXTEX;
01878 emr.nSize = sizeof( ::EMRSCALEWINDOWEXTEX );
01879 xNum = x_num;
01880 xDenom = x_den;
01881 yNum = y_num;
01882 yDenom = y_den;
01883 }
01888 EMRSCALEWINDOWEXTEX ( DATASTREAM& ds )
01889 {
01890 ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
01891 }
01895 bool serialize ( DATASTREAM ds )
01896 {
01897 ds << emr << xNum << xDenom << yNum << yDenom;
01898 return true;
01899 }
01903 int size ( void ) const { return emr.nSize; }
01909 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01910 {
01911 ScaleWindowExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
01912 }
01913 #ifdef ENABLE_EDITING
01914
01917 void edit ( void ) const
01918 {
01919 printf( "*SCALEWINDOWEXTEX*\n" );
01920 printf( "\txNum\t: %ld\n", xNum );
01921 printf( "\txDenom\t: %ld\n", xDenom );
01922 printf( "\tyNum\t: %ld\n", yNum );
01923 printf( "\tyDenom\t: %ld\n", yDenom );
01924 }
01925 #endif
01926 };
01927
01929
01935 class EMRMODIFYWORLDTRANSFORM : public METARECORD, ::EMRMODIFYWORLDTRANSFORM {
01936 public:
01942 EMRMODIFYWORLDTRANSFORM ( const XFORM* transform, DWORD mode )
01943 {
01944 emr.iType = EMR_MODIFYWORLDTRANSFORM;
01945 emr.nSize = sizeof( ::EMRMODIFYWORLDTRANSFORM );
01946 xform = *transform;
01947 iMode = mode;
01948 }
01953 EMRMODIFYWORLDTRANSFORM ( DATASTREAM& ds )
01954 {
01955 ds >> emr >> xform >> iMode;
01956 }
01960 bool serialize ( DATASTREAM ds )
01961 {
01962 ds << emr << xform << iMode;
01963 return true;
01964 }
01968 int size ( void ) const { return emr.nSize; }
01974 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01975 {
01976 ModifyWorldTransform( dc, &xform, iMode );
01977 }
01978 #ifdef ENABLE_EDITING
01979
01982 void edit ( void ) const
01983 {
01984 printf( "*MODIFYWORLDTRANSFORM*\n" );
01985 edit_xform( "xform", xform );
01986 printf( "\tiMode\t\t: " );
01987 switch ( iMode ) {
01988 case MWT_IDENTITY: printf( "MWT_IDENTITY\n" ); break;
01989 case MWT_LEFTMULTIPLY: printf( "MWT_LEFTMULTIPLY\n" ); break;
01990 case MWT_RIGHTMULTIPLY: printf( "MWT_RIGHTMULTIPLY\n" ); break;
01991 default: printf( "unknown(%ld)\n", iMode );
01992 }
01993 }
01994 #endif
01995 };
01996
01998
02004 class EMRSETWORLDTRANSFORM : public METARECORD, ::EMRSETWORLDTRANSFORM {
02005 public:
02009 EMRSETWORLDTRANSFORM ( const XFORM* transform )
02010 {
02011 emr.iType = EMR_SETWORLDTRANSFORM;
02012 emr.nSize = sizeof( ::EMRSETWORLDTRANSFORM );
02013 xform = *transform;
02014 }
02019 EMRSETWORLDTRANSFORM ( DATASTREAM& ds )
02020 {
02021 ds >> emr >> xform;
02022 }
02026 bool serialize ( DATASTREAM ds )
02027 {
02028 ds << emr << xform;
02029 return true;
02030 }
02034 int size ( void ) const { return emr.nSize; }
02040 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02041 {
02042 SetWorldTransform( dc, &xform );
02043 }
02044 #ifdef ENABLE_EDITING
02045
02048 void edit ( void ) const
02049 {
02050 printf( "*SETWORLDTRANSFORM*\n" );
02051 edit_xform( "xform", xform );
02052 }
02053 #endif
02054 };
02055
02057
02060 class EMRSETTEXTALIGN : public METARECORD, ::EMRSETTEXTALIGN {
02061 public:
02065 EMRSETTEXTALIGN ( UINT mode )
02066 {
02067 emr.iType = EMR_SETTEXTALIGN;
02068 emr.nSize = sizeof( ::EMRSETTEXTALIGN );
02069 iMode = mode;
02070 }
02075 EMRSETTEXTALIGN ( DATASTREAM& ds )
02076 {
02077 ds >> emr >> iMode;
02078 }
02082 bool serialize ( DATASTREAM ds )
02083 {
02084 ds << emr << iMode;
02085 return true;
02086 }
02090 int size ( void ) const { return emr.nSize; }
02096 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02097 {
02098 SetTextAlign( dc, iMode );
02099 }
02100 #ifdef ENABLE_EDITING
02101
02104 void edit ( void ) const
02105 {
02106 unsigned int known_bits = TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING;
02107 unsigned int unknown_bits = ~known_bits;
02108
02109 printf( "*SETTEXTALIGN*\n" );
02110 printf( "\tiMode\t: " );
02111 if ( iMode & TA_UPDATECP )
02112 printf( "TA_UPDATECP" );
02113 else
02114 printf( "TA_NOUPDATECP" );
02115 if ( iMode & TA_CENTER )
02116 printf( " | TA_CENTER" );
02117 else if ( iMode & TA_RIGHT )
02118 printf( " | TA_RIGHT" );
02119 else
02120 printf( " | TA_LEFT" );
02121 if ( iMode & TA_BASELINE )
02122 printf( " | TA_BASELINE" );
02123 else if ( iMode & TA_BOTTOM )
02124 printf( " | TA_BOTTOM" );
02125 else
02126 printf( " | TA_TOP" );
02127 if ( iMode & TA_RTLREADING )
02128 printf( " | TA_RTLREADING" );
02129 if ( iMode & unknown_bits )
02130 printf( " | unknown bits(0x%lx)", iMode & unknown_bits );
02131 printf( "\n" );
02132 }
02133 #endif
02134 };
02135
02137
02140 class EMRSETTEXTCOLOR : public METARECORD, ::EMRSETTEXTCOLOR {
02141 public:
02145 EMRSETTEXTCOLOR ( COLORREF color )
02146 {
02147 emr.iType = EMR_SETTEXTCOLOR;
02148 emr.nSize = sizeof( ::EMRSETTEXTCOLOR );
02149 crColor = color;
02150 }
02155 EMRSETTEXTCOLOR ( DATASTREAM& ds )
02156 {
02157 ds >> emr >> crColor;
02158 }
02162 bool serialize ( DATASTREAM ds )
02163 {
02164 ds << emr << crColor;
02165 return true;
02166 }
02170 int size ( void ) const { return emr.nSize; }
02176 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02177 {
02178 SetTextColor( dc, crColor );
02179 }
02180 #ifdef ENABLE_EDITING
02181
02184 void edit ( void ) const
02185 {
02186 printf( "*SETTEXTCOLOR*\n" );
02187 edit_color( "crColor", crColor );
02188 }
02189 #endif
02190 };
02191
02193
02196 class EMRSETBKCOLOR : public METARECORD, ::EMRSETBKCOLOR {
02197 public:
02201 EMRSETBKCOLOR ( COLORREF color )
02202 {
02203 emr.iType = EMR_SETBKCOLOR;
02204 emr.nSize = sizeof( ::EMRSETBKCOLOR );
02205 crColor = color;
02206 }
02211 EMRSETBKCOLOR ( DATASTREAM& ds )
02212 {
02213 ds >> emr >> crColor;
02214 }
02218 bool serialize ( DATASTREAM ds )
02219 {
02220 ds << emr << crColor;
02221 return true;
02222 }
02226 int size ( void ) const { return emr.nSize; }
02232 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02233 {
02234 SetBkColor( dc, crColor );
02235 }
02236 #ifdef ENABLE_EDITING
02237
02240 void edit ( void ) const
02241 {
02242 printf( "*SETBKCOLOR*\n" );
02243 edit_color( "crColor", crColor );
02244 }
02245 #endif
02246 };
02247
02249
02253 class EMRSETBKMODE : public METARECORD, ::EMRSETBKMODE {
02254 public:
02258 EMRSETBKMODE ( DWORD mode )
02259 {
02260 emr.iType = EMR_SETBKMODE;
02261 emr.nSize = sizeof( ::EMRSETBKMODE );
02262 iMode = mode;
02263 }
02268 EMRSETBKMODE ( DATASTREAM& ds )
02269 {
02270 ds >> emr >> iMode;
02271 }
02275 bool serialize ( DATASTREAM ds )
02276 {
02277 ds << emr << iMode;
02278 return true;
02279 }
02283 int size ( void ) const { return emr.nSize; }
02289 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02290 {
02291 SetBkMode( dc, iMode );
02292 }
02293 #ifdef ENABLE_EDITING
02294
02297 void edit ( void ) const
02298 {
02299 printf( "*SETBKMODE*\n" );
02300 printf( "\tiMode\t: " );
02301 switch ( iMode ) {
02302 case TRANSPARENT: printf( "TRANSPARENT\n" ); break;
02303 case OPAQUE: printf( "OPAQUE\n" ); break;
02304 default: printf( "unknown(%ld)\n", iMode );
02305 }
02306 }
02307 #endif
02308 };
02309
02311
02314 class EMRSETPOLYFILLMODE : public METARECORD, ::EMRSETPOLYFILLMODE {
02315 public:
02319 EMRSETPOLYFILLMODE ( DWORD mode )
02320 {
02321 emr.iType = EMR_SETPOLYFILLMODE;
02322 emr.nSize = sizeof( ::EMRSETPOLYFILLMODE );
02323 iMode = mode;
02324 }
02329 EMRSETPOLYFILLMODE ( DATASTREAM& ds )
02330 {
02331 ds >> emr >> iMode;
02332 }
02336 bool serialize ( DATASTREAM ds )
02337 {
02338 ds << emr << iMode;
02339 return true;
02340 }
02344 int size ( void ) const { return emr.nSize; }
02350 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02351 {
02352 SetPolyFillMode( dc, iMode );
02353 }
02354 #ifdef ENABLE_EDITING
02355
02358 void edit ( void ) const
02359 {
02360 printf( "*SETPOLYFILLMODE*\n" );
02361 printf( "\tiMode: " );
02362 switch ( iMode ) {
02363 case ALTERNATE: printf( "ALTERNATE\n" ); break;
02364 case WINDING: printf( "WINDING\n" ); break;
02365 default: printf( "unknown(%ld)\n", iMode );
02366 }
02367 }
02368 #endif
02369 };
02370
02372
02376 class EMRSETMAPMODE : public METARECORD, ::EMRSETMAPMODE {
02377 public:
02381 EMRSETMAPMODE ( DWORD mode )
02382 {
02383 emr.iType = EMR_SETMAPMODE;
02384 emr.nSize = sizeof( ::EMRSETMAPMODE );
02385 iMode = mode;
02386 }
02391 EMRSETMAPMODE ( DATASTREAM& ds )
02392 {
02393 ds >> emr >> iMode;
02394 }
02398 bool serialize ( DATASTREAM ds )
02399 {
02400 ds << emr << iMode;
02401 return true;
02402 }
02406 int size ( void ) const { return emr.nSize; }
02412 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02413 {
02414 SetMapMode( dc, iMode );
02415 }
02416 #ifdef ENABLE_EDITING
02417
02420 void edit ( void ) const
02421 {
02422 printf( "*SETMAPMODE*\n" );
02423 printf( "\tiMode\t: " );
02424 switch ( iMode ) {
02425 case MM_TEXT: printf( "MM_TEXT\n" ); break;
02426 case MM_LOMETRIC: printf( "MM_LOMETRIC\n" ); break;
02427 case MM_HIMETRIC: printf( "MM_HIMETRIC\n" ); break;
02428 case MM_LOENGLISH: printf( "MM_LOENGLISH\n" ); break;
02429 case MM_HIENGLISH: printf( "MM_HIENGLISH\n" ); break;
02430 case MM_TWIPS: printf( "MM_TWIPS\n" ); break;
02431 case MM_ISOTROPIC: printf( "MM_ISOTROPIC\n" ); break;
02432 case MM_ANISOTROPIC: printf( "MM_ANISOTROPIC\n" ); break;
02433 default: printf( "unknown(%ld)\n", iMode );
02434 }
02435 }
02436 #endif
02437 };
02438
02440
02443 class EMRSELECTOBJECT : public METARECORD, ::EMRSELECTOBJECT {
02444 public:
02448 EMRSELECTOBJECT ( HGDIOBJ object )
02449 {
02450 emr.iType = EMR_SELECTOBJECT;
02451 emr.nSize = sizeof( ::EMRSELECTOBJECT );
02452 ihObject = object;
02453 }
02458 EMRSELECTOBJECT ( DATASTREAM& ds )
02459 {
02460 ds >> emr >> ihObject;
02461 }
02465 bool serialize ( DATASTREAM ds )
02466 {
02467 ds << emr << ihObject;
02468 return true;
02469 }
02473 int size ( void ) const { return emr.nSize; }
02479 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
02480 #ifdef ENABLE_EDITING
02481
02484 void edit ( void ) const
02485 {
02486 printf( "*SELECTOBJECT*\n" );
02487 printf( "\tihObject\t: 0x%lx\n", ihObject );
02488 }
02489 #endif
02490 };
02491
02493
02496 class EMRDELETEOBJECT : public METARECORD, ::EMRDELETEOBJECT {
02497 public:
02501 EMRDELETEOBJECT ( HGDIOBJ object )
02502 {
02503 emr.iType = EMR_DELETEOBJECT;
02504 emr.nSize = sizeof( ::EMRDELETEOBJECT );
02505 ihObject = object;
02506 }
02511 EMRDELETEOBJECT ( DATASTREAM& ds )
02512 {
02513 ds >> emr >> ihObject;
02514 }
02518 bool serialize ( DATASTREAM ds )
02519 {
02520 ds << emr << ihObject;
02521 return true;
02522 }
02526 int size ( void ) const { return emr.nSize; }
02532 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
02533 #ifdef ENABLE_EDITING
02534
02537 void edit ( void ) const
02538 {
02539 printf( "*DELETEOBJECT*\n" );
02540 printf( "\tihObject\t: 0x%lx\n", ihObject );
02541 }
02542 #endif
02543 };
02544
02546
02549 class EMRMOVETOEX : public METARECORD, ::EMRMOVETOEX {
02550 public:
02555 EMRMOVETOEX ( INT x, INT y )
02556 {
02557 emr.iType = EMR_MOVETOEX;
02558 emr.nSize = sizeof( ::EMRMOVETOEX );
02559 ptl.x = x;
02560 ptl.y = y;
02561 }
02566 EMRMOVETOEX ( DATASTREAM& ds )
02567 {
02568 ds >> emr >> ptl;
02569 }
02573 bool serialize ( DATASTREAM ds )
02574 {
02575 ds << emr << ptl;
02576 return true;
02577 }
02581 int size ( void ) const { return emr.nSize; }
02587 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02588 {
02589 MoveToEx( dc, ptl.x, ptl.y, 0 );
02590 }
02591 #ifdef ENABLE_EDITING
02592
02595 void edit ( void ) const
02596 {
02597 printf( "*MOVETOEX*\n" );
02598 edit_pointl( "ptl", ptl );
02599 }
02600 #endif
02601 };
02602
02604
02607 class EMRLINETO : public METARECORD, ::EMRLINETO {
02608 public:
02613 EMRLINETO ( INT x, INT y )
02614 {
02615 emr.iType = EMR_LINETO;
02616 emr.nSize = sizeof( ::EMRLINETO );
02617 ptl.x = x;
02618 ptl.y = y;
02619 }
02624 EMRLINETO ( DATASTREAM& ds )
02625 {
02626 ds >> emr >> ptl;
02627 }
02631 bool serialize ( DATASTREAM ds )
02632 {
02633 ds << emr << ptl;
02634 return true;
02635 }
02639 int size ( void ) const { return emr.nSize; }
02645 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02646 {
02647 LineTo( dc, ptl.x, ptl.y );
02648 }
02649 #ifdef ENABLE_EDITING
02650
02653 void edit ( void ) const
02654 {
02655 printf( "*LINETO*\n" );
02656 edit_pointl( "ptl", ptl );
02657 }
02658 #endif
02659 };
02660
02662
02665 class EMRARC : public METARECORD, ::EMRARC {
02666 public:
02678 EMRARC ( INT left, INT top, INT right, INT bottom, INT xstart,
02679 INT ystart, INT xend, INT yend )
02680 {
02681 emr.iType = EMR_ARC;
02682 emr.nSize = sizeof( ::EMRARC );
02683 rclBox.left = left;
02684 rclBox.right = right;
02685 rclBox.bottom = bottom;
02686 rclBox.top = top;
02687 ptlStart.x = xstart;
02688 ptlStart.y = ystart;
02689 ptlEnd.x = xend;
02690 ptlEnd.y = yend;
02691 }
02696 EMRARC ( DATASTREAM& ds )
02697 {
02698 ds >> emr >> rclBox >> ptlStart >> ptlEnd;
02699 }
02703 bool serialize ( DATASTREAM ds )
02704 {
02705 ds << emr << rclBox << ptlStart << ptlEnd;
02706 return true;
02707 }
02711 int size ( void ) const { return emr.nSize; }
02717 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02718 {
02719 Arc( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
02720 ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
02721 }
02722 #ifdef ENABLE_EDITING
02723
02726 void edit ( void ) const
02727 {
02728 printf( "*ARC*\n" );
02729 edit_rectl( "rclBox\t", rclBox );
02730 edit_pointl( "ptlStart", ptlStart );
02731 edit_pointl( "ptlEnd\t", ptlEnd );
02732 }
02733 #endif
02734 };
02735
02737
02740 class EMRARCTO : public METARECORD, ::EMRARCTO {
02741 public:
02753 EMRARCTO ( INT left, INT top, INT right, INT bottom, INT xstart,
02754 INT ystart, INT xend, INT yend )
02755 {
02756 emr.iType = EMR_ARCTO;
02757 emr.nSize = sizeof( ::EMRARCTO );
02758 rclBox.left = left;
02759 rclBox.right = right;
02760 rclBox.bottom = bottom;
02761 rclBox.top = top;
02762 ptlStart.x = xstart;
02763 ptlStart.y = ystart;
02764 ptlEnd.x = xend;
02765 ptlEnd.y = yend;
02766 }
02771 EMRARCTO ( DATASTREAM& ds )
02772 {
02773 ds >> emr >> rclBox >> ptlStart >> ptlEnd;
02774 }
02778 bool serialize ( DATASTREAM ds )
02779 {
02780 ds << emr << rclBox << ptlStart << ptlEnd;
02781 return true;
02782 }
02786 int size ( void ) const { return emr.nSize; }
02792 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02793 {
02794 ArcTo( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
02795 ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
02796 }
02797 #ifdef ENABLE_EDITING
02798
02801 void edit ( void ) const
02802 {
02803 printf( "*ARCTO*\n" );
02804 edit_rectl( "rclBox\t", rclBox );
02805 edit_pointl( "ptlStart", ptlStart );
02806 edit_pointl( "ptlEnd\t", ptlEnd );
02807 }
02808 #endif
02809 };
02810
02812
02815 class EMRRECTANGLE : public METARECORD, ::EMRRECTANGLE {
02816 public:
02823 EMRRECTANGLE ( INT left, INT top, INT right, INT bottom )
02824 {
02825 emr.iType = EMR_RECTANGLE;
02826 emr.nSize = sizeof( ::EMRRECTANGLE );
02827 rclBox.left = left;
02828 rclBox.right = right;
02829 rclBox.bottom = bottom;
02830 rclBox.top = top;
02831 }
02836 EMRRECTANGLE ( DATASTREAM& ds )
02837 {
02838 ds >> emr >> rclBox;
02839 }
02843 bool serialize ( DATASTREAM ds )
02844 {
02845 ds << emr << rclBox;
02846 return true;
02847 }
02851 int size ( void ) const { return emr.nSize; }
02857 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02858 {
02859 Rectangle( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
02860 }
02861 #ifdef ENABLE_EDITING
02862
02865 void edit ( void ) const
02866 {
02867 printf( "*RECTANGLE*\n" );
02868 edit_rectl( "rclBox", rclBox );
02869 }
02870 #endif
02871 };
02872
02874
02877 class EMRELLIPSE : public METARECORD, ::EMRELLIPSE {
02878 public:
02886 EMRELLIPSE ( INT left, INT top, INT right, INT bottom )
02887 {
02888 emr.iType = EMR_ELLIPSE;
02889 emr.nSize = sizeof( ::EMRELLIPSE );
02890 rclBox.left = left;
02891 rclBox.right = right;
02892 rclBox.bottom = bottom;
02893 rclBox.top = top;
02894 }
02899 EMRELLIPSE ( DATASTREAM& ds )
02900 {
02901 ds >> emr >> rclBox;
02902 }
02906 bool serialize ( DATASTREAM ds )
02907 {
02908 ds << emr << rclBox;
02909 return true;
02910 }
02914 int size ( void ) const { return emr.nSize; }
02920 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02921 {
02922 Ellipse( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
02923 }
02924 #ifdef ENABLE_EDITING
02925
02928 void edit ( void ) const
02929 {
02930 printf( "*ELLIPSE*\n" );
02931 edit_rectl( "rclBox", rclBox );
02932 }
02933 #endif
02934 };
02935
02937
02940 class EMRPOLYLINE : public METARECORD, ::EMRPOLYLINE {
02941 POINTL* lpoints;
02942 public:
02948 EMRPOLYLINE ( const RECTL* bounds, const POINT* points, INT n )
02949 {
02950 cptl = n;
02951 aptl[0].x = 0;
02952 aptl[0].y = 0;
02953
02954 emr.iType = EMR_POLYLINE;
02955
02956 emr.nSize = sizeof( ::EMRPOLYLINE ) + sizeof( POINTL ) * ( cptl - 1);
02957
02958 lpoints = new POINTL[cptl];
02959
02960 for (int i=0; i<n; i++) {
02961 lpoints[i].x = points[i].x;
02962 lpoints[i].y = points[i].y;
02963 }
02964
02965 rclBounds = *bounds;
02966 }
02970 ~EMRPOLYLINE ( )
02971 {
02972 if ( lpoints ) delete[] lpoints;
02973 }
02978 EMRPOLYLINE ( DATASTREAM& ds )
02979 {
02980 ds >> emr >> rclBounds >> cptl;
02981
02982 lpoints = new POINTL[cptl];
02983
02984 POINTLARRAY points( lpoints, cptl );
02985
02986 ds >> points;
02987 }
02991 bool serialize ( DATASTREAM ds )
02992 {
02993 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
02994 return true;
02995 }
02999 int size ( void ) const { return emr.nSize; }
03005 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03006 {
03007
03008 Polyline( dc, (POINT*)lpoints, cptl );
03009 }
03010 #ifdef ENABLE_EDITING
03011
03014 void edit ( void ) const
03015 {
03016 printf( "*POLYLINE*\n" );
03017 edit_rectl( "rclBounds", rclBounds );
03018 #if 0
03019 printf( "\tcptl : %ld\n", cptl );
03020 printf( "\taptl->\n" );
03021 for ( unsigned int i = 0; i < cptl; i++ )
03022 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03023 #else
03024 edit_pointlarray( "\t", cptl, lpoints );
03025 #endif
03026 }
03027 #endif
03028 };
03029
03031
03034 class EMRPOLYLINE16 : public METARECORD, ::EMRPOLYLINE16 {
03035 POINT16* lpoints;
03036 public:
03042 EMRPOLYLINE16 ( const RECTL* bounds, const POINT16* points, INT n )
03043 {
03044 cpts = n;
03045 apts[0].x = 0;
03046 apts[0].y = 0;
03047
03048 emr.iType = EMR_POLYLINE16;
03049
03050 emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
03051
03052 lpoints = new POINT16[cpts];
03053
03054 for (int i=0; i<n; i++) {
03055 lpoints[i].x = points[i].x;
03056 lpoints[i].y = points[i].y;
03057 }
03058
03059 rclBounds = *bounds;
03060 }
03067 EMRPOLYLINE16 ( const RECTL* bounds, const POINT* points, INT n )
03068 {
03069 cpts = n;
03070 apts[0].x = 0;
03071 apts[0].y = 0;
03072
03073 emr.iType = EMR_POLYLINE16;
03074
03075 emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
03076
03077 lpoints = new POINT16[cpts];
03078
03079 for (int i=0; i<n; i++) {
03080 lpoints[i].x = points[i].x;
03081 lpoints[i].y = points[i].y;
03082 }
03083
03084 rclBounds = *bounds;
03085 }
03089 ~EMRPOLYLINE16 ( )
03090 {
03091 if ( lpoints ) delete[] lpoints;
03092 }
03097 EMRPOLYLINE16 ( DATASTREAM& ds )
03098 {
03099 ds >> emr >> rclBounds >> cpts;
03100
03101 lpoints = new POINT16[cpts];
03102
03103 POINT16ARRAY points( lpoints, cpts );
03104
03105 ds >> points;
03106 }
03110 bool serialize ( DATASTREAM ds )
03111 {
03112 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
03113 return true;
03114 }
03118 int size ( void ) const { return emr.nSize; }
03124 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03125 {
03126
03127 Polyline16( dc, lpoints, cpts );
03128 }
03129 #ifdef ENABLE_EDITING
03130
03133 void edit ( void ) const
03134 {
03135 printf( "*POLYLINE16*\n" );
03136 edit_rectl( "rclBounds", rclBounds );
03137 edit_point16array( "\t", cpts, lpoints );
03138 }
03139 #endif
03140 };
03141
03143
03146 class EMRPOLYGON : public METARECORD, ::EMRPOLYGON {
03147 POINTL* lpoints;
03148 public:
03154 EMRPOLYGON ( const RECTL* bounds, const POINT* points, INT n )
03155 {
03156 cptl = n;
03157 aptl[0].x = 0;
03158 aptl[0].y = 0;
03159
03160 emr.iType = EMR_POLYGON;
03161
03162 emr.nSize = sizeof( ::EMRPOLYGON ) + sizeof( POINTL ) * (cptl-1);
03163
03164 lpoints = new POINTL[cptl];
03165
03166 for (int i=0; i<n; i++) {
03167 lpoints[i].x = points[i].x;
03168 lpoints[i].y = points[i].y;
03169 }
03170
03171 rclBounds = *bounds;
03172 }
03177 EMRPOLYGON ( DATASTREAM& ds )
03178 {
03179 ds >> emr >> rclBounds >> cptl;
03180
03181 lpoints = new POINTL[cptl];
03182
03183 POINTLARRAY points( lpoints, cptl );
03184
03185 ds >> points;
03186 }
03190 ~EMRPOLYGON ( )
03191 {
03192 if ( lpoints ) delete[] lpoints;
03193 }
03197 bool serialize ( DATASTREAM ds )
03198 {
03199 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
03200 return true;
03201 }
03205 int size ( void ) const { return emr.nSize; }
03211 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03212 {
03213
03214 Polygon( dc, (POINT*)lpoints, cptl );
03215 }
03216 #ifdef ENABLE_EDITING
03217
03220 void edit ( void ) const
03221 {
03222 printf( "*POLYGON*\n" );
03223 edit_rectl( "rclBounds", rclBounds );
03224 #if 0
03225 printf( "\tcptl : %ld\n", cptl );
03226 printf( "\taptl->\n" );
03227 for ( unsigned int i = 0; i < cptl; i++ )
03228 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03229 #else
03230 edit_pointlarray( "\t", cptl, lpoints );
03231 #endif
03232 }
03233 #endif
03234 };
03235
03237
03240 class EMRPOLYGON16 : public METARECORD, ::EMRPOLYGON16 {
03241 POINT16* lpoints;
03242 public:
03248 EMRPOLYGON16 ( const RECTL* bounds, const POINT* points, INT16 n )
03249 {
03250 cpts = n;
03251 apts[0].x = 0;
03252 apts[0].y = 0;
03253
03254 emr.iType = EMR_POLYGON16;
03255
03256 emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
03257
03258 lpoints = new POINT16[cpts];
03259
03260 for (int i=0; i<n; i++) {
03261 lpoints[i].x = points[i].x;
03262 lpoints[i].y = points[i].y;
03263 }
03264
03265 rclBounds = *bounds;
03266 }
03273 EMRPOLYGON16 ( const RECTL* bounds, const POINT16* points, INT16 n )
03274 {
03275 cpts = n;
03276 apts[0].x = 0;
03277 apts[0].y = 0;
03278
03279 emr.iType = EMR_POLYGON16;
03280
03281 emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
03282
03283 lpoints = new POINT16[cpts];
03284
03285 for (int i=0; i<n; i++) {
03286 lpoints[i].x = points[i].x;
03287 lpoints[i].y = points[i].y;
03288 }
03289
03290 rclBounds = *bounds;
03291 }
03296 EMRPOLYGON16 ( DATASTREAM& ds )
03297 {
03298 ds >> emr >> rclBounds >> cpts;
03299
03300 lpoints = new POINT16[cpts];
03301
03302 POINT16ARRAY points( lpoints, cpts );
03303
03304 ds >> points;
03305 }
03309 ~EMRPOLYGON16 ( )
03310 {
03311 if ( lpoints ) delete[] lpoints;
03312 }
03316 bool serialize ( DATASTREAM ds )
03317 {
03318 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
03319 return true;
03320 }
03324 int size ( void ) const { return emr.nSize; }
03330 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03331 {
03332
03333 Polygon16( dc, lpoints, cpts );
03334 }
03335 #ifdef ENABLE_EDITING
03336
03339 void edit ( void ) const
03340 {
03341 printf( "*POLYGON16*\n" );
03342 edit_rectl( "rclBounds", rclBounds );
03343 edit_point16array( "\t", cpts, lpoints );
03344 }
03345 #endif
03346 };
03347
03349
03352 class EMRPOLYPOLYGON : public METARECORD, ::EMRPOLYPOLYGON {
03353 DWORD* lcounts;
03354 POINTL* lpoints;
03355 public:
03362 EMRPOLYPOLYGON ( const RECTL* bounds, const POINT* points, const INT* counts,
03363 UINT polygons )
03364 {
03365 nPolys = polygons;
03366
03367 int n = 0;
03368 for ( unsigned int i = 0; i < nPolys; i++ )
03369 n += counts[i];
03370
03371 cptl = n;
03372 aPolyCounts[0] = 0;
03373 aptl[0].x = 0;
03374 aptl[0].y = 0;
03375
03376 emr.iType = EMR_POLYPOLYGON;
03377
03378
03379 emr.nSize = sizeof( ::EMRPOLYPOLYGON ) + sizeof( POINTL ) * (cptl-1)
03380 + sizeof( DWORD ) * (nPolys-1);
03381
03382 lcounts = new DWORD[nPolys];
03383
03384 for ( unsigned int i = 0; i < nPolys; i++ )
03385 lcounts[i] = counts[i];
03386
03387 lpoints = new POINTL[cptl];
03388
03389 for (int i=0; i<n; i++) {
03390 lpoints[i].x = points[i].x;
03391 lpoints[i].y = points[i].y;
03392 }
03393
03394 rclBounds = *bounds;
03395 }
03399 ~EMRPOLYPOLYGON ( )
03400 {
03401 if ( lcounts ) delete[] lcounts;
03402 if ( lpoints ) delete[] lpoints;
03403 }
03408 EMRPOLYPOLYGON ( DATASTREAM& ds )
03409 {
03410 ds >> emr >> rclBounds >> nPolys >> cptl;
03411
03412 lcounts = new DWORD[nPolys];
03413
03414 DWORDARRAY counts( lcounts, nPolys );
03415
03416 ds >> counts;
03417
03418 lpoints = new POINTL[cptl];
03419
03420 POINTLARRAY points( lpoints, cptl );
03421
03422 ds >> points;
03423 }
03427 bool serialize ( DATASTREAM ds )
03428 {
03429 ds << emr << rclBounds << nPolys << cptl << DWORDARRAY( lcounts, nPolys )
03430 << POINTLARRAY( lpoints, cptl );
03431 return true;
03432 }
03436 int size ( void ) const { return emr.nSize; }
03442 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03443 {
03444
03445
03446 INT* counts = new INT[nPolys];
03447 for ( unsigned int i = 0; i < nPolys; i++ )
03448 counts[i] = lcounts[i];
03449
03450 PolyPolygon( dc, (POINT*)lpoints, counts, nPolys );
03451
03452 delete[] counts;
03453 }
03454 #ifdef ENABLE_EDITING
03455
03458 void edit ( void ) const
03459 {
03460 printf( "*POLYPOLYGON*\n" );
03461 edit_rectl( "rclBounds", rclBounds );
03462 printf( "\tnPolys\t\t: %ld\n", nPolys );
03463 printf( "\tcptl\t\t: %ld\n", cptl );
03464 printf( "\taPolyCounts\t: " );
03465 if ( nPolys > 0 )
03466 printf( "%ld\n", lcounts[0] );
03467 else
03468 puts( "" );
03469 for ( unsigned int i = 1; i < nPolys; i++ )
03470 printf( "\t\t\t %ld\n", lcounts[i] );
03471 printf( "\tapts\t\t: " );
03472 if ( cptl > 0 )
03473 printf( "%ld, %ld\n", lpoints[0].x, lpoints[0].y );
03474 else
03475 puts( "" );
03476 for ( unsigned int i = 1; i < cptl; i++ )
03477 printf( "\t\t\t %ld, %ld\n", lpoints[i].x, lpoints[i].y );
03478 }
03479 #endif
03480 };
03481
03483
03486 class EMRPOLYPOLYGON16 : public METARECORD, ::EMRPOLYPOLYGON16 {
03487 DWORD* lcounts;
03488 POINT16* lpoints;
03489 public:
03496 EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT* points,
03497 const INT* counts, UINT polygons )
03498 {
03499 nPolys = polygons;
03500
03501 int n = 0;
03502 for ( unsigned int i = 0; i < nPolys; i++ )
03503 n += counts[i];
03504
03505 cpts = n;
03506 aPolyCounts[0] = 0;
03507 apts[0].x = 0;
03508 apts[0].y = 0;
03509
03510 emr.iType = EMR_POLYPOLYGON16;
03511
03512
03513 emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
03514 + sizeof( DWORD ) * (nPolys-1);
03515
03516 lcounts = new DWORD[nPolys];
03517
03518 for ( unsigned int i = 0; i < nPolys; i++ )
03519 lcounts[i] = counts[i];
03520
03521 lpoints = new POINT16[cpts];
03522
03523 for (int i=0; i<n; i++) {
03524 lpoints[i].x = points[i].x;
03525 lpoints[i].y = points[i].y;
03526 }
03527
03528 rclBounds = *bounds;
03529 }
03537 EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT16* points,
03538 const INT* counts, UINT16 polygons )
03539 {
03540 nPolys = polygons;
03541
03542 int n = 0;
03543 for ( unsigned int i = 0; i < nPolys; i++ )
03544 n += counts[i];
03545
03546 cpts = n;
03547 aPolyCounts[0] = 0;
03548 apts[0].x = 0;
03549 apts[0].y = 0;
03550
03551 emr.iType = EMR_POLYPOLYGON16;
03552
03553
03554 emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
03555 + sizeof( DWORD ) * (nPolys-1);
03556
03557 lcounts = new DWORD[nPolys];
03558
03559 for ( unsigned int i = 0; i < nPolys; i++ )
03560 lcounts[i] = counts[i];
03561
03562 lpoints = new POINT16[cpts];
03563
03564 for (int i=0; i<n; i++) {
03565 lpoints[i].x = points[i].x;
03566 lpoints[i].y = points[i].y;
03567 }
03568
03569 rclBounds = *bounds;
03570 }
03574 ~EMRPOLYPOLYGON16 ( )
03575 {
03576 if ( lcounts ) delete[] lcounts;
03577 if ( lpoints ) delete[] lpoints;
03578 }
03583 EMRPOLYPOLYGON16 ( DATASTREAM& ds )
03584 {
03585 ds >> emr >> rclBounds >> nPolys >> cpts;
03586
03587 lcounts = new DWORD[nPolys];
03588
03589 DWORDARRAY counts( lcounts, nPolys );
03590
03591 ds >> counts;
03592
03593 lpoints = new POINT16[cpts];
03594
03595 POINT16ARRAY points( lpoints, cpts );
03596
03597 ds >> points;
03598 }
03602 bool serialize ( DATASTREAM ds )
03603 {
03604 ds << emr << rclBounds << nPolys << cpts << DWORDARRAY( lcounts, nPolys )
03605 << POINT16ARRAY( lpoints, cpts );
03606 return true;
03607 }
03611 int size ( void ) const { return emr.nSize; }
03617 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03618 {
03619
03620
03621 INT* counts = new INT[nPolys];
03622 for ( unsigned int i = 0; i < nPolys; i++ )
03623 counts[i] = lcounts[i];
03624
03625 PolyPolygon16( dc, lpoints, counts, nPolys );
03626
03627 delete[] counts;
03628 }
03629 #ifdef ENABLE_EDITING
03630
03633 void edit ( void ) const
03634 {
03635 printf( "*POLYPOLYGON16*\n" );
03636 edit_rectl( "rclBounds", rclBounds );
03637 printf( "\tnPolys\t\t: %ld\n", nPolys );
03638 printf( "\tcpts\t\t: %ld\n", cpts );
03639 printf( "\taPolyCounts\t: " );
03640 if ( nPolys > 0 )
03641 printf( "%ld\n", lcounts[0] );
03642 else
03643 puts( "" );
03644 for ( unsigned int i = 1; i < nPolys; i++ )
03645 printf( "\t\t\t %ld\n", lcounts[i] );
03646 printf( "\tapts\t\t: " );
03647 if ( cpts > 0 )
03648 printf( "%d, %d\n", lpoints[0].x, lpoints[0].y );
03649 else
03650 puts( "" );
03651 for ( unsigned int i = 1; i < cpts; i++ )
03652 printf( "\t\t\t %d, %d\n", lpoints[i].x, lpoints[i].y );
03653 }
03654 #endif
03655 };
03656
03658
03661 class EMRPOLYBEZIER : public METARECORD, ::EMRPOLYBEZIER {
03662 POINTL* lpoints;
03663 public:
03669 EMRPOLYBEZIER ( const RECTL* bounds, const POINT* points, INT n )
03670 {
03671 cptl = n;
03672 aptl[0].x = 0;
03673 aptl[0].y = 0;
03674
03675 emr.iType = EMR_POLYBEZIER;
03676
03677 emr.nSize = sizeof( ::EMRPOLYBEZIER ) + sizeof( POINTL ) * (cptl-1);
03678
03679 lpoints = new POINTL[cptl];
03680
03681 for (int i=0; i<n; i++) {
03682 lpoints[i].x = points[i].x;
03683 lpoints[i].y = points[i].y;
03684 }
03685
03686 rclBounds = *bounds;
03687 }
03692 EMRPOLYBEZIER ( DATASTREAM& ds )
03693 {
03694 ds >> emr >> rclBounds >> cptl;
03695
03696 lpoints = new POINTL[cptl];
03697
03698 POINTLARRAY points( lpoints, cptl );
03699
03700 ds >> points;
03701 }
03705 ~EMRPOLYBEZIER ( )
03706 {
03707 if ( lpoints ) delete[] lpoints;
03708 }
03712 bool serialize ( DATASTREAM ds )
03713 {
03714 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
03715 return true;
03716 }
03720 int size ( void ) const { return emr.nSize; }
03726 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03727 {
03728
03729 PolyBezier( dc, (POINT*)lpoints, cptl );
03730 }
03731 #ifdef ENABLE_EDITING
03732
03735 void edit ( void ) const
03736 {
03737 printf( "*POLYBEZIER*\n" );
03738 edit_rectl( "rclBounds", rclBounds );
03739 #if 0
03740 printf( "\tcptl : %ld\n", cptl );
03741 printf( "\taptl->\n" );
03742 for ( unsigned int i = 0; i < cptl; i++ )
03743 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03744 #else
03745 edit_pointlarray( "\t", cptl, lpoints );
03746 #endif
03747 }
03748 #endif
03749 };
03750
03752
03755 class EMRPOLYBEZIER16 : public METARECORD, ::EMRPOLYBEZIER16 {
03756 POINT16* lpoints;
03757 public:
03763 EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT16* points, INT n )
03764 {
03765 cpts = n;
03766 apts[0].x = 0;
03767 apts[0].y = 0;
03768
03769 emr.iType = EMR_POLYBEZIER16;
03770
03771 emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
03772
03773 lpoints = new POINT16[cpts];
03774
03775 for (int i=0; i<n; i++) {
03776 lpoints[i].x = points[i].x;
03777 lpoints[i].y = points[i].y;
03778 }
03779
03780 rclBounds = *bounds;
03781 }
03788 EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT* points, INT n )
03789 {
03790 cpts = n;
03791 apts[0].x = 0;
03792 apts[0].y = 0;
03793
03794 emr.iType = EMR_POLYBEZIER16;
03795
03796 emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
03797
03798 lpoints = new POINT16[cpts];
03799
03800 for (int i=0; i<n; i++) {
03801 lpoints[i].x = points[i].x;
03802 lpoints[i].y = points[i].y;
03803 }
03804
03805 rclBounds = *bounds;
03806 }
03811 EMRPOLYBEZIER16 ( DATASTREAM& ds )
03812 {
03813 ds >> emr >> rclBounds >> cpts;
03814
03815 lpoints = new POINT16[cpts];
03816
03817 POINT16ARRAY points( lpoints, cpts );
03818
03819 ds >> points;
03820 }
03824 ~EMRPOLYBEZIER16 ( )
03825 {
03826 if ( lpoints ) delete[] lpoints;
03827 }
03831 bool serialize ( DATASTREAM ds )
03832 {
03833 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
03834 return true;
03835 }
03839 int size ( void ) const { return emr.nSize; }
03845 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03846 {
03847
03848 PolyBezier16( dc, lpoints, cpts );
03849 }
03850 #ifdef ENABLE_EDITING
03851
03854 void edit ( void ) const
03855 {
03856 printf( "*POLYBEZIER16*\n" );
03857 edit_rectl( "rclBounds", rclBounds );
03858 edit_point16array( "\t", cpts, lpoints );
03859 }
03860 #endif
03861 };
03862
03864
03867 class EMRPOLYBEZIERTO : public METARECORD, ::EMRPOLYBEZIER {
03868 POINTL* lpoints;
03869 public:
03875 EMRPOLYBEZIERTO ( const RECTL* bounds, const POINT* points, INT n )
03876 {
03877 cptl = n;
03878 aptl[0].x = 0;
03879 aptl[0].y = 0;
03880
03881 emr.iType = EMR_POLYBEZIERTO;
03882
03883 emr.nSize = sizeof( ::EMRPOLYBEZIERTO ) + sizeof( POINTL ) * (cptl-1);
03884
03885 lpoints = new POINTL[cptl];
03886
03887 for (int i=0; i<n; i++) {
03888 lpoints[i].x = points[i].x;
03889 lpoints[i].y = points[i].y;
03890 }
03891
03892 rclBounds = *bounds;
03893 }
03898 EMRPOLYBEZIERTO ( DATASTREAM& ds )
03899 {
03900 ds >> emr >> rclBounds >> cptl;
03901
03902 lpoints = new POINTL[cptl];
03903
03904 POINTLARRAY points( lpoints, cptl );
03905
03906 ds >> points;
03907 }
03911 ~EMRPOLYBEZIERTO ( )
03912 {
03913 if ( lpoints ) delete[] lpoints;
03914 }
03918 bool serialize ( DATASTREAM ds )
03919 {
03920 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
03921 return true;
03922 }
03926 int size ( void ) const { return emr.nSize; }
03932 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03933 {
03934
03935 PolyBezierTo( dc, (POINT*)lpoints, cptl );
03936 }
03937 #ifdef ENABLE_EDITING
03938
03941 void edit ( void ) const
03942 {
03943 printf( "*POLYBEZIERTO*\n" );
03944 edit_rectl( "rclBounds", rclBounds );
03945 #if 0
03946 printf( "\tcptl : %ld\n", cptl );
03947 printf( "\taptl->\n" );
03948 for ( unsigned int i = 0; i < cptl; i++ )
03949 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03950 #else
03951 edit_pointlarray( "\t", cptl, lpoints );
03952 #endif
03953 }
03954 #endif
03955 };
03956
03958
03961 class EMRPOLYBEZIERTO16 : public METARECORD, ::EMRPOLYBEZIER16 {
03962 POINT16* lpoints;
03963 public:
03969 EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT16* points, INT n )
03970 {
03971 cpts = n;
03972 apts[0].x = 0;
03973 apts[0].y = 0;
03974
03975 emr.iType = EMR_POLYBEZIERTO16;
03976
03977 emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
03978
03979 lpoints = new POINT16[cpts];
03980
03981 for (int i=0; i<n; i++) {
03982 lpoints[i].x = points[i].x;
03983 lpoints[i].y = points[i].y;
03984 }
03985
03986 rclBounds = *bounds;
03987 }
03994 EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT* points, INT n )
03995 {
03996 cpts = n;
03997 apts[0].x = 0;
03998 apts[0].y = 0;
03999
04000 emr.iType = EMR_POLYBEZIERTO16;
04001
04002 emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
04003
04004 lpoints = new POINT16[cpts];
04005
04006 for (int i=0; i<n; i++) {
04007 lpoints[i].x = points[i].x;
04008 lpoints[i].y = points[i].y;
04009 }
04010
04011 rclBounds = *bounds;
04012 }
04017 EMRPOLYBEZIERTO16 ( DATASTREAM& ds )
04018 {
04019 ds >> emr >> rclBounds >> cpts;
04020
04021 lpoints = new POINT16[cpts];
04022
04023 POINT16ARRAY points( lpoints, cpts );
04024
04025 ds >> points;
04026 }
04030 ~EMRPOLYBEZIERTO16 ( )
04031 {
04032 if ( lpoints ) delete[] lpoints;
04033 }
04037 bool serialize ( DATASTREAM ds )
04038 {
04039 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
04040 return true;
04041 }
04045 int size ( void ) const { return emr.nSize; }
04051 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04052 {
04053
04054 PolyBezierTo16( dc, lpoints, cpts );
04055 }
04056 #ifdef ENABLE_EDITING
04057
04060 void edit ( void ) const
04061 {
04062 printf( "*POLYBEZIERTO16*\n" );
04063 edit_rectl( "rclBounds", rclBounds );
04064 edit_point16array( "\t", cpts, lpoints );
04065 }
04066 #endif
04067 };
04068
04070
04073 class EMRPOLYLINETO : public METARECORD, ::EMRPOLYLINETO {
04074 POINTL* lpoints;
04075 public:
04081 EMRPOLYLINETO ( const RECTL* bounds, const POINT* points, INT n )
04082 {
04083 cptl = n;
04084 aptl[0].x = 0;
04085 aptl[0].y = 0;
04086
04087 emr.iType = EMR_POLYLINETO;
04088
04089 emr.nSize = sizeof( ::EMRPOLYLINETO ) + sizeof( POINTL ) * (cptl-1);
04090
04091 lpoints = new POINTL[cptl];
04092
04093 for (int i=0; i<n; i++) {
04094 lpoints[i].x = points[i].x;
04095 lpoints[i].y = points[i].y;
04096 }
04097
04098 rclBounds = *bounds;
04099 }
04104 EMRPOLYLINETO ( DATASTREAM& ds )
04105 {
04106 ds >> emr >> rclBounds >> cptl;
04107
04108 lpoints = new POINTL[cptl];
04109
04110 POINTLARRAY points( lpoints, cptl );
04111
04112 ds >> points;
04113 }
04117 ~EMRPOLYLINETO ( )
04118 {
04119 if ( lpoints ) delete[] lpoints;
04120 }
04124 bool serialize ( DATASTREAM ds )
04125 {
04126 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
04127 return true;
04128 }
04132 int size ( void ) const { return emr.nSize; }
04138 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04139 {
04140
04141 PolylineTo( dc, (POINT*)lpoints, cptl );
04142 }
04143 #ifdef ENABLE_EDITING
04144
04147 void edit ( void ) const
04148 {
04149 printf( "*POLYLINETO*\n" );
04150 edit_rectl( "rclBounds", rclBounds );
04151 #if 0
04152 printf( "\tcptl : %ld\n", cptl );
04153 printf( "\taptl->\n" );
04154 for ( unsigned int i = 0; i < cptl; i++ )
04155 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
04156 #else
04157 edit_pointlarray( "\t", cptl, lpoints );
04158 #endif
04159 }
04160 #endif
04161 };
04162
04164
04167 class EMRPOLYLINETO16 : public METARECORD, ::EMRPOLYLINETO16 {
04168 POINT16* lpoints;
04169 public:
04175 EMRPOLYLINETO16 ( const RECTL* bounds, const POINT16* points, INT n )
04176 {
04177 cpts = n;
04178 apts[0].x = 0;
04179 apts[0].y = 0;
04180
04181 emr.iType = EMR_POLYLINETO16;
04182
04183 emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
04184
04185 lpoints = new POINT16[cpts];
04186
04187 for (int i=0; i<n; i++) {
04188 lpoints[i].x = points[i].x;
04189 lpoints[i].y = points[i].y;
04190 }
04191
04192 rclBounds = *bounds;
04193 }
04200 EMRPOLYLINETO16 ( const RECTL* bounds, const POINT* points, INT n )
04201 {
04202 cpts = n;
04203 apts[0].x = 0;
04204 apts[0].y = 0;
04205
04206 emr.iType = EMR_POLYLINETO16;
04207
04208 emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
04209
04210 lpoints = new POINT16[cpts];
04211
04212 for (int i=0; i<n; i++) {
04213 lpoints[i].x = points[i].x;
04214 lpoints[i].y = points[i].y;
04215 }
04216
04217 rclBounds = *bounds;
04218 }
04223 EMRPOLYLINETO16 ( DATASTREAM& ds )
04224 {
04225 ds >> emr >> rclBounds >> cpts;
04226
04227 lpoints = new POINT16[cpts];
04228
04229 POINT16ARRAY points( lpoints, cpts );
04230
04231 ds >> points;
04232 }
04236 ~EMRPOLYLINETO16 ( )
04237 {
04238 if ( lpoints ) delete[] lpoints;
04239 }
04243 bool serialize ( DATASTREAM ds )
04244 {
04245 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
04246 return true;
04247 }
04251 int size ( void ) const { return emr.nSize; }
04257 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04258 {
04259
04260 PolylineTo16( dc, lpoints, cpts );
04261 }
04262 #ifdef ENABLE_EDITING
04263
04266 void edit ( void ) const
04267 {
04268 printf( "*POLYLINETO16*\n" );
04269 edit_rectl( "rclBounds", rclBounds );
04270 edit_point16array( "\t", cpts, lpoints );
04271 }
04272 #endif
04273 };
04274
04276
04281 class EMREXTTEXTOUTA : public METARECORD, ::EMREXTTEXTOUTA {
04282 PSTR string_a;
04283 int string_size;
04284
04285 INT* dx_i;
04286 public:
04296 EMREXTTEXTOUTA ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
04297 FLOAT yScale, const PEMRTEXT text, LPCSTR string,
04298 const INT* dx )
04299 {
04300 emr.iType = EMR_EXTTEXTOUTA;
04301 emr.nSize = sizeof( ::EMREXTTEXTOUTA );
04302
04303 rclBounds = *bounds;
04304
04305 iGraphicsMode = graphicsMode;
04306 exScale = xScale;
04307 eyScale = yScale;
04308
04309 emrtext = *text;
04310
04311 string_size = ROUND_TO_LONG( emrtext.nChars );
04312
04313 string_a = new CHAR[ string_size ];
04314
04315 memset( string_a, 0, sizeof(CHAR) * string_size );
04316
04317 for ( unsigned int i=0; i<emrtext.nChars; i++ )
04318 string_a[i] = *string++;
04319
04320 emrtext.offString = emr.nSize;
04321 emr.nSize += string_size * sizeof(CHAR);
04322
04323 if ( dx ) {
04324
04325 dx_i = new INT[ emrtext.nChars ];
04326
04327 for ( unsigned int i=0; i<emrtext.nChars; i++ )
04328 dx_i[i] = *dx++;
04329
04330 emrtext.offDx = emr.nSize;
04331 emr.nSize += emrtext.nChars * sizeof(INT);
04332 }
04333 else {
04334 emrtext.offDx = 0;
04335 dx_i = 0;
04336 }
04337 }
04342 EMREXTTEXTOUTA ( DATASTREAM& ds )
04343 {
04344 ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
04345
04346 if ( emrtext.offString != 0 ) {
04347 string_size = ROUND_TO_LONG( emrtext.nChars );
04348
04349 string_a = new CHAR[ string_size ];
04350
04351 memset( string_a, 0, sizeof(CHAR) * string_size );
04352
04353 CHARSTR string( string_a, string_size );
04354
04355 ds >> string;
04356 }
04357 else
04358 string_a = 0;
04359
04360 if ( emrtext.offDx ) {
04361 dx_i = new INT[ emrtext.nChars ];
04362
04363 INTARRAY dx_is( dx_i, emrtext.nChars );
04364
04365 ds >> dx_is;
04366 }
04367 else
04368 dx_i = 0;
04369 }
04374 ~EMREXTTEXTOUTA ( )
04375 {
04376 if ( string_a ) delete[] string_a;
04377 if ( dx_i ) delete[] dx_i;
04378 }
04382 bool serialize ( DATASTREAM ds )
04383 {
04384 ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
04385 << emrtext << CHARSTR( string_a, string_size );
04386 if ( dx_i )
04387 ds << INTARRAY( dx_i, emrtext.nChars );
04388 return true;
04389 }
04393 int size ( void ) const { return emr.nSize; }
04399 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04400 {
04401 RECT rect;
04402 rect.left = emrtext.rcl.left;
04403 rect.top = emrtext.rcl.top;
04404 rect.right = emrtext.rcl.right;
04405 rect.bottom = emrtext.rcl.bottom;
04406
04407 ExtTextOutA( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
04408 emrtext.fOptions, &rect, string_a, emrtext.nChars,
04409 dx_i );
04410 }
04411 #ifdef ENABLE_EDITING
04412
04415 void edit ( void ) const
04416 {
04417 printf( "*EXTTEXTOUTA*\n" );
04418 edit_rectl( "rclBounds", rclBounds );
04419 printf( "\tiGraphicsMode\t: " );
04420 switch ( iGraphicsMode ) {
04421 case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
04422 case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
04423 default: printf( "unknown(%ld)\n", iGraphicsMode );
04424 }
04425 printf( "\texScale\t\t: %f\n", exScale );
04426 printf( "\teyScale\t\t: %f\n", eyScale );
04427 printf( "\tptlReference\t: (%ld,%ld)\n", emrtext.ptlReference.x,
04428 emrtext.ptlReference.y );
04429 printf( "\tnChars\t\t: %ld\n", emrtext.nChars );
04430 printf( "\toffString\t: %ld\n", emrtext.offString );
04431 printf( "\tfOptions\t: " );
04432 if ( emrtext.fOptions == 0 )
04433 printf( "None" );
04434 else {
04435 if ( emrtext.fOptions & ETO_GRAYED ) {
04436 printf( "ETO_GRAYED" );
04437 if ( emrtext.fOptions & ~ETO_GRAYED )
04438 printf( " | " );
04439 }
04440 if ( emrtext.fOptions & ETO_OPAQUE ) {
04441 printf( "ETO_OPAQUE" );
04442 if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
04443 printf( " | " );
04444 }
04445 if ( emrtext.fOptions & ETO_CLIPPED ) {
04446 printf( "ETO_CLIPPED" );
04447 if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
04448 printf( " | " );
04449 }
04450 if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
04451 printf( "ETO_GLYPH_INDEX" );
04452 if ( emrtext.fOptions &
04453 ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
04454 printf( " | " );
04455 }
04456 if ( emrtext.fOptions & ETO_RTLREADING ) {
04457 printf( "ETO_RTLREADING" );
04458 if ( emrtext.fOptions &
04459 ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
04460 ETO_RTLREADING) )
04461 printf( " | " );
04462 }
04463 if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
04464 printf( "ETO_IGNORELANGUAGE" );
04465 }
04466 printf( "\n" );
04467 edit_rectl( "rcl\t", emrtext.rcl );
04468 printf( "\toffDx\t\t: %ld\n", emrtext.offDx );
04469 printf( "\tString:\n\t\t%s\n", string_a );
04470
04471 if ( emrtext.offDx != 0 ) {
04472 printf( "\tOffsets:\n\t\t" );
04473 for ( unsigned int i = 0; i < emrtext.nChars; i++ )
04474 printf( "%d ", dx_i[i] );
04475 printf( "\n" );
04476 }
04477 }
04478 #endif
04479 };
04480
04482
04485 class EMRSETPIXELV : public METARECORD, ::EMRSETPIXELV {
04486 public:
04492 EMRSETPIXELV ( INT x, INT y, COLORREF color )
04493 {
04494 emr.iType = EMR_SETPIXELV;
04495 emr.nSize = sizeof( ::EMRSETPIXELV );
04496 ptlPixel.x = x;
04497 ptlPixel.y = y;
04498 crColor = color;
04499 }
04504 EMRSETPIXELV ( DATASTREAM& ds )
04505 {
04506 ds >> emr >> ptlPixel >> crColor;
04507 }
04511 bool serialize ( DATASTREAM ds )
04512 {
04513 ds << emr << ptlPixel << crColor;
04514 return true;
04515 }
04519 int size ( void ) const { return emr.nSize; }
04525 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04526 {
04527 SetPixel( dc, ptlPixel.x, ptlPixel.y, crColor );
04528 }
04529 #ifdef ENABLE_EDITING
04530
04533 void edit ( void ) const
04534 {
04535 printf( "*SETPIXELV*\n" );
04536 edit_pointl( "ptlPixel", ptlPixel );
04537 edit_color( "crColor\t", crColor );
04538 }
04539 #endif
04540 };
04541
04542 class PEN;
04543 class EXTPEN;
04544 class BRUSH;
04545 class FONT;
04546 class PALETTE;
04547
04549
04552 class EMRCREATEPEN : public METARECORD, public ::EMRCREATEPEN
04553 {
04554 public:
04559 EMRCREATEPEN ( PEN* pen, HGDIOBJ handle );
04564 EMRCREATEPEN ( DATASTREAM& ds );
04568 bool serialize ( DATASTREAM ds )
04569 {
04570 ds << emr << ihPen << lopn;
04571 return true;
04572 }
04576 int size ( void ) const { return emr.nSize; }
04582 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04583 #ifdef ENABLE_EDITING
04584
04587 void edit ( void ) const
04588 {
04589 printf( "*CREATEPEN*\n" );
04590 printf( "\tihPen\t\t: 0x%lx\n", ihPen );
04591 edit_pen_style( "lopn.lopnStyle", lopn.lopnStyle );
04592 printf( "\tlopn.lopnWidth\t: %ld, %ld\n", lopn.lopnWidth.x, lopn.lopnWidth.y );
04593 edit_color( "lopn.lopnColor", lopn.lopnColor );
04594 }
04595 #endif
04596 };
04597
04599
04603 class EMREXTCREATEPEN : public METARECORD, public ::EMREXTCREATEPEN
04604 {
04605 public:
04610 EMREXTCREATEPEN ( EXTPEN* pen, HGDIOBJ handle );
04615 EMREXTCREATEPEN ( DATASTREAM& ds );
04619 bool serialize ( DATASTREAM ds )
04620 {
04621 ds << emr << ihPen << offBmi << cbBmi << offBits << cbBits << elp;
04622 return true;
04623 }
04627 int size ( void ) const { return emr.nSize; }
04633 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04634 #ifdef ENABLE_EDITING
04635
04638 void edit ( void ) const
04639 {
04640 printf( "*EXTCREATEPEN*\n" );
04641 printf( "\tihPen\t\t\t: 0x%lx\n", ihPen );
04642 printf( "\toffBmi\t\t\t: %ld\n", offBmi );
04643 printf( "\tcbBmi\t\t\t: %ld\n", cbBmi );
04644 printf( "\toffBits\t\t\t: %ld\n", offBits );
04645 printf( "\tcbBits\t\t\t: %ld\n", cbBits );
04646 edit_pen_style( "elp.elpPenStyle\t", elp.elpPenStyle );
04647 printf( "\telp.elpWidth\t\t: %ld\n", elp.elpWidth );
04648 edit_brush_style( "elp.elpBrushStyle", elp.elpBrushStyle );
04649 edit_color( "elp.elpColor\t", elp.elpColor );
04650 edit_brush_hatch( "elp.elpHatch\t", elp.elpHatch );
04651 printf( "\telp.elpNumEntries\t: %ld\n", elp.elpNumEntries );
04652 }
04653 #endif
04654 };
04655
04657
04660 class EMRCREATEBRUSHINDIRECT : public METARECORD, public ::EMRCREATEBRUSHINDIRECT
04661 {
04662 public:
04667 EMRCREATEBRUSHINDIRECT ( BRUSH* brush, HGDIOBJ handle );
04672 EMRCREATEBRUSHINDIRECT ( DATASTREAM& ds );
04676 bool serialize ( DATASTREAM ds )
04677 {
04678 ds << emr << ihBrush << lb;
04679 return true;
04680 }
04684 int size ( void ) const { return emr.nSize; }
04690 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04691 #ifdef ENABLE_EDITING
04692
04695 void edit ( void ) const
04696 {
04697 printf( "*CREATEBRUSHINDIRECT*\n" );
04698 printf( "\tihBrush\t\t: 0x%lx\n", ihBrush );
04699 edit_brush_style( "lb.lbStyle", lb.lbStyle );
04700 edit_color( "lb.lbColor", lb.lbColor );
04701 edit_brush_hatch( "lb.lbHatch", lb.lbHatch );
04702 }
04703 #endif
04704 };
04705
04707
04710 class EMREXTCREATEFONTINDIRECTW : public METARECORD, public ::EMREXTCREATEFONTINDIRECTW
04711 {
04712 public:
04717 EMREXTCREATEFONTINDIRECTW ( FONT* font, HGDIOBJ handle );
04722 EMREXTCREATEFONTINDIRECTW ( DATASTREAM& ds );
04726 bool serialize ( DATASTREAM ds )
04727 {
04728
04729
04730
04731
04732 ds << emr << ihFont << elfw << PADDING( 2 );
04733
04734 return true;
04735 }
04739 int size ( void ) const { return emr.nSize; }
04745 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04746 #ifdef ENABLE_EDITING
04747
04750 void edit ( void ) const
04751 {
04752 printf( "*EXTCREATEFONTINDIRECTW*\n" );
04753 printf( "\tihFont\t\t\t: %ld\n", ihFont );
04754 printf( "\tlfHeight\t\t: %ld\n", elfw.elfLogFont.lfHeight );
04755 printf( "\tlfWidth\t\t\t: %ld\n", elfw.elfLogFont.lfWidth );
04756 printf( "\tlfEscapement\t\t: %ld\n", elfw.elfLogFont.lfEscapement );
04757 printf( "\tlfOrientation\t\t: %ld\n", elfw.elfLogFont.lfOrientation );
04758 printf( "\tlfWeight\t\t: " );
04759 switch ( elfw.elfLogFont.lfWeight ) {
04760 case FW_DONTCARE: printf( "FW_DONTCARE\n" ); break;
04761 case FW_THIN: printf( "FW_THIN\n" ); break;
04762 case FW_EXTRALIGHT: printf( "FW_EXTRALIGHT\n" ); break;
04763 case FW_LIGHT: printf( "FW_LIGHT\n" ); break;
04764 case FW_NORMAL: printf( "FW_NORMAL\n" ); break;
04765 case FW_MEDIUM: printf( "FW_MEDIUM\n" ); break;
04766 case FW_SEMIBOLD: printf( "FW_SEMIBOLD\n" ); break;
04767 case FW_BOLD: printf( "FW_BOLD\n" ); break;
04768 case FW_EXTRABOLD: printf( "FW_EXTRABOLD\n" ); break;
04769 case FW_BLACK: printf( "FW_BLACK\n" ); break;
04770 }
04771 printf( "\tlfItalic\t\t: %d\n", elfw.elfLogFont.lfItalic );
04772 printf( "\tlfUnderline\t\t: %d\n", elfw.elfLogFont.lfUnderline );
04773 printf( "\tlfStrikeOut\t\t: %d\n", elfw.elfLogFont.lfStrikeOut );
04774 printf( "\tlfCharSet\t\t: %d\n", elfw.elfLogFont.lfCharSet );
04775 printf( "\tlfOutPrecision\t\t: %d\n", elfw.elfLogFont.lfOutPrecision );
04776 printf( "\tlfClipPrecision\t\t: %d\n", elfw.elfLogFont.lfClipPrecision );
04777 printf( "\tlfQuality\t\t: %d\n", elfw.elfLogFont.lfQuality );
04778 printf( "\tlfPitchAndFamily\t: %d\n", elfw.elfLogFont.lfPitchAndFamily );
04779 int i = 0;
04780 printf( "\tlfFaceName\t\t: '" );
04781 while ( elfw.elfLogFont.lfFaceName[i] != 0 && i < LF_FACESIZE ) {
04782 putchar( elfw.elfLogFont.lfFaceName[i] );
04783 i++;
04784 }
04785 puts( "'" );
04786
04787 i = 0;
04788 printf( "\telfFullName\t\t: '" );
04789 while ( elfw.elfFullName[i] != 0 && i < LF_FULLFACESIZE ) {
04790 putchar( elfw.elfFullName[i] );
04791 i++;
04792 }
04793 puts( "'" );
04794
04795 i = 0;
04796 printf( "\telfStyle\t\t: '" );
04797 while ( elfw.elfStyle[i] != 0 && i < LF_FACESIZE ) {
04798 putchar( elfw.elfStyle[i] );
04799 i++;
04800 }
04801 puts( "'" );
04802
04803 printf( "\telfVersion\t\t: %ld\n", elfw.elfVersion );
04804 printf( "\telfStyleSize\t\t: %ld\n", elfw.elfStyleSize );
04805 printf( "\telfMatch\t\t: %ld\n", elfw.elfMatch );
04806 printf( "\telfVendorId\t\t: '%s'\n", elfw.elfVendorId );
04807 printf( "\telfCulture\t\t: %ld\n", elfw.elfCulture );
04808 printf( "\telfPanose\t\t:\n" );
04809 printf( "\t\tbFamilyType\t\t: %d\n", elfw.elfPanose.bFamilyType );
04810 printf( "\t\tbSerifStyle\t\t: %d\n", elfw.elfPanose.bSerifStyle );
04811 printf( "\t\tbWeight\t\t\t: %d\n", elfw.elfPanose.bWeight );
04812 printf( "\t\tbProportion\t\t: %d\n", elfw.elfPanose.bProportion );
04813 printf( "\t\tbContrast\t\t: %d\n", elfw.elfPanose.bContrast );
04814 printf( "\t\tbStrokeVariation\t: %d\n", elfw.elfPanose.bStrokeVariation );
04815 printf( "\t\tbArmStyle\t\t: %d\n", elfw.elfPanose.bArmStyle );
04816 printf( "\t\tbLetterform\t\t: %d\n", elfw.elfPanose.bLetterform );
04817 printf( "\t\tbMidline\t\t: %d\n", elfw.elfPanose.bMidline );
04818 printf( "\t\tbXHeight\t\t: %d\n", elfw.elfPanose.bXHeight );
04819 }
04820 #endif
04821 };
04822
04824
04827 class EMRCREATEPALETTE : public METARECORD, public ::EMRCREATEPALETTE
04828 {
04829 public:
04834 EMRCREATEPALETTE ( PALETTE* palette, HGDIOBJ handle );
04839 EMRCREATEPALETTE ( DATASTREAM& ds );
04843 bool serialize ( DATASTREAM ds )
04844 {
04845 ds << emr << ihPal << lgpl;
04846 return true;
04847 }
04851 int size ( void ) const { return emr.nSize; }
04857 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04858 #ifdef ENABLE_EDITING
04859
04862 void edit ( void ) const
04863 {
04864 printf( "*CREATEPALETTE* (not really handled by libEMF)\n" );
04865 }
04866 #endif
04867 };
04868
04870
04873 class EMRFILLPATH : public METARECORD, ::EMRFILLPATH {
04874 public:
04879 EMRFILLPATH ( const RECTL* bounds )
04880 {
04881 emr.iType = EMR_FILLPATH;
04882 emr.nSize = sizeof( ::EMRFILLPATH );
04883 rclBounds = *bounds;
04884 }
04889 EMRFILLPATH ( DATASTREAM& ds )
04890 {
04891 ds >> emr >> rclBounds;
04892 }
04896 bool serialize ( DATASTREAM ds )
04897 {
04898 ds << emr << rclBounds;
04899 return true;
04900 }
04904 int size ( void ) const { return emr.nSize; }
04910 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04911 {
04912 FillPath( dc );
04913 }
04914 #ifdef ENABLE_EDITING
04915
04918 void edit ( void ) const
04919 {
04920 printf( "*FILLPATH*\n" );
04921 edit_rectl( "rclBounds", rclBounds );
04922 }
04923 #endif
04924 };
04926
04929 class EMRSTROKEPATH : public METARECORD, ::EMRSTROKEPATH {
04930 public:
04935 EMRSTROKEPATH ( const RECTL* bounds )
04936 {
04937 emr.iType = EMR_STROKEPATH;
04938 emr.nSize = sizeof( ::EMRSTROKEPATH );
04939 rclBounds = *bounds;
04940 }
04945 EMRSTROKEPATH ( DATASTREAM& ds )
04946 {
04947 ds >> emr >> rclBounds;
04948 }
04952 bool serialize ( DATASTREAM ds )
04953 {
04954 ds << emr << rclBounds;
04955 return true;
04956 }
04960 int size ( void ) const { return emr.nSize; }
04966 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04967 {
04968 StrokePath( dc );
04969 }
04970 #ifdef ENABLE_EDITING
04971
04974 void edit ( void ) const
04975 {
04976 printf( "*STROKEPATH*\n" );
04977 edit_rectl( "rclBounds", rclBounds );
04978 }
04979 #endif
04980 };
04982
04985 class EMRSTROKEANDFILLPATH : public METARECORD, ::EMRSTROKEANDFILLPATH {
04986 public:
04991 EMRSTROKEANDFILLPATH ( const RECTL* bounds )
04992 {
04993 emr.iType = EMR_STROKEANDFILLPATH;
04994 emr.nSize = sizeof( ::EMRSTROKEANDFILLPATH );
04995 rclBounds = *bounds;
04996 }
05001 EMRSTROKEANDFILLPATH ( DATASTREAM& ds )
05002 {
05003 ds >> emr >> rclBounds;
05004 }
05008 bool serialize ( DATASTREAM ds )
05009 {
05010 ds << emr << rclBounds;
05011 return true;
05012 }
05016 int size ( void ) const { return emr.nSize; }
05022 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05023 {
05024 StrokeAndFillPath( dc );
05025 }
05026 #ifdef ENABLE_EDITING
05027
05030 void edit ( void ) const
05031 {
05032 printf( "*STROKEANDFILLPATH*\n" );
05033 edit_rectl( "rclBounds", rclBounds );
05034 }
05035 #endif
05036 };
05038
05041 class EMRBEGINPATH : public METARECORD, ::EMRBEGINPATH {
05042 public:
05046 EMRBEGINPATH ( void )
05047 {
05048 emr.iType = EMR_BEGINPATH;
05049 emr.nSize = sizeof( ::EMRBEGINPATH );
05050 }
05055 EMRBEGINPATH ( DATASTREAM& ds )
05056 {
05057 ds >> emr;
05058 }
05062 bool serialize ( DATASTREAM ds )
05063 {
05064 ds << emr;
05065 return true;
05066 }
05070 int size ( void ) const { return emr.nSize; }
05076 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05077 {
05078 BeginPath( dc );
05079 }
05080 #ifdef ENABLE_EDITING
05081
05084 void edit ( void ) const
05085 {
05086 printf( "*BEGINPATH*\n" );
05087 }
05088 #endif
05089 };
05091
05094 class EMRENDPATH : public METARECORD, ::EMRENDPATH {
05095 public:
05099 EMRENDPATH ( void )
05100 {
05101 emr.iType = EMR_ENDPATH;
05102 emr.nSize = sizeof( ::EMRENDPATH );
05103 }
05108 EMRENDPATH ( DATASTREAM& ds )
05109 {
05110 ds >> emr;
05111 }
05115 bool serialize ( DATASTREAM ds )
05116 {
05117 ds << emr;
05118 return true;
05119 }
05123 int size ( void ) const { return emr.nSize; }
05129 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05130 {
05131 EndPath( dc );
05132 }
05133 #ifdef ENABLE_EDITING
05134
05137 void edit ( void ) const
05138 {
05139 printf( "*ENDPATH*\n" );
05140 }
05141 #endif
05142 };
05144
05147 class EMRCLOSEFIGURE : public METARECORD, ::EMRCLOSEFIGURE {
05148 public:
05152 EMRCLOSEFIGURE ( void )
05153 {
05154 emr.iType = EMR_CLOSEFIGURE;
05155 emr.nSize = sizeof( ::EMRCLOSEFIGURE );
05156 }
05161 EMRCLOSEFIGURE ( DATASTREAM& ds )
05162 {
05163 ds >> emr;
05164 }
05168 bool serialize ( DATASTREAM ds )
05169 {
05170 ds << emr;
05171 return true;
05172 }
05176 int size ( void ) const { return emr.nSize; }
05182 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05183 {
05184 CloseFigure( dc );
05185 }
05186 #ifdef ENABLE_EDITING
05187
05190 void edit ( void ) const
05191 {
05192 printf( "*CLOSEFIGURE*\n" );
05193 }
05194 #endif
05195 };
05197
05201 class EMRSAVEDC : public METARECORD, ::EMRSAVEDC {
05202 public:
05206 EMRSAVEDC ( void )
05207 {
05208 emr.iType = EMR_SAVEDC;
05209 emr.nSize = sizeof( ::EMRSAVEDC );
05210 }
05215 EMRSAVEDC ( DATASTREAM& ds )
05216 {
05217 ds >> emr;
05218 }
05222 bool serialize ( DATASTREAM ds )
05223 {
05224 ds << emr;
05225 return true;
05226 }
05230 int size ( void ) const { return emr.nSize; }
05236 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05237 {
05238 SaveDC( dc );
05239 }
05240 #ifdef ENABLE_EDITING
05241
05244 void edit ( void ) const
05245 {
05246 printf( "*SAVEDC*\n" );
05247 }
05248 #endif
05249 };
05251
05254 class EMRRESTOREDC : public METARECORD, ::EMRRESTOREDC {
05255 public:
05259 EMRRESTOREDC ( INT n )
05260 {
05261 emr.iType = EMR_RESTOREDC;
05262 emr.nSize = sizeof( ::EMRRESTOREDC );
05263 iRelative = n;
05264 }
05269 EMRRESTOREDC ( DATASTREAM& ds )
05270 {
05271 ds >> emr >> iRelative;
05272 }
05276 bool serialize ( DATASTREAM ds )
05277 {
05278 ds << emr << iRelative;
05279 return true;
05280 }
05284 int size ( void ) const { return emr.nSize; }
05290 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05291 {
05292 RestoreDC( dc, iRelative );
05293 }
05294 #ifdef ENABLE_EDITING
05295
05298 void edit ( void ) const
05299 {
05300 printf( "*RESTOREDC*\n" );
05301 printf( "\tiRelative: %ld\n", iRelative );
05302 }
05303 #endif
05304 };
05306
05309 class EMRSETMETARGN : public METARECORD, ::EMRSETMETARGN {
05310 public:
05314 EMRSETMETARGN ( void )
05315 {
05316 emr.iType = EMR_SETMETARGN;
05317 emr.nSize = sizeof( ::EMRSETMETARGN );
05318 }
05323 EMRSETMETARGN ( DATASTREAM& ds )
05324 {
05325 ds >> emr;
05326 }
05330 bool serialize ( DATASTREAM ds )
05331 {
05332 ds << emr;
05333 return true;
05334 }
05338 int size ( void ) const { return emr.nSize; }
05344 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05345 {
05346 SetMetaRgn( dc );
05347 }
05348 #ifdef ENABLE_EDITING
05349
05352 void edit ( void ) const
05353 {
05354 printf( "*SETMETARGN*\n" );
05355 }
05356 #endif
05357 };
05358
05360
05363 class PEN : public GRAPHICSOBJECT, public LOGPEN {
05364 public:
05368 PEN ( const LOGPEN* lpen )
05369 {
05370 lopnStyle = lpen->lopnStyle;
05371 lopnWidth = lpen->lopnWidth;
05372 lopnColor = lpen->lopnColor;
05373 }
05377 OBJECTTYPE getType ( void ) const { return O_PEN; }
05384 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05385 {
05386 contexts[dc] = emf_handle;
05387 return new EMRCREATEPEN( this, emf_handle );
05388 }
05389 };
05390
05392
05395 class EXTPEN : public GRAPHICSOBJECT, public EXTLOGPEN {
05396 public:
05400 EXTPEN ( const EXTLOGPEN* lpen )
05401 {
05402 elpPenStyle = lpen->elpPenStyle;
05403 elpWidth = lpen->elpWidth;
05404 elpBrushStyle = lpen->elpBrushStyle;
05405 elpColor = lpen->elpColor;
05406 elpHatch = lpen->elpHatch;
05407 elpNumEntries = 0;
05408 elpStyleEntry[0] = 0;
05409 }
05413 OBJECTTYPE getType ( void ) const { return O_EXTPEN; }
05420 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05421 {
05422 contexts[dc] = emf_handle;
05423 return new EMREXTCREATEPEN( this, emf_handle );
05424 }
05425 };
05426
05428
05431 class BRUSH : public GRAPHICSOBJECT, public LOGBRUSH {
05432 public:
05436 BRUSH ( const LOGBRUSH* lbrush )
05437 {
05438 lbStyle = lbrush->lbStyle;
05439 lbColor = lbrush->lbColor;
05440 lbHatch = lbrush->lbHatch;
05441 }
05445 OBJECTTYPE getType ( void ) const { return O_BRUSH; }
05452 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05453 {
05454 contexts[dc] = emf_handle;
05455 return new EMRCREATEBRUSHINDIRECT( this, emf_handle );
05456 }
05457 };
05458
05460
05463 class FONT : public GRAPHICSOBJECT, public EXTLOGFONTW {
05464 public:
05468 FONT ( const LOGFONTW* lfont )
05469 {
05470 this->elfLogFont = *lfont;
05471
05472
05473 memset( &elfFullName, 0, sizeof elfFullName );
05474 memset( &elfStyle, 0, sizeof elfStyle );
05475 elfVersion = ELF_VERSION;
05476 elfStyleSize = 0;
05477 elfMatch = 0;
05478 elfReserved = 0;
05479 memset( &elfVendorId, 0, sizeof elfVendorId );
05480 elfCulture = ELF_CULTURE_LATIN;
05481 memset( &elfPanose, 1, sizeof(PANOSE) );
05482 }
05486 OBJECTTYPE getType ( void ) const { return O_FONT; }
05493 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05494 {
05495 contexts[dc] = emf_handle;
05496 return new EMREXTCREATEFONTINDIRECTW( this, emf_handle );
05497 }
05498 };
05499
05501
05504 class PALETTE : public GRAPHICSOBJECT, public LOGPALETTE {
05505 public:
05509 PALETTE ( const LOGPALETTE* lpalette )
05510 {
05511 (void)lpalette;
05512 palVersion = 0;
05513 palNumEntries = 0;
05514 PALETTEENTRY zero_entry = { 0, 0, 0, 0 };
05515 palPalEntry[0] = zero_entry;
05516 }
05520 OBJECTTYPE getType ( void ) const { return O_PALETTE; }
05527 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05528 {
05529 contexts[dc] = emf_handle;
05530 return new EMRCREATEPALETTE( this, emf_handle );
05531 }
05532 };
05533
05535
05541 class METAFILEDEVICECONTEXT : public OBJECT {
05549 void init ( const RECT* size, LPCWSTR description_w ) {
05550
05551
05552
05553
05554 handles.push_back( true );
05555
05556
05557
05558 header = new ENHMETAHEADER ( description_w );
05559 records.push_back( header );
05560
05561
05562
05563 if ( size ) {
05564 update_frame = false;
05565
05566 header->rclFrame.left = size->left;
05567 header->rclFrame.top = size->top;
05568 header->rclFrame.right = size->right;
05569 header->rclFrame.bottom = size->bottom;
05570
05571 header->rclBounds.left =
05572 size->left * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
05573 header->rclBounds.top =
05574 size->top * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
05575 header->rclBounds.right =
05576 size->right * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
05577 header->rclBounds.bottom =
05578 size->bottom * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
05579 }
05580 else {
05581 update_frame = true;
05582
05583 header->rclBounds.left = -10;
05584 header->rclBounds.top = -10;
05585 header->rclBounds.right = 10;
05586 header->rclBounds.bottom = 10;
05587
05588 header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
05589 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05590 header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
05591 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05592 header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
05593 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05594 header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
05595 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05596 }
05597
05598
05599
05600 SIZEL default_resolution = { RESOLUTION, RESOLUTION };
05601 resolution = default_resolution;
05602 SIZEL default_viewport_ext = { 1, 1 };
05603 viewport_ext = default_viewport_ext;
05604 POINT default_viewport_org = { 0, 0 };
05605 viewport_org = default_viewport_org;
05606 SIZEL default_window_ext = { 1, 1 };
05607 window_ext = default_window_ext;
05608 POINT default_window_org = { 0, 0 };
05609 window_org = default_window_org;
05610
05611 min_device_point = viewport_org;
05612 max_device_point = viewport_org;
05613
05614 pen = (PEN*)globalObjects.find( BLACK_PEN | ENHMETA_STOCK_OBJECT );
05615 brush = (BRUSH*)globalObjects.find( BLACK_BRUSH | ENHMETA_STOCK_OBJECT );
05616 font = (FONT*)globalObjects.find( DEVICE_DEFAULT_FONT | ENHMETA_STOCK_OBJECT);
05617 palette = (PALETTE*)globalObjects.find( DEFAULT_PALETTE|ENHMETA_STOCK_OBJECT);
05618
05619 text_alignment = TA_BASELINE;
05620 text_color = RGB(0,0,0);
05621 bk_color = RGB(0xff,0xff,0xff);
05622 bk_mode = OPAQUE;
05623 polyfill_mode = ALTERNATE;
05624 map_mode = MM_TEXT;
05625
05626 handle = globalObjects.add( this );
05627 }
05628
05629 public:
05633 ::FILE* fp;
05638 DATASTREAM ds;
05642 ENHMETAHEADER* header;
05646 std::vector< EMF::METARECORD* > records;
05647
05648
05649 SIZEL resolution;
05650 SIZEL viewport_ext;
05651 POINT viewport_org;
05652 SIZEL window_ext;
05653 POINT window_org;
05654 bool update_frame;
05655 POINT min_device_point;
05656 POINT max_device_point;
05657 POINT point;
05658 PEN* pen;
05659 BRUSH* brush;
05660 FONT* font;
05661 PALETTE* palette;
05662 UINT text_alignment;
05663 COLORREF text_color;
05664 COLORREF bk_color;
05665 INT bk_mode;
05666 INT polyfill_mode;
05667 INT map_mode;
05668
05674 std::vector< bool > handles;
05675
05681 std::map< HGDIOBJ, HGDIOBJ > emf_handles;
05682
05693 METAFILEDEVICECONTEXT ( FILE* fp_, const RECT* size,
05694 LPCWSTR description_w )
05695 : fp(fp_), ds( fp_ )
05696 {
05697 init( size, description_w );
05698 }
05703 virtual ~METAFILEDEVICECONTEXT ( )
05704 {
05705
05706
05707 if ( records.size() > 0 )
05708 deleteMetafile();
05709 }
05713 OBJECTTYPE getType ( void ) const { return O_METAFILEDEVICECONTEXT; }
05718 DWORD nextHandle ( void )
05719 {
05720 for ( unsigned int i = 1; i < handles.size(); i++ ) {
05721 if ( !handles[i] ) {
05722 handles[i] = true;
05723 return i;
05724 }
05725 }
05726 handles.push_back( true );
05727
05728
05729 header->nHandles = handles.size();
05730 return handles.size()-1;
05731 }
05735 void clearHandle ( DWORD handle )
05736 {
05737 handles[handle] = false;
05738 }
05744 void appendRecord ( METARECORD* record )
05745 {
05746 records.push_back( record );
05747
05748 header->nBytes += record->size();
05749 header->nRecords++;
05750 }
05756 void appendHandle ( METARECORD* record )
05757 {
05758 records.push_back( record );
05759
05760 header->nBytes += record->size();
05761 header->nRecords++;
05762 }
05767 void deleteMetafile ( void )
05768 {
05769 for ( std::vector<METARECORD*>::const_iterator r = records.begin();
05770 r != records.end();
05771 r++ ) {
05772 delete *r;
05773 }
05774 records.clear();
05775 }
05780 void mergePoint ( const LONG& x, const LONG& y )
05781 {
05782 POINT p;
05783 p.x = x;
05784 p.y = y;
05785 mergePoint( p );
05786 }
05791 void mergePoint( const POINT& p )
05792 {
05793 POINT device_point;
05794
05795
05796
05797
05798 device_point.x = (LONG)( (float)( p.x - window_org.x ) / window_ext.cx *
05799 viewport_ext.cx + viewport_org.x );
05800
05801 device_point.y = (LONG)( (float)( p.y - window_org.y ) / window_ext.cy *
05802 viewport_ext.cy + viewport_org.y );
05803
05804
05805
05806 if ( device_point.x < min_device_point.x ) {
05807 min_device_point.x = device_point.x;
05808 if ( update_frame ) {
05809 header->rclBounds.left = min_device_point.x - 10;
05810 header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
05811 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05812 }
05813 }
05814 else if ( device_point.x > max_device_point.x ) {
05815 max_device_point.x = device_point.x;
05816 if ( update_frame ) {
05817 header->rclBounds.right = max_device_point.x + 10;
05818 header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
05819 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05820 }
05821 }
05822
05823 if ( device_point.y < min_device_point.y ) {
05824 min_device_point.y = device_point.y;
05825 if ( update_frame ) {
05826 header->rclBounds.top = min_device_point.y - 10;
05827 header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
05828 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05829 }
05830 }
05831 else if ( device_point.y > max_device_point.y ) {
05832 max_device_point.y = device_point.y;
05833 if ( update_frame ) {
05834 header->rclBounds.bottom = max_device_point.y + 10;
05835 header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
05836 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05837 }
05838 }
05839 }
05840 };
05841
05842 }
05843
05844 #endif