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 edit ( void ) const
02169 {
02170 printf( "*SETTEXTCOLOR*\n" );
02171 edit_color( "crColor", crColor );
02172 }
02173 #endif
02174 };
02175
02177
02180 class EMRSETBKCOLOR : public METARECORD, ::EMRSETBKCOLOR {
02181 public:
02185 EMRSETBKCOLOR ( COLORREF color )
02186 {
02187 emr.iType = EMR_SETBKCOLOR;
02188 emr.nSize = sizeof( ::EMRSETBKCOLOR );
02189 crColor = color;
02190 }
02195 EMRSETBKCOLOR ( DATASTREAM& ds )
02196 {
02197 ds >> emr >> crColor;
02198 }
02202 bool serialize ( DATASTREAM ds )
02203 {
02204 ds << emr << crColor;
02205 return true;
02206 }
02210 int size ( void ) const { return emr.nSize; }
02216 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02217 {
02218 SetBkColor( dc, crColor );
02219 }
02220 #ifdef ENABLE_EDITING
02221
02224 void edit ( void ) const
02225 {
02226 printf( "*SETBKCOLOR*\n" );
02227 edit_color( "crColor", crColor );
02228 }
02229 #endif
02230 };
02231
02233
02237 class EMRSETBKMODE : public METARECORD, ::EMRSETBKMODE {
02238 public:
02242 EMRSETBKMODE ( DWORD mode )
02243 {
02244 emr.iType = EMR_SETBKMODE;
02245 emr.nSize = sizeof( ::EMRSETBKMODE );
02246 iMode = mode;
02247 }
02252 EMRSETBKMODE ( DATASTREAM& ds )
02253 {
02254 ds >> emr >> iMode;
02255 }
02259 bool serialize ( DATASTREAM ds )
02260 {
02261 ds << emr << iMode;
02262 return true;
02263 }
02267 int size ( void ) const { return emr.nSize; }
02273 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02274 {
02275 SetBkMode( dc, iMode );
02276 }
02277 #ifdef ENABLE_EDITING
02278
02281 void edit ( void ) const
02282 {
02283 printf( "*SETBKMODE*\n" );
02284 printf( "\tiMode\t: " );
02285 switch ( iMode ) {
02286 case TRANSPARENT: printf( "TRANSPARENT\n" ); break;
02287 case OPAQUE: printf( "OPAQUE\n" ); break;
02288 default: printf( "unknown(%ld)\n", iMode );
02289 }
02290 }
02291 #endif
02292 };
02293
02295
02298 class EMRSETPOLYFILLMODE : public METARECORD, ::EMRSETPOLYFILLMODE {
02299 public:
02303 EMRSETPOLYFILLMODE ( DWORD mode )
02304 {
02305 emr.iType = EMR_SETPOLYFILLMODE;
02306 emr.nSize = sizeof( ::EMRSETPOLYFILLMODE );
02307 iMode = mode;
02308 }
02313 EMRSETPOLYFILLMODE ( DATASTREAM& ds )
02314 {
02315 ds >> emr >> iMode;
02316 }
02320 bool serialize ( DATASTREAM ds )
02321 {
02322 ds << emr << iMode;
02323 return true;
02324 }
02328 int size ( void ) const { return emr.nSize; }
02334 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02335 {
02336 SetPolyFillMode( dc, iMode );
02337 }
02338 #ifdef ENABLE_EDITING
02339
02342 void edit ( void ) const
02343 {
02344 printf( "*SETPOLYFILLMODE*\n" );
02345 printf( "\tiMode: " );
02346 switch ( iMode ) {
02347 case ALTERNATE: printf( "ALTERNATE\n" ); break;
02348 case WINDING: printf( "WINDING\n" ); break;
02349 default: printf( "unknown(%ld)\n", iMode );
02350 }
02351 }
02352 #endif
02353 };
02354
02356
02360 class EMRSETMAPMODE : public METARECORD, ::EMRSETMAPMODE {
02361 public:
02365 EMRSETMAPMODE ( DWORD mode )
02366 {
02367 emr.iType = EMR_SETMAPMODE;
02368 emr.nSize = sizeof( ::EMRSETMAPMODE );
02369 iMode = mode;
02370 }
02375 EMRSETMAPMODE ( DATASTREAM& ds )
02376 {
02377 ds >> emr >> iMode;
02378 }
02382 bool serialize ( DATASTREAM ds )
02383 {
02384 ds << emr << iMode;
02385 return true;
02386 }
02390 int size ( void ) const { return emr.nSize; }
02396 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02397 {
02398 SetMapMode( dc, iMode );
02399 }
02400 #ifdef ENABLE_EDITING
02401
02404 void edit ( void ) const
02405 {
02406 printf( "*SETMAPMODE*\n" );
02407 printf( "\tiMode\t: " );
02408 switch ( iMode ) {
02409 case MM_TEXT: printf( "MM_TEXT\n" ); break;
02410 case MM_LOMETRIC: printf( "MM_LOMETRIC\n" ); break;
02411 case MM_HIMETRIC: printf( "MM_HIMETRIC\n" ); break;
02412 case MM_LOENGLISH: printf( "MM_LOENGLISH\n" ); break;
02413 case MM_HIENGLISH: printf( "MM_HIENGLISH\n" ); break;
02414 case MM_TWIPS: printf( "MM_TWIPS\n" ); break;
02415 case MM_ISOTROPIC: printf( "MM_ISOTROPIC\n" ); break;
02416 case MM_ANISOTROPIC: printf( "MM_ANISOTROPIC\n" ); break;
02417 default: printf( "unknown(%ld)\n", iMode );
02418 }
02419 }
02420 #endif
02421 };
02422
02424
02427 class EMRSELECTOBJECT : public METARECORD, ::EMRSELECTOBJECT {
02428 public:
02432 EMRSELECTOBJECT ( HGDIOBJ object )
02433 {
02434 emr.iType = EMR_SELECTOBJECT;
02435 emr.nSize = sizeof( ::EMRSELECTOBJECT );
02436 ihObject = object;
02437 }
02442 EMRSELECTOBJECT ( DATASTREAM& ds )
02443 {
02444 ds >> emr >> ihObject;
02445 }
02449 bool serialize ( DATASTREAM ds )
02450 {
02451 ds << emr << ihObject;
02452 return true;
02453 }
02457 int size ( void ) const { return emr.nSize; }
02463 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
02464 #ifdef ENABLE_EDITING
02465
02468 void edit ( void ) const
02469 {
02470 printf( "*SELECTOBJECT*\n" );
02471 printf( "\tihObject\t: 0x%lx\n", ihObject );
02472 }
02473 #endif
02474 };
02475
02477
02480 class EMRDELETEOBJECT : public METARECORD, ::EMRDELETEOBJECT {
02481 public:
02485 EMRDELETEOBJECT ( HGDIOBJ object )
02486 {
02487 emr.iType = EMR_DELETEOBJECT;
02488 emr.nSize = sizeof( ::EMRDELETEOBJECT );
02489 ihObject = object;
02490 }
02495 EMRDELETEOBJECT ( DATASTREAM& ds )
02496 {
02497 ds >> emr >> ihObject;
02498 }
02502 bool serialize ( DATASTREAM ds )
02503 {
02504 ds << emr << ihObject;
02505 return true;
02506 }
02510 int size ( void ) const { return emr.nSize; }
02516 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
02517 #ifdef ENABLE_EDITING
02518
02521 void edit ( void ) const
02522 {
02523 printf( "*DELETEOBJECT*\n" );
02524 printf( "\tihObject\t: 0x%lx\n", ihObject );
02525 }
02526 #endif
02527 };
02528
02530
02533 class EMRMOVETOEX : public METARECORD, ::EMRMOVETOEX {
02534 public:
02539 EMRMOVETOEX ( INT x, INT y )
02540 {
02541 emr.iType = EMR_MOVETOEX;
02542 emr.nSize = sizeof( ::EMRMOVETOEX );
02543 ptl.x = x;
02544 ptl.y = y;
02545 }
02550 EMRMOVETOEX ( DATASTREAM& ds )
02551 {
02552 ds >> emr >> ptl;
02553 }
02557 bool serialize ( DATASTREAM ds )
02558 {
02559 ds << emr << ptl;
02560 return true;
02561 }
02565 int size ( void ) const { return emr.nSize; }
02571 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02572 {
02573 MoveToEx( dc, ptl.x, ptl.y, 0 );
02574 }
02575 #ifdef ENABLE_EDITING
02576
02579 void edit ( void ) const
02580 {
02581 printf( "*MOVETOEX*\n" );
02582 edit_pointl( "ptl", ptl );
02583 }
02584 #endif
02585 };
02586
02588
02591 class EMRLINETO : public METARECORD, ::EMRLINETO {
02592 public:
02597 EMRLINETO ( INT x, INT y )
02598 {
02599 emr.iType = EMR_LINETO;
02600 emr.nSize = sizeof( ::EMRLINETO );
02601 ptl.x = x;
02602 ptl.y = y;
02603 }
02608 EMRLINETO ( DATASTREAM& ds )
02609 {
02610 ds >> emr >> ptl;
02611 }
02615 bool serialize ( DATASTREAM ds )
02616 {
02617 ds << emr << ptl;
02618 return true;
02619 }
02623 int size ( void ) const { return emr.nSize; }
02629 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02630 {
02631 LineTo( dc, ptl.x, ptl.y );
02632 }
02633 #ifdef ENABLE_EDITING
02634
02637 void edit ( void ) const
02638 {
02639 printf( "*LINETO*\n" );
02640 edit_pointl( "ptl", ptl );
02641 }
02642 #endif
02643 };
02644
02646
02649 class EMRARC : public METARECORD, ::EMRARC {
02650 public:
02662 EMRARC ( INT left, INT top, INT right, INT bottom, INT xstart,
02663 INT ystart, INT xend, INT yend )
02664 {
02665 emr.iType = EMR_ARC;
02666 emr.nSize = sizeof( ::EMRARC );
02667 rclBox.left = left;
02668 rclBox.right = right;
02669 rclBox.bottom = bottom;
02670 rclBox.top = top;
02671 ptlStart.x = xstart;
02672 ptlStart.y = ystart;
02673 ptlEnd.x = xend;
02674 ptlEnd.y = yend;
02675 }
02680 EMRARC ( DATASTREAM& ds )
02681 {
02682 ds >> emr >> rclBox >> ptlStart >> ptlEnd;
02683 }
02687 bool serialize ( DATASTREAM ds )
02688 {
02689 ds << emr << rclBox << ptlStart << ptlEnd;
02690 return true;
02691 }
02695 int size ( void ) const { return emr.nSize; }
02701 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02702 {
02703 Arc( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
02704 ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
02705 }
02706 #ifdef ENABLE_EDITING
02707
02710 void edit ( void ) const
02711 {
02712 printf( "*ARC*\n" );
02713 edit_rectl( "rclBox\t", rclBox );
02714 edit_pointl( "ptlStart", ptlStart );
02715 edit_pointl( "ptlEnd\t", ptlEnd );
02716 }
02717 #endif
02718 };
02719
02721
02724 class EMRARCTO : public METARECORD, ::EMRARCTO {
02725 public:
02737 EMRARCTO ( INT left, INT top, INT right, INT bottom, INT xstart,
02738 INT ystart, INT xend, INT yend )
02739 {
02740 emr.iType = EMR_ARCTO;
02741 emr.nSize = sizeof( ::EMRARCTO );
02742 rclBox.left = left;
02743 rclBox.right = right;
02744 rclBox.bottom = bottom;
02745 rclBox.top = top;
02746 ptlStart.x = xstart;
02747 ptlStart.y = ystart;
02748 ptlEnd.x = xend;
02749 ptlEnd.y = yend;
02750 }
02755 EMRARCTO ( DATASTREAM& ds )
02756 {
02757 ds >> emr >> rclBox >> ptlStart >> ptlEnd;
02758 }
02762 bool serialize ( DATASTREAM ds )
02763 {
02764 ds << emr << rclBox << ptlStart << ptlEnd;
02765 return true;
02766 }
02770 int size ( void ) const { return emr.nSize; }
02776 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02777 {
02778 ArcTo( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
02779 ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
02780 }
02781 #ifdef ENABLE_EDITING
02782
02785 void edit ( void ) const
02786 {
02787 printf( "*ARCTO*\n" );
02788 edit_rectl( "rclBox\t", rclBox );
02789 edit_pointl( "ptlStart", ptlStart );
02790 edit_pointl( "ptlEnd\t", ptlEnd );
02791 }
02792 #endif
02793 };
02794
02796
02799 class EMRRECTANGLE : public METARECORD, ::EMRRECTANGLE {
02800 public:
02807 EMRRECTANGLE ( INT left, INT top, INT right, INT bottom )
02808 {
02809 emr.iType = EMR_RECTANGLE;
02810 emr.nSize = sizeof( ::EMRRECTANGLE );
02811 rclBox.left = left;
02812 rclBox.right = right;
02813 rclBox.bottom = bottom;
02814 rclBox.top = top;
02815 }
02820 EMRRECTANGLE ( DATASTREAM& ds )
02821 {
02822 ds >> emr >> rclBox;
02823 }
02827 bool serialize ( DATASTREAM ds )
02828 {
02829 ds << emr << rclBox;
02830 return true;
02831 }
02835 int size ( void ) const { return emr.nSize; }
02841 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02842 {
02843 Rectangle( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
02844 }
02845 #ifdef ENABLE_EDITING
02846
02849 void edit ( void ) const
02850 {
02851 printf( "*RECTANGLE*\n" );
02852 edit_rectl( "rclBox", rclBox );
02853 }
02854 #endif
02855 };
02856
02858
02861 class EMRELLIPSE : public METARECORD, ::EMRELLIPSE {
02862 public:
02870 EMRELLIPSE ( INT left, INT top, INT right, INT bottom )
02871 {
02872 emr.iType = EMR_ELLIPSE;
02873 emr.nSize = sizeof( ::EMRELLIPSE );
02874 rclBox.left = left;
02875 rclBox.right = right;
02876 rclBox.bottom = bottom;
02877 rclBox.top = top;
02878 }
02883 EMRELLIPSE ( DATASTREAM& ds )
02884 {
02885 ds >> emr >> rclBox;
02886 }
02890 bool serialize ( DATASTREAM ds )
02891 {
02892 ds << emr << rclBox;
02893 return true;
02894 }
02898 int size ( void ) const { return emr.nSize; }
02904 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02905 {
02906 Ellipse( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
02907 }
02908 #ifdef ENABLE_EDITING
02909
02912 void edit ( void ) const
02913 {
02914 printf( "*ELLIPSE*\n" );
02915 edit_rectl( "rclBox", rclBox );
02916 }
02917 #endif
02918 };
02919
02921
02924 class EMRPOLYLINE : public METARECORD, ::EMRPOLYLINE {
02925 POINTL* lpoints;
02926 public:
02932 EMRPOLYLINE ( const RECTL* bounds, const POINT* points, INT n )
02933 {
02934 cptl = n;
02935 aptl[0].x = 0;
02936 aptl[0].y = 0;
02937
02938 emr.iType = EMR_POLYLINE;
02939
02940 emr.nSize = sizeof( ::EMRPOLYLINE ) + sizeof( POINTL ) * ( cptl - 1);
02941
02942 lpoints = new POINTL[cptl];
02943
02944 for (int i=0; i<n; i++) {
02945 lpoints[i].x = points[i].x;
02946 lpoints[i].y = points[i].y;
02947 }
02948
02949 rclBounds = *bounds;
02950 }
02954 ~EMRPOLYLINE ( )
02955 {
02956 if ( lpoints ) delete[] lpoints;
02957 }
02962 EMRPOLYLINE ( DATASTREAM& ds )
02963 {
02964 ds >> emr >> rclBounds >> cptl;
02965
02966 lpoints = new POINTL[cptl];
02967
02968 POINTLARRAY points( lpoints, cptl );
02969
02970 ds >> points;
02971 }
02975 bool serialize ( DATASTREAM ds )
02976 {
02977 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
02978 return true;
02979 }
02983 int size ( void ) const { return emr.nSize; }
02989 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
02990 {
02991
02992 Polyline( dc, (POINT*)lpoints, cptl );
02993 }
02994 #ifdef ENABLE_EDITING
02995
02998 void edit ( void ) const
02999 {
03000 printf( "*POLYLINE*\n" );
03001 edit_rectl( "rclBounds", rclBounds );
03002 #if 0
03003 printf( "\tcptl : %ld\n", cptl );
03004 printf( "\taptl->\n" );
03005 for ( unsigned int i = 0; i < cptl; i++ )
03006 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03007 #else
03008 edit_pointlarray( "\t", cptl, lpoints );
03009 #endif
03010 }
03011 #endif
03012 };
03013
03015
03018 class EMRPOLYLINE16 : public METARECORD, ::EMRPOLYLINE16 {
03019 POINT16* lpoints;
03020 public:
03026 EMRPOLYLINE16 ( const RECTL* bounds, const POINT16* points, INT n )
03027 {
03028 cpts = n;
03029 apts[0].x = 0;
03030 apts[0].y = 0;
03031
03032 emr.iType = EMR_POLYLINE16;
03033
03034 emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
03035
03036 lpoints = new POINT16[cpts];
03037
03038 for (int i=0; i<n; i++) {
03039 lpoints[i].x = points[i].x;
03040 lpoints[i].y = points[i].y;
03041 }
03042
03043 rclBounds = *bounds;
03044 }
03051 EMRPOLYLINE16 ( const RECTL* bounds, const POINT* points, INT n )
03052 {
03053 cpts = n;
03054 apts[0].x = 0;
03055 apts[0].y = 0;
03056
03057 emr.iType = EMR_POLYLINE16;
03058
03059 emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
03060
03061 lpoints = new POINT16[cpts];
03062
03063 for (int i=0; i<n; i++) {
03064 lpoints[i].x = points[i].x;
03065 lpoints[i].y = points[i].y;
03066 }
03067
03068 rclBounds = *bounds;
03069 }
03073 ~EMRPOLYLINE16 ( )
03074 {
03075 if ( lpoints ) delete[] lpoints;
03076 }
03081 EMRPOLYLINE16 ( DATASTREAM& ds )
03082 {
03083 ds >> emr >> rclBounds >> cpts;
03084
03085 lpoints = new POINT16[cpts];
03086
03087 POINT16ARRAY points( lpoints, cpts );
03088
03089 ds >> points;
03090 }
03094 bool serialize ( DATASTREAM ds )
03095 {
03096 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
03097 return true;
03098 }
03102 int size ( void ) const { return emr.nSize; }
03108 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03109 {
03110
03111 Polyline16( dc, lpoints, cpts );
03112 }
03113 #ifdef ENABLE_EDITING
03114
03117 void edit ( void ) const
03118 {
03119 printf( "*POLYLINE16*\n" );
03120 edit_rectl( "rclBounds", rclBounds );
03121 edit_point16array( "\t", cpts, lpoints );
03122 }
03123 #endif
03124 };
03125
03127
03130 class EMRPOLYGON : public METARECORD, ::EMRPOLYGON {
03131 POINTL* lpoints;
03132 public:
03138 EMRPOLYGON ( const RECTL* bounds, const POINT* points, INT n )
03139 {
03140 cptl = n;
03141 aptl[0].x = 0;
03142 aptl[0].y = 0;
03143
03144 emr.iType = EMR_POLYGON;
03145
03146 emr.nSize = sizeof( ::EMRPOLYGON ) + sizeof( POINTL ) * (cptl-1);
03147
03148 lpoints = new POINTL[cptl];
03149
03150 for (int i=0; i<n; i++) {
03151 lpoints[i].x = points[i].x;
03152 lpoints[i].y = points[i].y;
03153 }
03154
03155 rclBounds = *bounds;
03156 }
03161 EMRPOLYGON ( DATASTREAM& ds )
03162 {
03163 ds >> emr >> rclBounds >> cptl;
03164
03165 lpoints = new POINTL[cptl];
03166
03167 POINTLARRAY points( lpoints, cptl );
03168
03169 ds >> points;
03170 }
03174 ~EMRPOLYGON ( )
03175 {
03176 if ( lpoints ) delete[] lpoints;
03177 }
03181 bool serialize ( DATASTREAM ds )
03182 {
03183 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
03184 return true;
03185 }
03189 int size ( void ) const { return emr.nSize; }
03195 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03196 {
03197
03198 Polygon( dc, (POINT*)lpoints, cptl );
03199 }
03200 #ifdef ENABLE_EDITING
03201
03204 void edit ( void ) const
03205 {
03206 printf( "*POLYGON*\n" );
03207 edit_rectl( "rclBounds", rclBounds );
03208 #if 0
03209 printf( "\tcptl : %ld\n", cptl );
03210 printf( "\taptl->\n" );
03211 for ( unsigned int i = 0; i < cptl; i++ )
03212 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03213 #else
03214 edit_pointlarray( "\t", cptl, lpoints );
03215 #endif
03216 }
03217 #endif
03218 };
03219
03221
03224 class EMRPOLYGON16 : public METARECORD, ::EMRPOLYGON16 {
03225 POINT16* lpoints;
03226 public:
03232 EMRPOLYGON16 ( const RECTL* bounds, const POINT* points, INT16 n )
03233 {
03234 cpts = n;
03235 apts[0].x = 0;
03236 apts[0].y = 0;
03237
03238 emr.iType = EMR_POLYGON16;
03239
03240 emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
03241
03242 lpoints = new POINT16[cpts];
03243
03244 for (int i=0; i<n; i++) {
03245 lpoints[i].x = points[i].x;
03246 lpoints[i].y = points[i].y;
03247 }
03248
03249 rclBounds = *bounds;
03250 }
03257 EMRPOLYGON16 ( const RECTL* bounds, const POINT16* points, INT16 n )
03258 {
03259 cpts = n;
03260 apts[0].x = 0;
03261 apts[0].y = 0;
03262
03263 emr.iType = EMR_POLYGON16;
03264
03265 emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
03266
03267 lpoints = new POINT16[cpts];
03268
03269 for (int i=0; i<n; i++) {
03270 lpoints[i].x = points[i].x;
03271 lpoints[i].y = points[i].y;
03272 }
03273
03274 rclBounds = *bounds;
03275 }
03280 EMRPOLYGON16 ( DATASTREAM& ds )
03281 {
03282 ds >> emr >> rclBounds >> cpts;
03283
03284 lpoints = new POINT16[cpts];
03285
03286 POINT16ARRAY points( lpoints, cpts );
03287
03288 ds >> points;
03289 }
03293 ~EMRPOLYGON16 ( )
03294 {
03295 if ( lpoints ) delete[] lpoints;
03296 }
03300 bool serialize ( DATASTREAM ds )
03301 {
03302 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
03303 return true;
03304 }
03308 int size ( void ) const { return emr.nSize; }
03314 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03315 {
03316
03317 Polygon16( dc, lpoints, cpts );
03318 }
03319 #ifdef ENABLE_EDITING
03320
03323 void edit ( void ) const
03324 {
03325 printf( "*POLYGON16*\n" );
03326 edit_rectl( "rclBounds", rclBounds );
03327 edit_point16array( "\t", cpts, lpoints );
03328 }
03329 #endif
03330 };
03331
03333
03336 class EMRPOLYPOLYGON : public METARECORD, ::EMRPOLYPOLYGON {
03337 DWORD* lcounts;
03338 POINTL* lpoints;
03339 public:
03346 EMRPOLYPOLYGON ( const RECTL* bounds, const POINT* points, const INT* counts,
03347 UINT polygons )
03348 {
03349 nPolys = polygons;
03350
03351 int n = 0;
03352 for ( unsigned int i = 0; i < nPolys; i++ )
03353 n += counts[i];
03354
03355 cptl = n;
03356 aPolyCounts[0] = 0;
03357 aptl[0].x = 0;
03358 aptl[0].y = 0;
03359
03360 emr.iType = EMR_POLYPOLYGON;
03361
03362
03363 emr.nSize = sizeof( ::EMRPOLYPOLYGON ) + sizeof( POINTL ) * (cptl-1)
03364 + sizeof( DWORD ) * (nPolys-1);
03365
03366 lcounts = new DWORD[nPolys];
03367
03368 for ( unsigned int i = 0; i < nPolys; i++ )
03369 lcounts[i] = counts[i];
03370
03371 lpoints = new POINTL[cptl];
03372
03373 for (int i=0; i<n; i++) {
03374 lpoints[i].x = points[i].x;
03375 lpoints[i].y = points[i].y;
03376 }
03377
03378 rclBounds = *bounds;
03379 }
03383 ~EMRPOLYPOLYGON ( )
03384 {
03385 if ( lcounts ) delete[] lcounts;
03386 if ( lpoints ) delete[] lpoints;
03387 }
03392 EMRPOLYPOLYGON ( DATASTREAM& ds )
03393 {
03394 ds >> emr >> rclBounds >> nPolys >> cptl;
03395
03396 lcounts = new DWORD[nPolys];
03397
03398 DWORDARRAY counts( lcounts, nPolys );
03399
03400 ds >> counts;
03401
03402 lpoints = new POINTL[cptl];
03403
03404 POINTLARRAY points( lpoints, cptl );
03405
03406 ds >> points;
03407 }
03411 bool serialize ( DATASTREAM ds )
03412 {
03413 ds << emr << rclBounds << nPolys << cptl << DWORDARRAY( lcounts, nPolys )
03414 << POINTLARRAY( lpoints, cptl );
03415 return true;
03416 }
03420 int size ( void ) const { return emr.nSize; }
03426 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03427 {
03428
03429
03430 INT* counts = new INT[nPolys];
03431 for ( unsigned int i = 0; i < nPolys; i++ )
03432 counts[i] = lcounts[i];
03433
03434 PolyPolygon( dc, (POINT*)lpoints, counts, nPolys );
03435
03436 delete[] counts;
03437 }
03438 #ifdef ENABLE_EDITING
03439
03442 void edit ( void ) const
03443 {
03444 printf( "*POLYPOLYGON*\n" );
03445 edit_rectl( "rclBounds", rclBounds );
03446 printf( "\tnPolys\t\t: %ld\n", nPolys );
03447 printf( "\tcptl\t\t: %ld\n", cptl );
03448 printf( "\taPolyCounts\t: " );
03449 if ( nPolys > 0 )
03450 printf( "%ld\n", lcounts[0] );
03451 else
03452 puts( "" );
03453 for ( unsigned int i = 1; i < nPolys; i++ )
03454 printf( "\t\t\t %ld\n", lcounts[i] );
03455 printf( "\tapts\t\t: " );
03456 if ( cptl > 0 )
03457 printf( "%ld, %ld\n", lpoints[0].x, lpoints[0].y );
03458 else
03459 puts( "" );
03460 for ( unsigned int i = 1; i < cptl; i++ )
03461 printf( "\t\t\t %ld, %ld\n", lpoints[i].x, lpoints[i].y );
03462 }
03463 #endif
03464 };
03465
03467
03470 class EMRPOLYPOLYGON16 : public METARECORD, ::EMRPOLYPOLYGON16 {
03471 DWORD* lcounts;
03472 POINT16* lpoints;
03473 public:
03480 EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT* points,
03481 const INT* counts, UINT polygons )
03482 {
03483 nPolys = polygons;
03484
03485 int n = 0;
03486 for ( unsigned int i = 0; i < nPolys; i++ )
03487 n += counts[i];
03488
03489 cpts = n;
03490 aPolyCounts[0] = 0;
03491 apts[0].x = 0;
03492 apts[0].y = 0;
03493
03494 emr.iType = EMR_POLYPOLYGON16;
03495
03496
03497 emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
03498 + sizeof( DWORD ) * (nPolys-1);
03499
03500 lcounts = new DWORD[nPolys];
03501
03502 for ( unsigned int i = 0; i < nPolys; i++ )
03503 lcounts[i] = counts[i];
03504
03505 lpoints = new POINT16[cpts];
03506
03507 for (int i=0; i<n; i++) {
03508 lpoints[i].x = points[i].x;
03509 lpoints[i].y = points[i].y;
03510 }
03511
03512 rclBounds = *bounds;
03513 }
03521 EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT16* points,
03522 const INT* counts, UINT16 polygons )
03523 {
03524 nPolys = polygons;
03525
03526 int n = 0;
03527 for ( unsigned int i = 0; i < nPolys; i++ )
03528 n += counts[i];
03529
03530 cpts = n;
03531 aPolyCounts[0] = 0;
03532 apts[0].x = 0;
03533 apts[0].y = 0;
03534
03535 emr.iType = EMR_POLYPOLYGON16;
03536
03537
03538 emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
03539 + sizeof( DWORD ) * (nPolys-1);
03540
03541 lcounts = new DWORD[nPolys];
03542
03543 for ( unsigned int i = 0; i < nPolys; i++ )
03544 lcounts[i] = counts[i];
03545
03546 lpoints = new POINT16[cpts];
03547
03548 for (int i=0; i<n; i++) {
03549 lpoints[i].x = points[i].x;
03550 lpoints[i].y = points[i].y;
03551 }
03552
03553 rclBounds = *bounds;
03554 }
03558 ~EMRPOLYPOLYGON16 ( )
03559 {
03560 if ( lcounts ) delete[] lcounts;
03561 if ( lpoints ) delete[] lpoints;
03562 }
03567 EMRPOLYPOLYGON16 ( DATASTREAM& ds )
03568 {
03569 ds >> emr >> rclBounds >> nPolys >> cpts;
03570
03571 lcounts = new DWORD[nPolys];
03572
03573 DWORDARRAY counts( lcounts, nPolys );
03574
03575 ds >> counts;
03576
03577 lpoints = new POINT16[cpts];
03578
03579 POINT16ARRAY points( lpoints, cpts );
03580
03581 ds >> points;
03582 }
03586 bool serialize ( DATASTREAM ds )
03587 {
03588 ds << emr << rclBounds << nPolys << cpts << DWORDARRAY( lcounts, nPolys )
03589 << POINT16ARRAY( lpoints, cpts );
03590 return true;
03591 }
03595 int size ( void ) const { return emr.nSize; }
03601 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03602 {
03603
03604
03605 INT* counts = new INT[nPolys];
03606 for ( unsigned int i = 0; i < nPolys; i++ )
03607 counts[i] = lcounts[i];
03608
03609 PolyPolygon16( dc, lpoints, counts, nPolys );
03610
03611 delete[] counts;
03612 }
03613 #ifdef ENABLE_EDITING
03614
03617 void edit ( void ) const
03618 {
03619 printf( "*POLYPOLYGON16*\n" );
03620 edit_rectl( "rclBounds", rclBounds );
03621 printf( "\tnPolys\t\t: %ld\n", nPolys );
03622 printf( "\tcpts\t\t: %ld\n", cpts );
03623 printf( "\taPolyCounts\t: " );
03624 if ( nPolys > 0 )
03625 printf( "%ld\n", lcounts[0] );
03626 else
03627 puts( "" );
03628 for ( unsigned int i = 1; i < nPolys; i++ )
03629 printf( "\t\t\t %ld\n", lcounts[i] );
03630 printf( "\tapts\t\t: " );
03631 if ( cpts > 0 )
03632 printf( "%d, %d\n", lpoints[0].x, lpoints[0].y );
03633 else
03634 puts( "" );
03635 for ( unsigned int i = 1; i < cpts; i++ )
03636 printf( "\t\t\t %d, %d\n", lpoints[i].x, lpoints[i].y );
03637 }
03638 #endif
03639 };
03640
03642
03645 class EMRPOLYBEZIER : public METARECORD, ::EMRPOLYBEZIER {
03646 POINTL* lpoints;
03647 public:
03653 EMRPOLYBEZIER ( const RECTL* bounds, const POINT* points, INT n )
03654 {
03655 cptl = n;
03656 aptl[0].x = 0;
03657 aptl[0].y = 0;
03658
03659 emr.iType = EMR_POLYBEZIER;
03660
03661 emr.nSize = sizeof( ::EMRPOLYBEZIER ) + sizeof( POINTL ) * (cptl-1);
03662
03663 lpoints = new POINTL[cptl];
03664
03665 for (int i=0; i<n; i++) {
03666 lpoints[i].x = points[i].x;
03667 lpoints[i].y = points[i].y;
03668 }
03669
03670 rclBounds = *bounds;
03671 }
03676 EMRPOLYBEZIER ( DATASTREAM& ds )
03677 {
03678 ds >> emr >> rclBounds >> cptl;
03679
03680 lpoints = new POINTL[cptl];
03681
03682 POINTLARRAY points( lpoints, cptl );
03683
03684 ds >> points;
03685 }
03689 ~EMRPOLYBEZIER ( )
03690 {
03691 if ( lpoints ) delete[] lpoints;
03692 }
03696 bool serialize ( DATASTREAM ds )
03697 {
03698 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
03699 return true;
03700 }
03704 int size ( void ) const { return emr.nSize; }
03710 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03711 {
03712
03713 PolyBezier( dc, (POINT*)lpoints, cptl );
03714 }
03715 #ifdef ENABLE_EDITING
03716
03719 void edit ( void ) const
03720 {
03721 printf( "*POLYBEZIER*\n" );
03722 edit_rectl( "rclBounds", rclBounds );
03723 #if 0
03724 printf( "\tcptl : %ld\n", cptl );
03725 printf( "\taptl->\n" );
03726 for ( unsigned int i = 0; i < cptl; i++ )
03727 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03728 #else
03729 edit_pointlarray( "\t", cptl, lpoints );
03730 #endif
03731 }
03732 #endif
03733 };
03734
03736
03739 class EMRPOLYBEZIER16 : public METARECORD, ::EMRPOLYBEZIER16 {
03740 POINT16* lpoints;
03741 public:
03747 EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT16* points, INT n )
03748 {
03749 cpts = n;
03750 apts[0].x = 0;
03751 apts[0].y = 0;
03752
03753 emr.iType = EMR_POLYBEZIER16;
03754
03755 emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
03756
03757 lpoints = new POINT16[cpts];
03758
03759 for (int i=0; i<n; i++) {
03760 lpoints[i].x = points[i].x;
03761 lpoints[i].y = points[i].y;
03762 }
03763
03764 rclBounds = *bounds;
03765 }
03772 EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT* points, INT n )
03773 {
03774 cpts = n;
03775 apts[0].x = 0;
03776 apts[0].y = 0;
03777
03778 emr.iType = EMR_POLYBEZIER16;
03779
03780 emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
03781
03782 lpoints = new POINT16[cpts];
03783
03784 for (int i=0; i<n; i++) {
03785 lpoints[i].x = points[i].x;
03786 lpoints[i].y = points[i].y;
03787 }
03788
03789 rclBounds = *bounds;
03790 }
03795 EMRPOLYBEZIER16 ( DATASTREAM& ds )
03796 {
03797 ds >> emr >> rclBounds >> cpts;
03798
03799 lpoints = new POINT16[cpts];
03800
03801 POINT16ARRAY points( lpoints, cpts );
03802
03803 ds >> points;
03804 }
03808 ~EMRPOLYBEZIER16 ( )
03809 {
03810 if ( lpoints ) delete[] lpoints;
03811 }
03815 bool serialize ( DATASTREAM ds )
03816 {
03817 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
03818 return true;
03819 }
03823 int size ( void ) const { return emr.nSize; }
03829 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03830 {
03831
03832 PolyBezier16( dc, lpoints, cpts );
03833 }
03834 #ifdef ENABLE_EDITING
03835
03838 void edit ( void ) const
03839 {
03840 printf( "*POLYBEZIER16*\n" );
03841 edit_rectl( "rclBounds", rclBounds );
03842 edit_point16array( "\t", cpts, lpoints );
03843 }
03844 #endif
03845 };
03846
03848
03851 class EMRPOLYBEZIERTO : public METARECORD, ::EMRPOLYBEZIER {
03852 POINTL* lpoints;
03853 public:
03859 EMRPOLYBEZIERTO ( const RECTL* bounds, const POINT* points, INT n )
03860 {
03861 cptl = n;
03862 aptl[0].x = 0;
03863 aptl[0].y = 0;
03864
03865 emr.iType = EMR_POLYBEZIERTO;
03866
03867 emr.nSize = sizeof( ::EMRPOLYBEZIERTO ) + sizeof( POINTL ) * (cptl-1);
03868
03869 lpoints = new POINTL[cptl];
03870
03871 for (int i=0; i<n; i++) {
03872 lpoints[i].x = points[i].x;
03873 lpoints[i].y = points[i].y;
03874 }
03875
03876 rclBounds = *bounds;
03877 }
03882 EMRPOLYBEZIERTO ( DATASTREAM& ds )
03883 {
03884 ds >> emr >> rclBounds >> cptl;
03885
03886 lpoints = new POINTL[cptl];
03887
03888 POINTLARRAY points( lpoints, cptl );
03889
03890 ds >> points;
03891 }
03895 ~EMRPOLYBEZIERTO ( )
03896 {
03897 if ( lpoints ) delete[] lpoints;
03898 }
03902 bool serialize ( DATASTREAM ds )
03903 {
03904 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
03905 return true;
03906 }
03910 int size ( void ) const { return emr.nSize; }
03916 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
03917 {
03918
03919 PolyBezierTo( dc, (POINT*)lpoints, cptl );
03920 }
03921 #ifdef ENABLE_EDITING
03922
03925 void edit ( void ) const
03926 {
03927 printf( "*POLYBEZIERTO*\n" );
03928 edit_rectl( "rclBounds", rclBounds );
03929 #if 0
03930 printf( "\tcptl : %ld\n", cptl );
03931 printf( "\taptl->\n" );
03932 for ( unsigned int i = 0; i < cptl; i++ )
03933 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
03934 #else
03935 edit_pointlarray( "\t", cptl, lpoints );
03936 #endif
03937 }
03938 #endif
03939 };
03940
03942
03945 class EMRPOLYBEZIERTO16 : public METARECORD, ::EMRPOLYBEZIER16 {
03946 POINT16* lpoints;
03947 public:
03953 EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT16* points, INT n )
03954 {
03955 cpts = n;
03956 apts[0].x = 0;
03957 apts[0].y = 0;
03958
03959 emr.iType = EMR_POLYBEZIERTO16;
03960
03961 emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
03962
03963 lpoints = new POINT16[cpts];
03964
03965 for (int i=0; i<n; i++) {
03966 lpoints[i].x = points[i].x;
03967 lpoints[i].y = points[i].y;
03968 }
03969
03970 rclBounds = *bounds;
03971 }
03978 EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT* points, INT n )
03979 {
03980 cpts = n;
03981 apts[0].x = 0;
03982 apts[0].y = 0;
03983
03984 emr.iType = EMR_POLYBEZIERTO16;
03985
03986 emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
03987
03988 lpoints = new POINT16[cpts];
03989
03990 for (int i=0; i<n; i++) {
03991 lpoints[i].x = points[i].x;
03992 lpoints[i].y = points[i].y;
03993 }
03994
03995 rclBounds = *bounds;
03996 }
04001 EMRPOLYBEZIERTO16 ( DATASTREAM& ds )
04002 {
04003 ds >> emr >> rclBounds >> cpts;
04004
04005 lpoints = new POINT16[cpts];
04006
04007 POINT16ARRAY points( lpoints, cpts );
04008
04009 ds >> points;
04010 }
04014 ~EMRPOLYBEZIERTO16 ( )
04015 {
04016 if ( lpoints ) delete[] lpoints;
04017 }
04021 bool serialize ( DATASTREAM ds )
04022 {
04023 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
04024 return true;
04025 }
04029 int size ( void ) const { return emr.nSize; }
04035 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04036 {
04037
04038 PolyBezierTo16( dc, lpoints, cpts );
04039 }
04040 #ifdef ENABLE_EDITING
04041
04044 void edit ( void ) const
04045 {
04046 printf( "*POLYBEZIERTO16*\n" );
04047 edit_rectl( "rclBounds", rclBounds );
04048 edit_point16array( "\t", cpts, lpoints );
04049 }
04050 #endif
04051 };
04052
04054
04057 class EMRPOLYLINETO : public METARECORD, ::EMRPOLYLINETO {
04058 POINTL* lpoints;
04059 public:
04065 EMRPOLYLINETO ( const RECTL* bounds, const POINT* points, INT n )
04066 {
04067 cptl = n;
04068 aptl[0].x = 0;
04069 aptl[0].y = 0;
04070
04071 emr.iType = EMR_POLYLINETO;
04072
04073 emr.nSize = sizeof( ::EMRPOLYLINETO ) + sizeof( POINTL ) * (cptl-1);
04074
04075 lpoints = new POINTL[cptl];
04076
04077 for (int i=0; i<n; i++) {
04078 lpoints[i].x = points[i].x;
04079 lpoints[i].y = points[i].y;
04080 }
04081
04082 rclBounds = *bounds;
04083 }
04088 EMRPOLYLINETO ( DATASTREAM& ds )
04089 {
04090 ds >> emr >> rclBounds >> cptl;
04091
04092 lpoints = new POINTL[cptl];
04093
04094 POINTLARRAY points( lpoints, cptl );
04095
04096 ds >> points;
04097 }
04101 ~EMRPOLYLINETO ( )
04102 {
04103 if ( lpoints ) delete[] lpoints;
04104 }
04108 bool serialize ( DATASTREAM ds )
04109 {
04110 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
04111 return true;
04112 }
04116 int size ( void ) const { return emr.nSize; }
04122 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04123 {
04124
04125 PolylineTo( dc, (POINT*)lpoints, cptl );
04126 }
04127 #ifdef ENABLE_EDITING
04128
04131 void edit ( void ) const
04132 {
04133 printf( "*POLYLINETO*\n" );
04134 edit_rectl( "rclBounds", rclBounds );
04135 #if 0
04136 printf( "\tcptl : %ld\n", cptl );
04137 printf( "\taptl->\n" );
04138 for ( unsigned int i = 0; i < cptl; i++ )
04139 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y );
04140 #else
04141 edit_pointlarray( "\t", cptl, lpoints );
04142 #endif
04143 }
04144 #endif
04145 };
04146
04148
04151 class EMRPOLYLINETO16 : public METARECORD, ::EMRPOLYLINETO16 {
04152 POINT16* lpoints;
04153 public:
04159 EMRPOLYLINETO16 ( const RECTL* bounds, const POINT16* points, INT n )
04160 {
04161 cpts = n;
04162 apts[0].x = 0;
04163 apts[0].y = 0;
04164
04165 emr.iType = EMR_POLYLINETO16;
04166
04167 emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
04168
04169 lpoints = new POINT16[cpts];
04170
04171 for (int i=0; i<n; i++) {
04172 lpoints[i].x = points[i].x;
04173 lpoints[i].y = points[i].y;
04174 }
04175
04176 rclBounds = *bounds;
04177 }
04184 EMRPOLYLINETO16 ( const RECTL* bounds, const POINT* points, INT n )
04185 {
04186 cpts = n;
04187 apts[0].x = 0;
04188 apts[0].y = 0;
04189
04190 emr.iType = EMR_POLYLINETO16;
04191
04192 emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
04193
04194 lpoints = new POINT16[cpts];
04195
04196 for (int i=0; i<n; i++) {
04197 lpoints[i].x = points[i].x;
04198 lpoints[i].y = points[i].y;
04199 }
04200
04201 rclBounds = *bounds;
04202 }
04207 EMRPOLYLINETO16 ( DATASTREAM& ds )
04208 {
04209 ds >> emr >> rclBounds >> cpts;
04210
04211 lpoints = new POINT16[cpts];
04212
04213 POINT16ARRAY points( lpoints, cpts );
04214
04215 ds >> points;
04216 }
04220 ~EMRPOLYLINETO16 ( )
04221 {
04222 if ( lpoints ) delete[] lpoints;
04223 }
04227 bool serialize ( DATASTREAM ds )
04228 {
04229 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
04230 return true;
04231 }
04235 int size ( void ) const { return emr.nSize; }
04241 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04242 {
04243
04244 PolylineTo16( dc, lpoints, cpts );
04245 }
04246 #ifdef ENABLE_EDITING
04247
04250 void edit ( void ) const
04251 {
04252 printf( "*POLYLINETO16*\n" );
04253 edit_rectl( "rclBounds", rclBounds );
04254 edit_point16array( "\t", cpts, lpoints );
04255 }
04256 #endif
04257 };
04258
04260
04265 class EMREXTTEXTOUTA : public METARECORD, ::EMREXTTEXTOUTA {
04266 PSTR string_a;
04267 int string_size;
04268
04269 INT* dx_i;
04270 public:
04280 EMREXTTEXTOUTA ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
04281 FLOAT yScale, const PEMRTEXT text, LPCSTR string,
04282 const INT* dx )
04283 {
04284 emr.iType = EMR_EXTTEXTOUTA;
04285 emr.nSize = sizeof( ::EMREXTTEXTOUTA );
04286
04287 rclBounds = *bounds;
04288
04289 iGraphicsMode = graphicsMode;
04290 exScale = xScale;
04291 eyScale = yScale;
04292
04293 emrtext = *text;
04294
04295 string_size = ROUND_TO_LONG( emrtext.nChars );
04296
04297 string_a = new CHAR[ string_size ];
04298
04299 memset( string_a, 0, sizeof(CHAR) * string_size );
04300
04301 for ( unsigned int i=0; i<emrtext.nChars; i++ )
04302 string_a[i] = *string++;
04303
04304 emrtext.offString = emr.nSize;
04305 emr.nSize += string_size * sizeof(CHAR);
04306
04307 if ( dx ) {
04308
04309 dx_i = new INT[ emrtext.nChars ];
04310
04311 for ( unsigned int i=0; i<emrtext.nChars; i++ )
04312 dx_i[i] = *dx++;
04313
04314 emrtext.offDx = emr.nSize;
04315 emr.nSize += emrtext.nChars * sizeof(INT);
04316 }
04317 else {
04318 emrtext.offDx = 0;
04319 dx_i = 0;
04320 }
04321 }
04326 EMREXTTEXTOUTA ( DATASTREAM& ds )
04327 {
04328 ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
04329
04330 if ( emrtext.offString != 0 ) {
04331 string_size = ROUND_TO_LONG( emrtext.nChars );
04332
04333 string_a = new CHAR[ string_size ];
04334
04335 memset( string_a, 0, sizeof(CHAR) * string_size );
04336
04337 CHARSTR string( string_a, string_size );
04338
04339 ds >> string;
04340 }
04341 else
04342 string_a = 0;
04343
04344 if ( emrtext.offDx ) {
04345 dx_i = new INT[ emrtext.nChars ];
04346
04347 INTARRAY dx_is( dx_i, emrtext.nChars );
04348
04349 ds >> dx_is;
04350 }
04351 else
04352 dx_i = 0;
04353 }
04358 ~EMREXTTEXTOUTA ( )
04359 {
04360 if ( string_a ) delete[] string_a;
04361 if ( dx_i ) delete[] dx_i;
04362 }
04366 bool serialize ( DATASTREAM ds )
04367 {
04368 ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
04369 << emrtext << CHARSTR( string_a, string_size );
04370 if ( dx_i )
04371 ds << INTARRAY( dx_i, emrtext.nChars );
04372 return true;
04373 }
04377 int size ( void ) const { return emr.nSize; }
04383 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04384 {
04385 RECT rect;
04386 rect.left = emrtext.rcl.left;
04387 rect.top = emrtext.rcl.top;
04388 rect.right = emrtext.rcl.right;
04389 rect.bottom = emrtext.rcl.bottom;
04390
04391 ExtTextOutA( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
04392 emrtext.fOptions, &rect, string_a, emrtext.nChars,
04393 dx_i );
04394 }
04395 #ifdef ENABLE_EDITING
04396
04399 void edit ( void ) const
04400 {
04401 printf( "*EXTTEXTOUTA*\n" );
04402 edit_rectl( "rclBounds", rclBounds );
04403 printf( "\tiGraphicsMode\t: " );
04404 switch ( iGraphicsMode ) {
04405 case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
04406 case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
04407 default: printf( "unknown(%ld)\n", iGraphicsMode );
04408 }
04409 printf( "\texScale\t\t: %f\n", exScale );
04410 printf( "\teyScale\t\t: %f\n", eyScale );
04411 printf( "\tptlReference\t: (%ld,%ld)\n", emrtext.ptlReference.x,
04412 emrtext.ptlReference.y );
04413 printf( "\tnChars\t\t: %ld\n", emrtext.nChars );
04414 printf( "\toffString\t: %ld\n", emrtext.offString );
04415 printf( "\tfOptions\t: " );
04416 if ( emrtext.fOptions == 0 )
04417 printf( "None" );
04418 else {
04419 if ( emrtext.fOptions & ETO_GRAYED ) {
04420 printf( "ETO_GRAYED" );
04421 if ( emrtext.fOptions & ~ETO_GRAYED )
04422 printf( " | " );
04423 }
04424 if ( emrtext.fOptions & ETO_OPAQUE ) {
04425 printf( "ETO_OPAQUE" );
04426 if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
04427 printf( " | " );
04428 }
04429 if ( emrtext.fOptions & ETO_CLIPPED ) {
04430 printf( "ETO_CLIPPED" );
04431 if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
04432 printf( " | " );
04433 }
04434 if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
04435 printf( "ETO_GLYPH_INDEX" );
04436 if ( emrtext.fOptions &
04437 ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
04438 printf( " | " );
04439 }
04440 if ( emrtext.fOptions & ETO_RTLREADING ) {
04441 printf( "ETO_RTLREADING" );
04442 if ( emrtext.fOptions &
04443 ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
04444 ETO_RTLREADING) )
04445 printf( " | " );
04446 }
04447 if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
04448 printf( "ETO_IGNORELANGUAGE" );
04449 }
04450 printf( "\n" );
04451 edit_rectl( "rcl\t", emrtext.rcl );
04452 printf( "\toffDx\t\t: %ld\n", emrtext.offDx );
04453 printf( "\tString:\n\t\t%s\n", string_a );
04454
04455 if ( emrtext.offDx != 0 ) {
04456 printf( "\tOffsets:\n\t\t" );
04457 for ( unsigned int i = 0; i < emrtext.nChars; i++ )
04458 printf( "%d ", dx_i[i] );
04459 printf( "\n" );
04460 }
04461 }
04462 #endif
04463 };
04464
04466
04469 class EMRSETPIXELV : public METARECORD, ::EMRSETPIXELV {
04470 public:
04476 EMRSETPIXELV ( INT x, INT y, COLORREF color )
04477 {
04478 emr.iType = EMR_SETPIXELV;
04479 emr.nSize = sizeof( ::EMRSETPIXELV );
04480 ptlPixel.x = x;
04481 ptlPixel.y = y;
04482 crColor = color;
04483 }
04488 EMRSETPIXELV ( DATASTREAM& ds )
04489 {
04490 ds >> emr >> ptlPixel >> crColor;
04491 }
04495 bool serialize ( DATASTREAM ds )
04496 {
04497 ds << emr << ptlPixel << crColor;
04498 return true;
04499 }
04503 int size ( void ) const { return emr.nSize; }
04509 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04510 {
04511 SetPixel( dc, ptlPixel.x, ptlPixel.y, crColor );
04512 }
04513 #ifdef ENABLE_EDITING
04514
04517 void edit ( void ) const
04518 {
04519 printf( "*SETPIXELV*\n" );
04520 edit_pointl( "ptlPixel", ptlPixel );
04521 edit_color( "crColor\t", crColor );
04522 }
04523 #endif
04524 };
04525
04526 class PEN;
04527 class EXTPEN;
04528 class BRUSH;
04529 class FONT;
04530 class PALETTE;
04531
04533
04536 class EMRCREATEPEN : public METARECORD, public ::EMRCREATEPEN
04537 {
04538 public:
04543 EMRCREATEPEN ( PEN* pen, HGDIOBJ handle );
04548 EMRCREATEPEN ( DATASTREAM& ds );
04552 bool serialize ( DATASTREAM ds )
04553 {
04554 ds << emr << ihPen << lopn;
04555 return true;
04556 }
04560 int size ( void ) const { return emr.nSize; }
04566 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04567 #ifdef ENABLE_EDITING
04568
04571 void edit ( void ) const
04572 {
04573 printf( "*CREATEPEN*\n" );
04574 printf( "\tihPen\t\t: 0x%lx\n", ihPen );
04575 edit_pen_style( "lopn.lopnStyle", lopn.lopnStyle );
04576 printf( "\tlopn.lopnWidth\t: %ld, %ld\n", lopn.lopnWidth.x, lopn.lopnWidth.y );
04577 edit_color( "lopn.lopnColor", lopn.lopnColor );
04578 }
04579 #endif
04580 };
04581
04583
04587 class EMREXTCREATEPEN : public METARECORD, public ::EMREXTCREATEPEN
04588 {
04589 public:
04594 EMREXTCREATEPEN ( EXTPEN* pen, HGDIOBJ handle );
04599 EMREXTCREATEPEN ( DATASTREAM& ds );
04603 bool serialize ( DATASTREAM ds )
04604 {
04605 ds << emr << ihPen << offBmi << cbBmi << offBits << cbBits << elp;
04606 return true;
04607 }
04611 int size ( void ) const { return emr.nSize; }
04617 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04618 #ifdef ENABLE_EDITING
04619
04622 void edit ( void ) const
04623 {
04624 printf( "*EXTCREATEPEN*\n" );
04625 printf( "\tihPen\t\t\t: 0x%lx\n", ihPen );
04626 printf( "\toffBmi\t\t\t: %ld\n", offBmi );
04627 printf( "\tcbBmi\t\t\t: %ld\n", cbBmi );
04628 printf( "\toffBits\t\t\t: %ld\n", offBits );
04629 printf( "\tcbBits\t\t\t: %ld\n", cbBits );
04630 edit_pen_style( "elp.elpPenStyle\t", elp.elpPenStyle );
04631 printf( "\telp.elpWidth\t\t: %ld\n", elp.elpWidth );
04632 edit_brush_style( "elp.elpBrushStyle", elp.elpBrushStyle );
04633 edit_color( "elp.elpColor\t", elp.elpColor );
04634 edit_brush_hatch( "elp.elpHatch\t", elp.elpHatch );
04635 printf( "\telp.elpNumEntries\t: %ld\n", elp.elpNumEntries );
04636 }
04637 #endif
04638 };
04639
04641
04644 class EMRCREATEBRUSHINDIRECT : public METARECORD, public ::EMRCREATEBRUSHINDIRECT
04645 {
04646 public:
04651 EMRCREATEBRUSHINDIRECT ( BRUSH* brush, HGDIOBJ handle );
04656 EMRCREATEBRUSHINDIRECT ( DATASTREAM& ds );
04660 bool serialize ( DATASTREAM ds )
04661 {
04662 ds << emr << ihBrush << lb;
04663 return true;
04664 }
04668 int size ( void ) const { return emr.nSize; }
04674 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04675 #ifdef ENABLE_EDITING
04676
04679 void edit ( void ) const
04680 {
04681 printf( "*CREATEBRUSHINDIRECT*\n" );
04682 printf( "\tihBrush\t\t: 0x%lx\n", ihBrush );
04683 edit_brush_style( "lb.lbStyle", lb.lbStyle );
04684 edit_color( "lb.lbColor", lb.lbColor );
04685 edit_brush_hatch( "lb.lbHatch", lb.lbHatch );
04686 }
04687 #endif
04688 };
04689
04691
04694 class EMREXTCREATEFONTINDIRECTW : public METARECORD, public ::EMREXTCREATEFONTINDIRECTW
04695 {
04696 public:
04701 EMREXTCREATEFONTINDIRECTW ( FONT* font, HGDIOBJ handle );
04706 EMREXTCREATEFONTINDIRECTW ( DATASTREAM& ds );
04710 bool serialize ( DATASTREAM ds )
04711 {
04712
04713
04714
04715
04716 ds << emr << ihFont << elfw << PADDING( 2 );
04717
04718 return true;
04719 }
04723 int size ( void ) const { return emr.nSize; }
04729 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04730 #ifdef ENABLE_EDITING
04731
04734 void edit ( void ) const
04735 {
04736 printf( "*EXTCREATEFONTINDIRECTW*\n" );
04737 printf( "\tihFont\t\t\t: %ld\n", ihFont );
04738 printf( "\tlfHeight\t\t: %ld\n", elfw.elfLogFont.lfHeight );
04739 printf( "\tlfWidth\t\t\t: %ld\n", elfw.elfLogFont.lfWidth );
04740 printf( "\tlfEscapement\t\t: %ld\n", elfw.elfLogFont.lfEscapement );
04741 printf( "\tlfOrientation\t\t: %ld\n", elfw.elfLogFont.lfOrientation );
04742 printf( "\tlfWeight\t\t: " );
04743 switch ( elfw.elfLogFont.lfWeight ) {
04744 case FW_DONTCARE: printf( "FW_DONTCARE\n" ); break;
04745 case FW_THIN: printf( "FW_THIN\n" ); break;
04746 case FW_EXTRALIGHT: printf( "FW_EXTRALIGHT\n" ); break;
04747 case FW_LIGHT: printf( "FW_LIGHT\n" ); break;
04748 case FW_NORMAL: printf( "FW_NORMAL\n" ); break;
04749 case FW_MEDIUM: printf( "FW_MEDIUM\n" ); break;
04750 case FW_SEMIBOLD: printf( "FW_SEMIBOLD\n" ); break;
04751 case FW_BOLD: printf( "FW_BOLD\n" ); break;
04752 case FW_EXTRABOLD: printf( "FW_EXTRABOLD\n" ); break;
04753 case FW_BLACK: printf( "FW_BLACK\n" ); break;
04754 }
04755 printf( "\tlfItalic\t\t: %d\n", elfw.elfLogFont.lfItalic );
04756 printf( "\tlfUnderline\t\t: %d\n", elfw.elfLogFont.lfUnderline );
04757 printf( "\tlfStrikeOut\t\t: %d\n", elfw.elfLogFont.lfStrikeOut );
04758 printf( "\tlfCharSet\t\t: %d\n", elfw.elfLogFont.lfCharSet );
04759 printf( "\tlfOutPrecision\t\t: %d\n", elfw.elfLogFont.lfOutPrecision );
04760 printf( "\tlfClipPrecision\t\t: %d\n", elfw.elfLogFont.lfClipPrecision );
04761 printf( "\tlfQuality\t\t: %d\n", elfw.elfLogFont.lfQuality );
04762 printf( "\tlfPitchAndFamily\t: %d\n", elfw.elfLogFont.lfPitchAndFamily );
04763 int i = 0;
04764 printf( "\tlfFaceName\t\t: '" );
04765 while ( elfw.elfLogFont.lfFaceName[i] != 0 && i < LF_FACESIZE ) {
04766 putchar( elfw.elfLogFont.lfFaceName[i] );
04767 i++;
04768 }
04769 puts( "'" );
04770
04771 i = 0;
04772 printf( "\telfFullName\t\t: '" );
04773 while ( elfw.elfFullName[i] != 0 && i < LF_FULLFACESIZE ) {
04774 putchar( elfw.elfFullName[i] );
04775 i++;
04776 }
04777 puts( "'" );
04778
04779 i = 0;
04780 printf( "\telfStyle\t\t: '" );
04781 while ( elfw.elfStyle[i] != 0 && i < LF_FACESIZE ) {
04782 putchar( elfw.elfStyle[i] );
04783 i++;
04784 }
04785 puts( "'" );
04786
04787 printf( "\telfVersion\t\t: %ld\n", elfw.elfVersion );
04788 printf( "\telfStyleSize\t\t: %ld\n", elfw.elfStyleSize );
04789 printf( "\telfMatch\t\t: %ld\n", elfw.elfMatch );
04790 printf( "\telfVendorId\t\t: '%s'\n", elfw.elfVendorId );
04791 printf( "\telfCulture\t\t: %ld\n", elfw.elfCulture );
04792 printf( "\telfPanose\t\t:\n" );
04793 printf( "\t\tbFamilyType\t\t: %d\n", elfw.elfPanose.bFamilyType );
04794 printf( "\t\tbSerifStyle\t\t: %d\n", elfw.elfPanose.bSerifStyle );
04795 printf( "\t\tbWeight\t\t\t: %d\n", elfw.elfPanose.bWeight );
04796 printf( "\t\tbProportion\t\t: %d\n", elfw.elfPanose.bProportion );
04797 printf( "\t\tbContrast\t\t: %d\n", elfw.elfPanose.bContrast );
04798 printf( "\t\tbStrokeVariation\t: %d\n", elfw.elfPanose.bStrokeVariation );
04799 printf( "\t\tbArmStyle\t\t: %d\n", elfw.elfPanose.bArmStyle );
04800 printf( "\t\tbLetterform\t\t: %d\n", elfw.elfPanose.bLetterform );
04801 printf( "\t\tbMidline\t\t: %d\n", elfw.elfPanose.bMidline );
04802 printf( "\t\tbXHeight\t\t: %d\n", elfw.elfPanose.bXHeight );
04803 }
04804 #endif
04805 };
04806
04808
04811 class EMRCREATEPALETTE : public METARECORD, public ::EMRCREATEPALETTE
04812 {
04813 public:
04818 EMRCREATEPALETTE ( PALETTE* palette, HGDIOBJ handle );
04823 EMRCREATEPALETTE ( DATASTREAM& ds );
04827 bool serialize ( DATASTREAM ds )
04828 {
04829 ds << emr << ihPal << lgpl;
04830 return true;
04831 }
04835 int size ( void ) const { return emr.nSize; }
04841 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
04842 #ifdef ENABLE_EDITING
04843
04846 void edit ( void ) const
04847 {
04848 printf( "*CREATEPALETTE* (not really handled by libEMF)\n" );
04849 }
04850 #endif
04851 };
04852
04854
04857 class EMRFILLPATH : public METARECORD, ::EMRFILLPATH {
04858 public:
04863 EMRFILLPATH ( const RECTL* bounds )
04864 {
04865 emr.iType = EMR_FILLPATH;
04866 emr.nSize = sizeof( ::EMRFILLPATH );
04867 rclBounds = *bounds;
04868 }
04873 EMRFILLPATH ( DATASTREAM& ds )
04874 {
04875 ds >> emr >> rclBounds;
04876 }
04880 bool serialize ( DATASTREAM ds )
04881 {
04882 ds << emr << rclBounds;
04883 return true;
04884 }
04888 int size ( void ) const { return emr.nSize; }
04894 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04895 {
04896 FillPath( dc );
04897 }
04898 #ifdef ENABLE_EDITING
04899
04902 void edit ( void ) const
04903 {
04904 printf( "*FILLPATH*\n" );
04905 edit_rectl( "rclBounds", rclBounds );
04906 }
04907 #endif
04908 };
04910
04913 class EMRSTROKEPATH : public METARECORD, ::EMRSTROKEPATH {
04914 public:
04919 EMRSTROKEPATH ( const RECTL* bounds )
04920 {
04921 emr.iType = EMR_STROKEPATH;
04922 emr.nSize = sizeof( ::EMRSTROKEPATH );
04923 rclBounds = *bounds;
04924 }
04929 EMRSTROKEPATH ( DATASTREAM& ds )
04930 {
04931 ds >> emr >> rclBounds;
04932 }
04936 bool serialize ( DATASTREAM ds )
04937 {
04938 ds << emr << rclBounds;
04939 return true;
04940 }
04944 int size ( void ) const { return emr.nSize; }
04950 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
04951 {
04952 StrokePath( dc );
04953 }
04954 #ifdef ENABLE_EDITING
04955
04958 void edit ( void ) const
04959 {
04960 printf( "*STROKEPATH*\n" );
04961 edit_rectl( "rclBounds", rclBounds );
04962 }
04963 #endif
04964 };
04966
04969 class EMRBEGINPATH : public METARECORD, ::EMRBEGINPATH {
04970 public:
04974 EMRBEGINPATH ( void )
04975 {
04976 emr.iType = EMR_BEGINPATH;
04977 emr.nSize = sizeof( ::EMRBEGINPATH );
04978 }
04983 EMRBEGINPATH ( DATASTREAM& ds )
04984 {
04985 ds >> emr;
04986 }
04990 bool serialize ( DATASTREAM ds )
04991 {
04992 ds << emr;
04993 return true;
04994 }
04998 int size ( void ) const { return emr.nSize; }
05004 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05005 {
05006 BeginPath( dc );
05007 }
05008 #ifdef ENABLE_EDITING
05009
05012 void edit ( void ) const
05013 {
05014 printf( "*BEGINPATH*\n" );
05015 }
05016 #endif
05017 };
05019
05022 class EMRENDPATH : public METARECORD, ::EMRENDPATH {
05023 public:
05027 EMRENDPATH ( void )
05028 {
05029 emr.iType = EMR_ENDPATH;
05030 emr.nSize = sizeof( ::EMRENDPATH );
05031 }
05036 EMRENDPATH ( DATASTREAM& ds )
05037 {
05038 ds >> emr;
05039 }
05043 bool serialize ( DATASTREAM ds )
05044 {
05045 ds << emr;
05046 return true;
05047 }
05051 int size ( void ) const { return emr.nSize; }
05057 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05058 {
05059 EndPath( dc );
05060 }
05061 #ifdef ENABLE_EDITING
05062
05065 void edit ( void ) const
05066 {
05067 printf( "*ENDPATH*\n" );
05068 }
05069 #endif
05070 };
05072
05075 class EMRCLOSEFIGURE : public METARECORD, ::EMRCLOSEFIGURE {
05076 public:
05080 EMRCLOSEFIGURE ( void )
05081 {
05082 emr.iType = EMR_CLOSEFIGURE;
05083 emr.nSize = sizeof( ::EMRCLOSEFIGURE );
05084 }
05089 EMRCLOSEFIGURE ( DATASTREAM& ds )
05090 {
05091 ds >> emr;
05092 }
05096 bool serialize ( DATASTREAM ds )
05097 {
05098 ds << emr;
05099 return true;
05100 }
05104 int size ( void ) const { return emr.nSize; }
05110 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05111 {
05112 CloseFigure( dc );
05113 }
05114 #ifdef ENABLE_EDITING
05115
05118 void edit ( void ) const
05119 {
05120 printf( "*CLOSEFIGURE*\n" );
05121 }
05122 #endif
05123 };
05125
05129 class EMRSAVEDC : public METARECORD, ::EMRSAVEDC {
05130 public:
05134 EMRSAVEDC ( void )
05135 {
05136 emr.iType = EMR_SAVEDC;
05137 emr.nSize = sizeof( ::EMRSAVEDC );
05138 }
05143 EMRSAVEDC ( DATASTREAM& ds )
05144 {
05145 ds >> emr;
05146 }
05150 bool serialize ( DATASTREAM ds )
05151 {
05152 ds << emr;
05153 return true;
05154 }
05158 int size ( void ) const { return emr.nSize; }
05164 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05165 {
05166 SaveDC( dc );
05167 }
05168 #ifdef ENABLE_EDITING
05169
05172 void edit ( void ) const
05173 {
05174 printf( "*SAVEDC*\n" );
05175 }
05176 #endif
05177 };
05179
05182 class EMRRESTOREDC : public METARECORD, ::EMRRESTOREDC {
05183 public:
05187 EMRRESTOREDC ( INT n )
05188 {
05189 emr.iType = EMR_RESTOREDC;
05190 emr.nSize = sizeof( ::EMRRESTOREDC );
05191 iRelative = n;
05192 }
05197 EMRRESTOREDC ( DATASTREAM& ds )
05198 {
05199 ds >> emr >> iRelative;
05200 }
05204 bool serialize ( DATASTREAM ds )
05205 {
05206 ds << emr << iRelative;
05207 return true;
05208 }
05212 int size ( void ) const { return emr.nSize; }
05218 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05219 {
05220 RestoreDC( dc, iRelative );
05221 }
05222 #ifdef ENABLE_EDITING
05223
05226 void edit ( void ) const
05227 {
05228 printf( "*RESTOREDC*\n" );
05229 printf( "\tiRelative: %ld\n", iRelative );
05230 }
05231 #endif
05232 };
05234
05237 class EMRSETMETARGN : public METARECORD, ::EMRSETMETARGN {
05238 public:
05242 EMRSETMETARGN ( void )
05243 {
05244 emr.iType = EMR_SETMETARGN;
05245 emr.nSize = sizeof( ::EMRSETMETARGN );
05246 }
05251 EMRSETMETARGN ( DATASTREAM& ds )
05252 {
05253 ds >> emr;
05254 }
05258 bool serialize ( DATASTREAM ds )
05259 {
05260 ds << emr;
05261 return true;
05262 }
05266 int size ( void ) const { return emr.nSize; }
05272 void execute ( METAFILEDEVICECONTEXT* , HDC dc ) const
05273 {
05274 SetMetaRgn( dc );
05275 }
05276 #ifdef ENABLE_EDITING
05277
05280 void edit ( void ) const
05281 {
05282 printf( "*SETMETARGN*\n" );
05283 }
05284 #endif
05285 };
05286
05288
05291 class PEN : public GRAPHICSOBJECT, public LOGPEN {
05292 public:
05296 PEN ( const LOGPEN* lpen )
05297 {
05298 lopnStyle = lpen->lopnStyle;
05299 lopnWidth = lpen->lopnWidth;
05300 lopnColor = lpen->lopnColor;
05301 }
05305 OBJECTTYPE getType ( void ) const { return O_PEN; }
05312 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05313 {
05314 contexts[dc] = emf_handle;
05315 return new EMRCREATEPEN( this, emf_handle );
05316 }
05317 };
05318
05320
05323 class EXTPEN : public GRAPHICSOBJECT, public EXTLOGPEN {
05324 public:
05328 EXTPEN ( const EXTLOGPEN* lpen )
05329 {
05330 elpPenStyle = lpen->elpPenStyle;
05331 elpWidth = lpen->elpWidth;
05332 elpBrushStyle = lpen->elpBrushStyle;
05333 elpColor = lpen->elpColor;
05334 elpHatch = lpen->elpHatch;
05335 elpNumEntries = 0;
05336 elpStyleEntry[0] = 0;
05337 }
05341 OBJECTTYPE getType ( void ) const { return O_EXTPEN; }
05348 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05349 {
05350 contexts[dc] = emf_handle;
05351 return new EMREXTCREATEPEN( this, emf_handle );
05352 }
05353 };
05354
05356
05359 class BRUSH : public GRAPHICSOBJECT, public LOGBRUSH {
05360 public:
05364 BRUSH ( const LOGBRUSH* lbrush )
05365 {
05366 lbStyle = lbrush->lbStyle;
05367 lbColor = lbrush->lbColor;
05368 lbHatch = lbrush->lbHatch;
05369 }
05373 OBJECTTYPE getType ( void ) const { return O_BRUSH; }
05380 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05381 {
05382 contexts[dc] = emf_handle;
05383 return new EMRCREATEBRUSHINDIRECT( this, emf_handle );
05384 }
05385 };
05386
05388
05391 class FONT : public GRAPHICSOBJECT, public EXTLOGFONTW {
05392 public:
05396 FONT ( const LOGFONTW* lfont )
05397 {
05398 this->elfLogFont = *lfont;
05399
05400
05401 memset( &elfFullName, 0, sizeof elfFullName );
05402 memset( &elfStyle, 0, sizeof elfStyle );
05403 elfVersion = ELF_VERSION;
05404 elfStyleSize = 0;
05405 elfMatch = 0;
05406 elfReserved = 0;
05407 memset( &elfVendorId, 0, sizeof elfVendorId );
05408 elfCulture = ELF_CULTURE_LATIN;
05409 memset( &elfPanose, 1, sizeof(PANOSE) );
05410 }
05414 OBJECTTYPE getType ( void ) const { return O_FONT; }
05421 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05422 {
05423 contexts[dc] = emf_handle;
05424 return new EMREXTCREATEFONTINDIRECTW( this, emf_handle );
05425 }
05426 };
05427
05429
05432 class PALETTE : public GRAPHICSOBJECT, public LOGPALETTE {
05433 public:
05437 PALETTE ( const LOGPALETTE* lpalette )
05438 {
05439 (void)lpalette;
05440 palVersion = 0;
05441 palNumEntries = 0;
05442 PALETTEENTRY zero_entry = { 0, 0, 0, 0 };
05443 palPalEntry[0] = zero_entry;
05444 }
05448 OBJECTTYPE getType ( void ) const { return O_PALETTE; }
05455 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
05456 {
05457 contexts[dc] = emf_handle;
05458 return new EMRCREATEPALETTE( this, emf_handle );
05459 }
05460 };
05461
05463
05469 class METAFILEDEVICECONTEXT : public OBJECT {
05477 void init ( const RECT* size, LPCWSTR description_w ) {
05478
05479
05480
05481
05482 handles.push_back( true );
05483
05484
05485
05486 header = new ENHMETAHEADER ( description_w );
05487 records.push_back( header );
05488
05489
05490
05491 if ( size ) {
05492 update_frame = false;
05493
05494 header->rclFrame.left = size->left;
05495 header->rclFrame.top = size->top;
05496 header->rclFrame.right = size->right;
05497 header->rclFrame.bottom = size->bottom;
05498
05499 header->rclBounds.left =
05500 size->left * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
05501 header->rclBounds.top =
05502 size->top * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
05503 header->rclBounds.right =
05504 size->right * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
05505 header->rclBounds.bottom =
05506 size->bottom * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
05507 }
05508 else {
05509 update_frame = true;
05510
05511 header->rclBounds.left = -10;
05512 header->rclBounds.top = -10;
05513 header->rclBounds.right = 10;
05514 header->rclBounds.bottom = 10;
05515
05516 header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
05517 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05518 header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
05519 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05520 header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
05521 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05522 header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
05523 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05524 }
05525
05526
05527
05528 SIZEL default_resolution = { RESOLUTION, RESOLUTION };
05529 resolution = default_resolution;
05530 SIZEL default_viewport_ext = { 1, 1 };
05531 viewport_ext = default_viewport_ext;
05532 POINT default_viewport_org = { 0, 0 };
05533 viewport_org = default_viewport_org;
05534 SIZEL default_window_ext = { 1, 1 };
05535 window_ext = default_window_ext;
05536 POINT default_window_org = { 0, 0 };
05537 window_org = default_window_org;
05538
05539 min_device_point = viewport_org;
05540 max_device_point = viewport_org;
05541
05542 pen = (PEN*)globalObjects.find( BLACK_PEN | ENHMETA_STOCK_OBJECT );
05543 brush = (BRUSH*)globalObjects.find( BLACK_BRUSH | ENHMETA_STOCK_OBJECT );
05544 font = (FONT*)globalObjects.find( DEVICE_DEFAULT_FONT | ENHMETA_STOCK_OBJECT);
05545 palette = (PALETTE*)globalObjects.find( DEFAULT_PALETTE|ENHMETA_STOCK_OBJECT);
05546
05547 text_alignment = TA_BASELINE;
05548 text_color = RGB(0,0,0);
05549 bk_color = RGB(0xff,0xff,0xff);
05550 bk_mode = OPAQUE;
05551 polyfill_mode = ALTERNATE;
05552 map_mode = MM_TEXT;
05553
05554 handle = globalObjects.add( this );
05555 }
05556
05557 public:
05561 ::FILE* fp;
05566 DATASTREAM ds;
05570 ENHMETAHEADER* header;
05574 std::vector< EMF::METARECORD* > records;
05575
05576
05577 SIZEL resolution;
05578 SIZEL viewport_ext;
05579 POINT viewport_org;
05580 SIZEL window_ext;
05581 POINT window_org;
05582 bool update_frame;
05583 POINT min_device_point;
05584 POINT max_device_point;
05585 POINT point;
05586 PEN* pen;
05587 BRUSH* brush;
05588 FONT* font;
05589 PALETTE* palette;
05590 UINT text_alignment;
05591 COLORREF text_color;
05592 COLORREF bk_color;
05593 INT bk_mode;
05594 INT polyfill_mode;
05595 INT map_mode;
05596
05602 std::vector< bool > handles;
05603
05609 std::map< HGDIOBJ, HGDIOBJ > emf_handles;
05610
05621 METAFILEDEVICECONTEXT ( FILE* fp_, const RECT* size,
05622 LPCWSTR description_w )
05623 : fp(fp_), ds( fp_ )
05624 {
05625 init( size, description_w );
05626 }
05631 virtual ~METAFILEDEVICECONTEXT ( )
05632 {
05633
05634
05635 if ( records.size() > 0 )
05636 deleteMetafile();
05637 }
05641 OBJECTTYPE getType ( void ) const { return O_METAFILEDEVICECONTEXT; }
05646 DWORD nextHandle ( void )
05647 {
05648 for ( unsigned int i = 1; i < handles.size(); i++ ) {
05649 if ( !handles[i] ) {
05650 handles[i] = true;
05651 return i;
05652 }
05653 }
05654 handles.push_back( true );
05655
05656
05657 header->nHandles = handles.size();
05658 return handles.size()-1;
05659 }
05663 void clearHandle ( DWORD handle )
05664 {
05665 handles[handle] = false;
05666 }
05672 void appendRecord ( METARECORD* record )
05673 {
05674 records.push_back( record );
05675
05676 header->nBytes += record->size();
05677 header->nRecords++;
05678 }
05684 void appendHandle ( METARECORD* record )
05685 {
05686 records.push_back( record );
05687
05688 header->nBytes += record->size();
05689 header->nRecords++;
05690 }
05695 void deleteMetafile ( void )
05696 {
05697 for ( std::vector<METARECORD*>::const_iterator r = records.begin();
05698 r != records.end();
05699 r++ ) {
05700 delete *r;
05701 }
05702 records.clear();
05703 }
05708 void mergePoint ( const LONG& x, const LONG& y )
05709 {
05710 POINT p;
05711 p.x = x;
05712 p.y = y;
05713 mergePoint( p );
05714 }
05719 void mergePoint( const POINT& p )
05720 {
05721 POINT device_point;
05722
05723
05724
05725
05726 device_point.x = (LONG)( (float)( p.x - window_org.x ) / window_ext.cx *
05727 viewport_ext.cx + viewport_org.x );
05728
05729 device_point.y = (LONG)( (float)( p.y - window_org.y ) / window_ext.cy *
05730 viewport_ext.cy + viewport_org.y );
05731
05732
05733
05734 if ( device_point.x < min_device_point.x ) {
05735 min_device_point.x = device_point.x;
05736 if ( update_frame ) {
05737 header->rclBounds.left = min_device_point.x - 10;
05738 header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
05739 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05740 }
05741 }
05742 else if ( device_point.x > max_device_point.x ) {
05743 max_device_point.x = device_point.x;
05744 if ( update_frame ) {
05745 header->rclBounds.right = max_device_point.x + 10;
05746 header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
05747 header->szlMillimeters.cx * 100 / header->szlDevice.cx );
05748 }
05749 }
05750
05751 if ( device_point.y < min_device_point.y ) {
05752 min_device_point.y = device_point.y;
05753 if ( update_frame ) {
05754 header->rclBounds.top = min_device_point.y - 10;
05755 header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
05756 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05757 }
05758 }
05759 else if ( device_point.y > max_device_point.y ) {
05760 max_device_point.y = device_point.y;
05761 if ( update_frame ) {
05762 header->rclBounds.bottom = max_device_point.y + 10;
05763 header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
05764 header->szlMillimeters.cy * 100 / header->szlDevice.cy );
05765 }
05766 }
05767 }
05768 };
05769
05770 }
05771
05772 #endif