EMF
1.0
|
00001 /* -*- c++ -*- 00002 * EMF: A library for generating ECMA-234 Enhanced Metafiles 00003 * Copyright (C) 2002, 2003 lignum Computing, Inc. <dallenbarnett@users.sourceforge.net> 00004 * $Id: libemf.h 62 2012-11-06 12:16:29Z dallenbarnett $ 00005 * 00006 * This library is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * This library is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with this library; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00019 * 00020 */ 00021 #ifndef _LIBEMF_H 00022 #define _LIBEMF_H 1 00023 00024 #include <cmath> 00025 #include <vector> 00026 #include <map> 00027 #include <functional> 00028 #include <algorithm> 00029 00030 #include <config.h> 00031 #include <libEMF/emf.h> 00032 00033 #include <libEMF/wine/w16.h> 00034 00035 namespace EMF { 00040 #if 1 00041 const int XMAX_PIXELS = 1024; /*(INT_MAX)*/ 00042 #else 00043 const int XMAX_PIXELS = 1280; /*(INT_MAX)*/ 00044 #endif 00045 00049 #if 1 00050 const int YMAX_PIXELS = 768; /*(INT_MAX)*/ 00051 #else 00052 const int YMAX_PIXELS = 1024; /*(INT_MAX)*/ 00053 #endif 00054 00059 const int XMAX_MM = 320; 00065 const int YMAX_MM = 240; 00069 const int RESOLUTION = 96; 00073 static inline int ROUND_TO_LONG ( int n ) { return ((n+3)/4)*4; } 00074 00076 00081 struct WCHARSTR { 00082 WCHAR *const string_; 00083 const int length_; 00084 00089 WCHARSTR ( WCHAR *const string, const int length ) 00090 : string_( string ), length_( length ) {} 00091 }; 00092 00094 00099 struct CHARSTR { 00100 CHAR *const string_; 00101 const int length_; 00102 00107 CHARSTR ( CHAR *const string, const int length ) 00108 : string_( string ), length_( length ) {} 00109 }; 00110 00112 00116 struct BYTEARRAY { 00117 BYTE *const array_; 00118 const int n_; 00119 00124 BYTEARRAY ( BYTE *const array, const int n ) 00125 : array_( array ), n_( n ) {} 00126 }; 00127 00129 00132 struct POINTLARRAY { 00133 POINTL *const points_; 00134 const DWORD n_; 00135 00140 POINTLARRAY ( POINTL *const points, const DWORD n ) 00141 : points_( points ), n_( n ) {} 00142 }; 00143 00145 00148 struct POINT16ARRAY { 00149 POINT16 *const points_; 00150 const DWORD n_; 00151 00156 POINT16ARRAY ( POINT16 *const points, const DWORD n ) 00157 : points_( points ), n_( n ) {} 00158 }; 00159 00161 00164 struct INTARRAY { 00165 INT *const ints_; 00166 const DWORD n_; 00167 00172 INTARRAY ( INT *const ints, const DWORD n ) 00173 : ints_( ints ), n_( n ) {} 00174 }; 00175 00177 00180 struct DWORDARRAY { 00181 DWORD *const dwords_; 00182 const DWORD n_; 00183 00188 DWORDARRAY ( DWORD *const dwords, const DWORD n ) 00189 : dwords_( dwords ), n_( n ) {} 00190 }; 00191 00193 00196 struct PADDING { 00197 static const char padding_[4]; 00198 const int size_; 00199 00203 PADDING ( const int size ) : size_( size ) {} 00204 }; 00205 00207 00214 class DATASTREAM { 00215 bool swap_; 00216 ::FILE* fp_; 00217 00218 static bool bigEndian ( void ); 00219 public: 00225 DATASTREAM ( ::FILE* fp = 0 ) : swap_( bigEndian() ), fp_( fp ) {} 00230 void setStream ( ::FILE* fp ) { fp_ = fp; } 00235 DATASTREAM& operator<< ( const BYTE& byte ) 00236 { 00237 fwrite( &byte, sizeof(BYTE), 1, fp_ ); 00238 return *this; 00239 } 00244 DATASTREAM& operator>> ( BYTE& byte ) 00245 { 00246 fread( &byte, sizeof(BYTE), 1, fp_ ); 00247 return *this; 00248 } 00253 DATASTREAM& operator<< ( const WORD& word ) 00254 { 00255 if ( swap_ ) { 00256 unsigned char const * p = (unsigned char const*)&word; 00257 fwrite( &p[1], sizeof(unsigned char), 1, fp_ ); 00258 fwrite( &p[0], sizeof(unsigned char), 1, fp_ ); 00259 } 00260 else 00261 fwrite( &word, sizeof(WORD), 1, fp_ ); 00262 return *this; 00263 } 00268 DATASTREAM& operator>> ( WORD& word ) 00269 { 00270 if ( swap_ ) { 00271 unsigned char* p = (unsigned char*)&word; 00272 fread( &p[1], sizeof(unsigned char), 1, fp_ ); 00273 fread( &p[0], sizeof(unsigned char), 1, fp_ ); 00274 } 00275 else 00276 fread( &word, sizeof(WORD), 1, fp_ ); 00277 return *this; 00278 } 00283 DATASTREAM& operator<< ( const INT16& word ) 00284 { 00285 if ( swap_ ) { 00286 unsigned char const * p = (unsigned char const*)&word; 00287 fwrite( &p[1], sizeof(unsigned char), 1, fp_ ); 00288 fwrite( &p[0], sizeof(unsigned char), 1, fp_ ); 00289 } 00290 else 00291 fwrite( &word, sizeof(INT16), 1, fp_ ); 00292 return *this; 00293 } 00298 DATASTREAM& operator>> ( INT16& word ) 00299 { 00300 if ( swap_ ) { 00301 unsigned char* p = (unsigned char*)&word; 00302 fread( &p[1], sizeof(unsigned char), 1, fp_ ); 00303 fread( &p[0], sizeof(unsigned char), 1, fp_ ); 00304 } 00305 else 00306 fread( &word, sizeof(INT16), 1, fp_ ); 00307 return *this; 00308 } 00313 DATASTREAM& operator<< ( const DWORD& dword ) 00314 { 00315 if ( swap_ ) { 00316 unsigned char const* p = (unsigned char const*)&dword; 00317 fwrite( &p[3], sizeof(unsigned char), 1, fp_ ); 00318 fwrite( &p[2], sizeof(unsigned char), 1, fp_ ); 00319 fwrite( &p[1], sizeof(unsigned char), 1, fp_ ); 00320 fwrite( &p[0], sizeof(unsigned char), 1, fp_ ); 00321 } 00322 else 00323 fwrite( &dword, sizeof(DWORD), 1, fp_ ); 00324 return *this; 00325 } 00330 DATASTREAM& operator>> ( DWORD& dword ) 00331 { 00332 if ( swap_ ) { 00333 unsigned char* p = (unsigned char*)&dword; 00334 fread( &p[3], sizeof(unsigned char), 1, fp_ ); 00335 fread( &p[2], sizeof(unsigned char), 1, fp_ ); 00336 fread( &p[1], sizeof(unsigned char), 1, fp_ ); 00337 fread( &p[0], sizeof(unsigned char), 1, fp_ ); 00338 } 00339 else 00340 fread( &dword, sizeof(DWORD), 1, fp_ ); 00341 return *this; 00342 } 00343 #if !defined( __LP64__ ) 00344 00348 DATASTREAM& operator<< ( const LONG& long_ ) 00349 { 00350 if ( swap_ ) { 00351 unsigned char const* p = (unsigned char const*)&long_; 00352 fwrite( &p[3], sizeof(unsigned char), 1, fp_ ); 00353 fwrite( &p[2], sizeof(unsigned char), 1, fp_ ); 00354 fwrite( &p[1], sizeof(unsigned char), 1, fp_ ); 00355 fwrite( &p[0], sizeof(unsigned char), 1, fp_ ); 00356 } 00357 else 00358 fwrite( &long_, sizeof(LONG), 1, fp_ ); 00359 return *this; 00360 } 00365 DATASTREAM& operator>> ( LONG& long_ ) 00366 { 00367 if ( swap_ ) { 00368 unsigned char* p = (unsigned char*)&long_; 00369 fread( &p[3], sizeof(unsigned char), 1, fp_ ); 00370 fread( &p[2], sizeof(unsigned char), 1, fp_ ); 00371 fread( &p[1], sizeof(unsigned char), 1, fp_ ); 00372 fread( &p[0], sizeof(unsigned char), 1, fp_ ); 00373 } 00374 else 00375 fread( &long_, sizeof(LONG), 1, fp_ ); 00376 return *this; 00377 } 00378 #endif /* __x86_64__ */ 00379 00383 DATASTREAM& operator<< ( const INT& int_ ) 00384 { 00385 if ( swap_ ) { 00386 unsigned char const* p = (unsigned char const*)&int_; 00387 fwrite( &p[3], sizeof(unsigned char), 1, fp_ ); 00388 fwrite( &p[2], sizeof(unsigned char), 1, fp_ ); 00389 fwrite( &p[1], sizeof(unsigned char), 1, fp_ ); 00390 fwrite( &p[0], sizeof(unsigned char), 1, fp_ ); 00391 } 00392 else 00393 fwrite( &int_, sizeof(INT), 1, fp_ ); 00394 return *this; 00395 } 00400 DATASTREAM& operator>> ( INT& int_ ) 00401 { 00402 if ( swap_ ) { 00403 unsigned char* p = (unsigned char*)&int_; 00404 fread( &p[3], sizeof(unsigned char), 1, fp_ ); 00405 fread( &p[2], sizeof(unsigned char), 1, fp_ ); 00406 fread( &p[1], sizeof(unsigned char), 1, fp_ ); 00407 fread( &p[0], sizeof(unsigned char), 1, fp_ ); 00408 } 00409 else 00410 fread( &int_, sizeof(INT), 1, fp_ ); 00411 return *this; 00412 } 00413 #if !defined(__LP64__) 00414 00418 DATASTREAM& operator<< ( const UINT& uint ) 00419 { 00420 if ( swap_ ) { 00421 unsigned char const* p = (unsigned char const*)&uint; 00422 fwrite( &p[3], sizeof(unsigned char), 1, fp_ ); 00423 fwrite( &p[2], sizeof(unsigned char), 1, fp_ ); 00424 fwrite( &p[1], sizeof(unsigned char), 1, fp_ ); 00425 fwrite( &p[0], sizeof(unsigned char), 1, fp_ ); 00426 } 00427 else 00428 fwrite( &uint, sizeof(UINT), 1, fp_ ); 00429 return *this; 00430 } 00435 DATASTREAM& operator>> ( UINT& uint ) 00436 { 00437 if ( swap_ ) { 00438 unsigned char* p = (unsigned char*)&uint; 00439 fread( &p[3], sizeof(unsigned char), 1, fp_ ); 00440 fread( &p[2], sizeof(unsigned char), 1, fp_ ); 00441 fread( &p[1], sizeof(unsigned char), 1, fp_ ); 00442 fread( &p[0], sizeof(unsigned char), 1, fp_ ); 00443 } 00444 else 00445 fread( &uint, sizeof(UINT), 1, fp_ ); 00446 return *this; 00447 } 00448 #endif /* !__x86_64__ */ 00449 00453 DATASTREAM& operator<< ( const FLOAT& float_ ) 00454 { 00455 if ( swap_ ) { 00456 unsigned char const* p = (unsigned char const*)&float_; 00457 fwrite( &p[3], sizeof(unsigned char), 1, fp_ ); 00458 fwrite( &p[2], sizeof(unsigned char), 1, fp_ ); 00459 fwrite( &p[1], sizeof(unsigned char), 1, fp_ ); 00460 fwrite( &p[0], sizeof(unsigned char), 1, fp_ ); 00461 } 00462 else 00463 fwrite( &float_, sizeof(FLOAT), 1, fp_ ); 00464 return *this; 00465 } 00470 DATASTREAM& operator>> ( FLOAT& float_ ) 00471 { 00472 if ( swap_ ) { 00473 unsigned char* p = (unsigned char*)&float_; 00474 fread( &p[3], sizeof(unsigned char), 1, fp_ ); 00475 fread( &p[2], sizeof(unsigned char), 1, fp_ ); 00476 fread( &p[1], sizeof(unsigned char), 1, fp_ ); 00477 fread( &p[0], sizeof(unsigned char), 1, fp_ ); 00478 } 00479 else 00480 fread( &float_, sizeof(FLOAT), 1, fp_ ); 00481 return *this; 00482 } 00487 DATASTREAM& operator<< ( const PADDING& padding ) 00488 { 00489 if ( padding.size_ != 0 ) 00490 fwrite( &padding.padding_, sizeof(CHAR), padding.size_, fp_ ); 00491 return *this; 00492 } 00497 DATASTREAM& operator<< ( const RECTL& rectl ) 00498 { 00499 *this << rectl.left << rectl.top << rectl.right << rectl.bottom; 00500 return *this; 00501 } 00506 DATASTREAM& operator>> ( RECTL& rectl ) 00507 { 00508 *this >> rectl.left >> rectl.top >> rectl.right >> rectl.bottom; 00509 return *this; 00510 } 00515 DATASTREAM& operator<< ( const SIZEL& sizel ) 00516 { 00517 *this << sizel.cx << sizel.cy; 00518 return *this; 00519 } 00524 DATASTREAM& operator>> ( SIZEL& sizel ) 00525 { 00526 *this >> sizel.cx >> sizel.cy; 00527 return *this; 00528 } 00533 DATASTREAM& operator<< ( const WCHARSTR& wcharstr ) 00534 { 00535 for ( int i = 0; i < wcharstr.length_; i++ ) 00536 *this << wcharstr.string_[i]; 00537 return *this; 00538 } 00543 DATASTREAM& operator>> ( WCHARSTR& wcharstr ) 00544 { 00545 for ( int i = 0; i < wcharstr.length_; i++ ) 00546 *this >> wcharstr.string_[i]; 00547 return *this; 00548 } 00553 DATASTREAM& operator<< ( const CHARSTR& charstr ) 00554 { 00555 fwrite( charstr.string_, sizeof(CHAR), charstr.length_, fp_ ); 00556 return *this; 00557 } 00562 DATASTREAM& operator>> ( CHARSTR& charstr ) 00563 { 00564 fread( charstr.string_, sizeof(CHAR), charstr.length_, fp_ ); 00565 return *this; 00566 } 00571 DATASTREAM& operator<< ( const ::EMR& emr ) 00572 { 00573 *this << emr.iType << emr.nSize; 00574 return *this; 00575 } 00580 DATASTREAM& operator>> ( ::EMR& emr ) 00581 { 00582 *this >> emr.iType >> emr.nSize; 00583 return *this; 00584 } 00589 DATASTREAM& operator<< ( const POINT& point ) 00590 { 00591 *this << point.x << point.y; 00592 return *this; 00593 } 00598 DATASTREAM& operator>> ( POINT& point ) 00599 { 00600 *this >> point.x >> point.y; 00601 return *this; 00602 } 00607 DATASTREAM& operator<< ( const POINTL& pointl ) 00608 { 00609 *this << pointl.x << pointl.y; 00610 return *this; 00611 } 00616 DATASTREAM& operator>> ( POINTL& pointl ) 00617 { 00618 *this >> pointl.x >> pointl.y; 00619 return *this; 00620 } 00625 DATASTREAM& operator<< ( const POINT16& point ) 00626 { 00627 *this << point.x << point.y; 00628 return *this; 00629 } 00634 DATASTREAM& operator>> ( POINT16& point ) 00635 { 00636 *this >> point.x >> point.y; 00637 return *this; 00638 } 00643 DATASTREAM& operator<< ( const XFORM& xform ) 00644 { 00645 *this << xform.eM11 << xform.eM12 << xform.eM21 << xform.eM22 00646 << xform.eDx << xform.eDy; 00647 return *this; 00648 } 00653 DATASTREAM& operator>> ( XFORM& xform ) 00654 { 00655 *this >> xform.eM11 >> xform.eM12 >> xform.eM21 >> xform.eM22 00656 >> xform.eDx >> xform.eDy; 00657 return *this; 00658 } 00663 DATASTREAM& operator<< ( const BYTEARRAY& array ) 00664 { 00665 fwrite( array.array_, sizeof(BYTE), array.n_, fp_ ); 00666 return *this; 00667 } 00672 DATASTREAM& operator>> ( BYTEARRAY& array ) 00673 { 00674 fread( array.array_, sizeof(BYTE), array.n_, fp_ ); 00675 return *this; 00676 } 00681 DATASTREAM& operator<< ( const POINTLARRAY& array ) 00682 { 00683 for ( unsigned int i = 0; i < array.n_; i++ ) 00684 *this << array.points_[i]; 00685 return *this; 00686 } 00691 DATASTREAM& operator>> ( POINTLARRAY& array ) 00692 { 00693 for ( unsigned int i = 0; i < array.n_; i++ ) 00694 *this >> array.points_[i]; 00695 return *this; 00696 } 00701 DATASTREAM& operator<< ( const POINT16ARRAY& array ) 00702 { 00703 for ( unsigned int i = 0; i < array.n_; i++ ) 00704 *this << array.points_[i]; 00705 return *this; 00706 } 00711 DATASTREAM& operator>> ( POINT16ARRAY& array ) 00712 { 00713 for ( unsigned int i = 0; i < array.n_; i++ ) 00714 *this >> array.points_[i]; 00715 return *this; 00716 } 00721 DATASTREAM& operator<< ( const INTARRAY& array ) 00722 { 00723 for ( unsigned int i = 0; i < array.n_; i++ ) 00724 *this << array.ints_[i]; 00725 return *this; 00726 } 00731 DATASTREAM& operator>> ( INTARRAY& array ) 00732 { 00733 for ( unsigned int i = 0; i < array.n_; i++ ) 00734 *this >> array.ints_[i]; 00735 return *this; 00736 } 00741 DATASTREAM& operator<< ( const DWORDARRAY& array ) 00742 { 00743 for ( unsigned int i = 0; i < array.n_; i++ ) 00744 *this << array.dwords_[i]; 00745 return *this; 00746 } 00751 DATASTREAM& operator>> ( DWORDARRAY& array ) 00752 { 00753 for ( unsigned int i = 0; i < array.n_; i++ ) 00754 *this >> array.dwords_[i]; 00755 return *this; 00756 } 00761 DATASTREAM& operator<< ( const ::EMRTEXT& text ) 00762 { 00763 *this << text.ptlReference << text.nChars << text.offString << text.fOptions 00764 << text.rcl << text.offDx; 00765 return *this; 00766 } 00771 DATASTREAM& operator>> ( ::EMRTEXT& text ) 00772 { 00773 *this >> text.ptlReference >> text.nChars >> text.offString >> text.fOptions 00774 >> text.rcl >> text.offDx; 00775 return *this; 00776 } 00781 DATASTREAM& operator<< ( const LOGPEN& pen ) 00782 { 00783 *this << pen.lopnStyle << pen.lopnWidth << pen.lopnColor; 00784 return *this; 00785 } 00790 DATASTREAM& operator>> ( LOGPEN& pen ) 00791 { 00792 *this >> pen.lopnStyle >> pen.lopnWidth >> pen.lopnColor; 00793 return *this; 00794 } 00799 DATASTREAM& operator<< ( const EXTLOGPEN& pen ) 00800 { 00801 // *** How big is this structure if there are no style entries? *** 00802 *this << pen.elpPenStyle << pen.elpWidth << pen.elpBrushStyle << pen.elpColor 00803 << pen.elpHatch << pen.elpNumEntries; 00804 return *this; 00805 } 00810 DATASTREAM& operator>> ( EXTLOGPEN& pen ) 00811 { 00812 // *** How big is this structure if there are no style entries? *** 00813 *this >> pen.elpPenStyle >> pen.elpWidth >> pen.elpBrushStyle >> pen.elpColor 00814 >> pen.elpHatch >> pen.elpNumEntries; 00815 return *this; 00816 } 00821 DATASTREAM& operator<< ( const LOGBRUSH& brush ) 00822 { 00823 *this << brush.lbStyle << brush.lbColor << brush.lbHatch; 00824 return *this; 00825 } 00830 DATASTREAM& operator>> ( LOGBRUSH& brush ) 00831 { 00832 *this >> brush.lbStyle >> brush.lbColor >> brush.lbHatch; 00833 return *this; 00834 } 00839 DATASTREAM& operator<< ( const LOGFONTW& font ) 00840 { 00841 *this << font.lfHeight << font.lfWidth << font.lfEscapement 00842 << font.lfOrientation << font.lfWeight << font.lfItalic 00843 << font.lfUnderline << font.lfStrikeOut << font.lfCharSet 00844 << font.lfOutPrecision << font.lfClipPrecision << font.lfQuality 00845 << font.lfPitchAndFamily 00846 << WCHARSTR( const_cast<WCHAR*const>(font.lfFaceName), LF_FACESIZE ); 00847 return *this; 00848 } 00853 DATASTREAM& operator>> ( LOGFONTW& font ) 00854 { 00855 WCHARSTR wFaceName( font.lfFaceName, LF_FACESIZE ); 00856 00857 *this >> font.lfHeight >> font.lfWidth >> font.lfEscapement 00858 >> font.lfOrientation >> font.lfWeight >> font.lfItalic 00859 >> font.lfUnderline >> font.lfStrikeOut >> font.lfCharSet 00860 >> font.lfOutPrecision >> font.lfClipPrecision >> font.lfQuality 00861 >> font.lfPitchAndFamily 00862 >> wFaceName; 00863 return *this; 00864 } 00869 DATASTREAM& operator<< ( const PANOSE& panose ) 00870 { 00871 fwrite( &panose, sizeof(PANOSE), 1, fp_ ); 00872 return *this; 00873 } 00878 DATASTREAM& operator>> ( PANOSE& panose ) 00879 { 00880 fread( &panose, sizeof(PANOSE), 1, fp_ ); 00881 return *this; 00882 } 00887 DATASTREAM& operator<< ( const EXTLOGFONTW& font ) 00888 { 00889 *this << font.elfLogFont 00890 << WCHARSTR( const_cast<WCHAR*const>(font.elfFullName), 00891 LF_FULLFACESIZE ) 00892 << WCHARSTR( const_cast<WCHAR*const>(font.elfStyle), LF_FACESIZE ) 00893 << font.elfVersion << font.elfStyleSize << font.elfMatch 00894 << font.elfReserved 00895 << BYTEARRAY( const_cast<BYTE*const>(font.elfVendorId), 00896 ELF_VENDOR_SIZE ) 00897 << font.elfCulture << font.elfPanose; 00898 return *this; 00899 } 00904 DATASTREAM& operator>> ( EXTLOGFONTW& font ) 00905 { 00906 WCHARSTR wFullName( font.elfFullName, LF_FULLFACESIZE ); 00907 WCHARSTR wStyle( font.elfStyle, LF_FACESIZE ); 00908 BYTEARRAY bVendorId( font.elfVendorId, ELF_VENDOR_SIZE ); 00909 *this >> font.elfLogFont 00910 >> wFullName >> wStyle 00911 >> font.elfVersion >> font.elfStyleSize >> font.elfMatch 00912 >> font.elfReserved >> bVendorId 00913 >> font.elfCulture >> font.elfPanose; 00914 return *this; 00915 } 00920 DATASTREAM& operator<< ( const LOGPALETTE& palette ) 00921 { 00922 // *** How big is this structure if the palette is empty? *** 00923 *this << palette.palVersion << palette.palNumEntries; 00924 return *this; 00925 } 00930 DATASTREAM& operator>> ( LOGPALETTE& palette ) 00931 { 00932 // *** How big is this structure if the palette is empty? *** 00933 *this >> palette.palVersion >> palette.palNumEntries; 00934 return *this; 00935 } 00936 }; 00937 00938 class METAFILEDEVICECONTEXT; 00939 00941 00947 class METARECORD { 00948 public: 00955 virtual void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const = 0; 00962 virtual bool serialize ( DATASTREAM ds ) = 0; 00968 virtual int size ( void ) const = 0; 00974 virtual ~METARECORD( ) { } 00975 #ifdef ENABLE_EDITING 00976 00980 virtual void edit ( void ) const {} 00981 #endif 00982 }; 00983 00984 #ifdef ENABLE_EDITING 00985 /* Miscellaneous editing routines */ 00986 inline void edit_rectl ( const char* tag, const RECTL& rectl ) 00987 { 00988 #if defined(__LP64__) 00989 const char* FMT = "\t%s\t: (%d, %d) - (%d, %d)\n"; 00990 #else 00991 const char* FMT = "\t%s\t: (%ld, %ld) - (%ld, %ld)\n"; 00992 #endif /* __x86_64__ */ 00993 printf( FMT, tag, rectl.left, rectl.top, rectl.right, rectl.bottom ); 00994 } 00995 00996 inline void edit_xform ( const char* tag, const XFORM& xform ) 00997 { 00998 printf( "\t%s.eM11\t: %f\n", tag, xform.eM11 ); 00999 printf( "\t%s.eM12\t: %f\n", tag, xform.eM12 ); 01000 printf( "\t%s.eM21\t: %f\n", tag, xform.eM21 ); 01001 printf( "\t%s.eM22\t: %f\n", tag, xform.eM22 ); 01002 printf( "\t%s.eDx\t: %f\n", tag, xform.eDx ); 01003 printf( "\t%s.eDy\t: %f\n", tag, xform.eDy ); 01004 } 01005 01006 inline void edit_color ( const char* tag, const COLORREF& color ) 01007 { 01008 #if defined(__LP64__) 01009 const char* FMT = "\t%s\t: R(0x%02x) G(0x%02x) B(0x%02x)\n"; 01010 #else 01011 const char* FMT = "\t%s\t: R(0x%02lx) G(0x%02lx) B(0x%02lx)\n"; 01012 #endif /* __x86_64__ */ 01013 printf( FMT, tag, 01014 GetRValue( color ), GetGValue( color ), GetBValue( color ) ); 01015 } 01016 01017 inline void edit_sizel ( const char* tag, const SIZEL& size ) 01018 { 01019 #if defined(__LP64__) 01020 const char* FMT = "\t%s\t: (%d, %d)\n"; 01021 #else 01022 const char* FMT = "\t%s\t: (%ld, %ld)\n"; 01023 #endif /* __x86_64__ */ 01024 printf( FMT, tag, size.cx, size.cy ); 01025 } 01026 01027 inline void edit_pointl ( const char* tag, const POINTL& point ) 01028 { 01029 #if defined(__LP64__) 01030 const char* FMT = "\t%s\t: (%d, %d)\n"; 01031 #else 01032 const char* FMT = "\t%s\t: (%ld, %ld)\n"; 01033 #endif /* __x86_64__ */ 01034 printf( FMT, tag, point.x, point.y ); 01035 } 01036 01037 inline void edit_pointlarray ( const char* tag, const DWORD cptl, 01038 const POINTL* points ) 01039 { 01040 #if defined(__LP64__) 01041 const char* FMT0 = "\tcptl%s\t: %d\n"; 01042 const char* FMT1 = "%d, %d\n"; 01043 const char* FMT2 = "\t\t%s %d, %d\n"; 01044 #else 01045 const char* FMT0 = "\tcptl%s\t: %ld\n"; 01046 const char* FMT1 = "%ld, %ld\n"; 01047 const char* FMT2 = "\t\t%s %ld, %ld\n"; 01048 #endif /* __x86_64__ */ 01049 printf( FMT0, tag, cptl ); 01050 printf( "\taptl%s\t: ", tag ); 01051 if ( cptl > 0 ) 01052 printf( FMT1, points[0].x, points[0].y ); 01053 else 01054 puts( "" ); 01055 for ( DWORD i = 1; i < cptl; i++ ) 01056 printf( FMT2, tag, points[i].x, points[i].y ); 01057 } 01058 01059 inline void edit_point16array ( const char* tag, const unsigned int cpts, 01060 const POINT16* points ) 01061 { 01062 printf( "\tcpts%s\t: %d\n", tag, cpts ); 01063 printf( "\tapts%s\t: ", tag ); 01064 if ( cpts > 0 ) 01065 printf( "%d, %d\n", points[0].x, points[0].y ); 01066 else 01067 puts( "" ); 01068 for ( unsigned int i = 1; i < cpts; i++ ) 01069 printf( "\t\t%s %d, %d\n", tag, points[i].x, points[i].y ); 01070 } 01071 01072 inline void edit_pen_style ( const char* tag, DWORD style ) 01073 { 01074 printf( "\t%s\t: ", tag ); 01075 switch ( style & PS_STYLE_MASK ) { 01076 case PS_SOLID: printf( "PS_SOLID" ); break; 01077 case PS_DASH: printf( "PS_DASH" ); break; 01078 case PS_DOT: printf( "PS_DOT" ); break; 01079 case PS_DASHDOT: printf( "PS_DASHDOT" ); break; 01080 case PS_DASHDOTDOT: printf( "PS_DASHDOTDOT" ); break; 01081 case PS_NULL: printf( "PS_NULL" ); break; 01082 case PS_INSIDEFRAME: printf( "PS_INSIDEFRAME" ); break; 01083 case PS_USERSTYLE: printf( "PS_USERSTYLE" ); break; 01084 case PS_ALTERNATE: printf( "PS_ALTERNATE" ); break; 01085 } 01086 switch ( style & PS_ENDCAP_MASK ) { 01087 case PS_ENDCAP_ROUND: printf( " | PS_ENDCAP_ROUND" ); break; 01088 case PS_ENDCAP_SQUARE: printf( " | PS_ENDCAP_SQUARE" ); break; 01089 case PS_ENDCAP_FLAT: printf( " | PS_ENDCAP_FLAT" ); break; 01090 } 01091 switch ( style & PS_JOIN_MASK ) { 01092 case PS_JOIN_ROUND: printf( " | PS_JOIN_ROUND" ); break; 01093 case PS_JOIN_BEVEL: printf( " | PS_JOIN_BEVEL" ); break; 01094 case PS_JOIN_MITER: printf( " | PS_JOIN_MITER" ); break; 01095 } 01096 switch ( style & PS_TYPE_MASK ) { 01097 case PS_COSMETIC: printf( " | PS_COSMETIC" ); break; 01098 case PS_GEOMETRIC: printf( " | PS_GEOMETRIC" ); break; 01099 } 01100 printf( "\n" ); 01101 } 01102 01103 inline void edit_brush_style ( const char* tag, DWORD style ) 01104 { 01105 #if defined(__LP64__) 01106 const char* FMT = "unknown(%d)"; 01107 #else 01108 const char* FMT = "unknown(%ld)"; 01109 #endif /* __x86_64__ */ 01110 printf( "\t%s\t: ", tag ); 01111 switch ( style ) { 01112 case BS_SOLID: printf( "BS_SOLID" ); break; 01113 case BS_NULL: printf( "BS_NULL" ); break; 01114 case BS_HATCHED: printf( "BS_HATCHED" ); break; 01115 case BS_PATTERN: printf( "BS_PATTERN" ); break; 01116 case BS_INDEXED: printf( "BS_INDEXED" ); break; 01117 case BS_DIBPATTERN: printf( "BS_DIBPATTERN" ); break; 01118 case BS_DIBPATTERNPT: printf( "BS_DIBPATTERNPT" ); break; 01119 case BS_PATTERN8X8: printf( "BS_PATTERN8X8" ); break; 01120 case BS_DIBPATTERN8X8: printf( "BS_DIBPATTERN8X8" ); break; 01121 case BS_MONOPATTERN: printf( "BS_DIBPATTERN8X8" ); break; 01122 default: printf( FMT, style ); 01123 } 01124 printf( "\n" ); 01125 } 01126 01127 inline void edit_brush_hatch ( const char* tag, DWORD hatch ) 01128 { 01129 #if defined(__LP64__) 01130 const char* FMT = "unknown(%d)"; 01131 #else 01132 const char* FMT = "unknown(%ld)"; 01133 #endif /* __x86_64__ */ 01134 printf( "\t%s\t: ", tag ); 01135 switch ( hatch ) { 01136 case HS_HORIZONTAL: printf( "HS_HORIZONTAL" ); break; 01137 case HS_VERTICAL: printf( "HS_VERTICAL" ); break; 01138 case HS_FDIAGONAL: printf( "HS_FDIAGONAL" ); break; 01139 case HS_BDIAGONAL: printf( "HS_BDIAGONAL" ); break; 01140 case HS_CROSS: printf( "HS_CROSS" ); break; 01141 case HS_DIAGCROSS: printf( "HS_DIAGCROSS" ); break; 01142 default: printf( FMT, hatch ); 01143 } 01144 printf( "\n" ); 01145 } 01146 #endif 01147 01154 enum OBJECTTYPE { O_METAFILEDEVICECONTEXT = OBJ_METADC, 01155 O_FONT = OBJ_FONT, 01156 O_PEN = OBJ_PEN, 01157 O_EXTPEN = OBJ_EXTPEN, 01158 O_BRUSH = OBJ_BRUSH, 01159 O_PALETTE = OBJ_PAL }; 01160 #if 0 01161 01164 static char* typStr ( OBJECTTYPE type ) 01165 { 01166 switch (type) { 01167 case O_METAFILEDEVICECONTEXT: 01168 return "metafile device context"; 01169 case O_FONT: 01170 return "font"; 01171 case O_PEN: 01172 return "pen"; 01173 case O_EXTPEN: 01174 return "extended pen"; 01175 case O_BRUSH: 01176 return "brush"; 01177 case O_PALETTE: 01178 return "palette"; 01179 } 01180 return "unknown object"; 01181 } 01182 #endif 01183 01184 01189 class OBJECT { 01190 public: 01191 HGDIOBJ handle; 01192 01193 virtual ~OBJECT () {} 01198 OBJECT ( void ) : handle( 0 ) {} 01202 virtual OBJECTTYPE getType ( void ) const = 0; 01203 }; 01204 01206 01211 class GRAPHICSOBJECT : public OBJECT { 01212 public: 01214 virtual ~GRAPHICSOBJECT () {} 01219 std::map< HDC, HGDIOBJ > contexts; 01225 virtual METARECORD* newEMR ( HDC dc, HGDIOBJ handle ) = 0; 01226 }; 01227 01228 typedef METARECORD*(*METARECORDCTOR)(DATASTREAM&); 01229 01230 class GLOBALOBJECTS { 01234 std::vector<OBJECT*> objects; 01235 01242 std::map< DWORD, METARECORDCTOR > new_records; 01243 01244 public: 01245 GLOBALOBJECTS ( void ); 01246 ~GLOBALOBJECTS ( void ); 01247 HGDIOBJ add ( OBJECT* object ); 01248 OBJECT* find ( const HGDIOBJ handle ); 01249 void remove ( const OBJECT* object ); 01250 01251 std::vector<EMF::OBJECT*>::const_iterator begin ( void ) const 01252 { return objects.begin(); } 01253 std::vector<EMF::OBJECT*>::const_iterator end ( void ) const 01254 { return objects.end(); } 01255 01256 METARECORDCTOR newRecord ( DWORD iType ) const; 01257 01258 static EMF::METARECORD* new_eof ( DATASTREAM& ds ); 01259 static EMF::METARECORD* new_setviewportorgex ( DATASTREAM& ds ); 01260 static EMF::METARECORD* new_setwindoworgex ( DATASTREAM& ds ); 01261 static EMF::METARECORD* new_setviewportextex ( DATASTREAM& ds ); 01262 static EMF::METARECORD* new_setwindowextex ( DATASTREAM& ds ); 01263 static EMF::METARECORD* new_scaleviewportextex ( DATASTREAM& ds ); 01264 static EMF::METARECORD* new_scalewindowextex ( DATASTREAM& ds ); 01265 static EMF::METARECORD* new_modifyworldtransform ( DATASTREAM& ds ); 01266 static EMF::METARECORD* new_setworldtransform ( DATASTREAM& ds ); 01267 static EMF::METARECORD* new_settextalign ( DATASTREAM& ds ); 01268 static EMF::METARECORD* new_settextcolor ( DATASTREAM& ds ); 01269 static EMF::METARECORD* new_setbkcolor ( DATASTREAM& ds ); 01270 static EMF::METARECORD* new_setbkmode ( DATASTREAM& ds ); 01271 static EMF::METARECORD* new_setpolyfillmode ( DATASTREAM& ds ); 01272 static EMF::METARECORD* new_setmapmode ( DATASTREAM& ds ); 01273 static EMF::METARECORD* new_selectobject ( DATASTREAM& ds ); 01274 static EMF::METARECORD* new_deleteobject ( DATASTREAM& ds ); 01275 static EMF::METARECORD* new_movetoex ( DATASTREAM& ds ); 01276 static EMF::METARECORD* new_lineto ( DATASTREAM& ds ); 01277 static EMF::METARECORD* new_arc ( DATASTREAM& ds ); 01278 static EMF::METARECORD* new_arcto ( DATASTREAM& ds ); 01279 static EMF::METARECORD* new_rectangle ( DATASTREAM& ds ); 01280 static EMF::METARECORD* new_ellipse ( DATASTREAM& ds ); 01281 static EMF::METARECORD* new_polyline ( DATASTREAM& ds ); 01282 static EMF::METARECORD* new_polyline16 ( DATASTREAM& ds ); 01283 static EMF::METARECORD* new_polygon ( DATASTREAM& ds ); 01284 static EMF::METARECORD* new_polygon16 ( DATASTREAM& ds ); 01285 static EMF::METARECORD* new_polypolygon ( DATASTREAM& ds ); 01286 static EMF::METARECORD* new_polypolygon16 ( DATASTREAM& ds ); 01287 static EMF::METARECORD* new_polybezier ( DATASTREAM& ds ); 01288 static EMF::METARECORD* new_polybezier16 ( DATASTREAM& ds ); 01289 static EMF::METARECORD* new_polybezierto ( DATASTREAM& ds ); 01290 static EMF::METARECORD* new_polybezierto16 ( DATASTREAM& ds ); 01291 static EMF::METARECORD* new_polylineto ( DATASTREAM& ds ); 01292 static EMF::METARECORD* new_polylineto16 ( DATASTREAM& ds ); 01293 static EMF::METARECORD* new_exttextouta ( DATASTREAM& ds ); 01294 static EMF::METARECORD* new_setpixelv ( DATASTREAM& ds ); 01295 static EMF::METARECORD* new_createpen ( DATASTREAM& ds ); 01296 static EMF::METARECORD* new_extcreatepen ( DATASTREAM& ds ); 01297 static EMF::METARECORD* new_createbrushindirect ( DATASTREAM& ds ); 01298 static EMF::METARECORD* new_extcreatefontindirectw ( DATASTREAM& ds ); 01299 static EMF::METARECORD* new_fillpath ( DATASTREAM& ds ); 01300 static EMF::METARECORD* new_strokepath ( DATASTREAM& ds ); 01301 static EMF::METARECORD* new_strokeandfillpath ( DATASTREAM& ds ); 01302 static EMF::METARECORD* new_beginpath ( DATASTREAM& ds ); 01303 static EMF::METARECORD* new_endpath ( DATASTREAM& ds ); 01304 static EMF::METARECORD* new_closefigure ( DATASTREAM& ds ); 01305 static EMF::METARECORD* new_savedc ( DATASTREAM& ds ); 01306 static EMF::METARECORD* new_restoredc ( DATASTREAM& ds ); 01307 static EMF::METARECORD* new_setmetargn ( DATASTREAM& ds ); 01308 static EMF::METARECORD* new_setmiterlimit ( DATASTREAM& ds ); 01309 }; 01310 01311 extern GLOBALOBJECTS globalObjects; 01312 01314 01320 class ENHMETAHEADER : public METARECORD, public ::ENHMETAHEADER { 01321 01322 LPWSTR description_w; 01323 int description_size; 01324 01325 public: 01332 ENHMETAHEADER ( LPCWSTR description = 0 ) 01333 : description_w( 0 ), description_size( 0 ) 01334 { 01335 iType = EMR_HEADER; 01336 nSize = sizeof( ::ENHMETAHEADER ); 01337 01338 // Compute the bounds 01339 RECTL default_bounds = { 0, 0, 0, 0 }; 01340 rclBounds = default_bounds; 01341 RECTL default_frame = { 0, 0, 0, 0 }; 01342 rclFrame = default_frame; 01343 dSignature = ENHMETA_SIGNATURE; 01344 nVersion = 0x10000; 01345 nBytes = nSize; 01346 nRecords = 1; 01347 nHandles = 0; 01348 sReserved = 0; 01349 nDescription = 0; 01350 offDescription = 0; 01351 nPalEntries = 0; 01352 szlDevice.cx = XMAX_PIXELS; 01353 szlDevice.cy = YMAX_PIXELS; 01354 szlMillimeters.cx = XMAX_MM; 01355 szlMillimeters.cy = YMAX_MM; 01356 // 01357 cbPixelFormat = 0; 01358 offPixelFormat = 0; 01359 bOpenGL = FALSE; 01360 // 01361 #if 1 01362 szlMicrometers.cx = 1000 * szlMillimeters.cx; 01363 szlMicrometers.cy = 1000 * szlMillimeters.cy; 01364 #endif 01365 if ( description ) { 01366 // Count the number of characters in the description 01367 int description_count = 0, nulls = 0; 01368 LPCWSTR description_p = description; 01369 while ( nulls < 3 ) { 01370 description_count++; 01371 if ( (*description_p++) == 0 ) nulls++; 01372 } 01373 01374 // Make sure that the TOTAL record length will be a multiple of 4 01375 01376 int record_size = ROUND_TO_LONG( sizeof( ::ENHMETAHEADER ) + 01377 sizeof( WCHAR ) * description_count ); 01378 description_size = 01379 (record_size - sizeof( ::ENHMETAHEADER )) / sizeof( WCHAR ); 01380 01381 description_w = new WCHAR[ description_size ]; 01382 01383 memset( description_w, 0, sizeof(WCHAR) * description_size ); 01384 01385 for ( int i=0; i<description_count; i++ ) 01386 description_w[i] = *description++; 01387 01388 nSize = nBytes = record_size; 01389 nDescription = description_count; 01390 offDescription = sizeof( ::ENHMETAHEADER ); 01391 } 01392 } 01393 01397 ~ENHMETAHEADER ( ) 01398 { 01399 if ( description_w ) delete[] description_w; 01400 } 01405 bool serialize ( DATASTREAM ds ) 01406 { 01407 ds << iType << nSize 01408 << rclBounds << rclFrame 01409 << dSignature << nVersion << nBytes << nRecords << nHandles << sReserved 01410 << nDescription << offDescription << nPalEntries 01411 << szlDevice << szlMillimeters 01412 << cbPixelFormat << offPixelFormat << bOpenGL 01413 #if 1 01414 << szlMicrometers 01415 #endif 01416 << WCHARSTR( description_w, description_size ); 01417 return true; 01418 } 01422 bool unserialize ( DATASTREAM ds ) 01423 { 01424 ds >> iType >> nSize 01425 >> rclBounds >> rclFrame 01426 >> dSignature >> nVersion >> nBytes >> nRecords >> nHandles >> sReserved 01427 >> nDescription >> offDescription >> nPalEntries 01428 >> szlDevice >> szlMillimeters; 01429 01430 // Some elements of the metafile header were added at later dates 01431 01432 #define OffsetOf( a, b ) ((unsigned int)(((char*)&(((::ENHMETAHEADER*)a)->b)) - \ 01433 (char*)((::ENHMETAHEADER*)a))) 01434 #if 1 01435 if ( OffsetOf( this, szlMicrometers ) <= offDescription ) 01436 ds >> cbPixelFormat >> offPixelFormat >> bOpenGL; 01437 #else 01438 if ( sizeof(::ENHMETAHEADER) <= offDescription ) 01439 ds >> cbPixelFormat >> offPixelFormat >> bOpenGL; 01440 #endif 01441 #undef OffsetOf 01442 #if 1 01443 if ( sizeof(::ENHMETAHEADER) <= offDescription ) 01444 ds >> szlMicrometers; 01445 #endif 01446 // Should now probably check that the offset is correct... 01447 01448 description_size = ( nSize - offDescription ) / sizeof(WCHAR); 01449 description_w = new WCHAR[ description_size ]; 01450 01451 WCHARSTR description( description_w, description_size ); 01452 01453 ds >> description; 01454 01455 return true; 01456 } 01460 int size ( void ) const { return nSize; } 01466 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC /*dc*/ ) const 01467 { 01468 // Actually handled by the destination device context. 01469 } 01470 #ifdef ENABLE_EDITING 01471 01474 void edit ( void ) const 01475 { 01476 #if defined(__LP64__) 01477 const char* FMT0 = "\tiType\t\t\t: %d\n"; 01478 const char* FMT1 = "\tnSize\t\t\t: %d\n"; 01479 const char* FMT2 = "\tnBytes\t\t\t: %d\n"; 01480 const char* FMT3 = "\tnRecords\t\t: %d\n"; 01481 const char* FMT4 = "\tnDescription\t\t: %d\n"; 01482 const char* FMT5 = "\toffDescription\t\t: %d\n"; 01483 const char* FMT6 = "\tnPalEntries\t\t: %d\n"; 01484 const char* FMT7 = "\tcbPixelFormat\t\t: %d\n"; 01485 const char* FMT8 = "\toffPixelFormat\t\t: %d\n"; 01486 const char* FMT9 = "\tbOpenGL\t\t\t: %d\n"; 01487 #else 01488 const char* FMT0 = "\tiType\t\t\t: %ld\n"; 01489 const char* FMT1 = "\tnSize\t\t\t: %ld\n"; 01490 const char* FMT2 = "\tnBytes\t\t\t: %ld\n"; 01491 const char* FMT3 = "\tnRecords\t\t: %ld\n"; 01492 const char* FMT4 = "\tnDescription\t\t: %ld\n"; 01493 const char* FMT5 = "\toffDescription\t\t: %ld\n"; 01494 const char* FMT6 = "\tnPalEntries\t\t: %ld\n"; 01495 const char* FMT7 = "\tcbPixelFormat\t\t: %ld\n"; 01496 const char* FMT8 = "\toffPixelFormat\t\t: %ld\n"; 01497 const char* FMT9 = "\tbOpenGL\t\t\t: %ld\n"; 01498 #endif 01499 printf( "*HEADER*\n" ); 01500 printf( FMT0, iType ); 01501 printf( FMT1, nSize ); 01502 edit_rectl( "rclBounds\t", rclBounds ); 01503 edit_rectl( "rclFrame\t", rclFrame ); 01504 printf( "\tdSignature\t\t: %.4s\n", (const char*)&dSignature ); 01505 printf( "\tnVersion\t\t: 0x%x\n", (unsigned int)nVersion ); 01506 printf( FMT2, nBytes ); 01507 printf( FMT3, nRecords ); 01508 printf( "\tnHandles\t\t: %d\n", nHandles ); 01509 printf( FMT4, nDescription ); 01510 printf( FMT5, offDescription ); 01511 printf( FMT6, nPalEntries ); 01512 edit_sizel( "szlDevice\t", szlDevice ); 01513 edit_sizel( "szlMillimeters\t", szlMillimeters ); 01514 01515 /* Make a crude guess as to the age of this file */ 01516 #define OffsetOf( a, b ) ((unsigned int)(((const char*)&(((const ::ENHMETAHEADER*)a)->b)) - \ 01517 (const char*)((const ::ENHMETAHEADER*)a))) 01518 01519 if ( OffsetOf( this, cbPixelFormat ) <= offDescription ) { 01520 printf( FMT7, cbPixelFormat ); 01521 printf( FMT8, offPixelFormat ); 01522 printf( FMT9, bOpenGL ); 01523 #if 1 01524 if ( sizeof(::ENHMETAHEADER) <= offDescription ) { 01525 edit_sizel( "szlMicrometers\t", szlMicrometers ); 01526 } 01527 #endif 01528 } 01529 01530 #undef OffsetOf 01531 01532 if ( nDescription != 0 ) { 01533 01534 wchar_t last_w = 0; 01535 WCHAR* description = description_w; 01536 01537 printf( "\tDescription:" ); 01538 01539 for ( DWORD i = 0; i < nDescription; i++ ) { 01540 01541 wchar_t w = *description++; /* This is not true, really. UNICODE is not 01542 * glibc's wide character representation */ 01543 01544 if ( w != 0 ) { 01545 if ( last_w == 0 ) printf( "\n\t\t" ); 01546 putchar( w ); 01547 } 01548 01549 last_w = w; 01550 } 01551 printf( "\n" ); 01552 } 01553 } 01554 #endif /* ENABLE_EDITING */ 01555 }; 01556 01558 01563 class EMREOF : public METARECORD, ::EMREOF { 01564 public: 01568 EMREOF ( void ) 01569 { 01570 emr.iType = EMR_EOF; 01571 emr.nSize = sizeof( ::EMREOF ); 01572 nPalEntries = 0; 01573 offPalEntries = 0; 01574 nSizeLast = 0; 01575 } 01576 01581 EMREOF ( DATASTREAM& ds ) 01582 { 01583 ds >> emr >> nPalEntries >> offPalEntries >> nSizeLast; 01584 } 01585 01589 bool serialize ( DATASTREAM ds ) 01590 { 01591 ds << emr << nPalEntries << offPalEntries << nSizeLast; 01592 return true; 01593 } 01597 int size ( void ) const { return emr.nSize; } 01603 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC /*dc*/ ) const 01604 { 01605 // Actually handled by the destination device context. 01606 } 01607 #ifdef ENABLE_EDITING 01608 01611 void edit ( void ) const 01612 { 01613 printf( "*EOF*\n" ); 01614 } 01615 #endif /* ENABLE_EDITING */ 01616 }; 01617 01619 01624 class EMRSETVIEWPORTORGEX : public METARECORD, ::EMRSETVIEWPORTORGEX { 01625 public: 01630 EMRSETVIEWPORTORGEX ( INT x, INT y ) 01631 { 01632 emr.iType = EMR_SETVIEWPORTORGEX; 01633 emr.nSize = sizeof( ::EMRSETVIEWPORTORGEX ); 01634 ptlOrigin.x = x; 01635 ptlOrigin.y = y; 01636 } 01641 EMRSETVIEWPORTORGEX ( DATASTREAM& ds ) 01642 { 01643 ds >> emr >> ptlOrigin; 01644 } 01648 bool serialize ( DATASTREAM ds ) 01649 { 01650 ds << emr << ptlOrigin; 01651 return true; 01652 } 01656 int size ( void ) const { return emr.nSize; } 01662 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 01663 { 01664 SetViewportOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 ); 01665 } 01666 #ifdef ENABLE_EDITING 01667 01670 void edit ( void ) const 01671 { 01672 printf( "*SETVIEWPORTORGEX*\n" ); 01673 edit_pointl( "ptlOrigin", ptlOrigin ); 01674 } 01675 #endif /* ENABLE_EDITING */ 01676 }; 01677 01679 01686 class EMRSETWINDOWORGEX : public METARECORD, ::EMRSETWINDOWORGEX { 01687 public: 01692 EMRSETWINDOWORGEX ( INT x, INT y ) 01693 { 01694 emr.iType = EMR_SETWINDOWORGEX; 01695 emr.nSize = sizeof( ::EMRSETWINDOWORGEX ); 01696 ptlOrigin.x = x; 01697 ptlOrigin.y = y; 01698 } 01703 EMRSETWINDOWORGEX ( DATASTREAM& ds ) 01704 { 01705 ds >> emr >> ptlOrigin; 01706 } 01710 bool serialize ( DATASTREAM ds ) 01711 { 01712 ds << emr << ptlOrigin; 01713 return true; 01714 } 01718 int size ( void ) const { return emr.nSize; } 01724 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 01725 { 01726 SetWindowOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 ); 01727 } 01728 #ifdef ENABLE_EDITING 01729 01732 void edit ( void ) const 01733 { 01734 printf( "*SETWINDOWORGEX*\n" ); 01735 edit_pointl( "ptlOrigin", ptlOrigin ); 01736 } 01737 #endif /* ENABLE_EDITING */ 01738 }; 01739 01741 01746 class EMRSETVIEWPORTEXTEX : public METARECORD, ::EMRSETVIEWPORTEXTEX { 01747 public: 01752 EMRSETVIEWPORTEXTEX ( INT cx, INT cy ) 01753 { 01754 emr.iType = EMR_SETVIEWPORTEXTEX; 01755 emr.nSize = sizeof( ::EMRSETVIEWPORTEXTEX ); 01756 szlExtent.cx = cx; 01757 szlExtent.cy = cy; 01758 } 01763 EMRSETVIEWPORTEXTEX ( DATASTREAM& ds ) 01764 { 01765 ds >> emr >> szlExtent; 01766 } 01770 bool serialize ( DATASTREAM ds ) 01771 { 01772 ds << emr << szlExtent; 01773 return true; 01774 } 01778 int size ( void ) const { return emr.nSize; } 01784 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 01785 { 01786 SetViewportExtEx( dc, szlExtent.cx, szlExtent.cy, 0 ); 01787 } 01788 #ifdef ENABLE_EDITING 01789 01792 void edit ( void ) const 01793 { 01794 printf( "*SETVIEWPORTEXTEX*\n" ); 01795 edit_sizel( "szlExtent", szlExtent ); 01796 } 01797 #endif /* ENABLE_EDITING */ 01798 }; 01799 01801 01806 class EMRSCALEVIEWPORTEXTEX : public METARECORD, ::EMRSCALEVIEWPORTEXTEX { 01807 public: 01814 EMRSCALEVIEWPORTEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den ) 01815 { 01816 emr.iType = EMR_SCALEVIEWPORTEXTEX; 01817 emr.nSize = sizeof( ::EMRSCALEVIEWPORTEXTEX ); 01818 xNum = x_num; 01819 xDenom = x_den; 01820 yNum = y_num; 01821 yDenom = y_den; 01822 } 01827 EMRSCALEVIEWPORTEXTEX ( DATASTREAM& ds ) 01828 { 01829 ds >> emr >> xNum >> xDenom >> yNum >> yDenom; 01830 } 01834 bool serialize ( DATASTREAM ds ) 01835 { 01836 ds << emr << xNum << xDenom << yNum << yDenom; 01837 return true; 01838 } 01842 int size ( void ) const { return emr.nSize; } 01848 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 01849 { 01850 ScaleViewportExtEx( dc, xNum, xDenom, yNum, yDenom, 0 ); 01851 } 01852 #ifdef ENABLE_EDITING 01853 01856 void edit ( void ) const 01857 { 01858 #if defined(__LP64__) 01859 const char* FMT0 = "\txNum\t: %d\n"; 01860 const char* FMT1 = "\txDenom\t: %d\n"; 01861 const char* FMT2 = "\tyNum\t: %d\n"; 01862 const char* FMT3 = "\tyDenom\t: %d\n"; 01863 #else 01864 const char* FMT0 = "\txNum\t: %ld\n"; 01865 const char* FMT1 = "\txDenom\t: %ld\n"; 01866 const char* FMT2 = "\tyNum\t: %ld\n"; 01867 const char* FMT3 = "\tyDenom\t: %ld\n"; 01868 #endif 01869 printf( "*SCALEVIEWPORTEXTEX*\n" ); 01870 printf( FMT0, xNum ); 01871 printf( FMT1, xDenom ); 01872 printf( FMT2, yNum ); 01873 printf( FMT3, yDenom ); 01874 } 01875 #endif /* ENABLE_EDITING */ 01876 }; 01877 01879 01884 class EMRSETWINDOWEXTEX : public METARECORD, ::EMRSETWINDOWEXTEX { 01885 public: 01890 EMRSETWINDOWEXTEX ( INT cx, INT cy ) 01891 { 01892 emr.iType = EMR_SETWINDOWEXTEX; 01893 emr.nSize = sizeof( ::EMRSETWINDOWEXTEX ); 01894 szlExtent.cx = cx; 01895 szlExtent.cy = cy; 01896 } 01901 EMRSETWINDOWEXTEX ( DATASTREAM& ds ) 01902 { 01903 ds >> emr >> szlExtent; 01904 } 01908 bool serialize ( DATASTREAM ds ) 01909 { 01910 ds << emr << szlExtent; 01911 return true; 01912 } 01916 int size ( void ) const { return emr.nSize; } 01922 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 01923 { 01924 SetWindowExtEx( dc, szlExtent.cx, szlExtent.cy, 0 ); 01925 } 01926 #ifdef ENABLE_EDITING 01927 01930 void edit ( void ) const 01931 { 01932 printf( "*SETWINDOWEXTEX*\n" ); 01933 edit_sizel( "szlExtent", szlExtent ); 01934 } 01935 #endif /* ENABLE_EDITING */ 01936 }; 01937 01939 01944 class EMRSCALEWINDOWEXTEX : public METARECORD, ::EMRSCALEWINDOWEXTEX { 01945 public: 01952 EMRSCALEWINDOWEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den ) 01953 { 01954 emr.iType = EMR_SCALEWINDOWEXTEX; 01955 emr.nSize = sizeof( ::EMRSCALEWINDOWEXTEX ); 01956 xNum = x_num; 01957 xDenom = x_den; 01958 yNum = y_num; 01959 yDenom = y_den; 01960 } 01965 EMRSCALEWINDOWEXTEX ( DATASTREAM& ds ) 01966 { 01967 ds >> emr >> xNum >> xDenom >> yNum >> yDenom; 01968 } 01972 bool serialize ( DATASTREAM ds ) 01973 { 01974 ds << emr << xNum << xDenom << yNum << yDenom; 01975 return true; 01976 } 01980 int size ( void ) const { return emr.nSize; } 01986 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 01987 { 01988 ScaleWindowExtEx( dc, xNum, xDenom, yNum, yDenom, 0 ); 01989 } 01990 #ifdef ENABLE_EDITING 01991 01994 void edit ( void ) const 01995 { 01996 #if defined(__LP64__) 01997 const char* FMT0 = "\txNum\t: %d\n"; 01998 const char* FMT1 = "\txDenom\t: %d\n"; 01999 const char* FMT2 = "\tyNum\t: %d\n"; 02000 const char* FMT3 = "\tyDenom\t: %d\n"; 02001 #else 02002 const char* FMT0 = "\txNum\t: %ld\n"; 02003 const char* FMT1 = "\txDenom\t: %ld\n"; 02004 const char* FMT2 = "\tyNum\t: %ld\n"; 02005 const char* FMT3 = "\tyDenom\t: %ld\n"; 02006 #endif 02007 printf( "*SCALEWINDOWEXTEX*\n" ); 02008 printf( FMT0, xNum ); 02009 printf( FMT1, xDenom ); 02010 printf( FMT2, yNum ); 02011 printf( FMT3, yDenom ); 02012 } 02013 #endif /* ENABLE_EDITING */ 02014 }; 02015 02017 02023 class EMRMODIFYWORLDTRANSFORM : public METARECORD, ::EMRMODIFYWORLDTRANSFORM { 02024 public: 02030 EMRMODIFYWORLDTRANSFORM ( const XFORM* transform, DWORD mode ) 02031 { 02032 emr.iType = EMR_MODIFYWORLDTRANSFORM; 02033 emr.nSize = sizeof( ::EMRMODIFYWORLDTRANSFORM ); 02034 xform = *transform; 02035 iMode = mode; 02036 } 02041 EMRMODIFYWORLDTRANSFORM ( DATASTREAM& ds ) 02042 { 02043 ds >> emr >> xform >> iMode; 02044 } 02048 bool serialize ( DATASTREAM ds ) 02049 { 02050 ds << emr << xform << iMode; 02051 return true; 02052 } 02056 int size ( void ) const { return emr.nSize; } 02062 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02063 { 02064 ModifyWorldTransform( dc, &xform, iMode ); 02065 } 02066 #ifdef ENABLE_EDITING 02067 02070 void edit ( void ) const 02071 { 02072 #if defined(__LP64__) 02073 const char* FMT = "unknown(%d)\n"; 02074 #else 02075 const char* FMT = "unknown(%ld)\n"; 02076 #endif /* __x86_64__ */ 02077 printf( "*MODIFYWORLDTRANSFORM*\n" ); 02078 edit_xform( "xform", xform ); 02079 printf( "\tiMode\t\t: " ); 02080 switch ( iMode ) { 02081 case MWT_IDENTITY: printf( "MWT_IDENTITY\n" ); break; 02082 case MWT_LEFTMULTIPLY: printf( "MWT_LEFTMULTIPLY\n" ); break; 02083 case MWT_RIGHTMULTIPLY: printf( "MWT_RIGHTMULTIPLY\n" ); break; 02084 default: printf( FMT, iMode ); 02085 } 02086 } 02087 #endif /* ENABLE_EDITING */ 02088 }; 02089 02091 02097 class EMRSETWORLDTRANSFORM : public METARECORD, ::EMRSETWORLDTRANSFORM { 02098 public: 02102 EMRSETWORLDTRANSFORM ( const XFORM* transform ) 02103 { 02104 emr.iType = EMR_SETWORLDTRANSFORM; 02105 emr.nSize = sizeof( ::EMRSETWORLDTRANSFORM ); 02106 xform = *transform; 02107 } 02112 EMRSETWORLDTRANSFORM ( DATASTREAM& ds ) 02113 { 02114 ds >> emr >> xform; 02115 } 02119 bool serialize ( DATASTREAM ds ) 02120 { 02121 ds << emr << xform; 02122 return true; 02123 } 02127 int size ( void ) const { return emr.nSize; } 02133 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02134 { 02135 SetWorldTransform( dc, &xform ); 02136 } 02137 #ifdef ENABLE_EDITING 02138 02141 void edit ( void ) const 02142 { 02143 printf( "*SETWORLDTRANSFORM*\n" ); 02144 edit_xform( "xform", xform ); 02145 } 02146 #endif /* ENABLE_EDITING */ 02147 }; 02148 02150 02153 class EMRSETTEXTALIGN : public METARECORD, ::EMRSETTEXTALIGN { 02154 public: 02158 EMRSETTEXTALIGN ( UINT mode ) 02159 { 02160 emr.iType = EMR_SETTEXTALIGN; 02161 emr.nSize = sizeof( ::EMRSETTEXTALIGN ); 02162 iMode = mode; 02163 } 02168 EMRSETTEXTALIGN ( DATASTREAM& ds ) 02169 { 02170 ds >> emr >> iMode; 02171 } 02175 bool serialize ( DATASTREAM ds ) 02176 { 02177 ds << emr << iMode; 02178 return true; 02179 } 02183 int size ( void ) const { return emr.nSize; } 02189 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02190 { 02191 SetTextAlign( dc, iMode ); 02192 } 02193 #ifdef ENABLE_EDITING 02194 02197 void edit ( void ) const 02198 { 02199 #if defined(__LP64__) 02200 const char* FMT = "| unknown bits(0x%x)"; 02201 #else 02202 const char* FMT = "| unknown bits(0x%lx)"; 02203 #endif /* __x86_64__ */ 02204 unsigned int known_bits = TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING; 02205 unsigned int unknown_bits = ~known_bits; 02206 02207 printf( "*SETTEXTALIGN*\n" ); 02208 printf( "\tiMode\t: " ); 02209 if ( iMode & TA_UPDATECP ) 02210 printf( "TA_UPDATECP" ); 02211 else 02212 printf( "TA_NOUPDATECP" ); 02213 if ( iMode & TA_CENTER ) 02214 printf( " | TA_CENTER" ); 02215 else if ( iMode & TA_RIGHT ) 02216 printf( " | TA_RIGHT" ); 02217 else 02218 printf( " | TA_LEFT" ); 02219 if ( iMode & TA_BASELINE ) 02220 printf( " | TA_BASELINE" ); 02221 else if ( iMode & TA_BOTTOM ) 02222 printf( " | TA_BOTTOM" ); 02223 else 02224 printf( " | TA_TOP" ); 02225 if ( iMode & TA_RTLREADING ) 02226 printf( " | TA_RTLREADING" ); 02227 if ( iMode & unknown_bits ) 02228 printf( FMT, iMode & unknown_bits ); 02229 printf( "\n" ); 02230 } 02231 #endif /* ENABLE_EDITING */ 02232 }; 02233 02235 02238 class EMRSETTEXTCOLOR : public METARECORD, ::EMRSETTEXTCOLOR { 02239 public: 02243 EMRSETTEXTCOLOR ( COLORREF color ) 02244 { 02245 emr.iType = EMR_SETTEXTCOLOR; 02246 emr.nSize = sizeof( ::EMRSETTEXTCOLOR ); 02247 crColor = color; 02248 } 02253 EMRSETTEXTCOLOR ( DATASTREAM& ds ) 02254 { 02255 ds >> emr >> crColor; 02256 } 02260 bool serialize ( DATASTREAM ds ) 02261 { 02262 ds << emr << crColor; 02263 return true; 02264 } 02268 int size ( void ) const { return emr.nSize; } 02274 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02275 { 02276 SetTextColor( dc, crColor ); 02277 } 02278 #ifdef ENABLE_EDITING 02279 02282 void edit ( void ) const 02283 { 02284 printf( "*SETTEXTCOLOR*\n" ); 02285 edit_color( "crColor", crColor ); 02286 } 02287 #endif /* ENABLE_EDITING */ 02288 }; 02289 02291 02294 class EMRSETBKCOLOR : public METARECORD, ::EMRSETBKCOLOR { 02295 public: 02299 EMRSETBKCOLOR ( COLORREF color ) 02300 { 02301 emr.iType = EMR_SETBKCOLOR; 02302 emr.nSize = sizeof( ::EMRSETBKCOLOR ); 02303 crColor = color; 02304 } 02309 EMRSETBKCOLOR ( DATASTREAM& ds ) 02310 { 02311 ds >> emr >> crColor; 02312 } 02316 bool serialize ( DATASTREAM ds ) 02317 { 02318 ds << emr << crColor; 02319 return true; 02320 } 02324 int size ( void ) const { return emr.nSize; } 02330 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02331 { 02332 SetBkColor( dc, crColor ); 02333 } 02334 #ifdef ENABLE_EDITING 02335 02338 void edit ( void ) const 02339 { 02340 printf( "*SETBKCOLOR*\n" ); 02341 edit_color( "crColor", crColor ); 02342 } 02343 #endif /* ENABLE_EDITING */ 02344 }; 02345 02347 02351 class EMRSETBKMODE : public METARECORD, ::EMRSETBKMODE { 02352 public: 02356 EMRSETBKMODE ( DWORD mode ) 02357 { 02358 emr.iType = EMR_SETBKMODE; 02359 emr.nSize = sizeof( ::EMRSETBKMODE ); 02360 iMode = mode; 02361 } 02366 EMRSETBKMODE ( DATASTREAM& ds ) 02367 { 02368 ds >> emr >> iMode; 02369 } 02373 bool serialize ( DATASTREAM ds ) 02374 { 02375 ds << emr << iMode; 02376 return true; 02377 } 02381 int size ( void ) const { return emr.nSize; } 02387 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02388 { 02389 SetBkMode( dc, iMode ); 02390 } 02391 #ifdef ENABLE_EDITING 02392 02395 void edit ( void ) const 02396 { 02397 #if defined(__LP64__) 02398 const char* FMT = "unknown(%d)\n"; 02399 #else 02400 const char* FMT = "unknown(%ld)\n"; 02401 #endif /* __x86_64__ */ 02402 printf( "*SETBKMODE*\n" ); 02403 printf( "\tiMode\t: " ); 02404 switch ( iMode ) { 02405 case TRANSPARENT: printf( "TRANSPARENT\n" ); break; 02406 case OPAQUE: printf( "OPAQUE\n" ); break; 02407 default: printf( FMT, iMode ); 02408 } 02409 } 02410 #endif /* ENABLE_EDITING */ 02411 }; 02412 02414 02417 class EMRSETPOLYFILLMODE : public METARECORD, ::EMRSETPOLYFILLMODE { 02418 public: 02422 EMRSETPOLYFILLMODE ( DWORD mode ) 02423 { 02424 emr.iType = EMR_SETPOLYFILLMODE; 02425 emr.nSize = sizeof( ::EMRSETPOLYFILLMODE ); 02426 iMode = mode; 02427 } 02432 EMRSETPOLYFILLMODE ( DATASTREAM& ds ) 02433 { 02434 ds >> emr >> iMode; 02435 } 02439 bool serialize ( DATASTREAM ds ) 02440 { 02441 ds << emr << iMode; 02442 return true; 02443 } 02447 int size ( void ) const { return emr.nSize; } 02453 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02454 { 02455 SetPolyFillMode( dc, iMode ); 02456 } 02457 #ifdef ENABLE_EDITING 02458 02461 void edit ( void ) const 02462 { 02463 #if defined(__LP64__) 02464 const char* FMT = "unknown(%d)\n"; 02465 #else 02466 const char* FMT = "unknown(%ld)\n"; 02467 #endif /* __x86_64__ */ 02468 printf( "*SETPOLYFILLMODE*\n" ); 02469 printf( "\tiMode: " ); 02470 switch ( iMode ) { 02471 case ALTERNATE: printf( "ALTERNATE\n" ); break; 02472 case WINDING: printf( "WINDING\n" ); break; 02473 default: printf( FMT, iMode ); 02474 } 02475 } 02476 #endif /* ENABLE_EDITING */ 02477 }; 02478 02480 02484 class EMRSETMAPMODE : public METARECORD, ::EMRSETMAPMODE { 02485 public: 02489 EMRSETMAPMODE ( DWORD mode ) 02490 { 02491 emr.iType = EMR_SETMAPMODE; 02492 emr.nSize = sizeof( ::EMRSETMAPMODE ); 02493 iMode = mode; 02494 } 02499 EMRSETMAPMODE ( DATASTREAM& ds ) 02500 { 02501 ds >> emr >> iMode; 02502 } 02506 bool serialize ( DATASTREAM ds ) 02507 { 02508 ds << emr << iMode; 02509 return true; 02510 } 02514 int size ( void ) const { return emr.nSize; } 02520 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02521 { 02522 SetMapMode( dc, iMode ); 02523 } 02524 #ifdef ENABLE_EDITING 02525 02528 void edit ( void ) const 02529 { 02530 #if defined(__LP64__) 02531 const char* FMT = "unknown(%d)\n"; 02532 #else 02533 const char* FMT = "unknown(%ld)\n"; 02534 #endif /* __x86_64__ */ 02535 printf( "*SETMAPMODE*\n" ); 02536 printf( "\tiMode\t: " ); 02537 switch ( iMode ) { 02538 case MM_TEXT: printf( "MM_TEXT\n" ); break; 02539 case MM_LOMETRIC: printf( "MM_LOMETRIC\n" ); break; 02540 case MM_HIMETRIC: printf( "MM_HIMETRIC\n" ); break; 02541 case MM_LOENGLISH: printf( "MM_LOENGLISH\n" ); break; 02542 case MM_HIENGLISH: printf( "MM_HIENGLISH\n" ); break; 02543 case MM_TWIPS: printf( "MM_TWIPS\n" ); break; 02544 case MM_ISOTROPIC: printf( "MM_ISOTROPIC\n" ); break; 02545 case MM_ANISOTROPIC: printf( "MM_ANISOTROPIC\n" ); break; 02546 default: printf( FMT, iMode ); 02547 } 02548 } 02549 #endif /* ENABLE_EDITING */ 02550 }; 02551 02553 02556 class EMRSELECTOBJECT : public METARECORD, ::EMRSELECTOBJECT { 02557 public: 02561 EMRSELECTOBJECT ( HGDIOBJ object ) 02562 { 02563 emr.iType = EMR_SELECTOBJECT; 02564 emr.nSize = sizeof( ::EMRSELECTOBJECT ); 02565 ihObject = object; 02566 } 02571 EMRSELECTOBJECT ( DATASTREAM& ds ) 02572 { 02573 ds >> emr >> ihObject; 02574 } 02578 bool serialize ( DATASTREAM ds ) 02579 { 02580 ds << emr << ihObject; 02581 return true; 02582 } 02586 int size ( void ) const { return emr.nSize; } 02592 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const; 02593 #ifdef ENABLE_EDITING 02594 02597 void edit ( void ) const 02598 { 02599 #if defined(__LP64__) 02600 const char* FMT = "\tihObject\t: 0x%x\n"; 02601 #else 02602 const char* FMT = "\tihObject\t: 0x%lx\n"; 02603 #endif /* __x86_64__ */ 02604 printf( "*SELECTOBJECT*\n" ); 02605 printf( FMT, ihObject ); 02606 } 02607 #endif /* ENABLE_EDITING */ 02608 }; 02609 02611 02614 class EMRDELETEOBJECT : public METARECORD, ::EMRDELETEOBJECT { 02615 public: 02619 EMRDELETEOBJECT ( HGDIOBJ object ) 02620 { 02621 emr.iType = EMR_DELETEOBJECT; 02622 emr.nSize = sizeof( ::EMRDELETEOBJECT ); 02623 ihObject = object; 02624 } 02629 EMRDELETEOBJECT ( DATASTREAM& ds ) 02630 { 02631 ds >> emr >> ihObject; 02632 } 02636 bool serialize ( DATASTREAM ds ) 02637 { 02638 ds << emr << ihObject; 02639 return true; 02640 } 02644 int size ( void ) const { return emr.nSize; } 02650 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const; 02651 #ifdef ENABLE_EDITING 02652 02655 void edit ( void ) const 02656 { 02657 #if defined(__LP64__) 02658 const char* FMT = "\tihObject\t: 0x%x\n"; 02659 #else 02660 const char* FMT = "\tihObject\t: 0x%lx\n"; 02661 #endif /* __x86_64__ */ 02662 printf( "*DELETEOBJECT*\n" ); 02663 printf( FMT, ihObject ); 02664 } 02665 #endif /* ENABLE_EDITING */ 02666 }; 02667 02669 02672 class EMRMOVETOEX : public METARECORD, ::EMRMOVETOEX { 02673 public: 02678 EMRMOVETOEX ( INT x, INT y ) 02679 { 02680 emr.iType = EMR_MOVETOEX; 02681 emr.nSize = sizeof( ::EMRMOVETOEX ); 02682 ptl.x = x; 02683 ptl.y = y; 02684 } 02689 EMRMOVETOEX ( DATASTREAM& ds ) 02690 { 02691 ds >> emr >> ptl; 02692 } 02696 bool serialize ( DATASTREAM ds ) 02697 { 02698 ds << emr << ptl; 02699 return true; 02700 } 02704 int size ( void ) const { return emr.nSize; } 02710 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02711 { 02712 MoveToEx( dc, ptl.x, ptl.y, 0 ); 02713 } 02714 #ifdef ENABLE_EDITING 02715 02718 void edit ( void ) const 02719 { 02720 printf( "*MOVETOEX*\n" ); 02721 edit_pointl( "ptl", ptl ); 02722 } 02723 #endif /* ENABLE_EDITING */ 02724 }; 02725 02727 02730 class EMRLINETO : public METARECORD, ::EMRLINETO { 02731 public: 02736 EMRLINETO ( INT x, INT y ) 02737 { 02738 emr.iType = EMR_LINETO; 02739 emr.nSize = sizeof( ::EMRLINETO ); 02740 ptl.x = x; 02741 ptl.y = y; 02742 } 02747 EMRLINETO ( DATASTREAM& ds ) 02748 { 02749 ds >> emr >> ptl; 02750 } 02754 bool serialize ( DATASTREAM ds ) 02755 { 02756 ds << emr << ptl; 02757 return true; 02758 } 02762 int size ( void ) const { return emr.nSize; } 02768 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02769 { 02770 LineTo( dc, ptl.x, ptl.y ); 02771 } 02772 #ifdef ENABLE_EDITING 02773 02776 void edit ( void ) const 02777 { 02778 printf( "*LINETO*\n" ); 02779 edit_pointl( "ptl", ptl ); 02780 } 02781 #endif /* ENABLE_EDITING */ 02782 }; 02783 02785 02788 class EMRARC : public METARECORD, ::EMRARC { 02789 public: 02801 EMRARC ( INT left, INT top, INT right, INT bottom, INT xstart, 02802 INT ystart, INT xend, INT yend ) 02803 { 02804 emr.iType = EMR_ARC; 02805 emr.nSize = sizeof( ::EMRARC ); 02806 rclBox.left = left; 02807 rclBox.right = right; 02808 rclBox.bottom = bottom; 02809 rclBox.top = top; 02810 ptlStart.x = xstart; 02811 ptlStart.y = ystart; 02812 ptlEnd.x = xend; 02813 ptlEnd.y = yend; 02814 } 02819 EMRARC ( DATASTREAM& ds ) 02820 { 02821 ds >> emr >> rclBox >> ptlStart >> ptlEnd; 02822 } 02826 bool serialize ( DATASTREAM ds ) 02827 { 02828 ds << emr << rclBox << ptlStart << ptlEnd; 02829 return true; 02830 } 02834 int size ( void ) const { return emr.nSize; } 02840 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02841 { 02842 Arc( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom, 02843 ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y ); 02844 } 02845 #ifdef ENABLE_EDITING 02846 02849 void edit ( void ) const 02850 { 02851 printf( "*ARC*\n" ); 02852 edit_rectl( "rclBox\t", rclBox ); 02853 edit_pointl( "ptlStart", ptlStart ); 02854 edit_pointl( "ptlEnd\t", ptlEnd ); 02855 } 02856 #endif /* ENABLE_EDITING */ 02857 }; 02858 02860 02863 class EMRARCTO : public METARECORD, ::EMRARCTO { 02864 public: 02876 EMRARCTO ( INT left, INT top, INT right, INT bottom, INT xstart, 02877 INT ystart, INT xend, INT yend ) 02878 { 02879 emr.iType = EMR_ARCTO; 02880 emr.nSize = sizeof( ::EMRARCTO ); 02881 rclBox.left = left; 02882 rclBox.right = right; 02883 rclBox.bottom = bottom; 02884 rclBox.top = top; 02885 ptlStart.x = xstart; 02886 ptlStart.y = ystart; 02887 ptlEnd.x = xend; 02888 ptlEnd.y = yend; 02889 } 02894 EMRARCTO ( DATASTREAM& ds ) 02895 { 02896 ds >> emr >> rclBox >> ptlStart >> ptlEnd; 02897 } 02901 bool serialize ( DATASTREAM ds ) 02902 { 02903 ds << emr << rclBox << ptlStart << ptlEnd; 02904 return true; 02905 } 02909 int size ( void ) const { return emr.nSize; } 02915 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02916 { 02917 ArcTo( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom, 02918 ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y ); 02919 } 02920 #ifdef ENABLE_EDITING 02921 02924 void edit ( void ) const 02925 { 02926 printf( "*ARCTO*\n" ); 02927 edit_rectl( "rclBox\t", rclBox ); 02928 edit_pointl( "ptlStart", ptlStart ); 02929 edit_pointl( "ptlEnd\t", ptlEnd ); 02930 } 02931 #endif /* ENABLE_EDITING */ 02932 }; 02933 02935 02938 class EMRRECTANGLE : public METARECORD, ::EMRRECTANGLE { 02939 public: 02946 EMRRECTANGLE ( INT left, INT top, INT right, INT bottom ) 02947 { 02948 emr.iType = EMR_RECTANGLE; 02949 emr.nSize = sizeof( ::EMRRECTANGLE ); 02950 rclBox.left = left; 02951 rclBox.right = right; 02952 rclBox.bottom = bottom; 02953 rclBox.top = top; 02954 } 02959 EMRRECTANGLE ( DATASTREAM& ds ) 02960 { 02961 ds >> emr >> rclBox; 02962 } 02966 bool serialize ( DATASTREAM ds ) 02967 { 02968 ds << emr << rclBox; 02969 return true; 02970 } 02974 int size ( void ) const { return emr.nSize; } 02980 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 02981 { 02982 Rectangle( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom ); 02983 } 02984 #ifdef ENABLE_EDITING 02985 02988 void edit ( void ) const 02989 { 02990 printf( "*RECTANGLE*\n" ); 02991 edit_rectl( "rclBox", rclBox ); 02992 } 02993 #endif /* ENABLE_EDITING */ 02994 }; 02995 02997 03000 class EMRELLIPSE : public METARECORD, ::EMRELLIPSE { 03001 public: 03009 EMRELLIPSE ( INT left, INT top, INT right, INT bottom ) 03010 { 03011 emr.iType = EMR_ELLIPSE; 03012 emr.nSize = sizeof( ::EMRELLIPSE ); 03013 rclBox.left = left; 03014 rclBox.right = right; 03015 rclBox.bottom = bottom; 03016 rclBox.top = top; 03017 } 03022 EMRELLIPSE ( DATASTREAM& ds ) 03023 { 03024 ds >> emr >> rclBox; 03025 } 03029 bool serialize ( DATASTREAM ds ) 03030 { 03031 ds << emr << rclBox; 03032 return true; 03033 } 03037 int size ( void ) const { return emr.nSize; } 03043 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03044 { 03045 Ellipse( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom ); 03046 } 03047 #ifdef ENABLE_EDITING 03048 03051 void edit ( void ) const 03052 { 03053 printf( "*ELLIPSE*\n" ); 03054 edit_rectl( "rclBox", rclBox ); 03055 } 03056 #endif /* ENABLE_EDITING */ 03057 }; 03058 03060 03063 class EMRPOLYLINE : public METARECORD, ::EMRPOLYLINE { 03064 POINTL* lpoints; 03065 public: 03071 EMRPOLYLINE ( const RECTL* bounds, const POINT* points, INT n ) 03072 { 03073 cptl = n; 03074 aptl[0].x = 0; // Really unused 03075 aptl[0].y = 0; 03076 03077 emr.iType = EMR_POLYLINE; 03078 // The (cptl - 1) below is to account for aptl, which isn't written out 03079 emr.nSize = sizeof( ::EMRPOLYLINE ) + sizeof( POINTL ) * ( cptl - 1); 03080 03081 lpoints = new POINTL[cptl]; 03082 03083 for (int i=0; i<n; i++) { 03084 lpoints[i].x = points[i].x; 03085 lpoints[i].y = points[i].y; 03086 } 03087 03088 rclBounds = *bounds; 03089 } 03093 ~EMRPOLYLINE ( ) 03094 { 03095 if ( lpoints ) delete[] lpoints; 03096 } 03101 EMRPOLYLINE ( DATASTREAM& ds ) 03102 { 03103 ds >> emr >> rclBounds >> cptl; 03104 03105 lpoints = new POINTL[cptl]; 03106 03107 POINTLARRAY points( lpoints, cptl ); 03108 03109 ds >> points; 03110 } 03114 bool serialize ( DATASTREAM ds ) 03115 { 03116 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl ); 03117 return true; 03118 } 03122 int size ( void ) const { return emr.nSize; } 03128 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03129 { 03130 // According to the wine windef.h header, POINT and POINTL are equivalent 03131 Polyline( dc, (POINT*)lpoints, cptl ); 03132 } 03133 #ifdef ENABLE_EDITING 03134 03137 void edit ( void ) const 03138 { 03139 printf( "*POLYLINE*\n" ); 03140 edit_rectl( "rclBounds", rclBounds ); 03141 #if 0 03142 printf( "\tcptl : %ld\n", cptl ); 03143 printf( "\taptl->\n" ); 03144 for ( unsigned int i = 0; i < cptl; i++ ) 03145 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y ); 03146 #else 03147 edit_pointlarray( "\t", cptl, lpoints ); 03148 #endif 03149 } 03150 #endif /* ENABLE_EDITING */ 03151 }; 03152 03154 03157 class EMRPOLYLINE16 : public METARECORD, ::EMRPOLYLINE16 { 03158 POINT16* lpoints; 03159 public: 03165 EMRPOLYLINE16 ( const RECTL* bounds, const POINT16* points, INT n ) 03166 { 03167 cpts = n; 03168 apts[0].x = 0; // Really unused 03169 apts[0].y = 0; 03170 03171 emr.iType = EMR_POLYLINE16; 03172 // The (cptl - 1) below is to account for aptl, which isn't written out 03173 emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1); 03174 03175 lpoints = new POINT16[cpts]; 03176 03177 for (int i=0; i<n; i++) { 03178 lpoints[i].x = points[i].x; 03179 lpoints[i].y = points[i].y; 03180 } 03181 03182 rclBounds = *bounds; 03183 } 03190 EMRPOLYLINE16 ( const RECTL* bounds, const POINT* points, INT n ) 03191 { 03192 cpts = n; 03193 apts[0].x = 0; // Really unused 03194 apts[0].y = 0; 03195 03196 emr.iType = EMR_POLYLINE16; 03197 // The (cptl - 1) below is to account for aptl, which isn't written out 03198 emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1); 03199 03200 lpoints = new POINT16[cpts]; 03201 03202 for (int i=0; i<n; i++) { 03203 lpoints[i].x = points[i].x; 03204 lpoints[i].y = points[i].y; 03205 } 03206 03207 rclBounds = *bounds; 03208 } 03212 ~EMRPOLYLINE16 ( ) 03213 { 03214 if ( lpoints ) delete[] lpoints; 03215 } 03220 EMRPOLYLINE16 ( DATASTREAM& ds ) 03221 { 03222 ds >> emr >> rclBounds >> cpts; 03223 03224 lpoints = new POINT16[cpts]; 03225 03226 POINT16ARRAY points( lpoints, cpts ); 03227 03228 ds >> points; 03229 } 03233 bool serialize ( DATASTREAM ds ) 03234 { 03235 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts ); 03236 return true; 03237 } 03241 int size ( void ) const { return emr.nSize; } 03247 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03248 { 03249 // According to the wine windef.h header, POINT and POINTL are equivalent 03250 Polyline16( dc, lpoints, cpts ); 03251 } 03252 #ifdef ENABLE_EDITING 03253 03256 void edit ( void ) const 03257 { 03258 printf( "*POLYLINE16*\n" ); 03259 edit_rectl( "rclBounds", rclBounds ); 03260 edit_point16array( "\t", cpts, lpoints ); 03261 } 03262 #endif /* ENABLE_EDITING */ 03263 }; 03264 03266 03269 class EMRPOLYGON : public METARECORD, ::EMRPOLYGON { 03270 POINTL* lpoints; 03271 public: 03277 EMRPOLYGON ( const RECTL* bounds, const POINT* points, INT n ) 03278 { 03279 cptl = n; 03280 aptl[0].x = 0; // Really unused 03281 aptl[0].y = 0; 03282 03283 emr.iType = EMR_POLYGON; 03284 // The (cptl-1) below is to account for aptl, which isn't written out 03285 emr.nSize = sizeof( ::EMRPOLYGON ) + sizeof( POINTL ) * (cptl-1); 03286 03287 lpoints = new POINTL[cptl]; 03288 03289 for (int i=0; i<n; i++) { 03290 lpoints[i].x = points[i].x; 03291 lpoints[i].y = points[i].y; 03292 } 03293 03294 rclBounds = *bounds; 03295 } 03300 EMRPOLYGON ( DATASTREAM& ds ) 03301 { 03302 ds >> emr >> rclBounds >> cptl; 03303 03304 lpoints = new POINTL[cptl]; 03305 03306 POINTLARRAY points( lpoints, cptl ); 03307 03308 ds >> points; 03309 } 03313 ~EMRPOLYGON ( ) 03314 { 03315 if ( lpoints ) delete[] lpoints; 03316 } 03320 bool serialize ( DATASTREAM ds ) 03321 { 03322 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl ); 03323 return true; 03324 } 03328 int size ( void ) const { return emr.nSize; } 03334 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03335 { 03336 // According to the wine windef.h header, POINT and POINTL are equivalent 03337 Polygon( dc, (POINT*)lpoints, cptl ); 03338 } 03339 #ifdef ENABLE_EDITING 03340 03343 void edit ( void ) const 03344 { 03345 printf( "*POLYGON*\n" ); 03346 edit_rectl( "rclBounds", rclBounds ); 03347 #if 0 03348 printf( "\tcptl : %ld\n", cptl ); 03349 printf( "\taptl->\n" ); 03350 for ( unsigned int i = 0; i < cptl; i++ ) 03351 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y ); 03352 #else 03353 edit_pointlarray( "\t", cptl, lpoints ); 03354 #endif 03355 } 03356 #endif /* ENABLE_EDITING */ 03357 }; 03358 03360 03363 class EMRPOLYGON16 : public METARECORD, ::EMRPOLYGON16 { 03364 POINT16* lpoints; 03365 public: 03371 EMRPOLYGON16 ( const RECTL* bounds, const POINT* points, INT16 n ) 03372 { 03373 cpts = n; 03374 apts[0].x = 0; // Really unused 03375 apts[0].y = 0; 03376 03377 emr.iType = EMR_POLYGON16; 03378 // The (cptl-1) below is to account for aptl, which isn't written out 03379 emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1); 03380 03381 lpoints = new POINT16[cpts]; 03382 03383 for (int i=0; i<n; i++) { 03384 lpoints[i].x = points[i].x; 03385 lpoints[i].y = points[i].y; 03386 } 03387 03388 rclBounds = *bounds; 03389 } 03396 EMRPOLYGON16 ( const RECTL* bounds, const POINT16* points, INT16 n ) 03397 { 03398 cpts = n; 03399 apts[0].x = 0; // Really unused 03400 apts[0].y = 0; 03401 03402 emr.iType = EMR_POLYGON16; 03403 // The (cptl-1) below is to account for aptl, which isn't written out 03404 emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1); 03405 03406 lpoints = new POINT16[cpts]; 03407 03408 for (int i=0; i<n; i++) { 03409 lpoints[i].x = points[i].x; 03410 lpoints[i].y = points[i].y; 03411 } 03412 03413 rclBounds = *bounds; 03414 } 03419 EMRPOLYGON16 ( DATASTREAM& ds ) 03420 { 03421 ds >> emr >> rclBounds >> cpts; 03422 03423 lpoints = new POINT16[cpts]; 03424 03425 POINT16ARRAY points( lpoints, cpts ); 03426 03427 ds >> points; 03428 } 03432 ~EMRPOLYGON16 ( ) 03433 { 03434 if ( lpoints ) delete[] lpoints; 03435 } 03439 bool serialize ( DATASTREAM ds ) 03440 { 03441 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts ); 03442 return true; 03443 } 03447 int size ( void ) const { return emr.nSize; } 03453 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03454 { 03455 // According to the wine windef.h header, POINT and POINTL are equivalent 03456 Polygon16( dc, lpoints, cpts ); 03457 } 03458 #ifdef ENABLE_EDITING 03459 03462 void edit ( void ) const 03463 { 03464 printf( "*POLYGON16*\n" ); 03465 edit_rectl( "rclBounds", rclBounds ); 03466 edit_point16array( "\t", cpts, lpoints ); 03467 } 03468 #endif /* ENABLE_EDITING */ 03469 }; 03470 03472 03475 class EMRPOLYPOLYGON : public METARECORD, ::EMRPOLYPOLYGON { 03476 DWORD* lcounts; 03477 POINTL* lpoints; 03478 public: 03485 EMRPOLYPOLYGON ( const RECTL* bounds, const POINT* points, const INT* counts, 03486 UINT polygons ) 03487 { 03488 nPolys = polygons; 03489 // Count the number of points in points 03490 int n = 0; 03491 for ( unsigned int i = 0; i < nPolys; i++ ) 03492 n += counts[i]; 03493 03494 cptl = n; 03495 aPolyCounts[0] = 0; // Really unused 03496 aptl[0].x = 0; 03497 aptl[0].y = 0; 03498 03499 emr.iType = EMR_POLYPOLYGON; 03500 // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which 03501 // aren't directly written out 03502 emr.nSize = sizeof( ::EMRPOLYPOLYGON ) + sizeof( POINTL ) * (cptl-1) 03503 + sizeof( DWORD ) * (nPolys-1); 03504 03505 lcounts = new DWORD[nPolys]; 03506 03507 for ( unsigned int i = 0; i < nPolys; i++ ) 03508 lcounts[i] = counts[i]; 03509 03510 lpoints = new POINTL[cptl]; 03511 03512 for (int i=0; i<n; i++) { 03513 lpoints[i].x = points[i].x; 03514 lpoints[i].y = points[i].y; 03515 } 03516 03517 rclBounds = *bounds; 03518 } 03522 ~EMRPOLYPOLYGON ( ) 03523 { 03524 if ( lcounts ) delete[] lcounts; 03525 if ( lpoints ) delete[] lpoints; 03526 } 03531 EMRPOLYPOLYGON ( DATASTREAM& ds ) 03532 { 03533 ds >> emr >> rclBounds >> nPolys >> cptl; 03534 03535 lcounts = new DWORD[nPolys]; 03536 03537 DWORDARRAY counts( lcounts, nPolys ); 03538 03539 ds >> counts; 03540 03541 lpoints = new POINTL[cptl]; 03542 03543 POINTLARRAY points( lpoints, cptl ); 03544 03545 ds >> points; 03546 } 03550 bool serialize ( DATASTREAM ds ) 03551 { 03552 ds << emr << rclBounds << nPolys << cptl << DWORDARRAY( lcounts, nPolys ) 03553 << POINTLARRAY( lpoints, cptl ); 03554 return true; 03555 } 03559 int size ( void ) const { return emr.nSize; } 03565 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03566 { 03567 // According to the wine windef.h header, POINT and POINTL are equivalent 03568 // (but DWORD and INT are not) 03569 INT* counts = new INT[nPolys]; 03570 for ( unsigned int i = 0; i < nPolys; i++ ) 03571 counts[i] = lcounts[i]; 03572 03573 PolyPolygon( dc, (POINT*)lpoints, counts, nPolys ); 03574 03575 delete[] counts; 03576 } 03577 #ifdef ENABLE_EDITING 03578 03581 void edit ( void ) const 03582 { 03583 #if defined(__LP64__) 03584 const char* FMT0 = "\tnPolys\t\t: %d\n"; 03585 const char* FMT1 = "\tcptl\t\t: %d\n"; 03586 const char* FMT2 = "%d\n"; 03587 const char* FMT3 = "\t\t\t %d\n"; 03588 const char* FMT4 = "%d, %d\n"; 03589 const char* FMT5 = "\t\t\t %d, %d\n"; 03590 #else 03591 const char* FMT0 = "\tnPolys\t\t: %ld\n"; 03592 const char* FMT1 = "\tcptl\t\t: %ld\n"; 03593 const char* FMT2 = "%ld\n"; 03594 const char* FMT3 = "\t\t\t %ld\n"; 03595 const char* FMT4 = "%ld, %ld\n"; 03596 const char* FMT5 = "\t\t\t %ld, %ld\n"; 03597 #endif /* __x86_64__ */ 03598 printf( "*POLYPOLYGON*\n" ); 03599 edit_rectl( "rclBounds", rclBounds ); 03600 printf( FMT0, nPolys ); 03601 printf( FMT1, cptl ); 03602 printf( "\taPolyCounts\t: " ); 03603 if ( nPolys > 0 ) 03604 printf( FMT2, lcounts[0] ); 03605 else 03606 puts( "" ); 03607 for ( unsigned int i = 1; i < nPolys; i++ ) 03608 printf( FMT3, lcounts[i] ); 03609 printf( "\tapts\t\t: " ); 03610 if ( cptl > 0 ) 03611 printf( FMT4, lpoints[0].x, lpoints[0].y ); 03612 else 03613 puts( "" ); 03614 for ( unsigned int i = 1; i < cptl; i++ ) 03615 printf( FMT5, lpoints[i].x, lpoints[i].y ); 03616 } 03617 #endif /* ENABLE_EDITING */ 03618 }; 03619 03621 03624 class EMRPOLYPOLYGON16 : public METARECORD, ::EMRPOLYPOLYGON16 { 03625 DWORD* lcounts; 03626 POINT16* lpoints; 03627 public: 03634 EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT* points, 03635 const INT* counts, UINT polygons ) 03636 { 03637 nPolys = polygons; 03638 // Count the number of points in points 03639 int n = 0; 03640 for ( unsigned int i = 0; i < nPolys; i++ ) 03641 n += counts[i]; 03642 03643 cpts = n; 03644 aPolyCounts[0] = 0; // Really unused 03645 apts[0].x = 0; 03646 apts[0].y = 0; 03647 03648 emr.iType = EMR_POLYPOLYGON16; 03649 // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which 03650 // aren't directly written out 03651 emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1) 03652 + sizeof( DWORD ) * (nPolys-1); 03653 03654 lcounts = new DWORD[nPolys]; 03655 03656 for ( unsigned int i = 0; i < nPolys; i++ ) 03657 lcounts[i] = counts[i]; 03658 03659 lpoints = new POINT16[cpts]; 03660 03661 for (int i=0; i<n; i++) { 03662 lpoints[i].x = points[i].x; 03663 lpoints[i].y = points[i].y; 03664 } 03665 03666 rclBounds = *bounds; 03667 } 03675 EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT16* points, 03676 const INT* counts, UINT16 polygons ) 03677 { 03678 nPolys = polygons; 03679 // Count the number of points in points 03680 int n = 0; 03681 for ( unsigned int i = 0; i < nPolys; i++ ) 03682 n += counts[i]; 03683 03684 cpts = n; 03685 aPolyCounts[0] = 0; // Really unused 03686 apts[0].x = 0; 03687 apts[0].y = 0; 03688 03689 emr.iType = EMR_POLYPOLYGON16; 03690 // The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which 03691 // aren't directly written out 03692 emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1) 03693 + sizeof( DWORD ) * (nPolys-1); 03694 03695 lcounts = new DWORD[nPolys]; 03696 03697 for ( unsigned int i = 0; i < nPolys; i++ ) 03698 lcounts[i] = counts[i]; 03699 03700 lpoints = new POINT16[cpts]; 03701 03702 for (int i=0; i<n; i++) { 03703 lpoints[i].x = points[i].x; 03704 lpoints[i].y = points[i].y; 03705 } 03706 03707 rclBounds = *bounds; 03708 } 03712 ~EMRPOLYPOLYGON16 ( ) 03713 { 03714 if ( lcounts ) delete[] lcounts; 03715 if ( lpoints ) delete[] lpoints; 03716 } 03721 EMRPOLYPOLYGON16 ( DATASTREAM& ds ) 03722 { 03723 ds >> emr >> rclBounds >> nPolys >> cpts; 03724 03725 lcounts = new DWORD[nPolys]; 03726 03727 DWORDARRAY counts( lcounts, nPolys ); 03728 03729 ds >> counts; 03730 03731 lpoints = new POINT16[cpts]; 03732 03733 POINT16ARRAY points( lpoints, cpts ); 03734 03735 ds >> points; 03736 } 03740 bool serialize ( DATASTREAM ds ) 03741 { 03742 ds << emr << rclBounds << nPolys << cpts << DWORDARRAY( lcounts, nPolys ) 03743 << POINT16ARRAY( lpoints, cpts ); 03744 return true; 03745 } 03749 int size ( void ) const { return emr.nSize; } 03755 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03756 { 03757 // According to the wine windef.h header, POINT and POINTL are equivalent 03758 // (but DWORD and INT are not) 03759 INT* counts = new INT[nPolys]; 03760 for ( unsigned int i = 0; i < nPolys; i++ ) 03761 counts[i] = lcounts[i]; 03762 03763 PolyPolygon16( dc, lpoints, counts, nPolys ); 03764 03765 delete[] counts; 03766 } 03767 #ifdef ENABLE_EDITING 03768 03771 void edit ( void ) const 03772 { 03773 #if defined(__LP64__) 03774 const char* FMT0 = "\tnPolys\t\t: %d\n"; 03775 const char* FMT1 = "\tcptl\t\t: %d\n"; 03776 const char* FMT2 = "%d\n"; 03777 const char* FMT3 = "\t\t\t %d\n"; 03778 #else 03779 const char* FMT0 = "\tnPolys\t\t: %ld\n"; 03780 const char* FMT1 = "\tcptl\t\t: %ld\n"; 03781 const char* FMT2 = "%ld\n"; 03782 const char* FMT3 = "\t\t\t %ld\n"; 03783 #endif /* __x86_64__ */ 03784 printf( "*POLYPOLYGON16*\n" ); 03785 edit_rectl( "rclBounds", rclBounds ); 03786 printf( FMT0, nPolys ); 03787 printf( FMT1, cpts ); 03788 printf( "\taPolyCounts\t: " ); 03789 if ( nPolys > 0 ) 03790 printf( FMT2, lcounts[0] ); 03791 else 03792 puts( "" ); 03793 for ( unsigned int i = 1; i < nPolys; i++ ) 03794 printf( FMT3, lcounts[i] ); 03795 printf( "\tapts\t\t: " ); 03796 if ( cpts > 0 ) 03797 printf( "%d, %d\n", lpoints[0].x, lpoints[0].y ); 03798 else 03799 puts( "" ); 03800 for ( unsigned int i = 1; i < cpts; i++ ) 03801 printf( "\t\t\t %d, %d\n", lpoints[i].x, lpoints[i].y ); 03802 } 03803 #endif /* ENABLE_EDITING */ 03804 }; 03805 03807 03810 class EMRPOLYBEZIER : public METARECORD, ::EMRPOLYBEZIER { 03811 POINTL* lpoints; 03812 public: 03818 EMRPOLYBEZIER ( const RECTL* bounds, const POINT* points, INT n ) 03819 { 03820 cptl = n; 03821 aptl[0].x = 0; // Really unused 03822 aptl[0].y = 0; 03823 03824 emr.iType = EMR_POLYBEZIER; 03825 // The (cptl-1) below is to account for aptl, which isn't written out 03826 emr.nSize = sizeof( ::EMRPOLYBEZIER ) + sizeof( POINTL ) * (cptl-1); 03827 03828 lpoints = new POINTL[cptl]; 03829 03830 for (int i=0; i<n; i++) { 03831 lpoints[i].x = points[i].x; 03832 lpoints[i].y = points[i].y; 03833 } 03834 03835 rclBounds = *bounds; 03836 } 03841 EMRPOLYBEZIER ( DATASTREAM& ds ) 03842 { 03843 ds >> emr >> rclBounds >> cptl; 03844 03845 lpoints = new POINTL[cptl]; 03846 03847 POINTLARRAY points( lpoints, cptl ); 03848 03849 ds >> points; 03850 } 03854 ~EMRPOLYBEZIER ( ) 03855 { 03856 if ( lpoints ) delete[] lpoints; 03857 } 03861 bool serialize ( DATASTREAM ds ) 03862 { 03863 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl ); 03864 return true; 03865 } 03869 int size ( void ) const { return emr.nSize; } 03875 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03876 { 03877 // According to the wine windef.h header, POINT and POINTL are equivalent 03878 PolyBezier( dc, (POINT*)lpoints, cptl ); 03879 } 03880 #ifdef ENABLE_EDITING 03881 03884 void edit ( void ) const 03885 { 03886 printf( "*POLYBEZIER*\n" ); 03887 edit_rectl( "rclBounds", rclBounds ); 03888 #if 0 03889 printf( "\tcptl : %ld\n", cptl ); 03890 printf( "\taptl->\n" ); 03891 for ( unsigned int i = 0; i < cptl; i++ ) 03892 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y ); 03893 #else 03894 edit_pointlarray( "\t", cptl, lpoints ); 03895 #endif 03896 } 03897 #endif /* ENABLE_EDITING */ 03898 }; 03899 03901 03904 class EMRPOLYBEZIER16 : public METARECORD, ::EMRPOLYBEZIER16 { 03905 POINT16* lpoints; 03906 public: 03912 EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT16* points, INT n ) 03913 { 03914 cpts = n; 03915 apts[0].x = 0; // Really unused 03916 apts[0].y = 0; 03917 03918 emr.iType = EMR_POLYBEZIER16; 03919 // The (cptl-1) below is to account for aptl, which isn't written out 03920 emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1); 03921 03922 lpoints = new POINT16[cpts]; 03923 03924 for (int i=0; i<n; i++) { 03925 lpoints[i].x = points[i].x; 03926 lpoints[i].y = points[i].y; 03927 } 03928 03929 rclBounds = *bounds; 03930 } 03937 EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT* points, INT n ) 03938 { 03939 cpts = n; 03940 apts[0].x = 0; // Really unused 03941 apts[0].y = 0; 03942 03943 emr.iType = EMR_POLYBEZIER16; 03944 // The (cptl-1) below is to account for aptl, which isn't written out 03945 emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1); 03946 03947 lpoints = new POINT16[cpts]; 03948 03949 for (int i=0; i<n; i++) { 03950 lpoints[i].x = points[i].x; 03951 lpoints[i].y = points[i].y; 03952 } 03953 03954 rclBounds = *bounds; 03955 } 03960 EMRPOLYBEZIER16 ( DATASTREAM& ds ) 03961 { 03962 ds >> emr >> rclBounds >> cpts; 03963 03964 lpoints = new POINT16[cpts]; 03965 03966 POINT16ARRAY points( lpoints, cpts ); 03967 03968 ds >> points; 03969 } 03973 ~EMRPOLYBEZIER16 ( ) 03974 { 03975 if ( lpoints ) delete[] lpoints; 03976 } 03980 bool serialize ( DATASTREAM ds ) 03981 { 03982 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts ); 03983 return true; 03984 } 03988 int size ( void ) const { return emr.nSize; } 03994 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 03995 { 03996 // According to the wine windef.h header, POINT and POINTL are equivalent 03997 PolyBezier16( dc, lpoints, cpts ); 03998 } 03999 #ifdef ENABLE_EDITING 04000 04003 void edit ( void ) const 04004 { 04005 printf( "*POLYBEZIER16*\n" ); 04006 edit_rectl( "rclBounds", rclBounds ); 04007 edit_point16array( "\t", cpts, lpoints ); 04008 } 04009 #endif /* ENABLE_EDITING */ 04010 }; 04011 04013 04016 class EMRPOLYBEZIERTO : public METARECORD, ::EMRPOLYBEZIER { 04017 POINTL* lpoints; 04018 public: 04024 EMRPOLYBEZIERTO ( const RECTL* bounds, const POINT* points, INT n ) 04025 { 04026 cptl = n; 04027 aptl[0].x = 0; // Really unused 04028 aptl[0].y = 0; 04029 04030 emr.iType = EMR_POLYBEZIERTO; 04031 // The (cptl-1) below is to account for aptl, which isn't written out 04032 emr.nSize = sizeof( ::EMRPOLYBEZIERTO ) + sizeof( POINTL ) * (cptl-1); 04033 04034 lpoints = new POINTL[cptl]; 04035 04036 for (int i=0; i<n; i++) { 04037 lpoints[i].x = points[i].x; 04038 lpoints[i].y = points[i].y; 04039 } 04040 04041 rclBounds = *bounds; 04042 } 04047 EMRPOLYBEZIERTO ( DATASTREAM& ds ) 04048 { 04049 ds >> emr >> rclBounds >> cptl; 04050 04051 lpoints = new POINTL[cptl]; 04052 04053 POINTLARRAY points( lpoints, cptl ); 04054 04055 ds >> points; 04056 } 04060 ~EMRPOLYBEZIERTO ( ) 04061 { 04062 if ( lpoints ) delete[] lpoints; 04063 } 04067 bool serialize ( DATASTREAM ds ) 04068 { 04069 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl ); 04070 return true; 04071 } 04075 int size ( void ) const { return emr.nSize; } 04081 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 04082 { 04083 // According to the wine windef.h header, POINT and POINTL are equivalent 04084 PolyBezierTo( dc, (POINT*)lpoints, cptl ); 04085 } 04086 #ifdef ENABLE_EDITING 04087 04090 void edit ( void ) const 04091 { 04092 printf( "*POLYBEZIERTO*\n" ); 04093 edit_rectl( "rclBounds", rclBounds ); 04094 #if 0 04095 printf( "\tcptl : %ld\n", cptl ); 04096 printf( "\taptl->\n" ); 04097 for ( unsigned int i = 0; i < cptl; i++ ) 04098 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y ); 04099 #else 04100 edit_pointlarray( "\t", cptl, lpoints ); 04101 #endif 04102 } 04103 #endif /* ENABLE_EDITING */ 04104 }; 04105 04107 04110 class EMRPOLYBEZIERTO16 : public METARECORD, ::EMRPOLYBEZIER16 { 04111 POINT16* lpoints; 04112 public: 04118 EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT16* points, INT n ) 04119 { 04120 cpts = n; 04121 apts[0].x = 0; // Really unused 04122 apts[0].y = 0; 04123 04124 emr.iType = EMR_POLYBEZIERTO16; 04125 // The (cptl-1) below is to account for aptl, which isn't written out 04126 emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1); 04127 04128 lpoints = new POINT16[cpts]; 04129 04130 for (int i=0; i<n; i++) { 04131 lpoints[i].x = points[i].x; 04132 lpoints[i].y = points[i].y; 04133 } 04134 04135 rclBounds = *bounds; 04136 } 04143 EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT* points, INT n ) 04144 { 04145 cpts = n; 04146 apts[0].x = 0; // Really unused 04147 apts[0].y = 0; 04148 04149 emr.iType = EMR_POLYBEZIERTO16; 04150 // The (cptl-1) below is to account for aptl, which isn't written out 04151 emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1); 04152 04153 lpoints = new POINT16[cpts]; 04154 04155 for (int i=0; i<n; i++) { 04156 lpoints[i].x = points[i].x; 04157 lpoints[i].y = points[i].y; 04158 } 04159 04160 rclBounds = *bounds; 04161 } 04166 EMRPOLYBEZIERTO16 ( DATASTREAM& ds ) 04167 { 04168 ds >> emr >> rclBounds >> cpts; 04169 04170 lpoints = new POINT16[cpts]; 04171 04172 POINT16ARRAY points( lpoints, cpts ); 04173 04174 ds >> points; 04175 } 04179 ~EMRPOLYBEZIERTO16 ( ) 04180 { 04181 if ( lpoints ) delete[] lpoints; 04182 } 04186 bool serialize ( DATASTREAM ds ) 04187 { 04188 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts ); 04189 return true; 04190 } 04194 int size ( void ) const { return emr.nSize; } 04200 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 04201 { 04202 // According to the wine windef.h header, POINT and POINTL are equivalent 04203 PolyBezierTo16( dc, lpoints, cpts ); 04204 } 04205 #ifdef ENABLE_EDITING 04206 04209 void edit ( void ) const 04210 { 04211 printf( "*POLYBEZIERTO16*\n" ); 04212 edit_rectl( "rclBounds", rclBounds ); 04213 edit_point16array( "\t", cpts, lpoints ); 04214 } 04215 #endif /* ENABLE_EDITING */ 04216 }; 04217 04219 04222 class EMRPOLYLINETO : public METARECORD, ::EMRPOLYLINETO { 04223 POINTL* lpoints; 04224 public: 04230 EMRPOLYLINETO ( const RECTL* bounds, const POINT* points, INT n ) 04231 { 04232 cptl = n; 04233 aptl[0].x = 0; 04234 aptl[0].y = 0; 04235 04236 emr.iType = EMR_POLYLINETO; 04237 // The (cptl-1) below is to account for aptl, which isn't written out 04238 emr.nSize = sizeof( ::EMRPOLYLINETO ) + sizeof( POINTL ) * (cptl-1); 04239 04240 lpoints = new POINTL[cptl]; 04241 04242 for (int i=0; i<n; i++) { 04243 lpoints[i].x = points[i].x; 04244 lpoints[i].y = points[i].y; 04245 } 04246 04247 rclBounds = *bounds; 04248 } 04253 EMRPOLYLINETO ( DATASTREAM& ds ) 04254 { 04255 ds >> emr >> rclBounds >> cptl; 04256 04257 lpoints = new POINTL[cptl]; 04258 04259 POINTLARRAY points( lpoints, cptl ); 04260 04261 ds >> points; 04262 } 04266 ~EMRPOLYLINETO ( ) 04267 { 04268 if ( lpoints ) delete[] lpoints; 04269 } 04273 bool serialize ( DATASTREAM ds ) 04274 { 04275 ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl ); 04276 return true; 04277 } 04281 int size ( void ) const { return emr.nSize; } 04287 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 04288 { 04289 // According to the wine windef.h header, POINT and POINTL are equivalent 04290 PolylineTo( dc, (POINT*)lpoints, cptl ); 04291 } 04292 #ifdef ENABLE_EDITING 04293 04296 void edit ( void ) const 04297 { 04298 printf( "*POLYLINETO*\n" ); 04299 edit_rectl( "rclBounds", rclBounds ); 04300 #if 0 04301 printf( "\tcptl : %ld\n", cptl ); 04302 printf( "\taptl->\n" ); 04303 for ( unsigned int i = 0; i < cptl; i++ ) 04304 printf( "\t\t%ld, %ld\n", lpoints[i].x, lpoints[i].y ); 04305 #else 04306 edit_pointlarray( "\t", cptl, lpoints ); 04307 #endif 04308 } 04309 #endif /* ENABLE_EDITING */ 04310 }; 04311 04313 04316 class EMRPOLYLINETO16 : public METARECORD, ::EMRPOLYLINETO16 { 04317 POINT16* lpoints; 04318 public: 04324 EMRPOLYLINETO16 ( const RECTL* bounds, const POINT16* points, INT n ) 04325 { 04326 cpts = n; 04327 apts[0].x = 0; 04328 apts[0].y = 0; 04329 04330 emr.iType = EMR_POLYLINETO16; 04331 // The (cptl-1) below is to account for aptl, which isn't written out 04332 emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1); 04333 04334 lpoints = new POINT16[cpts]; 04335 04336 for (int i=0; i<n; i++) { 04337 lpoints[i].x = points[i].x; 04338 lpoints[i].y = points[i].y; 04339 } 04340 04341 rclBounds = *bounds; 04342 } 04349 EMRPOLYLINETO16 ( const RECTL* bounds, const POINT* points, INT n ) 04350 { 04351 cpts = n; 04352 apts[0].x = 0; 04353 apts[0].y = 0; 04354 04355 emr.iType = EMR_POLYLINETO16; 04356 // The (cptl-1) below is to account for aptl, which isn't written out 04357 emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1); 04358 04359 lpoints = new POINT16[cpts]; 04360 04361 for (int i=0; i<n; i++) { 04362 lpoints[i].x = points[i].x; 04363 lpoints[i].y = points[i].y; 04364 } 04365 04366 rclBounds = *bounds; 04367 } 04372 EMRPOLYLINETO16 ( DATASTREAM& ds ) 04373 { 04374 ds >> emr >> rclBounds >> cpts; 04375 04376 lpoints = new POINT16[cpts]; 04377 04378 POINT16ARRAY points( lpoints, cpts ); 04379 04380 ds >> points; 04381 } 04385 ~EMRPOLYLINETO16 ( ) 04386 { 04387 if ( lpoints ) delete[] lpoints; 04388 } 04392 bool serialize ( DATASTREAM ds ) 04393 { 04394 ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts ); 04395 return true; 04396 } 04400 int size ( void ) const { return emr.nSize; } 04406 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 04407 { 04408 // According to the wine windef.h header, POINT and POINTL are equivalent 04409 PolylineTo16( dc, lpoints, cpts ); 04410 } 04411 #ifdef ENABLE_EDITING 04412 04415 void edit ( void ) const 04416 { 04417 printf( "*POLYLINETO16*\n" ); 04418 edit_rectl( "rclBounds", rclBounds ); 04419 edit_point16array( "\t", cpts, lpoints ); 04420 } 04421 #endif /* ENABLE_EDITING */ 04422 }; 04423 04425 04430 class EMREXTTEXTOUTA : public METARECORD, ::EMREXTTEXTOUTA { 04431 PSTR string_a; 04432 int string_size; 04433 04434 INT* dx_i; 04435 public: 04445 EMREXTTEXTOUTA ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale, 04446 FLOAT yScale, const PEMRTEXT text, LPCSTR string, 04447 const INT* dx ) 04448 { 04449 emr.iType = EMR_EXTTEXTOUTA; 04450 emr.nSize = sizeof( ::EMREXTTEXTOUTA ); 04451 04452 rclBounds = *bounds; 04453 04454 iGraphicsMode = graphicsMode; 04455 exScale = xScale; 04456 eyScale = yScale; 04457 04458 emrtext = *text; 04459 04460 string_size = ROUND_TO_LONG( emrtext.nChars ); 04461 04462 string_a = new CHAR[ string_size ]; 04463 04464 memset( string_a, 0, sizeof(CHAR) * string_size ); 04465 04466 for ( unsigned int i=0; i<emrtext.nChars; i++ ) 04467 string_a[i] = *string++; 04468 04469 emrtext.offString = emr.nSize; 04470 emr.nSize += string_size * sizeof(CHAR); 04471 #if 0 04472 /* 04473 Test only - Problem: Windows requires this dx to be set - at least from 2K on 04474 but to calculate real dx values is hard 04475 For pstoedit - this is "fixed" now by estimating dx in pstoedit 04476 */ 04477 if ( !dx ) { 04478 int * dxn = new int [string_size]; 04479 for (unsigned int i=0; i < string_size; i++) dxn[i] = 10; 04480 dx = dxn; 04481 } 04482 #endif 04483 04484 if ( dx ) { 04485 04486 dx_i = new INT[ emrtext.nChars ]; 04487 04488 for ( unsigned int i=0; i<emrtext.nChars; i++ ) 04489 dx_i[i] = *dx++; 04490 04491 emrtext.offDx = emr.nSize; 04492 emr.nSize += emrtext.nChars * sizeof(INT); 04493 } 04494 else { 04495 emrtext.offDx = 0; 04496 dx_i = 0; 04497 } 04498 } 04503 EMREXTTEXTOUTA ( DATASTREAM& ds ) 04504 { 04505 ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext; 04506 04507 if ( emrtext.offString != 0 ) { 04508 string_size = ROUND_TO_LONG( emrtext.nChars ); 04509 04510 string_a = new CHAR[ string_size ]; 04511 04512 memset( string_a, 0, sizeof(CHAR) * string_size ); 04513 04514 CHARSTR string( string_a, string_size ); 04515 04516 ds >> string; 04517 } 04518 else 04519 string_a = 0; 04520 04521 if ( emrtext.offDx ) { 04522 dx_i = new INT[ emrtext.nChars ]; 04523 04524 INTARRAY dx_is( dx_i, emrtext.nChars ); 04525 04526 ds >> dx_is; 04527 } 04528 else 04529 dx_i = 0; 04530 } 04535 ~EMREXTTEXTOUTA ( ) 04536 { 04537 if ( string_a ) delete[] string_a; 04538 if ( dx_i ) delete[] dx_i; 04539 } 04543 bool serialize ( DATASTREAM ds ) 04544 { 04545 ds << emr << rclBounds << iGraphicsMode << exScale << eyScale 04546 << emrtext << CHARSTR( string_a, string_size ); 04547 if ( dx_i ) 04548 ds << INTARRAY( dx_i, emrtext.nChars ); 04549 return true; 04550 } 04554 int size ( void ) const { return emr.nSize; } 04560 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 04561 { 04562 RECT rect; 04563 rect.left = emrtext.rcl.left; 04564 rect.top = emrtext.rcl.top; 04565 rect.right = emrtext.rcl.right; 04566 rect.bottom = emrtext.rcl.bottom; 04567 04568 ExtTextOutA( dc, emrtext.ptlReference.x, emrtext.ptlReference.y, 04569 emrtext.fOptions, &rect, string_a, emrtext.nChars, 04570 dx_i ); 04571 } 04572 #ifdef ENABLE_EDITING 04573 04576 void edit ( void ) const 04577 { 04578 #if defined(__LP64__) 04579 const char* FMT0 = "unknown(%d)\n"; 04580 const char* FMT1 = "\tptlReference\t: (%d,%d)\n"; 04581 const char* FMT2 = "\tnChars\t\t: %d\n"; 04582 const char* FMT3 = "\toffString\t: %d\n"; 04583 const char* FMT4 = "\toffDx\t\t: %d\n"; 04584 #else 04585 const char* FMT0 = "unknown(%ld)\n"; 04586 const char* FMT1 = "\tptlReference\t: (%ld,%ld)\n"; 04587 const char* FMT2 = "\tnChars\t\t: %ld\n"; 04588 const char* FMT3 = "\toffString\t: %ld\n"; 04589 const char* FMT4 = "\toffDx\t\t: %ld\n"; 04590 #endif /* __x86_64__ */ 04591 printf( "*EXTTEXTOUTA*\n" ); 04592 edit_rectl( "rclBounds", rclBounds ); 04593 printf( "\tiGraphicsMode\t: " ); 04594 switch ( iGraphicsMode ) { 04595 case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break; 04596 case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break; 04597 default: printf( FMT0, iGraphicsMode ); 04598 } 04599 printf( "\texScale\t\t: %f\n", exScale ); 04600 printf( "\teyScale\t\t: %f\n", eyScale ); 04601 printf( FMT1, emrtext.ptlReference.x, emrtext.ptlReference.y ); 04602 printf( FMT2, emrtext.nChars ); 04603 printf( FMT3, emrtext.offString ); 04604 printf( "\tfOptions\t: " ); 04605 if ( emrtext.fOptions == 0 ) 04606 printf( "None" ); 04607 else { 04608 if ( emrtext.fOptions & ETO_GRAYED ) { 04609 printf( "ETO_GRAYED" ); 04610 if ( emrtext.fOptions & ~ETO_GRAYED ) 04611 printf( " | " ); 04612 } 04613 if ( emrtext.fOptions & ETO_OPAQUE ) { 04614 printf( "ETO_OPAQUE" ); 04615 if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) ) 04616 printf( " | " ); 04617 } 04618 if ( emrtext.fOptions & ETO_CLIPPED ) { 04619 printf( "ETO_CLIPPED" ); 04620 if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) ) 04621 printf( " | " ); 04622 } 04623 if ( emrtext.fOptions & ETO_GLYPH_INDEX ) { 04624 printf( "ETO_GLYPH_INDEX" ); 04625 if ( emrtext.fOptions & 04626 ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) ) 04627 printf( " | " ); 04628 } 04629 if ( emrtext.fOptions & ETO_RTLREADING ) { 04630 printf( "ETO_RTLREADING" ); 04631 if ( emrtext.fOptions & 04632 ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX | 04633 ETO_RTLREADING) ) 04634 printf( " | " ); 04635 } 04636 if ( emrtext.fOptions & ETO_IGNORELANGUAGE ) 04637 printf( "ETO_IGNORELANGUAGE" ); 04638 } 04639 printf( "\n" ); 04640 edit_rectl( "rcl\t", emrtext.rcl ); 04641 printf( FMT4, emrtext.offDx ); 04642 printf( "\tString:\n\t\t%s\n", string_a ); 04643 04644 if ( emrtext.offDx != 0 ) { 04645 printf( "\tOffsets:\n\t\t" ); 04646 for ( unsigned int i = 0; i < emrtext.nChars; i++ ) 04647 printf( "%d ", dx_i[i] ); 04648 printf( "\n" ); 04649 } 04650 } 04651 #endif /* ENABLE_EDITING */ 04652 }; 04653 04655 04658 class EMRSETPIXELV : public METARECORD, ::EMRSETPIXELV { 04659 public: 04665 EMRSETPIXELV ( INT x, INT y, COLORREF color ) 04666 { 04667 emr.iType = EMR_SETPIXELV; 04668 emr.nSize = sizeof( ::EMRSETPIXELV ); 04669 ptlPixel.x = x; 04670 ptlPixel.y = y; 04671 crColor = color; 04672 } 04677 EMRSETPIXELV ( DATASTREAM& ds ) 04678 { 04679 ds >> emr >> ptlPixel >> crColor; 04680 } 04684 bool serialize ( DATASTREAM ds ) 04685 { 04686 ds << emr << ptlPixel << crColor; 04687 return true; 04688 } 04692 int size ( void ) const { return emr.nSize; } 04698 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 04699 { 04700 SetPixel( dc, ptlPixel.x, ptlPixel.y, crColor ); 04701 } 04702 #ifdef ENABLE_EDITING 04703 04706 void edit ( void ) const 04707 { 04708 printf( "*SETPIXELV*\n" ); 04709 edit_pointl( "ptlPixel", ptlPixel ); 04710 edit_color( "crColor\t", crColor ); 04711 } 04712 #endif /* ENABLE_EDITING */ 04713 }; 04714 04715 class PEN; 04716 class EXTPEN; 04717 class BRUSH; 04718 class FONT; 04719 class PALETTE; 04720 04722 04725 class EMRCREATEPEN : public METARECORD, public ::EMRCREATEPEN 04726 { 04727 public: 04732 EMRCREATEPEN ( PEN* pen, HGDIOBJ handle ); 04737 EMRCREATEPEN ( DATASTREAM& ds ); 04741 bool serialize ( DATASTREAM ds ) 04742 { 04743 ds << emr << ihPen << lopn; 04744 return true; 04745 } 04749 int size ( void ) const { return emr.nSize; } 04755 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const; 04756 #ifdef ENABLE_EDITING 04757 04760 void edit ( void ) const 04761 { 04762 #if defined(__LP64__) 04763 const char* FMT0 = "\tihPen\t\t: 0x%x\n"; 04764 const char* FMT1 = "\tlopn.lopnWidth\t: %d, %d\n"; 04765 #else 04766 const char* FMT0 = "\tihPen\t\t: 0x%lx\n"; 04767 const char* FMT1 = "\tlopn.lopnWidth\t: %ld, %ld\n"; 04768 #endif /* __x86_64__ */ 04769 printf( "*CREATEPEN*\n" ); 04770 printf( FMT0, ihPen ); 04771 edit_pen_style( "lopn.lopnStyle", lopn.lopnStyle ); 04772 printf( FMT1, lopn.lopnWidth.x, lopn.lopnWidth.y ); 04773 edit_color( "lopn.lopnColor", lopn.lopnColor ); 04774 } 04775 #endif /* ENABLE_EDITING */ 04776 }; 04777 04779 04783 class EMREXTCREATEPEN : public METARECORD, public ::EMREXTCREATEPEN 04784 { 04785 public: 04790 EMREXTCREATEPEN ( EXTPEN* pen, HGDIOBJ handle ); 04795 EMREXTCREATEPEN ( DATASTREAM& ds ); 04799 bool serialize ( DATASTREAM ds ) 04800 { 04801 ds << emr << ihPen << offBmi << cbBmi << offBits << cbBits << elp; 04802 return true; 04803 } 04807 int size ( void ) const { return emr.nSize; } 04813 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const; 04814 #ifdef ENABLE_EDITING 04815 04818 void edit ( void ) const 04819 { 04820 #if defined(__LP64__) 04821 const char* FMT0 = "\tihPen\t\t\t: 0x%x\n"; 04822 const char* FMT1 = "\toffBmi\t\t\t: %d\n"; 04823 const char* FMT2 = "\tcbBmi\t\t\t: %d\n"; 04824 const char* FMT3 = "\toffBits\t\t\t: %d\n"; 04825 const char* FMT4 = "\tcbBits\t\t\t: %d\n"; 04826 const char* FMT5 = "\telp.elpWidth\t\t: %d\n"; 04827 const char* FMT6 = "\telp.elpNumEntries\t: %d\n"; 04828 #else 04829 const char* FMT0 = "\tihPen\t\t\t: 0x%lx\n"; 04830 const char* FMT1 = "\toffBmi\t\t\t: %ld\n"; 04831 const char* FMT2 = "\tcbBmi\t\t\t: %ld\n"; 04832 const char* FMT3 = "\toffBits\t\t\t: %ld\n"; 04833 const char* FMT4 = "\tcbBits\t\t\t: %ld\n"; 04834 const char* FMT5 = "\telp.elpWidth\t\t: %ld\n"; 04835 const char* FMT6 = "\telp.elpNumEntries\t: %ld\n"; 04836 #endif /* __x86_64__ */ 04837 printf( "*EXTCREATEPEN*\n" ); 04838 printf( FMT0, ihPen ); 04839 printf( FMT1, offBmi ); 04840 printf( FMT2, cbBmi ); 04841 printf( FMT3, offBits ); 04842 printf( FMT4, cbBits ); 04843 edit_pen_style( "elp.elpPenStyle\t", elp.elpPenStyle ); 04844 printf( FMT5, elp.elpWidth ); 04845 edit_brush_style( "elp.elpBrushStyle", elp.elpBrushStyle ); 04846 edit_color( "elp.elpColor\t", elp.elpColor ); 04847 edit_brush_hatch( "elp.elpHatch\t", elp.elpHatch ); 04848 printf( FMT6, elp.elpNumEntries ); 04849 } 04850 #endif /* ENABLE_EDITING */ 04851 }; 04852 04854 04857 class EMRCREATEBRUSHINDIRECT : public METARECORD, public ::EMRCREATEBRUSHINDIRECT 04858 { 04859 public: 04864 EMRCREATEBRUSHINDIRECT ( BRUSH* brush, HGDIOBJ handle ); 04869 EMRCREATEBRUSHINDIRECT ( DATASTREAM& ds ); 04873 bool serialize ( DATASTREAM ds ) 04874 { 04875 ds << emr << ihBrush << lb; 04876 return true; 04877 } 04881 int size ( void ) const { return emr.nSize; } 04887 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const; 04888 #ifdef ENABLE_EDITING 04889 04892 void edit ( void ) const 04893 { 04894 #if defined(__LP64__) 04895 const char* FMT = "\tihBrush\t\t: 0x%x\n"; 04896 #else 04897 const char* FMT = "\tihBrush\t\t: 0x%lx\n"; 04898 #endif /* __x86_64__ */ 04899 printf( "*CREATEBRUSHINDIRECT*\n" ); 04900 printf( FMT, ihBrush ); 04901 edit_brush_style( "lb.lbStyle", lb.lbStyle ); 04902 edit_color( "lb.lbColor", lb.lbColor ); 04903 edit_brush_hatch( "lb.lbHatch", lb.lbHatch ); 04904 } 04905 #endif /* ENABLE_EDITING */ 04906 }; 04907 04909 04912 class EMREXTCREATEFONTINDIRECTW : public METARECORD, public ::EMREXTCREATEFONTINDIRECTW 04913 { 04914 public: 04919 EMREXTCREATEFONTINDIRECTW ( FONT* font, HGDIOBJ handle ); 04924 EMREXTCREATEFONTINDIRECTW ( DATASTREAM& ds ); 04928 bool serialize ( DATASTREAM ds ) 04929 { 04930 // Since EMF records have to be multiples of 4 bytes, this 04931 // should perhaps be a general thing, but we know it's currently 04932 // only a problem for this structure. 04933 04934 ds << emr << ihFont << elfw << PADDING( 2 ); 04935 04936 return true; 04937 } 04941 int size ( void ) const { return emr.nSize; } 04947 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const; 04948 #ifdef ENABLE_EDITING 04949 04952 void edit ( void ) const 04953 { 04954 #if defined(__LP64__) 04955 const char* FMT0 = "\tihFont\t\t\t: %d\n"; 04956 const char* FMT1 = "\tlfHeight\t\t: %d\n"; 04957 const char* FMT2 = "\tlfWidth\t\t\t: %d\n"; 04958 const char* FMT3 = "\tlfEscapement\t\t: %d\n"; 04959 const char* FMT4 = "\tlfOrientation\t\t: %d\n"; 04960 const char* FMT5 = "\telfVersion\t\t: %d\n"; 04961 const char* FMT6 = "\telfStyleSize\t\t: %d\n"; 04962 const char* FMT7 = "\telfMatch\t\t: %d\n"; 04963 const char* FMT8 = "\telfCulture\t\t: %d\n"; 04964 #else 04965 const char* FMT0 = "\tihFont\t\t\t: %ld\n"; 04966 const char* FMT1 = "\tlfHeight\t\t: %ld\n"; 04967 const char* FMT2 = "\tlfWidth\t\t\t: %ld\n"; 04968 const char* FMT3 = "\tlfEscapement\t\t: %ld\n"; 04969 const char* FMT4 = "\tlfOrientation\t\t: %ld\n"; 04970 const char* FMT5 = "\telfVersion\t\t: %ld\n"; 04971 const char* FMT6 = "\telfStyleSize\t\t: %ld\n"; 04972 const char* FMT7 = "\telfMatch\t\t: %ld\n"; 04973 const char* FMT8 = "\telfCulture\t\t: %ld\n"; 04974 #endif /* __x86_64__ */ 04975 printf( "*EXTCREATEFONTINDIRECTW*\n" ); 04976 printf( FMT0, ihFont ); 04977 printf( FMT1, elfw.elfLogFont.lfHeight ); 04978 printf( FMT2, elfw.elfLogFont.lfWidth ); 04979 printf( FMT3, elfw.elfLogFont.lfEscapement ); 04980 printf( FMT4, elfw.elfLogFont.lfOrientation ); 04981 printf( "\tlfWeight\t\t: " ); 04982 switch ( elfw.elfLogFont.lfWeight ) { 04983 case FW_DONTCARE: printf( "FW_DONTCARE\n" ); break; 04984 case FW_THIN: printf( "FW_THIN\n" ); break; 04985 case FW_EXTRALIGHT: printf( "FW_EXTRALIGHT\n" ); break; 04986 case FW_LIGHT: printf( "FW_LIGHT\n" ); break; 04987 case FW_NORMAL: printf( "FW_NORMAL\n" ); break; 04988 case FW_MEDIUM: printf( "FW_MEDIUM\n" ); break; 04989 case FW_SEMIBOLD: printf( "FW_SEMIBOLD\n" ); break; 04990 case FW_BOLD: printf( "FW_BOLD\n" ); break; 04991 case FW_EXTRABOLD: printf( "FW_EXTRABOLD\n" ); break; 04992 case FW_BLACK: printf( "FW_BLACK\n" ); break; 04993 } 04994 printf( "\tlfItalic\t\t: %d\n", elfw.elfLogFont.lfItalic ); 04995 printf( "\tlfUnderline\t\t: %d\n", elfw.elfLogFont.lfUnderline ); 04996 printf( "\tlfStrikeOut\t\t: %d\n", elfw.elfLogFont.lfStrikeOut ); 04997 printf( "\tlfCharSet\t\t: %d\n", elfw.elfLogFont.lfCharSet ); 04998 printf( "\tlfOutPrecision\t\t: %d\n", elfw.elfLogFont.lfOutPrecision ); 04999 printf( "\tlfClipPrecision\t\t: %d\n", elfw.elfLogFont.lfClipPrecision ); 05000 printf( "\tlfQuality\t\t: %d\n", elfw.elfLogFont.lfQuality ); 05001 printf( "\tlfPitchAndFamily\t: %d\n", elfw.elfLogFont.lfPitchAndFamily ); 05002 int i = 0; 05003 printf( "\tlfFaceName\t\t: '" ); 05004 while ( elfw.elfLogFont.lfFaceName[i] != 0 && i < LF_FACESIZE ) { 05005 putchar( elfw.elfLogFont.lfFaceName[i] ); 05006 i++; 05007 } 05008 puts( "'" ); 05009 05010 i = 0; 05011 printf( "\telfFullName\t\t: '" ); 05012 while ( elfw.elfFullName[i] != 0 && i < LF_FULLFACESIZE ) { 05013 putchar( elfw.elfFullName[i] ); 05014 i++; 05015 } 05016 puts( "'" ); 05017 05018 i = 0; 05019 printf( "\telfStyle\t\t: '" ); 05020 while ( elfw.elfStyle[i] != 0 && i < LF_FACESIZE ) { 05021 putchar( elfw.elfStyle[i] ); 05022 i++; 05023 } 05024 puts( "'" ); 05025 05026 printf( FMT5, elfw.elfVersion ); 05027 printf( FMT6, elfw.elfStyleSize ); 05028 printf( FMT7, elfw.elfMatch ); 05029 printf( "\telfVendorId\t\t: '%s'\n", elfw.elfVendorId ); 05030 printf( FMT8, elfw.elfCulture ); 05031 printf( "\telfPanose\t\t:\n" ); 05032 printf( "\t\tbFamilyType\t\t: %d\n", elfw.elfPanose.bFamilyType ); 05033 printf( "\t\tbSerifStyle\t\t: %d\n", elfw.elfPanose.bSerifStyle ); 05034 printf( "\t\tbWeight\t\t\t: %d\n", elfw.elfPanose.bWeight ); 05035 printf( "\t\tbProportion\t\t: %d\n", elfw.elfPanose.bProportion ); 05036 printf( "\t\tbContrast\t\t: %d\n", elfw.elfPanose.bContrast ); 05037 printf( "\t\tbStrokeVariation\t: %d\n", elfw.elfPanose.bStrokeVariation ); 05038 printf( "\t\tbArmStyle\t\t: %d\n", elfw.elfPanose.bArmStyle ); 05039 printf( "\t\tbLetterform\t\t: %d\n", elfw.elfPanose.bLetterform ); 05040 printf( "\t\tbMidline\t\t: %d\n", elfw.elfPanose.bMidline ); 05041 printf( "\t\tbXHeight\t\t: %d\n", elfw.elfPanose.bXHeight ); 05042 } 05043 #endif /* ENABLE_EDITING */ 05044 }; 05045 05047 05050 class EMRCREATEPALETTE : public METARECORD, public ::EMRCREATEPALETTE 05051 { 05052 public: 05057 EMRCREATEPALETTE ( PALETTE* palette, HGDIOBJ handle ); 05062 EMRCREATEPALETTE ( DATASTREAM& ds ); 05066 bool serialize ( DATASTREAM ds ) 05067 { 05068 ds << emr << ihPal << lgpl; 05069 return true; 05070 } 05074 int size ( void ) const { return emr.nSize; } 05080 void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const; 05081 #ifdef ENABLE_EDITING 05082 05085 void edit ( void ) const 05086 { 05087 printf( "*CREATEPALETTE* (not really handled by libEMF)\n" ); 05088 } 05089 #endif /* ENABLE_EDITING */ 05090 }; 05091 05093 05096 class EMRFILLPATH : public METARECORD, ::EMRFILLPATH { 05097 public: 05102 EMRFILLPATH ( const RECTL* bounds ) 05103 { 05104 emr.iType = EMR_FILLPATH; 05105 emr.nSize = sizeof( ::EMRFILLPATH ); 05106 rclBounds = *bounds; 05107 } 05112 EMRFILLPATH ( DATASTREAM& ds ) 05113 { 05114 ds >> emr >> rclBounds; 05115 } 05119 bool serialize ( DATASTREAM ds ) 05120 { 05121 ds << emr << rclBounds; 05122 return true; 05123 } 05127 int size ( void ) const { return emr.nSize; } 05133 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05134 { 05135 FillPath( dc ); 05136 } 05137 #ifdef ENABLE_EDITING 05138 05141 void edit ( void ) const 05142 { 05143 printf( "*FILLPATH*\n" ); 05144 edit_rectl( "rclBounds", rclBounds ); 05145 } 05146 #endif /* ENABLE_EDITING */ 05147 }; 05149 05152 class EMRSTROKEPATH : public METARECORD, ::EMRSTROKEPATH { 05153 public: 05158 EMRSTROKEPATH ( const RECTL* bounds ) 05159 { 05160 emr.iType = EMR_STROKEPATH; 05161 emr.nSize = sizeof( ::EMRSTROKEPATH ); 05162 rclBounds = *bounds; 05163 } 05168 EMRSTROKEPATH ( DATASTREAM& ds ) 05169 { 05170 ds >> emr >> rclBounds; 05171 } 05175 bool serialize ( DATASTREAM ds ) 05176 { 05177 ds << emr << rclBounds; 05178 return true; 05179 } 05183 int size ( void ) const { return emr.nSize; } 05189 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05190 { 05191 StrokePath( dc ); 05192 } 05193 #ifdef ENABLE_EDITING 05194 05197 void edit ( void ) const 05198 { 05199 printf( "*STROKEPATH*\n" ); 05200 edit_rectl( "rclBounds", rclBounds ); 05201 } 05202 #endif /* ENABLE_EDITING */ 05203 }; 05205 05208 class EMRSTROKEANDFILLPATH : public METARECORD, ::EMRSTROKEANDFILLPATH { 05209 public: 05214 EMRSTROKEANDFILLPATH ( const RECTL* bounds ) 05215 { 05216 emr.iType = EMR_STROKEANDFILLPATH; 05217 emr.nSize = sizeof( ::EMRSTROKEANDFILLPATH ); 05218 rclBounds = *bounds; 05219 } 05224 EMRSTROKEANDFILLPATH ( DATASTREAM& ds ) 05225 { 05226 ds >> emr >> rclBounds; 05227 } 05231 bool serialize ( DATASTREAM ds ) 05232 { 05233 ds << emr << rclBounds; 05234 return true; 05235 } 05239 int size ( void ) const { return emr.nSize; } 05245 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05246 { 05247 StrokeAndFillPath( dc ); 05248 } 05249 #ifdef ENABLE_EDITING 05250 05253 void edit ( void ) const 05254 { 05255 printf( "*STROKEANDFILLPATH*\n" ); 05256 edit_rectl( "rclBounds", rclBounds ); 05257 } 05258 #endif /* ENABLE_EDITING */ 05259 }; 05261 05264 class EMRBEGINPATH : public METARECORD, ::EMRBEGINPATH { 05265 public: 05269 EMRBEGINPATH ( void ) 05270 { 05271 emr.iType = EMR_BEGINPATH; 05272 emr.nSize = sizeof( ::EMRBEGINPATH ); 05273 } 05278 EMRBEGINPATH ( DATASTREAM& ds ) 05279 { 05280 ds >> emr; 05281 } 05285 bool serialize ( DATASTREAM ds ) 05286 { 05287 ds << emr; 05288 return true; 05289 } 05293 int size ( void ) const { return emr.nSize; } 05299 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05300 { 05301 BeginPath( dc ); 05302 } 05303 #ifdef ENABLE_EDITING 05304 05307 void edit ( void ) const 05308 { 05309 printf( "*BEGINPATH*\n" ); 05310 } 05311 #endif /* ENABLE_EDITING */ 05312 }; 05314 05317 class EMRENDPATH : public METARECORD, ::EMRENDPATH { 05318 public: 05322 EMRENDPATH ( void ) 05323 { 05324 emr.iType = EMR_ENDPATH; 05325 emr.nSize = sizeof( ::EMRENDPATH ); 05326 } 05331 EMRENDPATH ( DATASTREAM& ds ) 05332 { 05333 ds >> emr; 05334 } 05338 bool serialize ( DATASTREAM ds ) 05339 { 05340 ds << emr; 05341 return true; 05342 } 05346 int size ( void ) const { return emr.nSize; } 05352 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05353 { 05354 EndPath( dc ); 05355 } 05356 #ifdef ENABLE_EDITING 05357 05360 void edit ( void ) const 05361 { 05362 printf( "*ENDPATH*\n" ); 05363 } 05364 #endif /* ENABLE_EDITING */ 05365 }; 05367 05370 class EMRCLOSEFIGURE : public METARECORD, ::EMRCLOSEFIGURE { 05371 public: 05375 EMRCLOSEFIGURE ( void ) 05376 { 05377 emr.iType = EMR_CLOSEFIGURE; 05378 emr.nSize = sizeof( ::EMRCLOSEFIGURE ); 05379 } 05384 EMRCLOSEFIGURE ( DATASTREAM& ds ) 05385 { 05386 ds >> emr; 05387 } 05391 bool serialize ( DATASTREAM ds ) 05392 { 05393 ds << emr; 05394 return true; 05395 } 05399 int size ( void ) const { return emr.nSize; } 05405 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05406 { 05407 CloseFigure( dc ); 05408 } 05409 #ifdef ENABLE_EDITING 05410 05413 void edit ( void ) const 05414 { 05415 printf( "*CLOSEFIGURE*\n" ); 05416 } 05417 #endif /* ENABLE_EDITING */ 05418 }; 05420 05424 class EMRSAVEDC : public METARECORD, ::EMRSAVEDC { 05425 public: 05429 EMRSAVEDC ( void ) 05430 { 05431 emr.iType = EMR_SAVEDC; 05432 emr.nSize = sizeof( ::EMRSAVEDC ); 05433 } 05438 EMRSAVEDC ( DATASTREAM& ds ) 05439 { 05440 ds >> emr; 05441 } 05445 bool serialize ( DATASTREAM ds ) 05446 { 05447 ds << emr; 05448 return true; 05449 } 05453 int size ( void ) const { return emr.nSize; } 05459 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05460 { 05461 SaveDC( dc ); 05462 } 05463 #ifdef ENABLE_EDITING 05464 05467 void edit ( void ) const 05468 { 05469 printf( "*SAVEDC*\n" ); 05470 } 05471 #endif /* ENABLE_EDITING */ 05472 }; 05474 05477 class EMRRESTOREDC : public METARECORD, ::EMRRESTOREDC { 05478 public: 05482 EMRRESTOREDC ( INT n ) 05483 { 05484 emr.iType = EMR_RESTOREDC; 05485 emr.nSize = sizeof( ::EMRRESTOREDC ); 05486 iRelative = n; 05487 } 05492 EMRRESTOREDC ( DATASTREAM& ds ) 05493 { 05494 ds >> emr >> iRelative; 05495 } 05499 bool serialize ( DATASTREAM ds ) 05500 { 05501 ds << emr << iRelative; 05502 return true; 05503 } 05507 int size ( void ) const { return emr.nSize; } 05513 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05514 { 05515 RestoreDC( dc, iRelative ); 05516 } 05517 #ifdef ENABLE_EDITING 05518 05521 void edit ( void ) const 05522 { 05523 #if defined(__LP64__) 05524 const char* FMT = "\tiRelative: %d\n"; 05525 #else 05526 const char* FMT = "\tiRelative: %ld\n"; 05527 #endif /* __x86_64__ */ 05528 printf( "*RESTOREDC*\n" ); 05529 printf( FMT, iRelative ); 05530 } 05531 #endif /* ENABLE_EDITING */ 05532 }; 05534 05537 class EMRSETMETARGN : public METARECORD, ::EMRSETMETARGN { 05538 public: 05542 EMRSETMETARGN ( void ) 05543 { 05544 emr.iType = EMR_SETMETARGN; 05545 emr.nSize = sizeof( ::EMRSETMETARGN ); 05546 } 05551 EMRSETMETARGN ( DATASTREAM& ds ) 05552 { 05553 ds >> emr; 05554 } 05558 bool serialize ( DATASTREAM ds ) 05559 { 05560 ds << emr; 05561 return true; 05562 } 05566 int size ( void ) const { return emr.nSize; } 05572 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05573 { 05574 SetMetaRgn( dc ); 05575 } 05576 #ifdef ENABLE_EDITING 05577 05580 void edit ( void ) const 05581 { 05582 printf( "*SETMETARGN*\n" ); 05583 } 05584 #endif /* ENABLE_EDITING */ 05585 }; 05586 05588 05591 class PEN : public GRAPHICSOBJECT, public LOGPEN { 05592 public: 05596 PEN ( const LOGPEN* lpen ) 05597 { 05598 lopnStyle = lpen->lopnStyle; 05599 lopnWidth = lpen->lopnWidth; 05600 lopnColor = lpen->lopnColor; 05601 } 05605 OBJECTTYPE getType ( void ) const { return O_PEN; } 05612 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle ) 05613 { 05614 contexts[dc] = emf_handle; 05615 return new EMRCREATEPEN( this, emf_handle ); 05616 } 05617 }; 05618 05620 05623 class EXTPEN : public GRAPHICSOBJECT, public EXTLOGPEN { 05624 public: 05628 EXTPEN ( const EXTLOGPEN* lpen ) 05629 { 05630 elpPenStyle = lpen->elpPenStyle; 05631 elpWidth = lpen->elpWidth; 05632 elpBrushStyle = lpen->elpBrushStyle; 05633 elpColor = lpen->elpColor; 05634 elpHatch = lpen->elpHatch; 05635 elpNumEntries = 0; 05636 elpStyleEntry[0] = 0; 05637 } 05641 OBJECTTYPE getType ( void ) const { return O_EXTPEN; } 05648 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle ) 05649 { 05650 contexts[dc] = emf_handle; 05651 return new EMREXTCREATEPEN( this, emf_handle ); 05652 } 05653 }; 05654 05656 05659 class BRUSH : public GRAPHICSOBJECT, public LOGBRUSH { 05660 public: 05664 BRUSH ( const LOGBRUSH* lbrush ) 05665 { 05666 lbStyle = lbrush->lbStyle; 05667 lbColor = lbrush->lbColor; 05668 lbHatch = lbrush->lbHatch; 05669 } 05673 OBJECTTYPE getType ( void ) const { return O_BRUSH; } 05680 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle ) 05681 { 05682 contexts[dc] = emf_handle; 05683 return new EMRCREATEBRUSHINDIRECT( this, emf_handle ); 05684 } 05685 }; 05686 05688 05691 class FONT : public GRAPHICSOBJECT, public EXTLOGFONTW { 05692 public: 05696 FONT ( const LOGFONTW* lfont ) 05697 { 05698 this->elfLogFont = *lfont; 05699 // There are a lot more entries in the EXTLOGFONTW structure than 05700 // the API has values for, so we invent them here 05701 memset( &elfFullName, 0, sizeof elfFullName ); 05702 memset( &elfStyle, 0, sizeof elfStyle ); 05703 elfVersion = ELF_VERSION; 05704 elfStyleSize = 0; 05705 elfMatch = 0; 05706 elfReserved = 0; 05707 memset( &elfVendorId, 0, sizeof elfVendorId ); 05708 elfCulture = ELF_CULTURE_LATIN; 05709 memset( &elfPanose, 1, sizeof(PANOSE) ); 05710 } 05714 OBJECTTYPE getType ( void ) const { return O_FONT; } 05721 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle ) 05722 { 05723 contexts[dc] = emf_handle; 05724 return new EMREXTCREATEFONTINDIRECTW( this, emf_handle ); 05725 } 05726 }; 05727 05729 05732 class PALETTE : public GRAPHICSOBJECT, public LOGPALETTE { 05733 public: 05737 PALETTE ( const LOGPALETTE* lpalette ) 05738 { 05739 (void)lpalette; 05740 palVersion = 0; 05741 palNumEntries = 0; 05742 PALETTEENTRY zero_entry = { 0, 0, 0, 0 }; 05743 palPalEntry[0] = zero_entry; 05744 } 05748 OBJECTTYPE getType ( void ) const { return O_PALETTE; } 05755 METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle ) 05756 { 05757 contexts[dc] = emf_handle; 05758 return new EMRCREATEPALETTE( this, emf_handle ); 05759 } 05760 }; 05761 05763 05766 class EMRSETMITERLIMIT : public METARECORD, ::EMRSETMITERLIMIT { 05767 public: 05771 EMRSETMITERLIMIT ( FLOAT limit ) 05772 { 05773 emr.iType = EMR_SETMITERLIMIT; 05774 emr.nSize = sizeof( ::EMRSETMITERLIMIT ); 05775 eMiterLimit = limit; 05776 } 05781 EMRSETMITERLIMIT ( DATASTREAM& ds ) 05782 { 05783 int miter_limit; 05784 ds >> emr >> miter_limit; 05785 eMiterLimit = float(miter_limit); 05786 } 05790 bool serialize ( DATASTREAM ds ) 05791 { 05792 ds << emr << (int)eMiterLimit; 05793 return true; 05794 } 05798 int size ( void ) const { return emr.nSize; } 05804 void execute ( METAFILEDEVICECONTEXT* /*source*/, HDC dc ) const 05805 { 05806 SetMiterLimit( dc, eMiterLimit, 0 ); 05807 } 05808 #ifdef ENABLE_EDITING 05809 05812 void edit ( void ) const 05813 { 05814 printf( "*SETMITERLIMIT*\n" ); 05815 printf( "\teMiterLimit\t: %f\n", eMiterLimit ); 05816 } 05817 #endif /* ENABLE_EDITING */ 05818 }; 05819 05821 05827 class METAFILEDEVICECONTEXT : public OBJECT { 05835 void init ( const RECT* size, LPCWSTR description_w ) { 05836 05837 // Evidently, metafile handles are numbered from 1, so don't 05838 // ever use 0. 05839 05840 handles.push_back( true ); 05841 05842 // Keep some of our graphics state in a header record 05843 05844 header = new ENHMETAHEADER ( description_w ); 05845 records.push_back( header ); 05846 05847 // Compute the size and position of the metafile on the "page" 05848 05849 if ( size ) { 05850 update_frame = false; 05851 05852 header->rclFrame.left = size->left; 05853 header->rclFrame.top = size->top; 05854 header->rclFrame.right = size->right; 05855 header->rclFrame.bottom = size->bottom; 05856 05857 header->rclBounds.left = 05858 size->left * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 ); 05859 header->rclBounds.top = 05860 size->top * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 ); 05861 header->rclBounds.right = 05862 size->right * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 ); 05863 header->rclBounds.bottom = 05864 size->bottom * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 ); 05865 } 05866 else { 05867 update_frame = true; 05868 05869 header->rclBounds.left = -10; 05870 header->rclBounds.top = -10; 05871 header->rclBounds.right = 10; 05872 header->rclBounds.bottom = 10; 05873 05874 header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left * 05875 header->szlMillimeters.cx * 100 / header->szlDevice.cx ); 05876 header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top * 05877 header->szlMillimeters.cy * 100 / header->szlDevice.cy ); 05878 header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right * 05879 header->szlMillimeters.cx * 100 / header->szlDevice.cx ); 05880 header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom * 05881 header->szlMillimeters.cy * 100 / header->szlDevice.cy ); 05882 } 05883 05884 // Some default graphics state (are they really, though?) 05885 05886 SIZEL default_resolution = { RESOLUTION, RESOLUTION }; 05887 resolution = default_resolution; 05888 SIZEL default_viewport_ext = { 1, 1 }; 05889 viewport_ext = default_viewport_ext; 05890 POINT default_viewport_org = { 0, 0 }; 05891 viewport_org = default_viewport_org; 05892 SIZEL default_window_ext = { 1, 1 }; 05893 window_ext = default_window_ext; 05894 POINT default_window_org = { 0, 0 }; 05895 window_org = default_window_org; 05896 05897 min_device_point = viewport_org; 05898 max_device_point = viewport_org; 05899 05900 pen = (PEN*)globalObjects.find( BLACK_PEN | ENHMETA_STOCK_OBJECT ); 05901 brush = (BRUSH*)globalObjects.find( BLACK_BRUSH | ENHMETA_STOCK_OBJECT ); 05902 font = (FONT*)globalObjects.find( DEVICE_DEFAULT_FONT | ENHMETA_STOCK_OBJECT); 05903 palette = (PALETTE*)globalObjects.find( DEFAULT_PALETTE|ENHMETA_STOCK_OBJECT); 05904 05905 text_alignment = TA_BASELINE; 05906 text_color = RGB(0,0,0); 05907 bk_color = RGB(0xff,0xff,0xff); 05908 bk_mode = OPAQUE; 05909 polyfill_mode = ALTERNATE; 05910 map_mode = MM_TEXT; 05911 miter_limit = 10.f; 05912 05913 handle = globalObjects.add( this ); 05914 } 05915 05916 public: 05920 ::FILE* fp; 05925 DATASTREAM ds; 05929 ENHMETAHEADER* header; 05933 std::vector< EMF::METARECORD* > records; 05934 05935 // Keep a small set of graphics state information 05936 SIZEL resolution; 05937 SIZEL viewport_ext; 05938 POINT viewport_org; 05939 SIZEL window_ext; 05940 POINT window_org; 05941 bool update_frame; 05942 POINT min_device_point; 05943 POINT max_device_point; 05944 POINT point; 05945 PEN* pen; 05946 BRUSH* brush; 05947 FONT* font; 05948 PALETTE* palette; 05949 UINT text_alignment; 05950 COLORREF text_color; 05951 COLORREF bk_color; 05952 INT bk_mode; 05953 INT polyfill_mode; 05954 INT map_mode; 05955 FLOAT miter_limit; 05956 05962 std::vector< bool > handles; 05963 05969 std::map< HGDIOBJ, HGDIOBJ > emf_handles; 05970 05981 METAFILEDEVICECONTEXT ( FILE* fp_, const RECT* size, 05982 LPCWSTR description_w ) 05983 : fp(fp_), ds( fp_ ) 05984 { 05985 init( size, description_w ); 05986 } 05991 virtual ~METAFILEDEVICECONTEXT ( ) 05992 { 05993 // Purge all the metarecords (if there are any) {this include the 05994 // header record, too} 05995 if ( records.size() > 0 ) 05996 deleteMetafile(); 05997 } 06001 OBJECTTYPE getType ( void ) const { return O_METAFILEDEVICECONTEXT; } 06006 DWORD nextHandle ( void ) 06007 { 06008 for ( unsigned int i = 1; i < handles.size(); i++ ) { 06009 if ( !handles[i] ) { 06010 handles[i] = true; 06011 return i; 06012 } 06013 } 06014 handles.push_back( true ); 06015 // Well, it appears that even StockObject handles count for something. 06016 // Not sure what the right value here is, then. 06017 header->nHandles = handles.size(); 06018 return handles.size()-1; 06019 } 06023 void clearHandle ( DWORD handle ) 06024 { 06025 handles[handle] = false; 06026 } 06032 void appendRecord ( METARECORD* record ) 06033 { 06034 records.push_back( record ); 06035 06036 header->nBytes += record->size(); 06037 header->nRecords++; 06038 } 06044 void appendHandle ( METARECORD* record ) 06045 { 06046 records.push_back( record ); 06047 06048 header->nBytes += record->size(); 06049 header->nRecords++; 06050 } 06055 void deleteMetafile ( void ) 06056 { 06057 for ( std::vector<METARECORD*>::const_iterator r = records.begin(); 06058 r != records.end(); 06059 r++ ) { 06060 delete *r; 06061 } 06062 records.clear(); 06063 } 06068 void mergePoint ( const LONG& x, const LONG& y ) 06069 { 06070 POINT p; 06071 p.x = x; 06072 p.y = y; 06073 mergePoint( p ); 06074 } 06079 void mergePoint( const POINT& p ) 06080 { 06081 POINT device_point; 06082 06083 // *** Note, it's possible for the global transformation matrix to 06084 // affect this too. *** 06085 06086 device_point.x = (LONG)( (float)( p.x - window_org.x ) / window_ext.cx * 06087 viewport_ext.cx + viewport_org.x ); 06088 06089 device_point.y = (LONG)( (float)( p.y - window_org.y ) / window_ext.cy * 06090 viewport_ext.cy + viewport_org.y ); 06091 06092 // If the user didn't specify a bounding rectangle in the constructor, 06093 // compute one from this data, too. 06094 if ( device_point.x < min_device_point.x ) { 06095 min_device_point.x = device_point.x; 06096 if ( update_frame ) { 06097 header->rclBounds.left = min_device_point.x - 10; 06098 header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left * 06099 header->szlMillimeters.cx * 100 / header->szlDevice.cx ); 06100 } 06101 } 06102 else if ( device_point.x > max_device_point.x ) { 06103 max_device_point.x = device_point.x; 06104 if ( update_frame ) { 06105 header->rclBounds.right = max_device_point.x + 10; 06106 header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right * 06107 header->szlMillimeters.cx * 100 / header->szlDevice.cx ); 06108 } 06109 } 06110 06111 if ( device_point.y < min_device_point.y ) { 06112 min_device_point.y = device_point.y; 06113 if ( update_frame ) { 06114 header->rclBounds.top = min_device_point.y - 10; 06115 header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top * 06116 header->szlMillimeters.cy * 100 / header->szlDevice.cy ); 06117 } 06118 } 06119 else if ( device_point.y > max_device_point.y ) { 06120 max_device_point.y = device_point.y; 06121 if ( update_frame ) { 06122 header->rclBounds.bottom = max_device_point.y + 10; 06123 header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom * 06124 header->szlMillimeters.cy * 100 / header->szlDevice.cy ); 06125 } 06126 } 06127 } 06128 }; 06129 06130 } // close EMF namespace 06131 06132 #endif /* _LIBEMF_H */