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 <emf.h>
00032
00033 #include <wine/w16.h>
00034
00035 namespace EMF {
00040 const int XMAX_PIXELS = 1024;
00045 const int YMAX_PIXELS = 768;
00051 const int XMAX_MM = 320;
00057 const int YMAX_MM = 240;
00061 const int RESOLUTION = 96;
00065 static inline int ROUND_TO_LONG ( int n ) { return ((n+3)/4)*4; }
00066
00068
00073 struct WCHARSTR {
00074 WCHAR *const string_;
00075 const int length_;
00076
00081 WCHARSTR ( WCHAR *const string, const int length )
00082 : string_( string ), length_( length ) {}
00083 };
00084
00086
00091 struct CHARSTR {
00092 CHAR *const string_;
00093 const int length_;
00094
00099 CHARSTR ( CHAR *const string, const int length )
00100 : string_( string ), length_( length ) {}
00101 };
00102
00104
00108 struct BYTEARRAY {
00109 BYTE *const array_;
00110 const int n_;
00111
00116 BYTEARRAY ( BYTE *const array, const int n )
00117 : array_( array ), n_( n ) {}
00118 };
00119
00121
00124 struct POINTLARRAY {
00125 POINTL *const points_;
00126 const DWORD n_;
00127
00132 POINTLARRAY ( POINTL *const points, const DWORD n )
00133 : points_( points ), n_( n ) {}
00134 };
00135
00137
00140 struct POINT16ARRAY {
00141 POINT16 *const points_;
00142 const DWORD n_;
00143
00148 POINT16ARRAY ( POINT16 *const points, const DWORD n )
00149 : points_( points ), n_( n ) {}
00150 };
00151
00153
00156 struct INTARRAY {
00157 INT *const ints_;
00158 const DWORD n_;
00159
00164 INTARRAY ( INT *const ints, const DWORD n )
00165 : ints_( ints ), n_( n ) {}
00166 };
00167
00169
00172 struct DWORDARRAY {
00173 DWORD *const dwords_;
00174 const DWORD n_;
00175
00180 DWORDARRAY ( DWORD *const dwords, const DWORD n )
00181 : dwords_( dwords ), n_( n ) {}
00182 };
00183
00185
00188 struct PADDING {
00189 static const char padding_[4];
00190 const int size_;
00191
00195 PADDING ( const int size ) : size_( size ) {}
00196 };
00197
00199
00206 class DATASTREAM {
00207 bool swap_;
00208 ::FILE* fp_;
00209
00210 static bool bigEndian ( void );
00211 public:
00217 DATASTREAM ( ::FILE* fp = 0 ) : swap_( bigEndian() ), fp_( fp ) {}
00222 void setStream ( ::FILE* fp ) { fp_ = fp; }
00227 DATASTREAM& operator<< ( const BYTE& byte )
00228 {
00229 fwrite( &byte, sizeof(BYTE), 1, fp_ );
00230 return *this;
00231 }
00236 DATASTREAM& operator>> ( BYTE& byte )
00237 {
00238 fread( &byte, sizeof(BYTE), 1, fp_ );
00239 return *this;
00240 }
00245 DATASTREAM& operator<< ( const WORD& word )
00246 {
00247 if ( swap_ ) {
00248 unsigned char const * p = (unsigned char const*)&word;
00249 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00250 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00251 }
00252 else
00253 fwrite( &word, sizeof(WORD), 1, fp_ );
00254 return *this;
00255 }
00260 DATASTREAM& operator>> ( WORD& word )
00261 {
00262 if ( swap_ ) {
00263 unsigned char* p = (unsigned char*)&word;
00264 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00265 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00266 }
00267 else
00268 fread( &word, sizeof(WORD), 1, fp_ );
00269 return *this;
00270 }
00275 DATASTREAM& operator<< ( const INT16& word )
00276 {
00277 if ( swap_ ) {
00278 unsigned char const * p = (unsigned char const*)&word;
00279 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00280 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00281 }
00282 else
00283 fwrite( &word, sizeof(INT16), 1, fp_ );
00284 return *this;
00285 }
00290 DATASTREAM& operator>> ( INT16& word )
00291 {
00292 if ( swap_ ) {
00293 unsigned char* p = (unsigned char*)&word;
00294 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00295 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00296 }
00297 else
00298 fread( &word, sizeof(INT16), 1, fp_ );
00299 return *this;
00300 }
00305 DATASTREAM& operator<< ( const DWORD& dword )
00306 {
00307 if ( swap_ ) {
00308 unsigned char const* p = (unsigned char const*)&dword;
00309 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00310 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00311 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00312 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00313 }
00314 else
00315 fwrite( &dword, sizeof(DWORD), 1, fp_ );
00316 return *this;
00317 }
00322 DATASTREAM& operator>> ( DWORD& dword )
00323 {
00324 if ( swap_ ) {
00325 unsigned char* p = (unsigned char*)&dword;
00326 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00327 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00328 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00329 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00330 }
00331 else
00332 fread( &dword, sizeof(DWORD), 1, fp_ );
00333 return *this;
00334 }
00339 DATASTREAM& operator<< ( const LONG& long_ )
00340 {
00341 if ( swap_ ) {
00342 unsigned char const* p = (unsigned char const*)&long_;
00343 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00344 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00345 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00346 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00347 }
00348 else
00349 fwrite( &long_, sizeof(LONG), 1, fp_ );
00350 return *this;
00351 }
00356 DATASTREAM& operator>> ( LONG& long_ )
00357 {
00358 if ( swap_ ) {
00359 unsigned char* p = (unsigned char*)&long_;
00360 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00361 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00362 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00363 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00364 }
00365 else
00366 fread( &long_, sizeof(LONG), 1, fp_ );
00367 return *this;
00368 }
00373 DATASTREAM& operator<< ( const INT& int_ )
00374 {
00375 if ( swap_ ) {
00376 unsigned char const* p = (unsigned char const*)&int_;
00377 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00378 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00379 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00380 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00381 }
00382 else
00383 fwrite( &int_, sizeof(INT), 1, fp_ );
00384 return *this;
00385 }
00390 DATASTREAM& operator>> ( INT& int_ )
00391 {
00392 if ( swap_ ) {
00393 unsigned char* p = (unsigned char*)&int_;
00394 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00395 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00396 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00397 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00398 }
00399 else
00400 fread( &int_, sizeof(INT), 1, fp_ );
00401 return *this;
00402 }
00407 DATASTREAM& operator<< ( const UINT& uint )
00408 {
00409 if ( swap_ ) {
00410 unsigned char const* p = (unsigned char const*)&uint;
00411 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00412 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00413 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00414 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00415 }
00416 else
00417 fwrite( &uint, sizeof(UINT), 1, fp_ );
00418 return *this;
00419 }
00424 DATASTREAM& operator>> ( UINT& uint )
00425 {
00426 if ( swap_ ) {
00427 unsigned char* p = (unsigned char*)&uint;
00428 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00429 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00430 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00431 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00432 }
00433 else
00434 fread( &uint, sizeof(UINT), 1, fp_ );
00435 return *this;
00436 }
00441 DATASTREAM& operator<< ( const FLOAT& float_ )
00442 {
00443 if ( swap_ ) {
00444 unsigned char const* p = (unsigned char const*)&float_;
00445 fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
00446 fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
00447 fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
00448 fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
00449 }
00450 else
00451 fwrite( &float_, sizeof(FLOAT), 1, fp_ );
00452 return *this;
00453 }
00458 DATASTREAM& operator>> ( FLOAT& float_ )
00459 {
00460 if ( swap_ ) {
00461 unsigned char* p = (unsigned char*)&float_;
00462 fread( &p[3], sizeof(unsigned char), 1, fp_ );
00463 fread( &p[2], sizeof(unsigned char), 1, fp_ );
00464 fread( &p[1], sizeof(unsigned char), 1, fp_ );
00465 fread( &p[0], sizeof(unsigned char), 1, fp_ );
00466 }
00467 else
00468 fread( &float_, sizeof(FLOAT), 1, fp_ );
00469 return *this;
00470 }
00475 DATASTREAM& operator<< ( const PADDING& padding )
00476 {
00477 if ( padding.size_ != 0 )
00478 fwrite( &padding.padding_, sizeof(CHAR), padding.size_, fp_ );
00479 return *this;
00480 }
00485 DATASTREAM& operator<< ( const RECTL& rectl )
00486 {
00487 *this << rectl.left << rectl.top << rectl.right << rectl.bottom;
00488 return *this;
00489 }
00494 DATASTREAM& operator>> ( RECTL& rectl )
00495 {
00496 *this >> rectl.left >> rectl.top >> rectl.right >> rectl.bottom;
00497 return *this;
00498 }
00503 DATASTREAM& operator<< ( const SIZEL& sizel )
00504 {
00505 *this << sizel.cx << sizel.cy;
00506 return *this;
00507 }
00512 DATASTREAM& operator>> ( SIZEL& sizel )
00513 {
00514 *this >> sizel.cx >> sizel.cy;
00515 return *this;
00516 }
00521 DATASTREAM& operator<< ( const WCHARSTR& wcharstr )
00522 {
00523 for ( int i = 0; i < wcharstr.length_; i++ )
00524 *this << wcharstr.string_[i];
00525 return *this;
00526 }
00531 DATASTREAM& operator>> ( WCHARSTR& wcharstr )
00532 {
00533 for ( int i = 0; i < wcharstr.length_; i++ )
00534 *this >> wcharstr.string_[i];
00535 return *this;
00536 }
00541 DATASTREAM& operator<< ( const CHARSTR& charstr )
00542 {
00543 fwrite( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
00544 return *this;
00545 }
00550 DATASTREAM& operator>> ( CHARSTR& charstr )
00551 {
00552 fread( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
00553 return *this;
00554 }
00559 DATASTREAM& operator<< ( const ::EMR& emr )
00560 {
00561 *this << emr.iType << emr.nSize;
00562 return *this;
00563 }
00568 DATASTREAM& operator>> ( ::EMR& emr )
00569 {
00570 *this >> emr.iType >> emr.nSize;
00571 return *this;
00572 }
00577 DATASTREAM& operator<< ( const POINT& point )
00578 {
00579 *this << point.x << point.y;
00580 return *this;
00581 }
00586 DATASTREAM& operator>> ( POINT& point )
00587 {
00588 *this >> point.x >> point.y;
00589 return *this;
00590 }
00595 DATASTREAM& operator<< ( const POINTL& pointl )
00596 {
00597 *this << pointl.x << pointl.y;
00598 return *this;
00599 }
00604 DATASTREAM& operator>> ( POINTL& pointl )
00605 {
00606 *this >> pointl.x >> pointl.y;
00607 return *this;
00608 }
00613 DATASTREAM& operator<< ( const POINT16& point )
00614 {
00615 *this << point.x << point.y;
00616 return *this;
00617 }
00622 DATASTREAM& operator>> ( POINT16& point )
00623 {
00624 *this >> point.x >> point.y;
00625 return *this;
00626 }
00631 DATASTREAM& operator<< ( const XFORM& xform )
00632 {
00633 *this << xform.eM11 << xform.eM12 << xform.eM21 << xform.eM22
00634 << xform.eDx << xform.eDy;
00635 return *this;
00636 }
00641 DATASTREAM& operator>> ( XFORM& xform )
00642 {
00643 *this >> xform.eM11 >> xform.eM12 >> xform.eM21 >> xform.eM22
00644 >> xform.eDx >> xform.eDy;
00645 return *this;
00646 }
00651 DATASTREAM& operator<< ( const BYTEARRAY& array )
00652 {
00653 fwrite( array.array_, sizeof(BYTE), array.n_, fp_ );
00654 return *this;
00655 }
00660 DATASTREAM& operator>> ( BYTEARRAY& array )
00661 {
00662 fread( array.array_, sizeof(BYTE), array.n_, fp_ );
00663 return *this;
00664 }
00669 DATASTREAM& operator<< ( const POINTLARRAY& array )
00670 {
00671 for ( unsigned int i = 0; i < array.n_; i++ )
00672 *this << array.points_[i];
00673 return *this;
00674 }
00679 DATASTREAM& operator>> ( POINTLARRAY& array )
00680 {
00681 for ( unsigned int i = 0; i < array.n_; i++ )
00682 *this >> array.points_[i];
00683 return *this;
00684 }
00689 DATASTREAM& operator<< ( const POINT16ARRAY& array )
00690 {
00691 for ( unsigned int i = 0; i < array.n_; i++ )
00692 *this << array.points_[i];
00693 return *this;
00694 }
00699 DATASTREAM& operator>> ( POINT16ARRAY& array )
00700 {
00701 for ( unsigned int i = 0; i < array.n_; i++ )
00702 *this >> array.points_[i];
00703 return *this;
00704 }
00709 DATASTREAM& operator<< ( const INTARRAY& array )
00710 {
00711 for ( unsigned int i = 0; i < array.n_; i++ )
00712 *this << array.ints_[i];
00713 return *this;
00714 }
00719 DATASTREAM& operator>> ( INTARRAY& array )
00720 {
00721 for ( unsigned int i = 0; i < array.n_; i++ )
00722 *this >> array.ints_[i];
00723 return *this;
00724 }
00729 DATASTREAM& operator<< ( const DWORDARRAY& array )
00730 {
00731 for ( unsigned int i = 0; i < array.n_; i++ )
00732 *this << array.dwords_[i];
00733 return *this;
00734 }
00739 DATASTREAM& operator>> ( DWORDARRAY& array )
00740 {
00741 for ( unsigned int i = 0; i < array.n_; i++ )
00742 *this >> array.dwords_[i];
00743 return *this;
00744 }
00749 DATASTREAM& operator<< ( const ::EMRTEXT& text )
00750 {
00751 *this << text.ptlReference << text.nChars << text.offString << text.fOptions
00752 << text.rcl << text.offDx;
00753 return *this;
00754 }
00759 DATASTREAM& operator>> ( ::EMRTEXT& text )
00760 {
00761 *this >> text.ptlReference >> text.nChars >> text.offString >> text.fOptions
00762 >> text.rcl >> text.offDx;
00763 return *this;
00764 }
00769 DATASTREAM& operator<< ( const LOGPEN& pen )
00770 {
00771 *this << pen.lopnStyle << pen.lopnWidth << pen.lopnColor;
00772 return *this;
00773 }
00778 DATASTREAM& operator>> ( LOGPEN& pen )
00779 {
00780 *this >> pen.lopnStyle >> pen.lopnWidth >> pen.lopnColor;
00781 return *this;
00782 }
00787 DATASTREAM& operator<< ( const EXTLOGPEN& pen )
00788 {
00789
00790 *this << pen.elpPenStyle << pen.elpWidth << pen.elpBrushStyle << pen.elpColor
00791 << pen.elpHatch << pen.elpNumEntries;
00792 return *this;
00793 }
00798 DATASTREAM& operator>> ( EXTLOGPEN& pen )
00799 {
00800
00801 *this >> pen.elpPenStyle >> pen.elpWidth >> pen.elpBrushStyle >> pen.elpColor
00802 >> pen.elpHatch >> pen.elpNumEntries;
00803 return *this;
00804 }
00809 DATASTREAM& operator<< ( const LOGBRUSH& brush )
00810 {
00811 *this << brush.lbStyle << brush.lbColor << brush.lbHatch;
00812 return *this;
00813 }
00818 DATASTREAM& operator>> ( LOGBRUSH& brush )
00819 {
00820 *this >> brush.lbStyle >> brush.lbColor >> brush.lbHatch;
00821 return *this;
00822 }
00827 DATASTREAM& operator<< ( const LOGFONTW& font )
00828 {
00829 *this << font.lfHeight << font.lfWidth << font.lfEscapement
00830 << font.lfOrientation << font.lfWeight << font.lfItalic
00831 << font.lfUnderline << font.lfStrikeOut << font.lfCharSet
00832 << font.lfOutPrecision << font.lfClipPrecision << font.lfQuality
00833 << font.lfPitchAndFamily
00834 << WCHARSTR( const_cast<WCHAR*const>(font.lfFaceName), LF_FACESIZE );
00835 return *this;
00836 }
00841 DATASTREAM& operator>> ( LOGFONTW& font )
00842 {
00843 WCHARSTR wFaceName( font.lfFaceName, LF_FACESIZE );
00844
00845 *this >> font.lfHeight >> font.lfWidth >> font.lfEscapement
00846 >> font.lfOrientation >> font.lfWeight >> font.lfItalic
00847 >> font.lfUnderline >> font.lfStrikeOut >> font.lfCharSet
00848 >> font.lfOutPrecision >> font.lfClipPrecision >> font.lfQuality
00849 >> font.lfPitchAndFamily
00850 >> wFaceName;
00851 return *this;
00852 }
00857 DATASTREAM& operator<< ( const PANOSE& panose )
00858 {
00859 fwrite( &panose, sizeof(PANOSE), 1, fp_ );
00860 return *this;
00861 }
00866 DATASTREAM& operator>> ( PANOSE& panose )
00867 {
00868 fread( &panose, sizeof(PANOSE), 1, fp_ );
00869 return *this;
00870 }
00875 DATASTREAM& operator<< ( const EXTLOGFONTW& font )
00876 {
00877 *this << font.elfLogFont
00878 << WCHARSTR( const_cast<WCHAR*const>(font.elfFullName),
00879 LF_FULLFACESIZE )
00880 << WCHARSTR( const_cast<WCHAR*const>(font.elfStyle), LF_FACESIZE )
00881 << font.elfVersion << font.elfStyleSize << font.elfMatch
00882 << font.elfReserved
00883 << BYTEARRAY( const_cast<BYTE*const>(font.elfVendorId),
00884 ELF_VENDOR_SIZE )
00885 << font.elfCulture << font.elfPanose;
00886 return *this;
00887 }
00892 DATASTREAM& operator>> ( EXTLOGFONTW& font )
00893 {
00894 WCHARSTR wFullName( font.elfFullName, LF_FULLFACESIZE );
00895 WCHARSTR wStyle( font.elfStyle, LF_FACESIZE );
00896 BYTEARRAY bVendorId( font.elfVendorId, ELF_VENDOR_SIZE );
00897 *this >> font.elfLogFont
00898 >> wFullName >> wStyle
00899 >> font.elfVersion >> font.elfStyleSize >> font.elfMatch
00900 >> font.elfReserved >> bVendorId
00901 >> font.elfCulture >> font.elfPanose;
00902 return *this;
00903 }
00908 DATASTREAM& operator<< ( const LOGPALETTE& palette )
00909 {
00910
00911 *this << palette.palVersion << palette.palNumEntries;
00912 return *this;
00913 }
00918 DATASTREAM& operator>> ( LOGPALETTE& palette )
00919 {
00920
00921 *this >> palette.palVersion >> palette.palNumEntries;
00922 return *this;
00923 }
00924 };
00925
00926 class METAFILEDEVICECONTEXT;
00927
00929
00935 class METARECORD {
00936 public:
00943 virtual void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const = 0;
00950 virtual bool serialize ( DATASTREAM ds ) = 0;
00956 virtual int size ( void ) const = 0;
00962 virtual ~METARECORD( ) { }
00963 #ifdef ENABLE_EDITING
00964
00968 virtual void edit ( void ) const {}
00969 #endif
00970 };
00971
00972 #ifdef ENABLE_EDITING
00973
00974 inline void edit_rectl ( const char* tag, const RECTL& rectl )
00975 {
00976 printf( "\t%s\t: (%ld, %ld) - (%ld, %ld)\n", tag, rectl.left, rectl.top,
00977 rectl.right, rectl.bottom );
00978 }
00979
00980 inline void edit_xform ( const char* tag, const XFORM& xform )
00981 {
00982 printf( "\t%s.eM11\t: %f\n", tag, xform.eM11 );
00983 printf( "\t%s.eM12\t: %f\n", tag, xform.eM12 );
00984 printf( "\t%s.eM21\t: %f\n", tag, xform.eM21 );
00985 printf( "\t%s.eM22\t: %f\n", tag, xform.eM22 );
00986 printf( "\t%s.eDx\t: %f\n", tag, xform.eDx );
00987 printf( "\t%s.eDy\t: %f\n", tag, xform.eDy );
00988 }
00989
00990 inline void edit_color ( const char* tag, const COLORREF& color )
00991 {
00992 printf( "\t%s\t: R(0x%02lx) G(0x%02lx) B(0x%02lx)\n", tag,
00993 GetRValue( color ), GetGValue( color ), GetBValue( color ) );
00994 }
00995
00996 inline void edit_sizel ( const char* tag, const SIZEL& size )
00997 {
00998 printf( "\t%s\t: (%ld, %ld)\n", tag, size.cx, size.cy );
00999 }
01000
01001 inline void edit_pointl ( const char* tag, const POINTL& point )
01002 {
01003 printf( "\t%s\t: (%ld, %ld)\n", tag, point.x, point.y );
01004 }
01005
01006 inline void edit_pointlarray ( const char* tag, const DWORD cptl,
01007 const POINTL* points )
01008 {
01009 printf( "\tcptl%s\t: %ld\n", tag, cptl );
01010 printf( "\taptl%s\t: ", tag );
01011 if ( cptl > 0 )
01012 printf( "%ld, %ld\n", points[0].x, points[0].y );
01013 else
01014 puts( "" );
01015 for ( DWORD i = 1; i < cptl; i++ )
01016 printf( "\t\t%s %ld, %ld\n", tag, points[i].x, points[i].y );
01017 }
01018
01019 inline void edit_point16array ( const char* tag, const unsigned int cpts,
01020 const POINT16* points )
01021 {
01022 printf( "\tcpts%s\t: %d\n", tag, cpts );
01023 printf( "\tapts%s\t: ", tag );
01024 if ( cpts > 0 )
01025 printf( "%d, %d\n", points[0].x, points[0].y );
01026 else
01027 puts( "" );
01028 for ( unsigned int i = 1; i < cpts; i++ )
01029 printf( "\t\t%s %d, %d\n", tag, points[i].x, points[i].y );
01030 }
01031
01032 inline void edit_pen_style ( const char* tag, DWORD style )
01033 {
01034 printf( "\t%s\t: ", tag );
01035 switch ( style & PS_STYLE_MASK ) {
01036 case PS_SOLID: printf( "PS_SOLID" ); break;
01037 case PS_DASH: printf( "PS_DASH" ); break;
01038 case PS_DOT: printf( "PS_DOT" ); break;
01039 case PS_DASHDOT: printf( "PS_DASHDOT" ); break;
01040 case PS_DASHDOTDOT: printf( "PS_DASHDOTDOT" ); break;
01041 case PS_NULL: printf( "PS_NULL" ); break;
01042 case PS_INSIDEFRAME: printf( "PS_INSIDEFRAME" ); break;
01043 case PS_USERSTYLE: printf( "PS_USERSTYLE" ); break;
01044 case PS_ALTERNATE: printf( "PS_ALTERNATE" ); break;
01045 }
01046 switch ( style & PS_ENDCAP_MASK ) {
01047 case PS_ENDCAP_ROUND: printf( " | PS_ENDCAP_ROUND" ); break;
01048 case PS_ENDCAP_SQUARE: printf( " | PS_ENDCAP_SQUARE" ); break;
01049 case PS_ENDCAP_FLAT: printf( " | PS_ENDCAP_FLAT" ); break;
01050 }
01051 switch ( style & PS_JOIN_MASK ) {
01052 case PS_JOIN_ROUND: printf( " | PS_JOIN_ROUND" ); break;
01053 case PS_JOIN_BEVEL: printf( " | PS_JOIN_BEVEL" ); break;
01054 case PS_JOIN_MITER: printf( " | PS_JOIN_MITER" ); break;
01055 }
01056 switch ( style & PS_TYPE_MASK ) {
01057 case PS_COSMETIC: printf( " | PS_COSMETIC" ); break;
01058 case PS_GEOMETRIC: printf( " | PS_GEOMETRIC" ); break;
01059 }
01060 printf( "\n" );
01061 }
01062
01063 inline void edit_brush_style ( const char* tag, DWORD style )
01064 {
01065 printf( "\t%s\t: ", tag );
01066 switch ( style ) {
01067 case BS_SOLID: printf( "BS_SOLID" ); break;
01068 case BS_NULL: printf( "BS_NULL" ); break;
01069 case BS_HATCHED: printf( "BS_HATCHED" ); break;
01070 case BS_PATTERN: printf( "BS_PATTERN" ); break;
01071 case BS_INDEXED: printf( "BS_INDEXED" ); break;
01072 case BS_DIBPATTERN: printf( "BS_DIBPATTERN" ); break;
01073 case BS_DIBPATTERNPT: printf( "BS_DIBPATTERNPT" ); break;
01074 case BS_PATTERN8X8: printf( "BS_PATTERN8X8" ); break;
01075 case BS_DIBPATTERN8X8: printf( "BS_DIBPATTERN8X8" ); break;
01076 case BS_MONOPATTERN: printf( "BS_DIBPATTERN8X8" ); break;
01077 default: printf( "unknown(%ld)", style );
01078 }
01079 printf( "\n" );
01080 }
01081
01082 inline void edit_brush_hatch ( const char* tag, DWORD hatch )
01083 {
01084 printf( "\t%s\t: ", tag );
01085 switch ( hatch ) {
01086 case HS_HORIZONTAL: printf( "HS_HORIZONTAL" ); break;
01087 case HS_VERTICAL: printf( "HS_VERTICAL" ); break;
01088 case HS_FDIAGONAL: printf( "HS_FDIAGONAL" ); break;
01089 case HS_BDIAGONAL: printf( "HS_BDIAGONAL" ); break;
01090 case HS_CROSS: printf( "HS_CROSS" ); break;
01091 case HS_DIAGCROSS: printf( "HS_DIAGCROSS" ); break;
01092 default: printf( "unknown(%ld)", hatch );
01093 }
01094 printf( "\n" );
01095 }
01096 #endif
01097
01104 enum OBJECTTYPE { O_METAFILEDEVICECONTEXT = OBJ_METADC,
01105 O_FONT = OBJ_FONT,
01106 O_PEN = OBJ_PEN,
01107 O_EXTPEN = OBJ_EXTPEN,
01108 O_BRUSH = OBJ_BRUSH,
01109 O_PALETTE = OBJ_PAL };
01110 #if 0
01111
01114 static char* typStr ( OBJECTTYPE type )
01115 {
01116 switch (type) {
01117 case O_METAFILEDEVICECONTEXT:
01118 return "metafile device context";
01119 case O_FONT:
01120 return "font";
01121 case O_PEN:
01122 return "pen";
01123 case O_EXTPEN:
01124 return "extended pen";
01125 case O_BRUSH:
01126 return "brush";
01127 case O_PALETTE:
01128 return "palette";
01129 }
01130 return "unknown object";
01131 }
01132 #endif
01133
01134
01139 class OBJECT {
01140 public:
01141 HGDIOBJ handle;
01142
01143 virtual ~OBJECT () {}
01148 OBJECT ( void ) : handle( 0 ) {}
01152 virtual OBJECTTYPE getType ( void ) const = 0;
01153 };
01154
01156
01161 class GRAPHICSOBJECT : public OBJECT {
01162 public:
01164 virtual ~GRAPHICSOBJECT () {}
01169 std::map< HDC, HGDIOBJ > contexts;
01175 virtual METARECORD* newEMR ( HDC dc, HGDIOBJ handle ) = 0;
01176 };
01177
01178 typedef METARECORD*(*METARECORDCTOR)(DATASTREAM&);
01179
01180 class GLOBALOBJECTS {
01184 std::vector<OBJECT*> objects;
01185
01192 std::map< DWORD, METARECORDCTOR > new_records;
01193
01194 public:
01195 GLOBALOBJECTS ( void );
01196 ~GLOBALOBJECTS ( void );
01197 HGDIOBJ add ( OBJECT* object );
01198 OBJECT* find ( const HGDIOBJ handle );
01199 void remove ( const OBJECT* object );
01200
01201 std::vector<EMF::OBJECT*>::const_iterator begin ( void ) const
01202 { return objects.begin(); }
01203 std::vector<EMF::OBJECT*>::const_iterator end ( void ) const
01204 { return objects.end(); }
01205
01206 METARECORDCTOR newRecord ( DWORD iType ) const;
01207
01208 static EMF::METARECORD* new_eof ( DATASTREAM& ds );
01209 static EMF::METARECORD* new_setviewportorgex ( DATASTREAM& ds );
01210 static EMF::METARECORD* new_setwindoworgex ( DATASTREAM& ds );
01211 static EMF::METARECORD* new_setviewportextex ( DATASTREAM& ds );
01212 static EMF::METARECORD* new_setwindowextex ( DATASTREAM& ds );
01213 static EMF::METARECORD* new_scaleviewportextex ( DATASTREAM& ds );
01214 static EMF::METARECORD* new_scalewindowextex ( DATASTREAM& ds );
01215 static EMF::METARECORD* new_modifyworldtransform ( DATASTREAM& ds );
01216 static EMF::METARECORD* new_setworldtransform ( DATASTREAM& ds );
01217 static EMF::METARECORD* new_settextalign ( DATASTREAM& ds );
01218 static EMF::METARECORD* new_settextcolor ( DATASTREAM& ds );
01219 static EMF::METARECORD* new_setbkcolor ( DATASTREAM& ds );
01220 static EMF::METARECORD* new_setbkmode ( DATASTREAM& ds );
01221 static EMF::METARECORD* new_setpolyfillmode ( DATASTREAM& ds );
01222 static EMF::METARECORD* new_setmapmode ( DATASTREAM& ds );
01223 static EMF::METARECORD* new_selectobject ( DATASTREAM& ds );
01224 static EMF::METARECORD* new_deleteobject ( DATASTREAM& ds );
01225 static EMF::METARECORD* new_movetoex ( DATASTREAM& ds );
01226 static EMF::METARECORD* new_lineto ( DATASTREAM& ds );
01227 static EMF::METARECORD* new_arc ( DATASTREAM& ds );
01228 static EMF::METARECORD* new_arcto ( DATASTREAM& ds );
01229 static EMF::METARECORD* new_rectangle ( DATASTREAM& ds );
01230 static EMF::METARECORD* new_ellipse ( DATASTREAM& ds );
01231 static EMF::METARECORD* new_polyline ( DATASTREAM& ds );
01232 static EMF::METARECORD* new_polyline16 ( DATASTREAM& ds );
01233 static EMF::METARECORD* new_polygon ( DATASTREAM& ds );
01234 static EMF::METARECORD* new_polygon16 ( DATASTREAM& ds );
01235 static EMF::METARECORD* new_polypolygon ( DATASTREAM& ds );
01236 static EMF::METARECORD* new_polypolygon16 ( DATASTREAM& ds );
01237 static EMF::METARECORD* new_polybezier ( DATASTREAM& ds );
01238 static EMF::METARECORD* new_polybezier16 ( DATASTREAM& ds );
01239 static EMF::METARECORD* new_polybezierto ( DATASTREAM& ds );
01240 static EMF::METARECORD* new_polybezierto16 ( DATASTREAM& ds );
01241 static EMF::METARECORD* new_polylineto ( DATASTREAM& ds );
01242 static EMF::METARECORD* new_polylineto16 ( DATASTREAM& ds );
01243 static EMF::METARECORD* new_exttextouta ( DATASTREAM& ds );
01244 static EMF::METARECORD* new_setpixelv ( DATASTREAM& ds );
01245 static EMF::METARECORD* new_createpen ( DATASTREAM& ds );
01246 static EMF::METARECORD* new_extcreatepen ( DATASTREAM& ds );
01247 static EMF::METARECORD* new_createbrushindirect ( DATASTREAM& ds );
01248 static EMF::METARECORD* new_extcreatefontindirectw ( DATASTREAM& ds );
01249 static EMF::METARECORD* new_fillpath ( DATASTREAM& ds );
01250 static EMF::METARECORD* new_strokepath ( DATASTREAM& ds );
01251 static EMF::METARECORD* new_beginpath ( DATASTREAM& ds );
01252 static EMF::METARECORD* new_endpath ( DATASTREAM& ds );
01253 static EMF::METARECORD* new_closefigure ( DATASTREAM& ds );
01254 static EMF::METARECORD* new_savedc ( DATASTREAM& ds );
01255 static EMF::METARECORD* new_restoredc ( DATASTREAM& ds );
01256 static EMF::METARECORD* new_setmetargn ( DATASTREAM& ds );
01257 };
01258
01259 extern GLOBALOBJECTS globalObjects;
01260
01262
01268 class ENHMETAHEADER : public METARECORD, public ::ENHMETAHEADER {
01269
01270 LPWSTR description_w;
01271 int description_size;
01272
01273 public:
01280 ENHMETAHEADER ( LPCWSTR description = 0 )
01281 : description_w( 0 ), description_size( 0 )
01282 {
01283 iType = EMR_HEADER;
01284 nSize = sizeof( ::ENHMETAHEADER );
01285
01286
01287 RECTL default_bounds = { 0, 0, 0, 0 };
01288 rclBounds = default_bounds;
01289 RECTL default_frame = { 0, 0, 0, 0 };
01290 rclFrame = default_frame;
01291 dSignature = ENHMETA_SIGNATURE;
01292 nVersion = 0x10000;
01293 nBytes = nSize;
01294 nRecords = 1;
01295 nHandles = 0;
01296 sReserved = 0;
01297 nDescription = 0;
01298 offDescription = 0;
01299 nPalEntries = 0;
01300 szlDevice.cx = XMAX_PIXELS;
01301 szlDevice.cy = YMAX_PIXELS;
01302 szlMillimeters.cx = XMAX_MM;
01303 szlMillimeters.cy = YMAX_MM;
01304
01305 cbPixelFormat = 0;
01306 offPixelFormat = 0;
01307 bOpenGL = FALSE;
01308
01309 szlMicrometers.cx = 1000 * szlMillimeters.cx;
01310 szlMicrometers.cy = 1000 * szlMillimeters.cy;
01311
01312 if ( description ) {
01313
01314 int description_count = 0, nulls = 0;
01315 LPCWSTR description_p = description;
01316 while ( nulls < 3 ) {
01317 description_count++;
01318 if ( (*description_p++) == 0 ) nulls++;
01319 }
01320
01321
01322
01323 int record_size = ROUND_TO_LONG( sizeof( ::ENHMETAHEADER ) +
01324 sizeof( WCHAR ) * description_count );
01325 description_size =
01326 (record_size - sizeof( ::ENHMETAHEADER )) / sizeof( WCHAR );
01327
01328 description_w = new WCHAR[ description_size ];
01329
01330 memset( description_w, 0, sizeof(WCHAR) * description_size );
01331
01332 for ( int i=0; i<description_count; i++ )
01333 description_w[i] = *description++;
01334
01335 nSize = nBytes = record_size;
01336 nDescription = description_count;
01337 offDescription = sizeof( ::ENHMETAHEADER );
01338 }
01339 }
01340
01344 ~ENHMETAHEADER ( )
01345 {
01346 if ( description_w ) delete[] description_w;
01347 }
01352 bool serialize ( DATASTREAM ds )
01353 {
01354 ds << iType << nSize
01355 << rclBounds << rclFrame
01356 << dSignature << nVersion << nBytes << nRecords << nHandles << sReserved
01357 << nDescription << offDescription << nPalEntries
01358 << szlDevice << szlMillimeters
01359 << cbPixelFormat << offPixelFormat << bOpenGL
01360 << szlMicrometers
01361 << WCHARSTR( description_w, description_size );
01362 return true;
01363 }
01367 bool unserialize ( DATASTREAM ds )
01368 {
01369 ds >> iType >> nSize
01370 >> rclBounds >> rclFrame
01371 >> dSignature >> nVersion >> nBytes >> nRecords >> nHandles >> sReserved
01372 >> nDescription >> offDescription >> nPalEntries
01373 >> szlDevice >> szlMillimeters;
01374
01375
01376
01377 #define OffsetOf( a, b ) ((unsigned int)(((char*)&(((::ENHMETAHEADER*)a)->b)) - \
01378 (char*)((::ENHMETAHEADER*)a)))
01379
01380 if ( OffsetOf( this, szlMicrometers ) <= offDescription )
01381 ds >> cbPixelFormat >> offPixelFormat >> bOpenGL;
01382
01383 #undef OffsetOf
01384
01385 if ( sizeof(::ENHMETAHEADER) <= offDescription )
01386 ds >> szlMicrometers;
01387
01388
01389
01390 description_size = ( nSize - offDescription ) / sizeof(WCHAR);
01391 description_w = new WCHAR[ description_size ];
01392
01393 WCHARSTR description( description_w, description_size );
01394
01395 ds >> description;
01396
01397 return true;
01398 }
01402 int size ( void ) const { return nSize; }
01408 void execute ( METAFILEDEVICECONTEXT* , HDC ) const
01409 {
01410
01411 }
01412 #ifdef ENABLE_EDITING
01413
01416 void edit ( void ) const
01417 {
01418 printf( "*HEADER*\n" );
01419 printf( "\tiType\t\t\t: %ld\n", iType );
01420 printf( "\tnSize\t\t\t: %ld\n", nSize );
01421 edit_rectl( "rclBounds\t", rclBounds );
01422 edit_rectl( "rclFrame\t", rclFrame );
01423 printf( "\tdSignature\t\t: %.4s\n", (const char*)&dSignature );
01424 printf( "\tnVersion\t\t: 0x%x\n", (unsigned int)nVersion );
01425 printf( "\tnBytes\t\t\t: %ld\n", nBytes );
01426 printf( "\tnRecords\t\t: %ld\n", nRecords );
01427 printf( "\tnHandles\t\t: %d\n", nHandles );
01428 printf( "\tnDescription\t\t: %ld\n", nDescription );
01429 printf( "\toffDescription\t\t: %ld\n", offDescription );
01430 printf( "\tnPalEntries\t\t: %ld\n", nPalEntries );
01431 edit_sizel( "szlDevice\t", szlDevice );
01432 edit_sizel( "szlMillimeters\t", szlMillimeters );
01433
01434
01435 #define OffsetOf( a, b ) ((unsigned int)(((const char*)&(((const ::ENHMETAHEADER*)a)->b)) - \
01436 (const char*)((const ::ENHMETAHEADER*)a)))
01437
01438 if ( OffsetOf( this, cbPixelFormat ) <= offDescription ) {
01439 printf( "\tcbPixelFormat\t\t: %ld\n", cbPixelFormat );
01440 printf( "\toffPixelFormat\t\t: %ld\n", offPixelFormat );
01441 printf( "\tbOpenGL\t\t\t: %ld\n", bOpenGL );
01442
01443 if ( sizeof(::ENHMETAHEADER) <= offDescription ) {
01444 edit_sizel( "szlMicrometers\t", szlMicrometers );
01445 }
01446 }
01447
01448 #undef OffsetOf
01449
01450 if ( nDescription != 0 ) {
01451
01452 wchar_t last_w = 0;
01453 WCHAR* description = description_w;
01454
01455 printf( "\tDescription:" );
01456
01457 for ( DWORD i = 0; i < nDescription; i++ ) {
01458
01459 wchar_t w = *description++;
01460
01461
01462 if ( w != 0 ) {
01463 if ( last_w == 0 ) printf( "\n\t\t" );
01464 putchar( w );
01465 }
01466
01467 last_w = w;
01468 }
01469 printf( "\n" );
01470 }
01471 }
01472 #endif
01473 };
01474
01476
01481 class EMREOF : public METARECORD, ::EMREOF {
01482 public:
01486 EMREOF ( void )
01487 {
01488 emr.iType = EMR_EOF;
01489 emr.nSize = sizeof( ::EMREOF );
01490 nPalEntries = 0;
01491 offPalEntries = 0;
01492 nSizeLast = 0;
01493 }
01494
01499 EMREOF ( DATASTREAM& ds )
01500 {
01501 ds >> emr >> nPalEntries >> offPalEntries >> nSizeLast;
01502 }
01503
01507 bool serialize ( DATASTREAM ds )
01508 {
01509 ds << emr << nPalEntries << offPalEntries << nSizeLast;
01510 return true;
01511 }
01515 int size ( void ) const { return emr.nSize; }
01521 void execute ( METAFILEDEVICECONTEXT* , HDC ) const
01522 {
01523
01524 }
01525 #ifdef ENABLE_EDITING
01526
01529 void edit ( void ) const
01530 {
01531 printf( "*EOF*\n" );
01532 }
01533 #endif
01534 };
01535
01537
01542 class EMRSETVIEWPORTORGEX : public METARECORD, ::EMRSETVIEWPORTORGEX {
01543 public:
01548 EMRSETVIEWPORTORGEX ( INT x, INT y )
01549 {
01550 emr.iType = EMR_SETVIEWPORTORGEX;
01551 emr.nSize = sizeof( ::EMRSETVIEWPORTORGEX );
01552 ptlOrigin.x = x;
01553 ptlOrigin.y = y;
01554 }
01559 EMRSETVIEWPORTORGEX ( DATASTREAM& ds )
01560 {
01561 ds >> emr >> ptlOrigin;
01562 }
01566 bool serialize ( DATASTREAM ds )
01567 {
01568 ds << emr << ptlOrigin;
01569 return true;
01570 }
01574 int size ( void ) const { return emr.nSize; }
01580 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01581 {
01582 SetViewportOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
01583 }
01584 #ifdef ENABLE_EDITING
01585
01588 void edit ( void ) const
01589 {
01590 printf( "*SETVIEWPORTORGEX*\n" );
01591 edit_pointl( "ptlOrigin", ptlOrigin );
01592 }
01593 #endif
01594 };
01595
01597
01604 class EMRSETWINDOWORGEX : public METARECORD, ::EMRSETWINDOWORGEX {
01605 public:
01610 EMRSETWINDOWORGEX ( INT x, INT y )
01611 {
01612 emr.iType = EMR_SETWINDOWORGEX;
01613 emr.nSize = sizeof( ::EMRSETWINDOWORGEX );
01614 ptlOrigin.x = x;
01615 ptlOrigin.y = y;
01616 }
01621 EMRSETWINDOWORGEX ( DATASTREAM& ds )
01622 {
01623 ds >> emr >> ptlOrigin;
01624 }
01628 bool serialize ( DATASTREAM ds )
01629 {
01630 ds << emr << ptlOrigin;
01631 return true;
01632 }
01636 int size ( void ) const { return emr.nSize; }
01642 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01643 {
01644 SetWindowOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
01645 }
01646 #ifdef ENABLE_EDITING
01647
01650 void edit ( void ) const
01651 {
01652 printf( "*SETWINDOWORGEX*\n" );
01653 edit_pointl( "ptlOrigin", ptlOrigin );
01654 }
01655 #endif
01656 };
01657
01659
01664 class EMRSETVIEWPORTEXTEX : public METARECORD, ::EMRSETVIEWPORTEXTEX {
01665 public:
01670 EMRSETVIEWPORTEXTEX ( INT cx, INT cy )
01671 {
01672 emr.iType = EMR_SETVIEWPORTEXTEX;
01673 emr.nSize = sizeof( ::EMRSETVIEWPORTEXTEX );
01674 szlExtent.cx = cx;
01675 szlExtent.cy = cy;
01676 }
01681 EMRSETVIEWPORTEXTEX ( DATASTREAM& ds )
01682 {
01683 ds >> emr >> szlExtent;
01684 }
01688 bool serialize ( DATASTREAM ds )
01689 {
01690 ds << emr << szlExtent;
01691 return true;
01692 }
01696 int size ( void ) const { return emr.nSize; }
01702 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01703 {
01704 SetViewportExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
01705 }
01706 #ifdef ENABLE_EDITING
01707
01710 void edit ( void ) const
01711 {
01712 printf( "*SETVIEWPORTEXTEX*\n" );
01713 edit_sizel( "szlExtent", szlExtent );
01714 }
01715 #endif
01716 };
01717
01719
01724 class EMRSCALEVIEWPORTEXTEX : public METARECORD, ::EMRSCALEVIEWPORTEXTEX {
01725 public:
01732 EMRSCALEVIEWPORTEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
01733 {
01734 emr.iType = EMR_SCALEVIEWPORTEXTEX;
01735 emr.nSize = sizeof( ::EMRSCALEVIEWPORTEXTEX );
01736 xNum = x_num;
01737 xDenom = x_den;
01738 yNum = y_num;
01739 yDenom = y_den;
01740 }
01745 EMRSCALEVIEWPORTEXTEX ( DATASTREAM& ds )
01746 {
01747 ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
01748 }
01752 bool serialize ( DATASTREAM ds )
01753 {
01754 ds << emr << xNum << xDenom << yNum << yDenom;
01755 return true;
01756 }
01760 int size ( void ) const { return emr.nSize; }
01766 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01767 {
01768 ScaleViewportExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
01769 }
01770 #ifdef ENABLE_EDITING
01771
01774 void edit ( void ) const
01775 {
01776 printf( "*SCALEVIEWPORTEXTEX*\n" );
01777 printf( "\txNum\t: %ld\n", xNum );
01778 printf( "\txDenom\t: %ld\n", xDenom );
01779 printf( "\tyNum\t: %ld\n", yNum );
01780 printf( "\tyDenom\t: %ld\n", yDenom );
01781 }
01782 #endif
01783 };
01784
01786
01791 class EMRSETWINDOWEXTEX : public METARECORD, ::EMRSETWINDOWEXTEX {
01792 public:
01797 EMRSETWINDOWEXTEX ( INT cx, INT cy )
01798 {
01799 emr.iType = EMR_SETWINDOWEXTEX;
01800 emr.nSize = sizeof( ::EMRSETWINDOWEXTEX );
01801 szlExtent.cx = cx;
01802 szlExtent.cy = cy;
01803 }
01808 EMRSETWINDOWEXTEX ( DATASTREAM& ds )
01809 {
01810 ds >> emr >> szlExtent;
01811 }
01815 bool serialize ( DATASTREAM ds )
01816 {
01817 ds << emr << szlExtent;
01818 return true;
01819 }
01823 int size ( void ) const { return emr.nSize; }
01829 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01830 {
01831 SetWindowExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
01832 }
01833 #ifdef ENABLE_EDITING
01834
01837 void edit ( void ) const
01838 {
01839 printf( "*SETWINDOWEXTEX*\n" );
01840 edit_sizel( "szlExtent", szlExtent );
01841 }
01842 #endif
01843 };
01844
01846
01851 class EMRSCALEWINDOWEXTEX : public METARECORD, ::EMRSCALEWINDOWEXTEX {
01852 public:
01859 EMRSCALEWINDOWEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
01860 {
01861 emr.iType = EMR_SCALEWINDOWEXTEX;
01862 emr.nSize = sizeof( ::EMRSCALEWINDOWEXTEX );
01863 xNum = x_num;
01864 xDenom = x_den;
01865 yNum = y_num;
01866 yDenom = y_den;
01867 }
01872 EMRSCALEWINDOWEXTEX ( DATASTREAM& ds )
01873 {
01874 ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
01875 }
01879 bool serialize ( DATASTREAM ds )
01880 {
01881 ds << emr << xNum << xDenom << yNum << yDenom;
01882 return true;
01883 }
01887 int size ( void ) const { return emr.nSize; }
01893 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01894 {
01895 ScaleWindowExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
01896 }
01897 #ifdef ENABLE_EDITING
01898
01901 void edit ( void ) const
01902 {
01903 printf( "*SCALEWINDOWEXTEX*\n" );
01904 printf( "\txNum\t: %ld\n", xNum );
01905 printf( "\txDenom\t: %ld\n", xDenom );
01906 printf( "\tyNum\t: %ld\n", yNum );
01907 printf( "\tyDenom\t: %ld\n", yDenom );
01908 }
01909 #endif
01910 };
01911
01913
01919 class EMRMODIFYWORLDTRANSFORM : public METARECORD, ::EMRMODIFYWORLDTRANSFORM {
01920 public:
01926 EMRMODIFYWORLDTRANSFORM ( const XFORM* transform, DWORD mode )
01927 {
01928 emr.iType = EMR_MODIFYWORLDTRANSFORM;
01929 emr.nSize = sizeof( ::EMRMODIFYWORLDTRANSFORM );
01930 xform = *transform;
01931 iMode = mode;
01932 }
01937 EMRMODIFYWORLDTRANSFORM ( DATASTREAM& ds )
01938 {
01939 ds >> emr >> xform >> iMode;
01940 }
01944 bool serialize ( DATASTREAM ds )
01945 {
01946 ds << emr << xform << iMode;
01947 return true;
01948 }
01952 int size ( void ) const { return emr.nSize; }
01958 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
01959 {
01960 ModifyWorldTransform( dc, &xform, iMode );
01961 }
01962 #ifdef ENABLE_EDITING
01963
01966 void edit ( void ) const
01967 {
01968 printf( "*MODIFYWORLDTRANSFORM*\n" );
01969 edit_xform( "xform", xform );
01970 printf( "\tiMode\t\t: " );
01971 switch ( iMode ) {
01972 case MWT_IDENTITY: printf( "MWT_IDENTITY\n" ); break;
01973 case MWT_LEFTMULTIPLY: printf( "MWT_LEFTMULTIPLY\n" ); break;
01974 case MWT_RIGHTMULTIPLY: printf( "MWT_RIGHTMULTIPLY\n" ); break;
01975 default: printf( "unknown(%ld)\n", iMode );
01976 }
01977 }
01978 #endif
01979 };
01980
01982
01988 class EMRSETWORLDTRANSFORM : public METARECORD, ::EMRSETWORLDTRANSFORM {
01989 public:
01993 EMRSETWORLDTRANSFORM ( const XFORM* transform )
01994 {
01995 emr.iType = EMR_SETWORLDTRANSFORM;
01996 emr.nSize = sizeof( ::EMRSETWORLDTRANSFORM );
01997 xform = *transform;
01998 }
02003 EMRSETWORLDTRANSFORM ( DATASTREAM& ds )
02004 {
02005 ds >> emr >> xform;
02006 }
02010 bool serialize ( DATASTREAM ds )
02011 {
02012 ds << emr << xform;
02013 return true;
02014 }
02018 int size ( void ) const { return emr.nSize; }
02024 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02025 {
02026 SetWorldTransform( dc, &xform );
02027 }
02028 #ifdef ENABLE_EDITING
02029
02032 void edit ( void ) const
02033 {
02034 printf( "*SETWORLDTRANSFORM*\n" );
02035 edit_xform( "xform", xform );
02036 }
02037 #endif
02038 };
02039
02041
02044 class EMRSETTEXTALIGN : public METARECORD, ::EMRSETTEXTALIGN {
02045 public:
02049 EMRSETTEXTALIGN ( UINT mode )
02050 {
02051 emr.iType = EMR_SETTEXTALIGN;
02052 emr.nSize = sizeof( ::EMRSETTEXTALIGN );
02053 iMode = mode;
02054 }
02059 EMRSETTEXTALIGN ( DATASTREAM& ds )
02060 {
02061 ds >> emr >> iMode;
02062 }
02066 bool serialize ( DATASTREAM ds )
02067 {
02068 ds << emr << iMode;
02069 return true;
02070 }
02074 int size ( void ) const { return emr.nSize; }
02080 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02081 {
02082 SetTextAlign( dc, iMode );
02083 }
02084 #ifdef ENABLE_EDITING
02085
02088 void edit ( void ) const
02089 {
02090 unsigned int known_bits = TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING;
02091 unsigned int unknown_bits = ~known_bits;
02092
02093 printf( "*SETTEXTALIGN*\n" );
02094 printf( "\tiMode\t: " );
02095 if ( iMode & TA_UPDATECP )
02096 printf( "TA_UPDATECP" );
02097 else
02098 printf( "TA_NOUPDATECP" );
02099 if ( iMode & TA_CENTER )
02100 printf( " | TA_CENTER" );
02101 else if ( iMode & TA_RIGHT )
02102 printf( " | TA_RIGHT" );
02103 else
02104 printf( " | TA_LEFT" );
02105 if ( iMode & TA_BASELINE )
02106 printf( " | TA_BASELINE" );
02107 else if ( iMode & TA_BOTTOM )
02108 printf( " | TA_BOTTOM" );
02109 else
02110 printf( " | TA_TOP" );
02111 if ( iMode & TA_RTLREADING )
02112 printf( " | TA_RTLREADING" );
02113 if ( iMode & unknown_bits )
02114 printf( " | unknown bits(0x%lx)", iMode & unknown_bits );
02115 printf( "\n" );
02116 }
02117 #endif
02118 };
02119
02121
02124 class EMRSETTEXTCOLOR : public METARECORD, ::EMRSETTEXTCOLOR {
02125 public:
02129 EMRSETTEXTCOLOR ( COLORREF color )
02130 {
02131 emr.iType = EMR_SETTEXTCOLOR;
02132 emr.nSize = sizeof( ::EMRSETTEXTCOLOR );
02133 crColor = color;
02134 }
02139 EMRSETTEXTCOLOR ( DATASTREAM& ds )
02140 {
02141 ds >> emr >> crColor;
02142 }
02146 bool serialize ( DATASTREAM ds )
02147 {
02148 ds << emr << crColor;
02149 return true;
02150 }
02154 int size ( void ) const { return emr.nSize; }
02160 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02161 {
02162 SetTextColor( dc, crColor );
02163 }
02164 #ifdef ENABLE_EDITING
02165
02168 void