libemf.h
/* -*- c++ -*-
* EMF: A library for generating ECMA-234 Enhanced Metafiles
* Copyright (C) 2002, 2003 lignum Computing, Inc. <dallenbarnett@users.sourceforge.net>
* $Id: libemf.h 94 2020-04-25 18:46:06Z dallenbarnett $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#ifndef _LIBEMF_H
#define _LIBEMF_H 1
#include <cmath>
#include <vector>
#include <map>
#include <functional>
#include <algorithm>
#include <stdexcept>
#include <memory>
#include <config.h>
#include <libEMF/emf.h>
#include <libEMF/wine/w16.h>
#ifdef ENABLE_EDITING
#include <iconv.h>
#include <errno.h>
#endif
#define EMF_UNUSED(x) (void)x;
namespace EMF {
#if 1
const int XMAX_PIXELS = 1024; /*(INT_MAX)*/
#else
const int XMAX_PIXELS = 1280; /*(INT_MAX)*/
#endif
#if 1
const int YMAX_PIXELS = 768; /*(INT_MAX)*/
#else
const int YMAX_PIXELS = 1024; /*(INT_MAX)*/
#endif
const int XMAX_MM = 320;
const int YMAX_MM = 240;
const int RESOLUTION = 96;
static inline DWORD ROUND_TO_LONG ( DWORD n ) { return ((n+3)/4)*4; }
static bool bigEndian ( void );
struct WCHARSTR {
WCHAR *const string_;
const int length_;
WCHARSTR ( WCHAR *const string, const int length )
: string_( string ), length_( length ) {}
};
struct CHARSTR {
CHAR *const string_;
const int length_;
CHARSTR ( CHAR *const string, const int length )
: string_( string ), length_( length ) {}
};
struct BYTEARRAY {
BYTE *const array_;
const int n_;
BYTEARRAY ( BYTE *const array, const int n )
: array_( array ), n_( n ) {}
};
struct POINTLARRAY {
POINTL *const points_;
const DWORD n_;
POINTLARRAY ( POINTL *const points, const DWORD n )
: points_( points ), n_( n ) {}
};
struct POINT16ARRAY {
POINT16 *const points_;
const DWORD n_;
POINT16ARRAY ( POINT16 *const points, const DWORD n )
: points_( points ), n_( n ) {}
};
struct INTARRAY {
INT *const ints_;
const DWORD n_;
INTARRAY ( INT *const ints, const DWORD n )
: ints_( ints ), n_( n ) {}
};
struct DWORDARRAY {
DWORD *const dwords_;
const DWORD n_;
DWORDARRAY ( DWORD *const dwords, const DWORD n )
: dwords_( dwords ), n_( n ) {}
};
struct PADDING {
static const char padding_[4];
const int size_;
PADDING ( const int size ) : size_( size ) {}
};
class DATASTREAM {
bool swap_;
::FILE* fp_;
public:
DATASTREAM ( ::FILE* fp = 0 ) : swap_( bigEndian() ), fp_( fp ) {}
void setStream ( ::FILE* fp ) { fp_ = fp; }
DATASTREAM& operator<< ( const BYTE& byte )
{
fwrite( &byte, sizeof(BYTE), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( BYTE& byte )
{
fread( &byte, sizeof(BYTE), 1, fp_ );
return *this;
}
DATASTREAM& operator<< ( const WORD& word )
{
if ( swap_ ) {
unsigned char const * p = (unsigned char const*)&word;
fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fwrite( &word, sizeof(WORD), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( WORD& word )
{
if ( swap_ ) {
unsigned char* p = (unsigned char*)&word;
fread( &p[1], sizeof(unsigned char), 1, fp_ );
fread( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fread( &word, sizeof(WORD), 1, fp_ );
return *this;
}
DATASTREAM& operator<< ( const INT16& word )
{
if ( swap_ ) {
unsigned char const * p = (unsigned char const*)&word;
fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fwrite( &word, sizeof(INT16), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( INT16& word )
{
if ( swap_ ) {
unsigned char* p = (unsigned char*)&word;
fread( &p[1], sizeof(unsigned char), 1, fp_ );
fread( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fread( &word, sizeof(INT16), 1, fp_ );
return *this;
}
DATASTREAM& operator<< ( const DWORD& dword )
{
if ( swap_ ) {
unsigned char const* p = (unsigned char const*)&dword;
fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fwrite( &dword, sizeof(DWORD), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( DWORD& dword )
{
if ( swap_ ) {
unsigned char* p = (unsigned char*)&dword;
fread( &p[3], sizeof(unsigned char), 1, fp_ );
fread( &p[2], sizeof(unsigned char), 1, fp_ );
fread( &p[1], sizeof(unsigned char), 1, fp_ );
fread( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fread( &dword, sizeof(DWORD), 1, fp_ );
return *this;
}
#if !defined( __LP64__ )
DATASTREAM& operator<< ( const LONG& long_ )
{
if ( swap_ ) {
unsigned char const* p = (unsigned char const*)&long_;
fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fwrite( &long_, sizeof(LONG), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( LONG& long_ )
{
if ( swap_ ) {
unsigned char* p = (unsigned char*)&long_;
fread( &p[3], sizeof(unsigned char), 1, fp_ );
fread( &p[2], sizeof(unsigned char), 1, fp_ );
fread( &p[1], sizeof(unsigned char), 1, fp_ );
fread( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fread( &long_, sizeof(LONG), 1, fp_ );
return *this;
}
#endif /* __x86_64__ */
DATASTREAM& operator<< ( const INT& int_ )
{
if ( swap_ ) {
unsigned char const* p = (unsigned char const*)&int_;
fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fwrite( &int_, sizeof(INT), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( INT& int_ )
{
if ( swap_ ) {
unsigned char* p = (unsigned char*)&int_;
fread( &p[3], sizeof(unsigned char), 1, fp_ );
fread( &p[2], sizeof(unsigned char), 1, fp_ );
fread( &p[1], sizeof(unsigned char), 1, fp_ );
fread( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fread( &int_, sizeof(INT), 1, fp_ );
return *this;
}
#if !defined(__LP64__)
DATASTREAM& operator<< ( const UINT& uint )
{
if ( swap_ ) {
unsigned char const* p = (unsigned char const*)&uint;
fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fwrite( &uint, sizeof(UINT), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( UINT& uint )
{
if ( swap_ ) {
unsigned char* p = (unsigned char*)&uint;
fread( &p[3], sizeof(unsigned char), 1, fp_ );
fread( &p[2], sizeof(unsigned char), 1, fp_ );
fread( &p[1], sizeof(unsigned char), 1, fp_ );
fread( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fread( &uint, sizeof(UINT), 1, fp_ );
return *this;
}
#endif /* !__x86_64__ */
DATASTREAM& operator<< ( const FLOAT& float_ )
{
if ( swap_ ) {
unsigned char const* p = (unsigned char const*)&float_;
fwrite( &p[3], sizeof(unsigned char), 1, fp_ );
fwrite( &p[2], sizeof(unsigned char), 1, fp_ );
fwrite( &p[1], sizeof(unsigned char), 1, fp_ );
fwrite( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fwrite( &float_, sizeof(FLOAT), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( FLOAT& float_ )
{
if ( swap_ ) {
unsigned char* p = (unsigned char*)&float_;
fread( &p[3], sizeof(unsigned char), 1, fp_ );
fread( &p[2], sizeof(unsigned char), 1, fp_ );
fread( &p[1], sizeof(unsigned char), 1, fp_ );
fread( &p[0], sizeof(unsigned char), 1, fp_ );
}
else
fread( &float_, sizeof(FLOAT), 1, fp_ );
return *this;
}
DATASTREAM& operator<< ( const PADDING& padding )
{
if ( padding.size_ != 0 )
fwrite( &padding.padding_, sizeof(CHAR), padding.size_, fp_ );
return *this;
}
DATASTREAM& operator<< ( const RECTL& rectl )
{
*this << rectl.left << rectl.top << rectl.right << rectl.bottom;
return *this;
}
DATASTREAM& operator>> ( RECTL& rectl )
{
*this >> rectl.left >> rectl.top >> rectl.right >> rectl.bottom;
return *this;
}
DATASTREAM& operator<< ( const SIZEL& sizel )
{
*this << sizel.cx << sizel.cy;
return *this;
}
DATASTREAM& operator>> ( SIZEL& sizel )
{
*this >> sizel.cx >> sizel.cy;
return *this;
}
DATASTREAM& operator<< ( const WCHARSTR& wcharstr )
{
for ( int i = 0; i < wcharstr.length_; i++ )
*this << wcharstr.string_[i];
return *this;
}
DATASTREAM& operator>> ( WCHARSTR& wcharstr )
{
for ( int i = 0; i < wcharstr.length_; i++ )
*this >> wcharstr.string_[i];
return *this;
}
DATASTREAM& operator<< ( const CHARSTR& charstr )
{
fwrite( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
return *this;
}
DATASTREAM& operator>> ( CHARSTR& charstr )
{
fread( charstr.string_, sizeof(CHAR), charstr.length_, fp_ );
return *this;
}
DATASTREAM& operator<< ( const ::EMR& emr )
{
*this << emr.iType << emr.nSize;
return *this;
}
DATASTREAM& operator>> ( ::EMR& emr )
{
*this >> emr.iType >> emr.nSize;
return *this;
}
DATASTREAM& operator<< ( const POINT& point )
{
*this << point.x << point.y;
return *this;
}
DATASTREAM& operator>> ( POINT& point )
{
*this >> point.x >> point.y;
return *this;
}
DATASTREAM& operator<< ( const POINTL& pointl )
{
*this << pointl.x << pointl.y;
return *this;
}
DATASTREAM& operator>> ( POINTL& pointl )
{
*this >> pointl.x >> pointl.y;
return *this;
}
DATASTREAM& operator<< ( const POINT16& point )
{
*this << point.x << point.y;
return *this;
}
DATASTREAM& operator>> ( POINT16& point )
{
*this >> point.x >> point.y;
return *this;
}
DATASTREAM& operator<< ( const XFORM& xform )
{
*this << xform.eM11 << xform.eM12 << xform.eM21 << xform.eM22
<< xform.eDx << xform.eDy;
return *this;
}
DATASTREAM& operator>> ( XFORM& xform )
{
*this >> xform.eM11 >> xform.eM12 >> xform.eM21 >> xform.eM22
>> xform.eDx >> xform.eDy;
return *this;
}
DATASTREAM& operator<< ( const BYTEARRAY& array )
{
fwrite( array.array_, sizeof(BYTE), array.n_, fp_ );
return *this;
}
DATASTREAM& operator>> ( BYTEARRAY& array )
{
fread( array.array_, sizeof(BYTE), array.n_, fp_ );
return *this;
}
DATASTREAM& operator<< ( const POINTLARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this << array.points_[i];
return *this;
}
DATASTREAM& operator>> ( POINTLARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this >> array.points_[i];
return *this;
}
DATASTREAM& operator<< ( const POINT16ARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this << array.points_[i];
return *this;
}
DATASTREAM& operator>> ( POINT16ARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this >> array.points_[i];
return *this;
}
DATASTREAM& operator<< ( const INTARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this << array.ints_[i];
return *this;
}
DATASTREAM& operator>> ( INTARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this >> array.ints_[i];
return *this;
}
DATASTREAM& operator<< ( const DWORDARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this << array.dwords_[i];
return *this;
}
DATASTREAM& operator>> ( DWORDARRAY& array )
{
for ( unsigned int i = 0; i < array.n_; i++ )
*this >> array.dwords_[i];
return *this;
}
DATASTREAM& operator<< ( const ::EMRTEXT& text )
{
*this << text.ptlReference << text.nChars << text.offString << text.fOptions
<< text.rcl << text.offDx;
return *this;
}
DATASTREAM& operator>> ( ::EMRTEXT& text )
{
*this >> text.ptlReference >> text.nChars >> text.offString >> text.fOptions
>> text.rcl >> text.offDx;
return *this;
}
DATASTREAM& operator<< ( const LOGPEN& pen )
{
*this << pen.lopnStyle << pen.lopnWidth << pen.lopnColor;
return *this;
}
DATASTREAM& operator>> ( LOGPEN& pen )
{
*this >> pen.lopnStyle >> pen.lopnWidth >> pen.lopnColor;
return *this;
}
DATASTREAM& operator<< ( const EXTLOGPEN& pen )
{
// *** How big is this structure if there are no style entries? ***
*this << pen.elpPenStyle << pen.elpWidth << pen.elpBrushStyle << pen.elpColor
<< pen.elpHatch << pen.elpNumEntries;
return *this;
}
DATASTREAM& operator>> ( EXTLOGPEN& pen )
{
// *** How big is this structure if there are no style entries? ***
*this >> pen.elpPenStyle >> pen.elpWidth >> pen.elpBrushStyle >> pen.elpColor
>> pen.elpHatch >> pen.elpNumEntries;
return *this;
}
DATASTREAM& operator<< ( const LOGBRUSH& brush )
{
*this << brush.lbStyle << brush.lbColor << brush.lbHatch;
return *this;
}
DATASTREAM& operator>> ( LOGBRUSH& brush )
{
*this >> brush.lbStyle >> brush.lbColor >> brush.lbHatch;
return *this;
}
DATASTREAM& operator<< ( const LOGFONTW& font )
{
*this << font.lfHeight << font.lfWidth << font.lfEscapement
<< font.lfOrientation << font.lfWeight << font.lfItalic
<< font.lfUnderline << font.lfStrikeOut << font.lfCharSet
<< font.lfOutPrecision << font.lfClipPrecision << font.lfQuality
<< font.lfPitchAndFamily
<< WCHARSTR( const_cast<WCHAR*>(font.lfFaceName), LF_FACESIZE );
return *this;
}
DATASTREAM& operator>> ( LOGFONTW& font )
{
WCHARSTR wFaceName( font.lfFaceName, LF_FACESIZE );
*this >> font.lfHeight >> font.lfWidth >> font.lfEscapement
>> font.lfOrientation >> font.lfWeight >> font.lfItalic
>> font.lfUnderline >> font.lfStrikeOut >> font.lfCharSet
>> font.lfOutPrecision >> font.lfClipPrecision >> font.lfQuality
>> font.lfPitchAndFamily
>> wFaceName;
return *this;
}
DATASTREAM& operator<< ( const PANOSE& panose )
{
fwrite( &panose, sizeof(PANOSE), 1, fp_ );
return *this;
}
DATASTREAM& operator>> ( PANOSE& panose )
{
fread( &panose, sizeof(PANOSE), 1, fp_ );
return *this;
}
DATASTREAM& operator<< ( const EXTLOGFONTW& font )
{
*this << font.elfLogFont
<< WCHARSTR( const_cast<WCHAR*>(font.elfFullName),
LF_FULLFACESIZE )
<< WCHARSTR( const_cast<WCHAR*>(font.elfStyle), LF_FACESIZE )
<< font.elfVersion << font.elfStyleSize << font.elfMatch
<< font.elfReserved
<< BYTEARRAY( const_cast<BYTE*>(font.elfVendorId),
ELF_VENDOR_SIZE )
<< font.elfCulture << font.elfPanose;
return *this;
}
DATASTREAM& operator>> ( EXTLOGFONTW& font )
{
WCHARSTR wFullName( font.elfFullName, LF_FULLFACESIZE );
WCHARSTR wStyle( font.elfStyle, LF_FACESIZE );
BYTEARRAY bVendorId( font.elfVendorId, ELF_VENDOR_SIZE );
*this >> font.elfLogFont
>> wFullName >> wStyle
>> font.elfVersion >> font.elfStyleSize >> font.elfMatch
>> font.elfReserved >> bVendorId
>> font.elfCulture >> font.elfPanose;
return *this;
}
DATASTREAM& operator<< ( const LOGPALETTE& palette )
{
// *** How big is this structure if the palette is empty? ***
*this << palette.palVersion << palette.palNumEntries;
return *this;
}
DATASTREAM& operator>> ( LOGPALETTE& palette )
{
// *** How big is this structure if the palette is empty? ***
*this >> palette.palVersion >> palette.palNumEntries;
return *this;
}
private:
void fread ( void* ptr, size_t size, size_t nmemb, FILE* stream )
{
size_t res = ::fread( ptr, size, nmemb, stream );
if ( res < nmemb ) {
throw std::runtime_error( "Premature EOF on EMF stream" );
}
}
void fwrite ( const void* ptr, size_t size, size_t nmemb, FILE* stream )
{
size_t res = ::fwrite( ptr, size, nmemb, stream );
if ( res < nmemb ) {
throw std::runtime_error( "error writing EMF stream" );
}
}
};
class METAFILEDEVICECONTEXT;
class METARECORD {
public:
virtual void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const = 0;
virtual bool serialize ( DATASTREAM ds ) = 0;
virtual int size ( void ) const = 0;
virtual ~METARECORD( ) { }
#ifdef ENABLE_EDITING
virtual void edit ( void ) const {}
#endif
};
#ifdef ENABLE_EDITING
/* Miscellaneous editing routines */
inline void edit_rectl ( const char* tag, const RECTL& rectl )
{
#if defined(__LP64__)
const char* FMT = "\t%s\t: (%d, %d) - (%d, %d)\n";
#else
const char* FMT = "\t%s\t: (%ld, %ld) - (%ld, %ld)\n";
#endif /* __x86_64__ */
printf( FMT, tag, rectl.left, rectl.top, rectl.right, rectl.bottom );
}
inline void edit_xform ( const char* tag, const XFORM& xform )
{
printf( "\t%s.eM11\t: %f\n", tag, xform.eM11 );
printf( "\t%s.eM12\t: %f\n", tag, xform.eM12 );
printf( "\t%s.eM21\t: %f\n", tag, xform.eM21 );
printf( "\t%s.eM22\t: %f\n", tag, xform.eM22 );
printf( "\t%s.eDx\t: %f\n", tag, xform.eDx );
printf( "\t%s.eDy\t: %f\n", tag, xform.eDy );
}
inline void edit_color ( const char* tag, const COLORREF& color )
{
#if defined(__LP64__)
const char* FMT = "\t%s\t: R(0x%02x) G(0x%02x) B(0x%02x)\n";
#else
const char* FMT = "\t%s\t: R(0x%02lx) G(0x%02lx) B(0x%02lx)\n";
#endif /* __x86_64__ */
printf( FMT, tag,
GetRValue( color ), GetGValue( color ), GetBValue( color ) );
}
inline void edit_sizel ( const char* tag, const SIZEL& size )
{
#if defined(__LP64__)
const char* FMT = "\t%s\t: (%d, %d)\n";
#else
const char* FMT = "\t%s\t: (%ld, %ld)\n";
#endif /* __x86_64__ */
printf( FMT, tag, size.cx, size.cy );
}
inline void edit_pointl ( const char* tag, const POINTL& point )
{
#if defined(__LP64__)
const char* FMT = "\t%s\t: (%d, %d)\n";
#else
const char* FMT = "\t%s\t: (%ld, %ld)\n";
#endif /* __x86_64__ */
printf( FMT, tag, point.x, point.y );
}
inline void edit_pointlarray ( const char* tag, const DWORD cptl,
const POINTL* points )
{
#if defined(__LP64__)
const char* FMT0 = "\tcptl%s\t: %d\n";
const char* FMT1 = "%d, %d\n";
const char* FMT2 = "\t\t%s %d, %d\n";
#else
const char* FMT0 = "\tcptl%s\t: %ld\n";
const char* FMT1 = "%ld, %ld\n";
const char* FMT2 = "\t\t%s %ld, %ld\n";
#endif /* __x86_64__ */
printf( FMT0, tag, cptl );
printf( "\taptl%s\t: ", tag );
if ( cptl > 0 )
printf( FMT1, points[0].x, points[0].y );
else
puts( "" );
for ( DWORD i = 1; i < cptl; i++ )
printf( FMT2, tag, points[i].x, points[i].y );
}
inline void edit_point16array ( const char* tag, const unsigned int cpts,
const POINT16* points )
{
printf( "\tcpts%s\t: %d\n", tag, cpts );
printf( "\tapts%s\t: ", tag );
if ( cpts > 0 )
printf( "%d, %d\n", points[0].x, points[0].y );
else
puts( "" );
for ( unsigned int i = 1; i < cpts; i++ )
printf( "\t\t%s %d, %d\n", tag, points[i].x, points[i].y );
}
inline void edit_pen_style ( const char* tag, DWORD style )
{
printf( "\t%s\t: ", tag );
switch ( style & PS_STYLE_MASK ) {
case PS_SOLID: printf( "PS_SOLID" ); break;
case PS_DASH: printf( "PS_DASH" ); break;
case PS_DOT: printf( "PS_DOT" ); break;
case PS_DASHDOT: printf( "PS_DASHDOT" ); break;
case PS_DASHDOTDOT: printf( "PS_DASHDOTDOT" ); break;
case PS_NULL: printf( "PS_NULL" ); break;
case PS_INSIDEFRAME: printf( "PS_INSIDEFRAME" ); break;
case PS_USERSTYLE: printf( "PS_USERSTYLE" ); break;
case PS_ALTERNATE: printf( "PS_ALTERNATE" ); break;
}
switch ( style & PS_ENDCAP_MASK ) {
case PS_ENDCAP_ROUND: printf( " | PS_ENDCAP_ROUND" ); break;
case PS_ENDCAP_SQUARE: printf( " | PS_ENDCAP_SQUARE" ); break;
case PS_ENDCAP_FLAT: printf( " | PS_ENDCAP_FLAT" ); break;
}
switch ( style & PS_JOIN_MASK ) {
case PS_JOIN_ROUND: printf( " | PS_JOIN_ROUND" ); break;
case PS_JOIN_BEVEL: printf( " | PS_JOIN_BEVEL" ); break;
case PS_JOIN_MITER: printf( " | PS_JOIN_MITER" ); break;
}
switch ( style & PS_TYPE_MASK ) {
case PS_COSMETIC: printf( " | PS_COSMETIC" ); break;
case PS_GEOMETRIC: printf( " | PS_GEOMETRIC" ); break;
}
printf( "\n" );
}
inline void edit_brush_style ( const char* tag, DWORD style )
{
#if defined(__LP64__)
const char* FMT = "unknown(%d)";
#else
const char* FMT = "unknown(%ld)";
#endif /* __x86_64__ */
printf( "\t%s\t: ", tag );
switch ( style ) {
case BS_SOLID: printf( "BS_SOLID" ); break;
case BS_NULL: printf( "BS_NULL" ); break;
case BS_HATCHED: printf( "BS_HATCHED" ); break;
case BS_PATTERN: printf( "BS_PATTERN" ); break;
case BS_INDEXED: printf( "BS_INDEXED" ); break;
case BS_DIBPATTERN: printf( "BS_DIBPATTERN" ); break;
case BS_DIBPATTERNPT: printf( "BS_DIBPATTERNPT" ); break;
case BS_PATTERN8X8: printf( "BS_PATTERN8X8" ); break;
case BS_DIBPATTERN8X8: printf( "BS_DIBPATTERN8X8" ); break;
case BS_MONOPATTERN: printf( "BS_DIBPATTERN8X8" ); break;
default: printf( FMT, style );
}
printf( "\n" );
}
inline void edit_brush_hatch ( const char* tag, DWORD hatch )
{
#if defined(__LP64__)
const char* FMT = "unknown(%d)";
#else
const char* FMT = "unknown(%ld)";
#endif /* __x86_64__ */
printf( "\t%s\t: ", tag );
switch ( hatch ) {
case HS_HORIZONTAL: printf( "HS_HORIZONTAL" ); break;
case HS_VERTICAL: printf( "HS_VERTICAL" ); break;
case HS_FDIAGONAL: printf( "HS_FDIAGONAL" ); break;
case HS_BDIAGONAL: printf( "HS_BDIAGONAL" ); break;
case HS_CROSS: printf( "HS_CROSS" ); break;
case HS_DIAGCROSS: printf( "HS_DIAGCROSS" ); break;
default: printf( FMT, hatch );
}
printf( "\n" );
}
#endif
enum OBJECTTYPE { O_METAFILEDEVICECONTEXT = OBJ_METADC,
O_FONT = OBJ_FONT,
O_PEN = OBJ_PEN,
O_EXTPEN = OBJ_EXTPEN,
O_BRUSH = OBJ_BRUSH,
O_PALETTE = OBJ_PAL };
#if 0
static char* typStr ( OBJECTTYPE type )
{
switch (type) {
case O_METAFILEDEVICECONTEXT:
return "metafile device context";
case O_FONT:
return "font";
case O_PEN:
return "pen";
case O_EXTPEN:
return "extended pen";
case O_BRUSH:
return "brush";
case O_PALETTE:
return "palette";
}
return "unknown object";
}
#endif
class OBJECT {
public:
HGDIOBJ handle;
virtual ~OBJECT () {}
OBJECT ( void ) : handle( 0 ) {}
virtual OBJECTTYPE getType ( void ) const = 0;
};
class GRAPHICSOBJECT : public OBJECT {
public:
virtual ~GRAPHICSOBJECT () {}
std::map< HDC, HGDIOBJ > contexts;
virtual METARECORD* newEMR ( HDC dc, HGDIOBJ handle ) = 0;
};
typedef METARECORD*(*METARECORDCTOR)(DATASTREAM&);
class GLOBALOBJECTS {
std::vector<OBJECT*> objects;
std::map< DWORD, METARECORDCTOR > new_records;
public:
GLOBALOBJECTS ( void );
~GLOBALOBJECTS ( void );
HGDIOBJ add ( OBJECT* object );
OBJECT* find ( const HGDIOBJ handle );
void remove ( const OBJECT* object );
auto begin ( void ) const { return objects.begin(); }
auto end ( void ) const { return objects.end(); }
METARECORDCTOR newRecord ( DWORD iType ) const;
static EMF::METARECORD* new_eof ( DATASTREAM& ds );
static EMF::METARECORD* new_setviewportorgex ( DATASTREAM& ds );
static EMF::METARECORD* new_setwindoworgex ( DATASTREAM& ds );
static EMF::METARECORD* new_setviewportextex ( DATASTREAM& ds );
static EMF::METARECORD* new_setwindowextex ( DATASTREAM& ds );
static EMF::METARECORD* new_scaleviewportextex ( DATASTREAM& ds );
static EMF::METARECORD* new_scalewindowextex ( DATASTREAM& ds );
static EMF::METARECORD* new_modifyworldtransform ( DATASTREAM& ds );
static EMF::METARECORD* new_setworldtransform ( DATASTREAM& ds );
static EMF::METARECORD* new_settextalign ( DATASTREAM& ds );
static EMF::METARECORD* new_settextcolor ( DATASTREAM& ds );
static EMF::METARECORD* new_setbkcolor ( DATASTREAM& ds );
static EMF::METARECORD* new_setbkmode ( DATASTREAM& ds );
static EMF::METARECORD* new_setpolyfillmode ( DATASTREAM& ds );
static EMF::METARECORD* new_setmapmode ( DATASTREAM& ds );
static EMF::METARECORD* new_selectobject ( DATASTREAM& ds );
static EMF::METARECORD* new_deleteobject ( DATASTREAM& ds );
static EMF::METARECORD* new_movetoex ( DATASTREAM& ds );
static EMF::METARECORD* new_lineto ( DATASTREAM& ds );
static EMF::METARECORD* new_arc ( DATASTREAM& ds );
static EMF::METARECORD* new_arcto ( DATASTREAM& ds );
static EMF::METARECORD* new_rectangle ( DATASTREAM& ds );
static EMF::METARECORD* new_ellipse ( DATASTREAM& ds );
static EMF::METARECORD* new_polyline ( DATASTREAM& ds );
static EMF::METARECORD* new_polyline16 ( DATASTREAM& ds );
static EMF::METARECORD* new_polygon ( DATASTREAM& ds );
static EMF::METARECORD* new_polygon16 ( DATASTREAM& ds );
static EMF::METARECORD* new_polypolygon ( DATASTREAM& ds );
static EMF::METARECORD* new_polypolygon16 ( DATASTREAM& ds );
static EMF::METARECORD* new_polybezier ( DATASTREAM& ds );
static EMF::METARECORD* new_polybezier16 ( DATASTREAM& ds );
static EMF::METARECORD* new_polybezierto ( DATASTREAM& ds );
static EMF::METARECORD* new_polybezierto16 ( DATASTREAM& ds );
static EMF::METARECORD* new_polylineto ( DATASTREAM& ds );
static EMF::METARECORD* new_polylineto16 ( DATASTREAM& ds );
static EMF::METARECORD* new_exttextouta ( DATASTREAM& ds );
static EMF::METARECORD* new_exttextoutw ( DATASTREAM& ds );
static EMF::METARECORD* new_setpixelv ( DATASTREAM& ds );
static EMF::METARECORD* new_createpen ( DATASTREAM& ds );
static EMF::METARECORD* new_extcreatepen ( DATASTREAM& ds );
static EMF::METARECORD* new_createbrushindirect ( DATASTREAM& ds );
static EMF::METARECORD* new_extcreatefontindirectw ( DATASTREAM& ds );
static EMF::METARECORD* new_fillpath ( DATASTREAM& ds );
static EMF::METARECORD* new_strokepath ( DATASTREAM& ds );
static EMF::METARECORD* new_strokeandfillpath ( DATASTREAM& ds );
static EMF::METARECORD* new_beginpath ( DATASTREAM& ds );
static EMF::METARECORD* new_endpath ( DATASTREAM& ds );
static EMF::METARECORD* new_closefigure ( DATASTREAM& ds );
static EMF::METARECORD* new_savedc ( DATASTREAM& ds );
static EMF::METARECORD* new_restoredc ( DATASTREAM& ds );
static EMF::METARECORD* new_setmetargn ( DATASTREAM& ds );
static EMF::METARECORD* new_setmiterlimit ( DATASTREAM& ds );
};
extern GLOBALOBJECTS globalObjects;
class ENHMETAHEADER : public METARECORD, public ::ENHMETAHEADER {
LPWSTR description_w{ nullptr };
int description_size{ 0 };
public:
ENHMETAHEADER ( LPCWSTR description = 0 )
: description_w( 0 ), description_size( 0 )
{
iType = EMR_HEADER;
nSize = sizeof( ::ENHMETAHEADER );
// Compute the bounds
RECTL default_bounds = { 0, 0, 0, 0 };
rclBounds = default_bounds;
RECTL default_frame = { 0, 0, 0, 0 };
rclFrame = default_frame;
dSignature = ENHMETA_SIGNATURE;
nVersion = 0x10000;
nBytes = nSize;
nRecords = 1;
nHandles = 0;
sReserved = 0;
nDescription = 0;
offDescription = 0;
nPalEntries = 0;
szlDevice.cx = XMAX_PIXELS;
szlDevice.cy = YMAX_PIXELS;
szlMillimeters.cx = XMAX_MM;
szlMillimeters.cy = YMAX_MM;
//
cbPixelFormat = 0;
offPixelFormat = 0;
bOpenGL = FALSE;
//
#if 1
szlMicrometers.cx = 1000 * szlMillimeters.cx;
szlMicrometers.cy = 1000 * szlMillimeters.cy;
#endif
if ( description ) {
// Count the number of characters in the description
int description_count = 0, nulls = 0;
LPCWSTR description_p = description;
while ( nulls < 3 ) {
description_count++;
if ( (*description_p++) == 0 ) nulls++;
}
// Make sure that the TOTAL record length will be a multiple of 4
int record_size = ROUND_TO_LONG( sizeof( ::ENHMETAHEADER ) +
sizeof( WCHAR ) * description_count );
description_size =
(record_size - sizeof( ::ENHMETAHEADER )) / sizeof( WCHAR );
std::unique_ptr<WCHAR[]>
description_tmp( new WCHAR[ description_size ] );
description_w = description_tmp.release();
memset( description_w, 0, sizeof(WCHAR) * description_size );
for ( int i=0; i<description_count; i++ )
description_w[i] = *description++;
nSize = nBytes = record_size;
nDescription = description_count;
offDescription = sizeof( ::ENHMETAHEADER );
}
}
~ENHMETAHEADER ( )
{
if ( description_w ) delete[] description_w;
}
bool serialize ( DATASTREAM ds )
{
ds << iType << nSize
<< rclBounds << rclFrame
<< dSignature << nVersion << nBytes << nRecords << nHandles << sReserved
<< nDescription << offDescription << nPalEntries
<< szlDevice << szlMillimeters
<< cbPixelFormat << offPixelFormat << bOpenGL
<< szlMicrometers
<< WCHARSTR( description_w, description_size );
return true;
}
bool unserialize ( DATASTREAM ds )
{
ds >> iType >> nSize
>> rclBounds >> rclFrame
>> dSignature >> nVersion >> nBytes >> nRecords >> nHandles >> sReserved
>> nDescription >> offDescription >> nPalEntries
>> szlDevice >> szlMillimeters;
// Some elements of the metafile header were added at later dates
#define OffsetOf( a, b ) ((unsigned int)(((char*)&(((::ENHMETAHEADER*)a)->b)) - \
(char*)((::ENHMETAHEADER*)a)))
if ( OffsetOf( this, szlMicrometers ) <= offDescription )
ds >> cbPixelFormat >> offPixelFormat >> bOpenGL;
#undef OffsetOf
if ( sizeof(::ENHMETAHEADER) <= offDescription )
ds >> szlMicrometers;
// Should now probably check that the offset is correct...
int description_size_to_read = ( nSize - offDescription ) / sizeof(WCHAR);
if ( description_size_to_read < (int)nDescription ) {
throw std::runtime_error( "record size inconsistent with description size" );
}
description_size = max( 2, description_size_to_read );
std::unique_ptr<WCHAR[]> buffer( new WCHAR[description_size] );
WCHARSTR description( buffer.get(), description_size_to_read );
ds >> description;
description_w = buffer.release();
// Make sure it's terminated properly.
description_w[description_size-1] = 0;
description_w[description_size-2] = 0;
return true;
}
int size ( void ) const { return nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
// Actually handled by the destination device context.
EMF_UNUSED(source);
EMF_UNUSED(dc);
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\tiType\t\t\t: %d\n";
const char* FMT1 = "\tnSize\t\t\t: %d\n";
const char* FMT2 = "\tnBytes\t\t\t: %d\n";
const char* FMT3 = "\tnRecords\t\t: %d\n";
const char* FMT4 = "\tnDescription\t\t: %d\n";
const char* FMT5 = "\toffDescription\t\t: %d\n";
const char* FMT6 = "\tnPalEntries\t\t: %d\n";
const char* FMT7 = "\tcbPixelFormat\t\t: %d\n";
const char* FMT8 = "\toffPixelFormat\t\t: %d\n";
const char* FMT9 = "\tbOpenGL\t\t\t: %d\n";
#else
const char* FMT0 = "\tiType\t\t\t: %ld\n";
const char* FMT1 = "\tnSize\t\t\t: %ld\n";
const char* FMT2 = "\tnBytes\t\t\t: %ld\n";
const char* FMT3 = "\tnRecords\t\t: %ld\n";
const char* FMT4 = "\tnDescription\t\t: %ld\n";
const char* FMT5 = "\toffDescription\t\t: %ld\n";
const char* FMT6 = "\tnPalEntries\t\t: %ld\n";
const char* FMT7 = "\tcbPixelFormat\t\t: %ld\n";
const char* FMT8 = "\toffPixelFormat\t\t: %ld\n";
const char* FMT9 = "\tbOpenGL\t\t\t: %ld\n";
#endif
printf( "*HEADER*\n" );
printf( FMT0, iType );
printf( FMT1, nSize );
edit_rectl( "rclBounds\t", rclBounds );
edit_rectl( "rclFrame\t", rclFrame );
printf( "\tdSignature\t\t: %.4s\n", (const char*)&dSignature );
printf( "\tnVersion\t\t: 0x%x\n", (unsigned int)nVersion );
printf( FMT2, nBytes );
printf( FMT3, nRecords );
printf( "\tnHandles\t\t: %d\n", nHandles );
printf( FMT4, nDescription );
printf( FMT5, offDescription );
printf( FMT6, nPalEntries );
edit_sizel( "szlDevice\t", szlDevice );
edit_sizel( "szlMillimeters\t", szlMillimeters );
/* Make a crude guess as to the age of this file */
#define OffsetOf( a, b ) ((unsigned int)(((const char*)&(((const ::ENHMETAHEADER*)a)->b)) - \
(const char*)((const ::ENHMETAHEADER*)a)))
if ( OffsetOf( this, cbPixelFormat ) <= offDescription ) {
printf( FMT7, cbPixelFormat );
printf( FMT8, offPixelFormat );
printf( FMT9, bOpenGL );
#if 1
if ( sizeof(::ENHMETAHEADER) <= offDescription ) {
edit_sizel( "szlMicrometers\t", szlMicrometers );
}
#endif
}
#undef OffsetOf
if ( nDescription != 0 ) {
wchar_t last_w = 0;
WCHAR* description = description_w;
printf( "\tDescription:" );
for ( DWORD i = 0; i < nDescription; i++ ) {
wchar_t w = *description++; /* This is not true, really. UNICODE is not
* glibc's wide character representation */
if ( w != 0 ) {
if ( last_w == 0 ) printf( "\n\t\t" );
putchar( w );
}
last_w = w;
}
printf( "\n" );
}
}
#endif /* ENABLE_EDITING */
};
class EMREOF : public METARECORD, ::EMREOF {
public:
EMREOF ( void )
{
emr.iType = EMR_EOF;
emr.nSize = sizeof( ::EMREOF );
nPalEntries = 0;
offPalEntries = 0;
nSizeLast = 0;
}
EMREOF ( DATASTREAM& ds )
{
ds >> emr >> nPalEntries >> offPalEntries >> nSizeLast;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << nPalEntries << offPalEntries << nSizeLast;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
// Actually handled by the destination device context.
EMF_UNUSED(source);
EMF_UNUSED(dc);
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*EOF*\n" );
}
#endif /* ENABLE_EDITING */
};
class EMRSETVIEWPORTORGEX : public METARECORD, ::EMRSETVIEWPORTORGEX {
public:
EMRSETVIEWPORTORGEX ( INT x, INT y )
{
emr.iType = EMR_SETVIEWPORTORGEX;
emr.nSize = sizeof( ::EMRSETVIEWPORTORGEX );
ptlOrigin.x = x;
ptlOrigin.y = y;
}
EMRSETVIEWPORTORGEX ( DATASTREAM& ds )
{
ds >> emr >> ptlOrigin;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << ptlOrigin;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetViewportOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETVIEWPORTORGEX*\n" );
edit_pointl( "ptlOrigin", ptlOrigin );
}
#endif /* ENABLE_EDITING */
};
class EMRSETWINDOWORGEX : public METARECORD, ::EMRSETWINDOWORGEX {
public:
EMRSETWINDOWORGEX ( INT x, INT y )
{
emr.iType = EMR_SETWINDOWORGEX;
emr.nSize = sizeof( ::EMRSETWINDOWORGEX );
ptlOrigin.x = x;
ptlOrigin.y = y;
}
EMRSETWINDOWORGEX ( DATASTREAM& ds )
{
ds >> emr >> ptlOrigin;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << ptlOrigin;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetWindowOrgEx( dc, ptlOrigin.x, ptlOrigin.y, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETWINDOWORGEX*\n" );
edit_pointl( "ptlOrigin", ptlOrigin );
}
#endif /* ENABLE_EDITING */
};
class EMRSETVIEWPORTEXTEX : public METARECORD, ::EMRSETVIEWPORTEXTEX {
public:
EMRSETVIEWPORTEXTEX ( INT cx, INT cy )
{
emr.iType = EMR_SETVIEWPORTEXTEX;
emr.nSize = sizeof( ::EMRSETVIEWPORTEXTEX );
szlExtent.cx = cx;
szlExtent.cy = cy;
}
EMRSETVIEWPORTEXTEX ( DATASTREAM& ds )
{
ds >> emr >> szlExtent;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << szlExtent;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetViewportExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETVIEWPORTEXTEX*\n" );
edit_sizel( "szlExtent", szlExtent );
}
#endif /* ENABLE_EDITING */
};
class EMRSCALEVIEWPORTEXTEX : public METARECORD, ::EMRSCALEVIEWPORTEXTEX {
public:
EMRSCALEVIEWPORTEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
{
emr.iType = EMR_SCALEVIEWPORTEXTEX;
emr.nSize = sizeof( ::EMRSCALEVIEWPORTEXTEX );
xNum = x_num;
xDenom = x_den;
yNum = y_num;
yDenom = y_den;
}
EMRSCALEVIEWPORTEXTEX ( DATASTREAM& ds )
{
ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << xNum << xDenom << yNum << yDenom;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
ScaleViewportExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\txNum\t: %d\n";
const char* FMT1 = "\txDenom\t: %d\n";
const char* FMT2 = "\tyNum\t: %d\n";
const char* FMT3 = "\tyDenom\t: %d\n";
#else
const char* FMT0 = "\txNum\t: %ld\n";
const char* FMT1 = "\txDenom\t: %ld\n";
const char* FMT2 = "\tyNum\t: %ld\n";
const char* FMT3 = "\tyDenom\t: %ld\n";
#endif
printf( "*SCALEVIEWPORTEXTEX*\n" );
printf( FMT0, xNum );
printf( FMT1, xDenom );
printf( FMT2, yNum );
printf( FMT3, yDenom );
}
#endif /* ENABLE_EDITING */
};
class EMRSETWINDOWEXTEX : public METARECORD, ::EMRSETWINDOWEXTEX {
public:
EMRSETWINDOWEXTEX ( INT cx, INT cy )
{
emr.iType = EMR_SETWINDOWEXTEX;
emr.nSize = sizeof( ::EMRSETWINDOWEXTEX );
szlExtent.cx = cx;
szlExtent.cy = cy;
}
EMRSETWINDOWEXTEX ( DATASTREAM& ds )
{
ds >> emr >> szlExtent;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << szlExtent;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetWindowExtEx( dc, szlExtent.cx, szlExtent.cy, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETWINDOWEXTEX*\n" );
edit_sizel( "szlExtent", szlExtent );
}
#endif /* ENABLE_EDITING */
};
class EMRSCALEWINDOWEXTEX : public METARECORD, ::EMRSCALEWINDOWEXTEX {
public:
EMRSCALEWINDOWEXTEX ( LONG x_num, LONG x_den, LONG y_num, LONG y_den )
{
emr.iType = EMR_SCALEWINDOWEXTEX;
emr.nSize = sizeof( ::EMRSCALEWINDOWEXTEX );
xNum = x_num;
xDenom = x_den;
yNum = y_num;
yDenom = y_den;
}
EMRSCALEWINDOWEXTEX ( DATASTREAM& ds )
{
ds >> emr >> xNum >> xDenom >> yNum >> yDenom;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << xNum << xDenom << yNum << yDenom;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
ScaleWindowExtEx( dc, xNum, xDenom, yNum, yDenom, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\txNum\t: %d\n";
const char* FMT1 = "\txDenom\t: %d\n";
const char* FMT2 = "\tyNum\t: %d\n";
const char* FMT3 = "\tyDenom\t: %d\n";
#else
const char* FMT0 = "\txNum\t: %ld\n";
const char* FMT1 = "\txDenom\t: %ld\n";
const char* FMT2 = "\tyNum\t: %ld\n";
const char* FMT3 = "\tyDenom\t: %ld\n";
#endif
printf( "*SCALEWINDOWEXTEX*\n" );
printf( FMT0, xNum );
printf( FMT1, xDenom );
printf( FMT2, yNum );
printf( FMT3, yDenom );
}
#endif /* ENABLE_EDITING */
};
class EMRMODIFYWORLDTRANSFORM : public METARECORD, ::EMRMODIFYWORLDTRANSFORM {
public:
EMRMODIFYWORLDTRANSFORM ( const XFORM* transform, DWORD mode )
{
emr.iType = EMR_MODIFYWORLDTRANSFORM;
emr.nSize = sizeof( ::EMRMODIFYWORLDTRANSFORM );
xform = *transform;
iMode = mode;
}
EMRMODIFYWORLDTRANSFORM ( DATASTREAM& ds )
{
ds >> emr >> xform >> iMode;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << xform << iMode;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
ModifyWorldTransform( dc, &xform, iMode );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "unknown(%d)\n";
#else
const char* FMT = "unknown(%ld)\n";
#endif /* __x86_64__ */
printf( "*MODIFYWORLDTRANSFORM*\n" );
edit_xform( "xform", xform );
printf( "\tiMode\t\t: " );
switch ( iMode ) {
case MWT_IDENTITY: printf( "MWT_IDENTITY\n" ); break;
case MWT_LEFTMULTIPLY: printf( "MWT_LEFTMULTIPLY\n" ); break;
case MWT_RIGHTMULTIPLY: printf( "MWT_RIGHTMULTIPLY\n" ); break;
default: printf( FMT, iMode );
}
}
#endif /* ENABLE_EDITING */
};
class EMRSETWORLDTRANSFORM : public METARECORD, ::EMRSETWORLDTRANSFORM {
public:
EMRSETWORLDTRANSFORM ( const XFORM* transform )
{
emr.iType = EMR_SETWORLDTRANSFORM;
emr.nSize = sizeof( ::EMRSETWORLDTRANSFORM );
xform = *transform;
}
EMRSETWORLDTRANSFORM ( DATASTREAM& ds )
{
ds >> emr >> xform;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << xform;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetWorldTransform( dc, &xform );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETWORLDTRANSFORM*\n" );
edit_xform( "xform", xform );
}
#endif /* ENABLE_EDITING */
};
class EMRSETTEXTALIGN : public METARECORD, ::EMRSETTEXTALIGN {
public:
EMRSETTEXTALIGN ( UINT mode )
{
emr.iType = EMR_SETTEXTALIGN;
emr.nSize = sizeof( ::EMRSETTEXTALIGN );
iMode = mode;
}
EMRSETTEXTALIGN ( DATASTREAM& ds )
{
ds >> emr >> iMode;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << iMode;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetTextAlign( dc, iMode );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "| unknown bits(0x%x)";
#else
const char* FMT = "| unknown bits(0x%lx)";
#endif /* __x86_64__ */
unsigned int known_bits = TA_BASELINE+TA_CENTER+TA_UPDATECP+TA_RTLREADING;
unsigned int unknown_bits = ~known_bits;
printf( "*SETTEXTALIGN*\n" );
printf( "\tiMode\t: " );
if ( iMode & TA_UPDATECP )
printf( "TA_UPDATECP" );
else
printf( "TA_NOUPDATECP" );
if ( iMode & TA_CENTER )
printf( " | TA_CENTER" );
else if ( iMode & TA_RIGHT )
printf( " | TA_RIGHT" );
else
printf( " | TA_LEFT" );
if ( iMode & TA_BASELINE )
printf( " | TA_BASELINE" );
else if ( iMode & TA_BOTTOM )
printf( " | TA_BOTTOM" );
else
printf( " | TA_TOP" );
if ( iMode & TA_RTLREADING )
printf( " | TA_RTLREADING" );
if ( iMode & unknown_bits )
printf( FMT, iMode & unknown_bits );
printf( "\n" );
}
#endif /* ENABLE_EDITING */
};
class EMRSETTEXTCOLOR : public METARECORD, ::EMRSETTEXTCOLOR {
public:
EMRSETTEXTCOLOR ( COLORREF color )
{
emr.iType = EMR_SETTEXTCOLOR;
emr.nSize = sizeof( ::EMRSETTEXTCOLOR );
crColor = color;
}
EMRSETTEXTCOLOR ( DATASTREAM& ds )
{
ds >> emr >> crColor;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << crColor;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetTextColor( dc, crColor );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETTEXTCOLOR*\n" );
edit_color( "crColor", crColor );
}
#endif /* ENABLE_EDITING */
};
class EMRSETBKCOLOR : public METARECORD, ::EMRSETBKCOLOR {
public:
EMRSETBKCOLOR ( COLORREF color )
{
emr.iType = EMR_SETBKCOLOR;
emr.nSize = sizeof( ::EMRSETBKCOLOR );
crColor = color;
}
EMRSETBKCOLOR ( DATASTREAM& ds )
{
ds >> emr >> crColor;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << crColor;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetBkColor( dc, crColor );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETBKCOLOR*\n" );
edit_color( "crColor", crColor );
}
#endif /* ENABLE_EDITING */
};
class EMRSETBKMODE : public METARECORD, ::EMRSETBKMODE {
public:
EMRSETBKMODE ( DWORD mode )
{
emr.iType = EMR_SETBKMODE;
emr.nSize = sizeof( ::EMRSETBKMODE );
iMode = mode;
}
EMRSETBKMODE ( DATASTREAM& ds )
{
ds >> emr >> iMode;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << iMode;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetBkMode( dc, iMode );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "unknown(%d)\n";
#else
const char* FMT = "unknown(%ld)\n";
#endif /* __x86_64__ */
printf( "*SETBKMODE*\n" );
printf( "\tiMode\t: " );
switch ( iMode ) {
case TRANSPARENT: printf( "TRANSPARENT\n" ); break;
case OPAQUE: printf( "OPAQUE\n" ); break;
default: printf( FMT, iMode );
}
}
#endif /* ENABLE_EDITING */
};
class EMRSETPOLYFILLMODE : public METARECORD, ::EMRSETPOLYFILLMODE {
public:
EMRSETPOLYFILLMODE ( DWORD mode )
{
emr.iType = EMR_SETPOLYFILLMODE;
emr.nSize = sizeof( ::EMRSETPOLYFILLMODE );
iMode = mode;
}
EMRSETPOLYFILLMODE ( DATASTREAM& ds )
{
ds >> emr >> iMode;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << iMode;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetPolyFillMode( dc, iMode );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "unknown(%d)\n";
#else
const char* FMT = "unknown(%ld)\n";
#endif /* __x86_64__ */
printf( "*SETPOLYFILLMODE*\n" );
printf( "\tiMode: " );
switch ( iMode ) {
case ALTERNATE: printf( "ALTERNATE\n" ); break;
case WINDING: printf( "WINDING\n" ); break;
default: printf( FMT, iMode );
}
}
#endif /* ENABLE_EDITING */
};
class EMRSETMAPMODE : public METARECORD, ::EMRSETMAPMODE {
public:
EMRSETMAPMODE ( DWORD mode )
{
emr.iType = EMR_SETMAPMODE;
emr.nSize = sizeof( ::EMRSETMAPMODE );
iMode = mode;
}
EMRSETMAPMODE ( DATASTREAM& ds )
{
ds >> emr >> iMode;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << iMode;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetMapMode( dc, iMode );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "unknown(%d)\n";
#else
const char* FMT = "unknown(%ld)\n";
#endif /* __x86_64__ */
printf( "*SETMAPMODE*\n" );
printf( "\tiMode\t: " );
switch ( iMode ) {
case MM_TEXT: printf( "MM_TEXT\n" ); break;
case MM_LOMETRIC: printf( "MM_LOMETRIC\n" ); break;
case MM_HIMETRIC: printf( "MM_HIMETRIC\n" ); break;
case MM_LOENGLISH: printf( "MM_LOENGLISH\n" ); break;
case MM_HIENGLISH: printf( "MM_HIENGLISH\n" ); break;
case MM_TWIPS: printf( "MM_TWIPS\n" ); break;
case MM_ISOTROPIC: printf( "MM_ISOTROPIC\n" ); break;
case MM_ANISOTROPIC: printf( "MM_ANISOTROPIC\n" ); break;
default: printf( FMT, iMode );
}
}
#endif /* ENABLE_EDITING */
};
class EMRSELECTOBJECT : public METARECORD, ::EMRSELECTOBJECT {
public:
EMRSELECTOBJECT ( HGDIOBJ object )
{
emr.iType = EMR_SELECTOBJECT;
emr.nSize = sizeof( ::EMRSELECTOBJECT );
ihObject = object;
}
EMRSELECTOBJECT ( DATASTREAM& ds )
{
ds >> emr >> ihObject;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << ihObject;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "\tihObject\t: 0x%x\n";
#else
const char* FMT = "\tihObject\t: 0x%lx\n";
#endif /* __x86_64__ */
printf( "*SELECTOBJECT*\n" );
printf( FMT, ihObject );
}
#endif /* ENABLE_EDITING */
};
class EMRDELETEOBJECT : public METARECORD, ::EMRDELETEOBJECT {
public:
EMRDELETEOBJECT ( HGDIOBJ object )
{
emr.iType = EMR_DELETEOBJECT;
emr.nSize = sizeof( ::EMRDELETEOBJECT );
ihObject = object;
}
EMRDELETEOBJECT ( DATASTREAM& ds )
{
ds >> emr >> ihObject;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << ihObject;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "\tihObject\t: 0x%x\n";
#else
const char* FMT = "\tihObject\t: 0x%lx\n";
#endif /* __x86_64__ */
printf( "*DELETEOBJECT*\n" );
printf( FMT, ihObject );
}
#endif /* ENABLE_EDITING */
};
class EMRMOVETOEX : public METARECORD, ::EMRMOVETOEX {
public:
EMRMOVETOEX ( INT x, INT y )
{
emr.iType = EMR_MOVETOEX;
emr.nSize = sizeof( ::EMRMOVETOEX );
ptl.x = x;
ptl.y = y;
}
EMRMOVETOEX ( DATASTREAM& ds )
{
ds >> emr >> ptl;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << ptl;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
MoveToEx( dc, ptl.x, ptl.y, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*MOVETOEX*\n" );
edit_pointl( "ptl", ptl );
}
#endif /* ENABLE_EDITING */
};
class EMRLINETO : public METARECORD, ::EMRLINETO {
public:
EMRLINETO ( INT x, INT y )
{
emr.iType = EMR_LINETO;
emr.nSize = sizeof( ::EMRLINETO );
ptl.x = x;
ptl.y = y;
}
EMRLINETO ( DATASTREAM& ds )
{
ds >> emr >> ptl;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << ptl;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
LineTo( dc, ptl.x, ptl.y );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*LINETO*\n" );
edit_pointl( "ptl", ptl );
}
#endif /* ENABLE_EDITING */
};
class EMRARC : public METARECORD, ::EMRARC {
public:
EMRARC ( INT left, INT top, INT right, INT bottom, INT xstart,
INT ystart, INT xend, INT yend )
{
emr.iType = EMR_ARC;
emr.nSize = sizeof( ::EMRARC );
rclBox.left = left;
rclBox.right = right;
rclBox.bottom = bottom;
rclBox.top = top;
ptlStart.x = xstart;
ptlStart.y = ystart;
ptlEnd.x = xend;
ptlEnd.y = yend;
}
EMRARC ( DATASTREAM& ds )
{
ds >> emr >> rclBox >> ptlStart >> ptlEnd;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBox << ptlStart << ptlEnd;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
Arc( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*ARC*\n" );
edit_rectl( "rclBox\t", rclBox );
edit_pointl( "ptlStart", ptlStart );
edit_pointl( "ptlEnd\t", ptlEnd );
}
#endif /* ENABLE_EDITING */
};
class EMRARCTO : public METARECORD, ::EMRARCTO {
public:
EMRARCTO ( INT left, INT top, INT right, INT bottom, INT xstart,
INT ystart, INT xend, INT yend )
{
emr.iType = EMR_ARCTO;
emr.nSize = sizeof( ::EMRARCTO );
rclBox.left = left;
rclBox.right = right;
rclBox.bottom = bottom;
rclBox.top = top;
ptlStart.x = xstart;
ptlStart.y = ystart;
ptlEnd.x = xend;
ptlEnd.y = yend;
}
EMRARCTO ( DATASTREAM& ds )
{
ds >> emr >> rclBox >> ptlStart >> ptlEnd;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBox << ptlStart << ptlEnd;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
ArcTo( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom,
ptlStart.x, ptlStart.y, ptlEnd.x, ptlEnd.y );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*ARCTO*\n" );
edit_rectl( "rclBox\t", rclBox );
edit_pointl( "ptlStart", ptlStart );
edit_pointl( "ptlEnd\t", ptlEnd );
}
#endif /* ENABLE_EDITING */
};
class EMRRECTANGLE : public METARECORD, ::EMRRECTANGLE {
public:
EMRRECTANGLE ( INT left, INT top, INT right, INT bottom )
{
emr.iType = EMR_RECTANGLE;
emr.nSize = sizeof( ::EMRRECTANGLE );
rclBox.left = left;
rclBox.right = right;
rclBox.bottom = bottom;
rclBox.top = top;
}
EMRRECTANGLE ( DATASTREAM& ds )
{
ds >> emr >> rclBox;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBox;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
Rectangle( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*RECTANGLE*\n" );
edit_rectl( "rclBox", rclBox );
}
#endif /* ENABLE_EDITING */
};
class EMRELLIPSE : public METARECORD, ::EMRELLIPSE {
public:
EMRELLIPSE ( INT left, INT top, INT right, INT bottom )
{
emr.iType = EMR_ELLIPSE;
emr.nSize = sizeof( ::EMRELLIPSE );
rclBox.left = left;
rclBox.right = right;
rclBox.bottom = bottom;
rclBox.top = top;
}
EMRELLIPSE ( DATASTREAM& ds )
{
ds >> emr >> rclBox;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBox;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
Ellipse( dc, rclBox.left, rclBox.top, rclBox.right, rclBox.bottom );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*ELLIPSE*\n" );
edit_rectl( "rclBox", rclBox );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYLINE : public METARECORD, ::EMRPOLYLINE {
POINTL* lpoints{nullptr};
public:
EMRPOLYLINE ( const RECTL* bounds, const POINT* points, INT n )
{
cptl = n;
aptl[0].x = 0; // Really unused
aptl[0].y = 0;
emr.iType = EMR_POLYLINE;
// The (cptl - 1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYLINE ) + sizeof( POINTL ) * ( cptl - 1);
lpoints = new POINTL[cptl];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
~EMRPOLYLINE ( )
{
if ( lpoints ) delete[] lpoints;
}
EMRPOLYLINE ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cptl;
if ( emr.nSize - (sizeof(::EMRPOLYLINE)-sizeof(POINTL) ) <
sizeof(POINTL) * cptl ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
POINTLARRAY points( buffer.get(), cptl );
ds >> points;
lpoints = buffer.release();
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
Polyline( dc, (POINT*)lpoints, cptl );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYLINE*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_pointlarray( "\t", cptl, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYLINE16 : public METARECORD, ::EMRPOLYLINE16 {
POINT16* lpoints{ nullptr };
public:
EMRPOLYLINE16 ( const RECTL* bounds, const POINT16* points, INT n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYLINE16;
// The (cptl - 1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYLINE16 ( const RECTL* bounds, const POINT* points, INT n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYLINE16;
// The (cptl - 1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYLINE16 ) + sizeof( POINT16 ) * ( cpts - 1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
~EMRPOLYLINE16 ( )
{
if ( lpoints ) delete[] lpoints;
}
EMRPOLYLINE16 ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cpts;
if ( emr.nSize - (sizeof(::EMRPOLYLINE16)-sizeof(POINT16) ) <
sizeof(POINT16) * cpts ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
POINT16ARRAY points( buffer.get(), cpts );
ds >> points;
lpoints = buffer.release();
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
Polyline16( dc, lpoints, cpts );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYLINE16*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_point16array( "\t", cpts, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYGON : public METARECORD, ::EMRPOLYGON {
POINTL* lpoints{ nullptr };
public:
EMRPOLYGON ( const RECTL* bounds, const POINT* points, INT n )
{
cptl = n;
aptl[0].x = 0; // Really unused
aptl[0].y = 0;
emr.iType = EMR_POLYGON;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYGON ) + sizeof( POINTL ) * (cptl-1);
lpoints = new POINTL[cptl];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYGON ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cptl;
if ( emr.nSize - (sizeof(::EMRPOLYGON) - sizeof(POINTL)) <
cptl * sizeof(POINTL) ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
POINTLARRAY points( buffer.get(), cptl );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYGON ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
Polygon( dc, (POINT*)lpoints, cptl );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYGON*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_pointlarray( "\t", cptl, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYGON16 : public METARECORD, ::EMRPOLYGON16 {
POINT16* lpoints{ nullptr };
public:
EMRPOLYGON16 ( const RECTL* bounds, const POINT* points, INT16 n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYGON16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYGON16 ( const RECTL* bounds, const POINT16* points, INT16 n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYGON16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYGON16 ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cpts;
if ( emr.nSize - (sizeof(::EMRPOLYGON16) - sizeof(POINT16)) <
cpts * sizeof(POINT16) ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
POINT16ARRAY points( buffer.get(), cpts );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYGON16 ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
Polygon16( dc, lpoints, cpts );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYGON16*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_point16array( "\t", cpts, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYPOLYGON : public METARECORD, ::EMRPOLYPOLYGON {
DWORD* lcounts{ nullptr };
POINTL* lpoints{ nullptr };
public:
EMRPOLYPOLYGON ( const RECTL* bounds, const POINT* points, const INT* counts,
UINT polygons )
{
nPolys = polygons;
// Count the number of points in points
int n = 0;
for ( unsigned int i = 0; i < nPolys; i++ )
n += counts[i];
cptl = n;
aPolyCounts[0] = 0; // Really unused
aptl[0].x = 0;
aptl[0].y = 0;
emr.iType = EMR_POLYPOLYGON;
// The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
// aren't directly written out
emr.nSize = sizeof( ::EMRPOLYPOLYGON ) + sizeof( POINTL ) * (cptl-1)
+ sizeof( DWORD ) * (nPolys-1);
lcounts = new DWORD[nPolys];
for ( unsigned int i = 0; i < nPolys; i++ )
lcounts[i] = counts[i];
lpoints = new POINTL[cptl];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
~EMRPOLYPOLYGON ( )
{
if ( lcounts ) delete[] lcounts;
if ( lpoints ) delete[] lpoints;
}
EMRPOLYPOLYGON ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> nPolys >> cptl;
if ( emr.nSize - ( sizeof( ::EMRPOLYPOLYGON ) - sizeof(POINTL) - sizeof(DWORD) ) <
sizeof( POINTL ) * cptl + sizeof( DWORD ) * nPolys ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<DWORD[]> cbuffer( new DWORD[nPolys] );
DWORDARRAY counts( cbuffer.get(), nPolys );
ds >> counts;
// Counts have to add up to less than the number of points
// we have. DWORD is unsigned so we most care about overflow.
DWORD n{0}, n_old{0};
for ( DWORD c{0}; c < nPolys; ++c ) {
n_old = n;
n += cbuffer[c];
if ( n < n_old ) {
throw std::runtime_error( "Unsigned overflow" );
}
}
if ( n > cptl ) {
throw std::runtime_error( "Too few points" );
}
std::unique_ptr<POINTL[]> pbuffer( new POINTL[cptl] );
POINTLARRAY points( pbuffer.get(), cptl );
ds >> points;
// Don't do this until we won't have any more exceptions.
lcounts = cbuffer.release();
lpoints = pbuffer.release();
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << nPolys << cptl << DWORDARRAY( lcounts, nPolys )
<< POINTLARRAY( lpoints, cptl );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
// (but DWORD and INT are not)
std::vector<INT> countsv( lcounts, lcounts + nPolys );
PolyPolygon( dc, (POINT*)lpoints, countsv.data(), nPolys );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\tnPolys\t\t: %d\n";
const char* FMT1 = "\tcptl\t\t: %d\n";
const char* FMT2 = "%d\n";
const char* FMT3 = "\t\t\t %d\n";
const char* FMT4 = "%d, %d\n";
const char* FMT5 = "\t\t\t %d, %d\n";
#else
const char* FMT0 = "\tnPolys\t\t: %ld\n";
const char* FMT1 = "\tcptl\t\t: %ld\n";
const char* FMT2 = "%ld\n";
const char* FMT3 = "\t\t\t %ld\n";
const char* FMT4 = "%ld, %ld\n";
const char* FMT5 = "\t\t\t %ld, %ld\n";
#endif /* __x86_64__ */
printf( "*POLYPOLYGON*\n" );
edit_rectl( "rclBounds", rclBounds );
printf( FMT0, nPolys );
printf( FMT1, cptl );
printf( "\taPolyCounts\t: " );
if ( nPolys > 0 )
printf( FMT2, lcounts[0] );
else
puts( "" );
for ( unsigned int i = 1; i < nPolys; i++ )
printf( FMT3, lcounts[i] );
printf( "\tapts\t\t: " );
if ( cptl > 0 )
printf( FMT4, lpoints[0].x, lpoints[0].y );
else
puts( "" );
for ( unsigned int i = 1; i < cptl; i++ )
printf( FMT5, lpoints[i].x, lpoints[i].y );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYPOLYGON16 : public METARECORD, ::EMRPOLYPOLYGON16 {
DWORD* lcounts{ nullptr };
POINT16* lpoints{ nullptr };
public:
EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT* points,
const INT* counts, UINT polygons )
{
nPolys = polygons;
// Count the number of points in points
int n = 0;
for ( unsigned int i = 0; i < nPolys; i++ )
n += counts[i];
cpts = n;
aPolyCounts[0] = 0; // Really unused
apts[0].x = 0;
apts[0].y = 0;
emr.iType = EMR_POLYPOLYGON16;
// The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
// aren't directly written out
emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
+ sizeof( DWORD ) * (nPolys-1);
lcounts = new DWORD[nPolys];
for ( unsigned int i = 0; i < nPolys; i++ )
lcounts[i] = counts[i];
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYPOLYGON16 ( const RECTL* bounds, const POINT16* points,
const INT* counts, UINT16 polygons )
{
nPolys = polygons;
// Count the number of points in points
int n = 0;
for ( unsigned int i = 0; i < nPolys; i++ )
n += counts[i];
cpts = n;
aPolyCounts[0] = 0; // Really unused
apts[0].x = 0;
apts[0].y = 0;
emr.iType = EMR_POLYPOLYGON16;
// The (#-1)'s below are to account for aPolyCounts[0] and aptl[0], which
// aren't directly written out
emr.nSize = sizeof( ::EMRPOLYPOLYGON16 ) + sizeof( POINT16 ) * (cpts-1)
+ sizeof( DWORD ) * (nPolys-1);
lcounts = new DWORD[nPolys];
for ( unsigned int i = 0; i < nPolys; i++ )
lcounts[i] = counts[i];
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
~EMRPOLYPOLYGON16 ( )
{
if ( lcounts ) delete[] lcounts;
if ( lpoints ) delete[] lpoints;
}
EMRPOLYPOLYGON16 ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> nPolys >> cpts;
if ( emr.nSize - ( sizeof( ::EMRPOLYPOLYGON16 ) - sizeof(POINT16) - sizeof(DWORD) ) <
sizeof( POINT16 ) * cpts + sizeof( DWORD ) * nPolys ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<DWORD[]> cbuffer( new DWORD[nPolys] );
DWORDARRAY counts( cbuffer.get(), nPolys );
ds >> counts;
// Counts have to add up to less than the number of points
// we have. DWORD is unsigned so we most care about overflow.
DWORD n{0}, n_old{0};
for ( DWORD c{0}; c < nPolys; ++c ) {
n_old = n;
n += cbuffer[c];
if ( n < n_old ) {
throw std::runtime_error( "Unsigned overflow" );
}
}
if ( n > cpts ) {
throw std::runtime_error( "Too few points" );
}
std::unique_ptr<POINT16[]> pbuffer( new POINT16[cpts] );
POINT16ARRAY points( pbuffer.get(), cpts );
ds >> points;
lcounts = cbuffer.release();
lpoints = pbuffer.release();
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << nPolys << cpts << DWORDARRAY( lcounts, nPolys )
<< POINT16ARRAY( lpoints, cpts );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
// (but DWORD and INT are not)
std::vector<INT> counts( lcounts, lcounts + nPolys );
PolyPolygon16( dc, lpoints, counts.data(), nPolys );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\tnPolys\t\t: %d\n";
const char* FMT1 = "\tcptl\t\t: %d\n";
const char* FMT2 = "%d\n";
const char* FMT3 = "\t\t\t %d\n";
#else
const char* FMT0 = "\tnPolys\t\t: %ld\n";
const char* FMT1 = "\tcptl\t\t: %ld\n";
const char* FMT2 = "%ld\n";
const char* FMT3 = "\t\t\t %ld\n";
#endif /* __x86_64__ */
printf( "*POLYPOLYGON16*\n" );
edit_rectl( "rclBounds", rclBounds );
printf( FMT0, nPolys );
printf( FMT1, cpts );
printf( "\taPolyCounts\t: " );
if ( nPolys > 0 )
printf( FMT2, lcounts[0] );
else
puts( "" );
for ( unsigned int i = 1; i < nPolys; i++ )
printf( FMT3, lcounts[i] );
printf( "\tapts\t\t: " );
if ( cpts > 0 )
printf( "%d, %d\n", lpoints[0].x, lpoints[0].y );
else
puts( "" );
for ( unsigned int i = 1; i < cpts; i++ )
printf( "\t\t\t %d, %d\n", lpoints[i].x, lpoints[i].y );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYBEZIER : public METARECORD, ::EMRPOLYBEZIER {
POINTL* lpoints{ nullptr };
public:
EMRPOLYBEZIER ( const RECTL* bounds, const POINT* points, INT n )
{
cptl = n;
aptl[0].x = 0; // Really unused
aptl[0].y = 0;
emr.iType = EMR_POLYBEZIER;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYBEZIER ) + sizeof( POINTL ) * (cptl-1);
lpoints = new POINTL[cptl];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYBEZIER ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cptl;
if ( emr.nSize - (sizeof( ::EMRPOLYBEZIER ) - sizeof(POINTL)) <
sizeof( POINTL ) * cptl ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
POINTLARRAY points( buffer.get(), cptl );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYBEZIER ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
PolyBezier( dc, (POINT*)lpoints, cptl );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYBEZIER*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_pointlarray( "\t", cptl, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYBEZIER16 : public METARECORD, ::EMRPOLYBEZIER16 {
POINT16* lpoints{ nullptr };
public:
EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT16* points, INT n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYBEZIER16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYBEZIER16 ( const RECTL* bounds, const POINT* points, INT n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYBEZIER16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYBEZIER16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYBEZIER16 ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cpts;
if ( emr.nSize - (sizeof( ::EMRPOLYBEZIER16 ) - sizeof(POINT16)) <
sizeof( POINT16 ) * cpts ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
POINT16ARRAY points( buffer.get(), cpts );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYBEZIER16 ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
PolyBezier16( dc, lpoints, cpts );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYBEZIER16*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_point16array( "\t", cpts, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYBEZIERTO : public METARECORD, ::EMRPOLYBEZIER {
POINTL* lpoints{ nullptr };
public:
EMRPOLYBEZIERTO ( const RECTL* bounds, const POINT* points, INT n )
{
cptl = n;
aptl[0].x = 0; // Really unused
aptl[0].y = 0;
emr.iType = EMR_POLYBEZIERTO;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYBEZIERTO ) + sizeof( POINTL ) * (cptl-1);
lpoints = new POINTL[cptl];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYBEZIERTO ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cptl;
if ( emr.nSize - (sizeof( ::EMRPOLYBEZIERTO ) - sizeof(POINTL)) <
sizeof( POINTL ) * cptl ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
POINTLARRAY points( buffer.get(), cptl );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYBEZIERTO ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
PolyBezierTo( dc, (POINT*)lpoints, cptl );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYBEZIERTO*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_pointlarray( "\t", cptl, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYBEZIERTO16 : public METARECORD, ::EMRPOLYBEZIER16 {
POINT16* lpoints{ nullptr };
public:
EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT16* points, INT n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYBEZIERTO16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYBEZIERTO16 ( const RECTL* bounds, const POINT* points, INT n )
{
cpts = n;
apts[0].x = 0; // Really unused
apts[0].y = 0;
emr.iType = EMR_POLYBEZIERTO16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYBEZIERTO16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYBEZIERTO16 ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cpts;
if ( emr.nSize - (sizeof( ::EMRPOLYBEZIERTO16 ) - sizeof(POINT16)) <
sizeof( POINT16 ) * cpts ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
POINT16ARRAY points( buffer.get(), cpts );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYBEZIERTO16 ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
PolyBezierTo16( dc, lpoints, cpts );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYBEZIERTO16*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_point16array( "\t", cpts, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYLINETO : public METARECORD, ::EMRPOLYLINETO {
POINTL* lpoints{ nullptr };
public:
EMRPOLYLINETO ( const RECTL* bounds, const POINT* points, INT n )
{
cptl = n;
aptl[0].x = 0;
aptl[0].y = 0;
emr.iType = EMR_POLYLINETO;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYLINETO ) + sizeof( POINTL ) * (cptl-1);
lpoints = new POINTL[cptl];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYLINETO ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cptl;
if ( emr.nSize - (sizeof( ::EMRPOLYLINETO ) - sizeof(POINTL)) <
sizeof( POINTL ) * cptl ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINTL[]> buffer( new POINTL[cptl] );
POINTLARRAY points( buffer.get(), cptl );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYLINETO ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cptl << POINTLARRAY( lpoints, cptl );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
PolylineTo( dc, (POINT*)lpoints, cptl );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYLINETO*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_pointlarray( "\t", cptl, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMRPOLYLINETO16 : public METARECORD, ::EMRPOLYLINETO16 {
POINT16* lpoints{ nullptr };
public:
EMRPOLYLINETO16 ( const RECTL* bounds, const POINT16* points, INT n )
{
cpts = n;
apts[0].x = 0;
apts[0].y = 0;
emr.iType = EMR_POLYLINETO16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYLINETO16 ( const RECTL* bounds, const POINT* points, INT n )
{
cpts = n;
apts[0].x = 0;
apts[0].y = 0;
emr.iType = EMR_POLYLINETO16;
// The (cptl-1) below is to account for aptl, which isn't written out
emr.nSize = sizeof( ::EMRPOLYLINETO16 ) + sizeof( POINT16 ) * (cpts-1);
lpoints = new POINT16[cpts];
for (int i=0; i<n; i++) {
lpoints[i].x = points[i].x;
lpoints[i].y = points[i].y;
}
rclBounds = *bounds;
}
EMRPOLYLINETO16 ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> cpts;
if ( emr.nSize - (sizeof( ::EMRPOLYLINETO16 ) - sizeof(POINT16)) <
sizeof( POINT16 ) * cpts ) {
throw std::runtime_error( "Invalid record size" );
}
std::unique_ptr<POINT16[]> buffer( new POINT16[cpts] );
POINT16ARRAY points( buffer.get(), cpts );
ds >> points;
lpoints = buffer.release();
}
~EMRPOLYLINETO16 ( )
{
if ( lpoints ) delete[] lpoints;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << cpts << POINT16ARRAY( lpoints, cpts );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
// According to the wine windef.h header, POINT and POINTL are equivalent
PolylineTo16( dc, lpoints, cpts );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*POLYLINETO16*\n" );
edit_rectl( "rclBounds", rclBounds );
edit_point16array( "\t", cpts, lpoints );
}
#endif /* ENABLE_EDITING */
};
class EMREXTTEXTOUTA : public METARECORD, ::EMREXTTEXTOUTA {
PSTR string_a{ nullptr };
int string_size;
INT* dx_i{ nullptr };
public:
EMREXTTEXTOUTA ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
FLOAT yScale, const PEMRTEXT text, LPCSTR string,
const INT* dx )
{
emr.iType = EMR_EXTTEXTOUTA;
emr.nSize = sizeof( ::EMREXTTEXTOUTA );
rclBounds = *bounds;
iGraphicsMode = graphicsMode;
exScale = xScale;
eyScale = yScale;
emrtext = *text;
string_size = ROUND_TO_LONG( emrtext.nChars );
string_a = new CHAR[ string_size ];
memset( string_a, 0, sizeof(CHAR) * string_size );
for ( unsigned int i=0; i<emrtext.nChars; i++ )
string_a[i] = *string++;
emrtext.offString = emr.nSize;
emr.nSize += string_size * sizeof(CHAR);
#if 0
/*
Test only - Problem: Windows requires this dx to be set - at least from 2K on
but to calculate real dx values is hard
For pstoedit - this is "fixed" now by estimating dx in pstoedit
*/
if ( !dx ) {
int * dxn = new int [string_size];
for (unsigned int i=0; i < string_size; i++) dxn[i] = 10;
dx = dxn;
}
#endif
if ( dx ) {
dx_i = new INT[ emrtext.nChars ];
for ( unsigned int i=0; i<emrtext.nChars; i++ )
dx_i[i] = *dx++;
emrtext.offDx = emr.nSize;
emr.nSize += emrtext.nChars * sizeof(INT);
}
else {
emrtext.offDx = 0;
dx_i = 0;
}
}
EMREXTTEXTOUTA ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
if ( emrtext.nChars > 0 and emrtext.offString == 0 ) {
throw std::runtime_error( "Invalid text specification" );
}
if ( emrtext.nChars > emr.nSize - emrtext.offString ) {
throw std::runtime_error( "Invalid text specification" );
}
std::unique_ptr<char[]> cbuffer;
std::unique_ptr<INT[]> ibuffer;
if ( emrtext.offString != 0 ) {
string_size = ROUND_TO_LONG( emrtext.nChars );
cbuffer.reset( new char[string_size] );
memset( cbuffer.get(), 0, sizeof(CHAR) * string_size );
CHARSTR string( cbuffer.get(), string_size );
ds >> string;
}
if ( emrtext.offDx ) {
ibuffer.reset( new INT[emrtext.nChars] );
INTARRAY dx_is( ibuffer.get(), emrtext.nChars );
ds >> dx_is;
}
string_a = cbuffer.release();
dx_i = ibuffer.release();
}
~EMREXTTEXTOUTA ( )
{
if ( string_a ) delete[] string_a;
if ( dx_i ) delete[] dx_i;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
<< emrtext << CHARSTR( string_a, string_size );
if ( dx_i )
ds << INTARRAY( dx_i, emrtext.nChars );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
RECT rect;
rect.left = emrtext.rcl.left;
rect.top = emrtext.rcl.top;
rect.right = emrtext.rcl.right;
rect.bottom = emrtext.rcl.bottom;
ExtTextOutA( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
emrtext.fOptions, &rect, string_a, emrtext.nChars,
dx_i );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "unknown(%d)\n";
const char* FMT1 = "\tptlReference\t: (%d,%d)\n";
const char* FMT2 = "\tnChars\t\t: %d\n";
const char* FMT3 = "\toffString\t: %d\n";
const char* FMT4 = "\toffDx\t\t: %d\n";
#else
const char* FMT0 = "unknown(%ld)\n";
const char* FMT1 = "\tptlReference\t: (%ld,%ld)\n";
const char* FMT2 = "\tnChars\t\t: %ld\n";
const char* FMT3 = "\toffString\t: %ld\n";
const char* FMT4 = "\toffDx\t\t: %ld\n";
#endif /* __x86_64__ */
printf( "*EXTTEXTOUTA*\n" );
edit_rectl( "rclBounds", rclBounds );
printf( "\tiGraphicsMode\t: " );
switch ( iGraphicsMode ) {
case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
default: printf( FMT0, iGraphicsMode );
}
printf( "\texScale\t\t: %f\n", exScale );
printf( "\teyScale\t\t: %f\n", eyScale );
printf( FMT1, emrtext.ptlReference.x, emrtext.ptlReference.y );
printf( FMT2, emrtext.nChars );
printf( FMT3, emrtext.offString );
printf( "\tfOptions\t: " );
if ( emrtext.fOptions == 0 )
printf( "None" );
else {
if ( emrtext.fOptions & ETO_GRAYED ) {
printf( "ETO_GRAYED" );
if ( emrtext.fOptions & ~ETO_GRAYED )
printf( " | " );
}
if ( emrtext.fOptions & ETO_OPAQUE ) {
printf( "ETO_OPAQUE" );
if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_CLIPPED ) {
printf( "ETO_CLIPPED" );
if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
printf( "ETO_GLYPH_INDEX" );
if ( emrtext.fOptions &
~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_RTLREADING ) {
printf( "ETO_RTLREADING" );
if ( emrtext.fOptions &
~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
ETO_RTLREADING) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
printf( "ETO_IGNORELANGUAGE" );
}
printf( "\n" );
edit_rectl( "rcl\t", emrtext.rcl );
printf( FMT4, emrtext.offDx );
printf( "\tString:\n\t\t" );
if ( emrtext.nChars > 0 ) {
for ( DWORD i = 0; i < emrtext.nChars; ++i ) {
putchar( string_a[i] );
}
}
else {
printf( "<empty>" );
}
putchar( '\n' );
if ( emrtext.offDx != 0 ) {
printf( "\tOffsets:\n\t\t" );
for ( unsigned int i = 0; i < emrtext.nChars; i++ )
printf( "%d ", dx_i[i] );
printf( "\n" );
}
}
#endif /* ENABLE_EDITING */
};
class EMREXTTEXTOUTW : public METARECORD, ::EMREXTTEXTOUTW {
PWSTR string_a{ nullptr };
int string_size;
INT* dx_i{ nullptr };
public:
EMREXTTEXTOUTW ( const RECTL* bounds, DWORD graphicsMode, FLOAT xScale,
FLOAT yScale, const PEMRTEXT text, LPCWSTR string,
const INT* dx )
{
emr.iType = EMR_EXTTEXTOUTW;
emr.nSize = sizeof( ::EMREXTTEXTOUTW );
rclBounds = *bounds;
iGraphicsMode = graphicsMode;
exScale = xScale;
eyScale = yScale;
emrtext = *text;
string_size = ROUND_TO_LONG( emrtext.nChars );
string_a = new WCHAR[ string_size ];
memset( string_a, 0, sizeof(WCHAR) * string_size );
for ( unsigned int i=0; i<emrtext.nChars; i++ )
string_a[i] = *string++;
emrtext.offString = emr.nSize;
emr.nSize += string_size * sizeof(WCHAR);
#if 0
/*
Test only - Problem: Windows requires this dx to be set - at least from 2K on
but to calculate real dx values is hard
For pstoedit - this is "fixed" now by estimating dx in pstoedit
*/
if ( !dx ) {
int * dxn = new int [string_size];
for (unsigned int i=0; i < string_size; i++) dxn[i] = 10;
dx = dxn;
}
#endif
if ( dx ) {
dx_i = new INT[ emrtext.nChars ];
for ( unsigned int i=0; i<emrtext.nChars; i++ )
dx_i[i] = *dx++;
emrtext.offDx = emr.nSize;
emr.nSize += emrtext.nChars * sizeof(INT);
}
else {
emrtext.offDx = 0;
dx_i = 0;
}
}
EMREXTTEXTOUTW ( DATASTREAM& ds )
{
ds >> emr >> rclBounds >> iGraphicsMode >> exScale >> eyScale >> emrtext;
if ( emrtext.nChars > 0 and emrtext.offString == 0 ) {
throw std::runtime_error( "Invalid text specification" );
}
if ( emrtext.nChars > emr.nSize - emrtext.offString ) {
throw std::runtime_error( "Invalid text specification" );
}
std::unique_ptr<WCHAR[]> cbuffer;
std::unique_ptr<INT[]> ibuffer;
if ( emrtext.offString != 0 ) { // So, what is the point of this check?
string_size = ROUND_TO_LONG( emrtext.nChars );
cbuffer.reset( new WCHAR[string_size] );
memset( cbuffer.get(), 0, sizeof(WCHAR) * string_size );
WCHARSTR string( cbuffer.get(), string_size );
ds >> string;
}
if ( emrtext.offDx ) {
ibuffer.reset( new INT[ emrtext.nChars ] );
INTARRAY dx_is( ibuffer.get(), emrtext.nChars );
ds >> dx_is;
}
string_a = cbuffer.release();
dx_i = ibuffer.release();
}
~EMREXTTEXTOUTW ( )
{
if ( string_a ) delete[] string_a;
if ( dx_i ) delete[] dx_i;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds << iGraphicsMode << exScale << eyScale
<< emrtext << WCHARSTR( string_a, string_size );
if ( dx_i )
ds << INTARRAY( dx_i, emrtext.nChars );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
RECT rect;
rect.left = emrtext.rcl.left;
rect.top = emrtext.rcl.top;
rect.right = emrtext.rcl.right;
rect.bottom = emrtext.rcl.bottom;
ExtTextOutW( dc, emrtext.ptlReference.x, emrtext.ptlReference.y,
emrtext.fOptions, &rect, string_a, emrtext.nChars,
dx_i );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "unknown(%d)\n";
const char* FMT1 = "\tptlReference\t: (%d,%d)\n";
const char* FMT2 = "\tnChars\t\t: %d\n";
const char* FMT3 = "\toffString\t: %d\n";
const char* FMT4 = "\toffDx\t\t: %d\n";
#else
const char* FMT0 = "unknown(%ld)\n";
const char* FMT1 = "\tptlReference\t: (%ld,%ld)\n";
const char* FMT2 = "\tnChars\t\t: %ld\n";
const char* FMT3 = "\toffString\t: %ld\n";
const char* FMT4 = "\toffDx\t\t: %ld\n";
#endif /* __x86_64__ */
printf( "*EXTTEXTOUTW*\n" );
edit_rectl( "rclBounds", rclBounds );
printf( "\tiGraphicsMode\t: " );
switch ( iGraphicsMode ) {
case GM_COMPATIBLE: printf( "GM_COMPATIBLE\n" ); break;
case GM_ADVANCED: printf( "GM_ADVANCED\n" ); break;
default: printf( FMT0, iGraphicsMode );
}
printf( "\texScale\t\t: %f\n", exScale );
printf( "\teyScale\t\t: %f\n", eyScale );
printf( FMT1, emrtext.ptlReference.x, emrtext.ptlReference.y );
printf( FMT2, emrtext.nChars );
printf( FMT3, emrtext.offString );
printf( "\tfOptions\t: " );
if ( emrtext.fOptions == 0 )
printf( "None" );
else {
if ( emrtext.fOptions & ETO_GRAYED ) {
printf( "ETO_GRAYED" );
if ( emrtext.fOptions & ~ETO_GRAYED )
printf( " | " );
}
if ( emrtext.fOptions & ETO_OPAQUE ) {
printf( "ETO_OPAQUE" );
if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_CLIPPED ) {
printf( "ETO_CLIPPED" );
if ( emrtext.fOptions & ~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED ) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_GLYPH_INDEX ) {
printf( "ETO_GLYPH_INDEX" );
if ( emrtext.fOptions &
~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_RTLREADING ) {
printf( "ETO_RTLREADING" );
if ( emrtext.fOptions &
~(ETO_GRAYED | ETO_OPAQUE | ETO_CLIPPED | ETO_GLYPH_INDEX |
ETO_RTLREADING) )
printf( " | " );
}
if ( emrtext.fOptions & ETO_IGNORELANGUAGE )
printf( "ETO_IGNORELANGUAGE" );
}
printf( "\n" );
edit_rectl( "rcl\t", emrtext.rcl );
printf( FMT4, emrtext.offDx );
if ( emrtext.nChars > 0 ) {
// iconv_open arguments are TO, FROM (not the other way around).
iconv_t cvt = iconv_open( "UTF-8", "UTF-16LE" );
std::vector<char> utf8_buffer( emrtext.nChars );
// Cannot predict the space necessary to hold the converted
// string. So, we loop until conversion is complete.
size_t size = emrtext.nChars;
size_t in_bytes_left = emrtext.nChars * sizeof(*string_a);
size_t converted = 0;
char* in_buffer = (char*)string_a;
while ( 1 ) {
char* out_buffer = &utf8_buffer[converted];
size_t out_bytes_left = size - converted;
size_t n = iconv( cvt, &in_buffer, &in_bytes_left,
&out_buffer, &out_bytes_left );
converted = size - out_bytes_left;
if ( n == (size_t)-1 ) {
if ( errno == E2BIG ) {
size_t new_size = 2 * utf8_buffer.size();
utf8_buffer.resize( new_size );
size = utf8_buffer.size();
}
else {
// Real conversion error.
break;
}
}
else {
break;
}
}
iconv_close( cvt );
if ( converted == utf8_buffer.size() )
utf8_buffer.push_back( '\0' );
else
utf8_buffer[converted] = '\0';
printf( "\tString:\n\t\t%s\n", utf8_buffer.data() );
}
else {
puts( "\tString:\n\t\t<empty>\n" );
}
if ( emrtext.offDx != 0 and emrtext.nChars > 0 ) {
printf( "\tOffsets:\n\t\t" );
for ( unsigned int i = 0; i < emrtext.nChars; i++ )
printf( "%d ", dx_i[i] );
printf( "\n" );
}
}
#endif /* ENABLE_EDITING */
};
class EMRSETPIXELV : public METARECORD, ::EMRSETPIXELV {
public:
EMRSETPIXELV ( INT x, INT y, COLORREF color )
{
emr.iType = EMR_SETPIXELV;
emr.nSize = sizeof( ::EMRSETPIXELV );
ptlPixel.x = x;
ptlPixel.y = y;
crColor = color;
}
EMRSETPIXELV ( DATASTREAM& ds )
{
ds >> emr >> ptlPixel >> crColor;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << ptlPixel << crColor;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetPixel( dc, ptlPixel.x, ptlPixel.y, crColor );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETPIXELV*\n" );
edit_pointl( "ptlPixel", ptlPixel );
edit_color( "crColor\t", crColor );
}
#endif /* ENABLE_EDITING */
};
class PEN;
class EXTPEN;
class BRUSH;
class FONT;
class PALETTE;
class EMRCREATEPEN : public METARECORD, public ::EMRCREATEPEN
{
public:
EMRCREATEPEN ( PEN* pen, HGDIOBJ handle );
EMRCREATEPEN ( DATASTREAM& ds );
bool serialize ( DATASTREAM ds )
{
ds << emr << ihPen << lopn;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\tihPen\t\t: 0x%x\n";
const char* FMT1 = "\tlopn.lopnWidth\t: %d, %d\n";
#else
const char* FMT0 = "\tihPen\t\t: 0x%lx\n";
const char* FMT1 = "\tlopn.lopnWidth\t: %ld, %ld\n";
#endif /* __x86_64__ */
printf( "*CREATEPEN*\n" );
printf( FMT0, ihPen );
edit_pen_style( "lopn.lopnStyle", lopn.lopnStyle );
printf( FMT1, lopn.lopnWidth.x, lopn.lopnWidth.y );
edit_color( "lopn.lopnColor", lopn.lopnColor );
}
#endif /* ENABLE_EDITING */
};
class EMREXTCREATEPEN : public METARECORD, public ::EMREXTCREATEPEN
{
public:
EMREXTCREATEPEN ( EXTPEN* pen, HGDIOBJ handle );
EMREXTCREATEPEN ( DATASTREAM& ds );
bool serialize ( DATASTREAM ds )
{
ds << emr << ihPen << offBmi << cbBmi << offBits << cbBits << elp;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\tihPen\t\t\t: 0x%x\n";
const char* FMT1 = "\toffBmi\t\t\t: %d\n";
const char* FMT2 = "\tcbBmi\t\t\t: %d\n";
const char* FMT3 = "\toffBits\t\t\t: %d\n";
const char* FMT4 = "\tcbBits\t\t\t: %d\n";
const char* FMT5 = "\telp.elpWidth\t\t: %d\n";
const char* FMT6 = "\telp.elpNumEntries\t: %d\n";
#else
const char* FMT0 = "\tihPen\t\t\t: 0x%lx\n";
const char* FMT1 = "\toffBmi\t\t\t: %ld\n";
const char* FMT2 = "\tcbBmi\t\t\t: %ld\n";
const char* FMT3 = "\toffBits\t\t\t: %ld\n";
const char* FMT4 = "\tcbBits\t\t\t: %ld\n";
const char* FMT5 = "\telp.elpWidth\t\t: %ld\n";
const char* FMT6 = "\telp.elpNumEntries\t: %ld\n";
#endif /* __x86_64__ */
printf( "*EXTCREATEPEN*\n" );
printf( FMT0, ihPen );
printf( FMT1, offBmi );
printf( FMT2, cbBmi );
printf( FMT3, offBits );
printf( FMT4, cbBits );
edit_pen_style( "elp.elpPenStyle\t", elp.elpPenStyle );
printf( FMT5, elp.elpWidth );
edit_brush_style( "elp.elpBrushStyle", elp.elpBrushStyle );
edit_color( "elp.elpColor\t", elp.elpColor );
edit_brush_hatch( "elp.elpHatch\t", elp.elpHatch );
printf( FMT6, elp.elpNumEntries );
}
#endif /* ENABLE_EDITING */
};
class EMRCREATEBRUSHINDIRECT : public METARECORD, public ::EMRCREATEBRUSHINDIRECT
{
public:
EMRCREATEBRUSHINDIRECT ( BRUSH* brush, HGDIOBJ handle );
EMRCREATEBRUSHINDIRECT ( DATASTREAM& ds );
bool serialize ( DATASTREAM ds )
{
ds << emr << ihBrush << lb;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "\tihBrush\t\t: 0x%x\n";
#else
const char* FMT = "\tihBrush\t\t: 0x%lx\n";
#endif /* __x86_64__ */
printf( "*CREATEBRUSHINDIRECT*\n" );
printf( FMT, ihBrush );
edit_brush_style( "lb.lbStyle", lb.lbStyle );
edit_color( "lb.lbColor", lb.lbColor );
edit_brush_hatch( "lb.lbHatch", lb.lbHatch );
}
#endif /* ENABLE_EDITING */
};
class EMREXTCREATEFONTINDIRECTW : public METARECORD, public ::EMREXTCREATEFONTINDIRECTW
{
public:
EMREXTCREATEFONTINDIRECTW ( FONT* font, HGDIOBJ handle );
EMREXTCREATEFONTINDIRECTW ( DATASTREAM& ds );
bool serialize ( DATASTREAM ds )
{
// Since EMF records have to be multiples of 4 bytes, this
// should perhaps be a general thing, but we know it's currently
// only a problem for this structure.
ds << emr << ihFont << elfw << PADDING( 2 );
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT0 = "\tihFont\t\t\t: %d\n";
const char* FMT1 = "\tlfHeight\t\t: %d\n";
const char* FMT2 = "\tlfWidth\t\t\t: %d\n";
const char* FMT3 = "\tlfEscapement\t\t: %d\n";
const char* FMT4 = "\tlfOrientation\t\t: %d\n";
const char* FMT5 = "\telfVersion\t\t: %d\n";
const char* FMT6 = "\telfStyleSize\t\t: %d\n";
const char* FMT7 = "\telfMatch\t\t: %d\n";
const char* FMT8 = "\telfCulture\t\t: %d\n";
#else
const char* FMT0 = "\tihFont\t\t\t: %ld\n";
const char* FMT1 = "\tlfHeight\t\t: %ld\n";
const char* FMT2 = "\tlfWidth\t\t\t: %ld\n";
const char* FMT3 = "\tlfEscapement\t\t: %ld\n";
const char* FMT4 = "\tlfOrientation\t\t: %ld\n";
const char* FMT5 = "\telfVersion\t\t: %ld\n";
const char* FMT6 = "\telfStyleSize\t\t: %ld\n";
const char* FMT7 = "\telfMatch\t\t: %ld\n";
const char* FMT8 = "\telfCulture\t\t: %ld\n";
#endif /* __x86_64__ */
printf( "*EXTCREATEFONTINDIRECTW*\n" );
printf( FMT0, ihFont );
printf( FMT1, elfw.elfLogFont.lfHeight );
printf( FMT2, elfw.elfLogFont.lfWidth );
printf( FMT3, elfw.elfLogFont.lfEscapement );
printf( FMT4, elfw.elfLogFont.lfOrientation );
printf( "\tlfWeight\t\t: " );
switch ( elfw.elfLogFont.lfWeight ) {
case FW_DONTCARE: printf( "FW_DONTCARE\n" ); break;
case FW_THIN: printf( "FW_THIN\n" ); break;
case FW_EXTRALIGHT: printf( "FW_EXTRALIGHT\n" ); break;
case FW_LIGHT: printf( "FW_LIGHT\n" ); break;
case FW_NORMAL: printf( "FW_NORMAL\n" ); break;
case FW_MEDIUM: printf( "FW_MEDIUM\n" ); break;
case FW_SEMIBOLD: printf( "FW_SEMIBOLD\n" ); break;
case FW_BOLD: printf( "FW_BOLD\n" ); break;
case FW_EXTRABOLD: printf( "FW_EXTRABOLD\n" ); break;
case FW_BLACK: printf( "FW_BLACK\n" ); break;
}
printf( "\tlfItalic\t\t: %d\n", elfw.elfLogFont.lfItalic );
printf( "\tlfUnderline\t\t: %d\n", elfw.elfLogFont.lfUnderline );
printf( "\tlfStrikeOut\t\t: %d\n", elfw.elfLogFont.lfStrikeOut );
printf( "\tlfCharSet\t\t: %d\n", elfw.elfLogFont.lfCharSet );
printf( "\tlfOutPrecision\t\t: %d\n", elfw.elfLogFont.lfOutPrecision );
printf( "\tlfClipPrecision\t\t: %d\n", elfw.elfLogFont.lfClipPrecision );
printf( "\tlfQuality\t\t: %d\n", elfw.elfLogFont.lfQuality );
printf( "\tlfPitchAndFamily\t: %d\n", elfw.elfLogFont.lfPitchAndFamily );
int i = 0;
printf( "\tlfFaceName\t\t: '" );
while ( elfw.elfLogFont.lfFaceName[i] != 0 && i < LF_FACESIZE ) {
putchar( elfw.elfLogFont.lfFaceName[i] );
i++;
}
puts( "'" );
i = 0;
printf( "\telfFullName\t\t: '" );
while ( elfw.elfFullName[i] != 0 && i < LF_FULLFACESIZE ) {
putchar( elfw.elfFullName[i] );
i++;
}
puts( "'" );
i = 0;
printf( "\telfStyle\t\t: '" );
while ( elfw.elfStyle[i] != 0 && i < LF_FACESIZE ) {
putchar( elfw.elfStyle[i] );
i++;
}
puts( "'" );
printf( FMT5, elfw.elfVersion );
printf( FMT6, elfw.elfStyleSize );
printf( FMT7, elfw.elfMatch );
printf( "\telfVendorId\t\t: '%s'\n", elfw.elfVendorId );
printf( FMT8, elfw.elfCulture );
printf( "\telfPanose\t\t:\n" );
printf( "\t\tbFamilyType\t\t: %d\n", elfw.elfPanose.bFamilyType );
printf( "\t\tbSerifStyle\t\t: %d\n", elfw.elfPanose.bSerifStyle );
printf( "\t\tbWeight\t\t\t: %d\n", elfw.elfPanose.bWeight );
printf( "\t\tbProportion\t\t: %d\n", elfw.elfPanose.bProportion );
printf( "\t\tbContrast\t\t: %d\n", elfw.elfPanose.bContrast );
printf( "\t\tbStrokeVariation\t: %d\n", elfw.elfPanose.bStrokeVariation );
printf( "\t\tbArmStyle\t\t: %d\n", elfw.elfPanose.bArmStyle );
printf( "\t\tbLetterform\t\t: %d\n", elfw.elfPanose.bLetterform );
printf( "\t\tbMidline\t\t: %d\n", elfw.elfPanose.bMidline );
printf( "\t\tbXHeight\t\t: %d\n", elfw.elfPanose.bXHeight );
}
#endif /* ENABLE_EDITING */
};
class EMRCREATEPALETTE : public METARECORD, public ::EMRCREATEPALETTE
{
public:
EMRCREATEPALETTE ( PALETTE* palette, HGDIOBJ handle );
EMRCREATEPALETTE ( DATASTREAM& ds );
bool serialize ( DATASTREAM ds )
{
ds << emr << ihPal << lgpl;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const;
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*CREATEPALETTE* (not really handled by libEMF)\n" );
}
#endif /* ENABLE_EDITING */
};
class EMRFILLPATH : public METARECORD, ::EMRFILLPATH {
public:
EMRFILLPATH ( const RECTL* bounds )
{
emr.iType = EMR_FILLPATH;
emr.nSize = sizeof( ::EMRFILLPATH );
rclBounds = *bounds;
}
EMRFILLPATH ( DATASTREAM& ds )
{
ds >> emr >> rclBounds;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
FillPath( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*FILLPATH*\n" );
edit_rectl( "rclBounds", rclBounds );
}
#endif /* ENABLE_EDITING */
};
class EMRSTROKEPATH : public METARECORD, ::EMRSTROKEPATH {
public:
EMRSTROKEPATH ( const RECTL* bounds )
{
emr.iType = EMR_STROKEPATH;
emr.nSize = sizeof( ::EMRSTROKEPATH );
rclBounds = *bounds;
}
EMRSTROKEPATH ( DATASTREAM& ds )
{
ds >> emr >> rclBounds;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
StrokePath( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*STROKEPATH*\n" );
edit_rectl( "rclBounds", rclBounds );
}
#endif /* ENABLE_EDITING */
};
class EMRSTROKEANDFILLPATH : public METARECORD, ::EMRSTROKEANDFILLPATH {
public:
EMRSTROKEANDFILLPATH ( const RECTL* bounds )
{
emr.iType = EMR_STROKEANDFILLPATH;
emr.nSize = sizeof( ::EMRSTROKEANDFILLPATH );
rclBounds = *bounds;
}
EMRSTROKEANDFILLPATH ( DATASTREAM& ds )
{
ds >> emr >> rclBounds;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << rclBounds;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
StrokeAndFillPath( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*STROKEANDFILLPATH*\n" );
edit_rectl( "rclBounds", rclBounds );
}
#endif /* ENABLE_EDITING */
};
class EMRBEGINPATH : public METARECORD, ::EMRBEGINPATH {
public:
EMRBEGINPATH ( void )
{
emr.iType = EMR_BEGINPATH;
emr.nSize = sizeof( ::EMRBEGINPATH );
}
EMRBEGINPATH ( DATASTREAM& ds )
{
ds >> emr;
}
bool serialize ( DATASTREAM ds )
{
ds << emr;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
BeginPath( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*BEGINPATH*\n" );
}
#endif /* ENABLE_EDITING */
};
class EMRENDPATH : public METARECORD, ::EMRENDPATH {
public:
EMRENDPATH ( void )
{
emr.iType = EMR_ENDPATH;
emr.nSize = sizeof( ::EMRENDPATH );
}
EMRENDPATH ( DATASTREAM& ds )
{
ds >> emr;
}
bool serialize ( DATASTREAM ds )
{
ds << emr;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
EndPath( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*ENDPATH*\n" );
}
#endif /* ENABLE_EDITING */
};
class EMRCLOSEFIGURE : public METARECORD, ::EMRCLOSEFIGURE {
public:
EMRCLOSEFIGURE ( void )
{
emr.iType = EMR_CLOSEFIGURE;
emr.nSize = sizeof( ::EMRCLOSEFIGURE );
}
EMRCLOSEFIGURE ( DATASTREAM& ds )
{
ds >> emr;
}
bool serialize ( DATASTREAM ds )
{
ds << emr;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
CloseFigure( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*CLOSEFIGURE*\n" );
}
#endif /* ENABLE_EDITING */
};
class EMRSAVEDC : public METARECORD, ::EMRSAVEDC {
public:
EMRSAVEDC ( void )
{
emr.iType = EMR_SAVEDC;
emr.nSize = sizeof( ::EMRSAVEDC );
}
EMRSAVEDC ( DATASTREAM& ds )
{
ds >> emr;
}
bool serialize ( DATASTREAM ds )
{
ds << emr;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SaveDC( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SAVEDC*\n" );
}
#endif /* ENABLE_EDITING */
};
class EMRRESTOREDC : public METARECORD, ::EMRRESTOREDC {
public:
EMRRESTOREDC ( INT n )
{
emr.iType = EMR_RESTOREDC;
emr.nSize = sizeof( ::EMRRESTOREDC );
iRelative = n;
}
EMRRESTOREDC ( DATASTREAM& ds )
{
ds >> emr >> iRelative;
}
bool serialize ( DATASTREAM ds )
{
ds << emr << iRelative;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
RestoreDC( dc, iRelative );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
#if defined(__LP64__)
const char* FMT = "\tiRelative: %d\n";
#else
const char* FMT = "\tiRelative: %ld\n";
#endif /* __x86_64__ */
printf( "*RESTOREDC*\n" );
printf( FMT, iRelative );
}
#endif /* ENABLE_EDITING */
};
class EMRSETMETARGN : public METARECORD, ::EMRSETMETARGN {
public:
EMRSETMETARGN ( void )
{
emr.iType = EMR_SETMETARGN;
emr.nSize = sizeof( ::EMRSETMETARGN );
}
EMRSETMETARGN ( DATASTREAM& ds )
{
ds >> emr;
}
bool serialize ( DATASTREAM ds )
{
ds << emr;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetMetaRgn( dc );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETMETARGN*\n" );
}
#endif /* ENABLE_EDITING */
};
class PEN : public GRAPHICSOBJECT, public LOGPEN {
public:
PEN ( const LOGPEN* lpen )
{
lopnStyle = lpen->lopnStyle;
lopnWidth = lpen->lopnWidth;
lopnColor = lpen->lopnColor;
}
OBJECTTYPE getType ( void ) const { return O_PEN; }
METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
{
contexts[dc] = emf_handle;
return new EMRCREATEPEN( this, emf_handle );
}
};
class EXTPEN : public GRAPHICSOBJECT, public EXTLOGPEN {
public:
EXTPEN ( const EXTLOGPEN* lpen )
{
elpPenStyle = lpen->elpPenStyle;
elpWidth = lpen->elpWidth;
elpBrushStyle = lpen->elpBrushStyle;
elpColor = lpen->elpColor;
elpHatch = lpen->elpHatch;
elpNumEntries = 0;
elpStyleEntry[0] = 0;
}
OBJECTTYPE getType ( void ) const { return O_EXTPEN; }
METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
{
contexts[dc] = emf_handle;
return new EMREXTCREATEPEN( this, emf_handle );
}
};
class BRUSH : public GRAPHICSOBJECT, public LOGBRUSH {
public:
BRUSH ( const LOGBRUSH* lbrush )
{
lbStyle = lbrush->lbStyle;
lbColor = lbrush->lbColor;
lbHatch = lbrush->lbHatch;
}
OBJECTTYPE getType ( void ) const { return O_BRUSH; }
METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
{
contexts[dc] = emf_handle;
return new EMRCREATEBRUSHINDIRECT( this, emf_handle );
}
};
class FONT : public GRAPHICSOBJECT, public EXTLOGFONTW {
public:
FONT ( const LOGFONTW* lfont )
{
this->elfLogFont = *lfont;
// There are a lot more entries in the EXTLOGFONTW structure than
// the API has values for, so we invent them here
memset( &elfFullName, 0, sizeof elfFullName );
memset( &elfStyle, 0, sizeof elfStyle );
elfVersion = ELF_VERSION;
elfStyleSize = 0;
elfMatch = 0;
elfReserved = 0;
memset( &elfVendorId, 0, sizeof elfVendorId );
elfCulture = ELF_CULTURE_LATIN;
memset( &elfPanose, 1, sizeof(PANOSE) );
}
OBJECTTYPE getType ( void ) const { return O_FONT; }
METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
{
contexts[dc] = emf_handle;
return new EMREXTCREATEFONTINDIRECTW( this, emf_handle );
}
};
class PALETTE : public GRAPHICSOBJECT, public LOGPALETTE {
public:
PALETTE ( const LOGPALETTE* lpalette )
{
EMF_UNUSED(lpalette);
palVersion = 0;
palNumEntries = 0;
PALETTEENTRY zero_entry = { 0, 0, 0, 0 };
palPalEntry[0] = zero_entry;
}
OBJECTTYPE getType ( void ) const { return O_PALETTE; }
METARECORD* newEMR ( HDC dc, HGDIOBJ emf_handle )
{
contexts[dc] = emf_handle;
return new EMRCREATEPALETTE( this, emf_handle );
}
};
class EMRSETMITERLIMIT : public METARECORD, ::EMRSETMITERLIMIT {
public:
EMRSETMITERLIMIT ( FLOAT limit )
{
emr.iType = EMR_SETMITERLIMIT;
emr.nSize = sizeof( ::EMRSETMITERLIMIT );
eMiterLimit = limit;
}
EMRSETMITERLIMIT ( DATASTREAM& ds )
{
int miter_limit;
ds >> emr >> miter_limit;
eMiterLimit = float(miter_limit);
}
bool serialize ( DATASTREAM ds )
{
ds << emr << (int)eMiterLimit;
return true;
}
int size ( void ) const { return emr.nSize; }
void execute ( METAFILEDEVICECONTEXT* source, HDC dc ) const
{
EMF_UNUSED(source);
SetMiterLimit( dc, eMiterLimit, 0 );
}
#ifdef ENABLE_EDITING
void edit ( void ) const
{
printf( "*SETMITERLIMIT*\n" );
printf( "\teMiterLimit\t: %f\n", eMiterLimit );
}
#endif /* ENABLE_EDITING */
};
class METAFILEDEVICECONTEXT : public OBJECT {
void init ( const RECT* size, LPCWSTR description_w ) {
// Evidently, metafile handles are numbered from 1, so don't
// ever use 0.
handles.push_back( true );
// Keep some of our graphics state in a header record
header = new ENHMETAHEADER ( description_w );
records.push_back( header );
// Compute the size and position of the metafile on the "page"
if ( size ) {
update_frame = false;
header->rclFrame.left = size->left;
header->rclFrame.top = size->top;
header->rclFrame.right = size->right;
header->rclFrame.bottom = size->bottom;
header->rclBounds.left =
size->left * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
header->rclBounds.top =
size->top * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
header->rclBounds.right =
size->right * header->szlDevice.cx / ( header->szlMillimeters.cx * 100 );
header->rclBounds.bottom =
size->bottom * header->szlDevice.cy / ( header->szlMillimeters.cy * 100 );
}
else {
update_frame = true;
header->rclBounds.left = -10;
header->rclBounds.top = -10;
header->rclBounds.right = 10;
header->rclBounds.bottom = 10;
header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
header->szlMillimeters.cx * 100 / header->szlDevice.cx );
header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
header->szlMillimeters.cy * 100 / header->szlDevice.cy );
header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
header->szlMillimeters.cx * 100 / header->szlDevice.cx );
header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
header->szlMillimeters.cy * 100 / header->szlDevice.cy );
}
// Some default graphics state (are they really, though?)
SIZEL default_resolution = { RESOLUTION, RESOLUTION };
resolution = default_resolution;
SIZEL default_viewport_ext = { 1, 1 };
viewport_ext = default_viewport_ext;
POINT default_viewport_org = { 0, 0 };
viewport_org = default_viewport_org;
SIZEL default_window_ext = { 1, 1 };
window_ext = default_window_ext;
POINT default_window_org = { 0, 0 };
window_org = default_window_org;
min_device_point = viewport_org;
max_device_point = viewport_org;
pen = (PEN*)globalObjects.find( BLACK_PEN | ENHMETA_STOCK_OBJECT );
brush = (BRUSH*)globalObjects.find( BLACK_BRUSH | ENHMETA_STOCK_OBJECT );
font = (FONT*)globalObjects.find( DEVICE_DEFAULT_FONT | ENHMETA_STOCK_OBJECT);
palette = (PALETTE*)globalObjects.find( DEFAULT_PALETTE|ENHMETA_STOCK_OBJECT);
text_alignment = TA_BASELINE;
text_color = RGB(0,0,0);
bk_color = RGB(0xff,0xff,0xff);
bk_mode = OPAQUE;
polyfill_mode = ALTERNATE;
map_mode = MM_TEXT;
miter_limit = 10.f;
handle = globalObjects.add( this );
}
public:
::FILE* fp;
DATASTREAM ds;
ENHMETAHEADER* header;
std::vector< EMF::METARECORD* > records;
// Keep a small set of graphics state information
SIZEL resolution;
SIZEL viewport_ext;
POINT viewport_org;
SIZEL window_ext;
POINT window_org;
bool update_frame;
POINT min_device_point;
POINT max_device_point;
POINT point;
PEN* pen;
BRUSH* brush;
FONT* font;
PALETTE* palette;
UINT text_alignment;
COLORREF text_color;
COLORREF bk_color;
INT bk_mode;
INT polyfill_mode;
INT map_mode;
FLOAT miter_limit;
std::vector< bool > handles;
std::map< HGDIOBJ, HGDIOBJ > emf_handles;
METAFILEDEVICECONTEXT ( FILE* fp_, const RECT* size,
LPCWSTR description_w )
: fp(fp_), ds( fp_ )
{
init( size, description_w );
}
virtual ~METAFILEDEVICECONTEXT ( )
{
// Purge all the metarecords (if there are any) {this include the
// header record, too}
if ( records.size() > 0 )
deleteMetafile();
}
OBJECTTYPE getType ( void ) const { return O_METAFILEDEVICECONTEXT; }
DWORD nextHandle ( void )
{
for ( unsigned int i = 1; i < handles.size(); i++ ) {
if ( !handles[i] ) {
handles[i] = true;
return i;
}
}
handles.push_back( true );
// Well, it appears that even StockObject handles count for something.
// Not sure what the right value here is, then.
header->nHandles = handles.size();
return handles.size()-1;
}
void clearHandle ( DWORD handle )
{
if ( handle < handles.size() ) {
handles[handle] = false;
}
}
void appendRecord ( METARECORD* record )
{
records.push_back( record );
header->nBytes += record->size();
header->nRecords++;
}
void appendHandle ( METARECORD* record )
{
records.push_back( record );
header->nBytes += record->size();
header->nRecords++;
}
void deleteMetafile ( void )
{
for ( auto r = records.begin(); r != records.end(); r++ ) {
delete *r;
}
records.clear();
}
void mergePoint ( const LONG& x, const LONG& y )
{
POINT p;
p.x = x;
p.y = y;
mergePoint( p );
}
void mergePoint( const POINT& p )
{
POINT device_point;
// *** Note, it's possible for the global transformation matrix to
// affect this too. ***
int window_width = window_ext.cx <= 0 ? 1 : window_ext.cx;
int window_height = window_ext.cy <= 0 ? 1 : window_ext.cy;
device_point.x = (LONG)( (float)( p.x - window_org.x ) / window_width *
viewport_ext.cx + viewport_org.x );
device_point.y = (LONG)( (float)( p.y - window_org.y ) / window_height *
viewport_ext.cy + viewport_org.y );
// If the user didn't specify a bounding rectangle in the constructor,
// compute one from this data, too.
if ( device_point.x < min_device_point.x ) {
min_device_point.x = device_point.x;
if ( update_frame ) {
header->rclBounds.left = min_device_point.x - 10;
int device_width = header->szlDevice.cx <= 0 ? 1 : header->szlDevice.cx;
header->rclFrame.left = (LONG)floor( (float)header->rclBounds.left *
header->szlMillimeters.cx * 100 / device_width );
}
}
else if ( device_point.x > max_device_point.x ) {
max_device_point.x = device_point.x;
if ( update_frame ) {
header->rclBounds.right = max_device_point.x + 10;
int device_width = header->szlDevice.cx <= 0 ? 1 : header->szlDevice.cx;
header->rclFrame.right = (LONG)ceil( (float)header->rclBounds.right *
header->szlMillimeters.cx * 100 / device_width );
}
}
if ( device_point.y < min_device_point.y ) {
min_device_point.y = device_point.y;
if ( update_frame ) {
header->rclBounds.top = min_device_point.y - 10;
int device_height = header->szlDevice.cy <= 0 ? 1 : header->szlDevice.cy;
header->rclFrame.top = (LONG)floor( (float)header->rclBounds.top *
header->szlMillimeters.cy * 100 / device_height );
}
}
else if ( device_point.y > max_device_point.y ) {
max_device_point.y = device_point.y;
if ( update_frame ) {
header->rclBounds.bottom = max_device_point.y + 10;
int device_height = header->szlDevice.cy <= 0 ? 1 : header->szlDevice.cy;
header->rclFrame.bottom = (LONG)ceil( (float)header->rclBounds.bottom *
header->szlMillimeters.cy * 100 / device_height );
}
}
}
};
} // close EMF namespace
#undef EMF_UNUSED
#endif /* _LIBEMF_H */
EMF::BRUSH
Graphics Brush.
Definition libemf.h:6191
EMF::BRUSH::getType
OBJECTTYPE getType(void) const
Definition libemf.h:6205
EMF::BRUSH::BRUSH
BRUSH(const LOGBRUSH *lbrush)
Definition libemf.h:6196
EMF::BRUSH::newEMR
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition libemf.h:6212
EMF::DATASTREAM
Support different endian modes when reading and writing the metafile.
Definition libemf.h:225
EMF::DATASTREAM::setStream
void setStream(::FILE *fp)
Definition libemf.h:239
EMF::DATASTREAM::operator>>
DATASTREAM & operator>>(BYTE &byte)
Definition libemf.h:253
EMF::DATASTREAM::DATASTREAM
DATASTREAM(::FILE *fp=0)
Definition libemf.h:234
EMF::DATASTREAM::operator<<
DATASTREAM & operator<<(const BYTE &byte)
Definition libemf.h:244
EMF::EMRARCTO::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3048
EMF::EMRARCTO::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3034
EMF::EMRARCTO::EMRARCTO
EMRARCTO(INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition libemf.h:3009
EMF::EMRARCTO::EMRARCTO
EMRARCTO(DATASTREAM &ds)
Definition libemf.h:3027
EMF::EMRARCTO::size
int size(void) const
Definition libemf.h:3042
EMF::EMRARC::EMRARC
EMRARC(INT left, INT top, INT right, INT bottom, INT xstart, INT ystart, INT xend, INT yend)
Definition libemf.h:2933
EMF::EMRARC::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2958
EMF::EMRARC::EMRARC
EMRARC(DATASTREAM &ds)
Definition libemf.h:2951
EMF::EMRARC::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2972
EMF::EMRARC::size
int size(void) const
Definition libemf.h:2966
EMF::EMRBEGINPATH::EMRBEGINPATH
EMRBEGINPATH(DATASTREAM &ds)
Definition libemf.h:5804
EMF::EMRBEGINPATH::EMRBEGINPATH
EMRBEGINPATH(void)
Definition libemf.h:5795
EMF::EMRBEGINPATH::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5825
EMF::EMRBEGINPATH::size
int size(void) const
Definition libemf.h:5819
EMF::EMRBEGINPATH::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5811
EMF::EMRCLOSEFIGURE::size
int size(void) const
Definition libemf.h:5927
EMF::EMRCLOSEFIGURE::EMRCLOSEFIGURE
EMRCLOSEFIGURE(DATASTREAM &ds)
Definition libemf.h:5912
EMF::EMRCLOSEFIGURE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5933
EMF::EMRCLOSEFIGURE::EMRCLOSEFIGURE
EMRCLOSEFIGURE(void)
Definition libemf.h:5903
EMF::EMRCLOSEFIGURE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5919
EMF::EMRCREATEBRUSHINDIRECT
EMF Brush.
Definition libemf.h:5384
EMF::EMRCREATEBRUSHINDIRECT::size
int size(void) const
Definition libemf.h:5407
EMF::EMRCREATEBRUSHINDIRECT::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5399
EMF::EMRCREATEBRUSHINDIRECT::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.cpp:633
EMF::EMRCREATEBRUSHINDIRECT::EMRCREATEBRUSHINDIRECT
EMRCREATEBRUSHINDIRECT(BRUSH *brush, HGDIOBJ handle)
Definition libemf.cpp:625
EMF::EMRCREATEPALETTE
EMF Palette.
Definition libemf.h:5577
EMF::EMRCREATEPALETTE::EMRCREATEPALETTE
EMRCREATEPALETTE(PALETTE *palette, HGDIOBJ handle)
Definition libemf.cpp:680
EMF::EMRCREATEPALETTE::size
int size(void) const
Definition libemf.h:5600
EMF::EMRCREATEPALETTE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5592
EMF::EMRCREATEPALETTE::EMRCREATEPALETTE
EMRCREATEPALETTE(DATASTREAM &ds)
EMF::EMRCREATEPALETTE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.cpp:688
EMF::EMRCREATEPEN
EMF Pen.
Definition libemf.h:5252
EMF::EMRCREATEPEN::EMRCREATEPEN
EMRCREATEPEN(PEN *pen, HGDIOBJ handle)
Definition libemf.cpp:532
EMF::EMRCREATEPEN::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.cpp:575
EMF::EMRCREATEPEN::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5267
EMF::EMRCREATEPEN::size
int size(void) const
Definition libemf.h:5275
EMF::EMRDELETEOBJECT::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2766
EMF::EMRDELETEOBJECT::EMRDELETEOBJECT
EMRDELETEOBJECT(DATASTREAM &ds)
Definition libemf.h:2759
EMF::EMRDELETEOBJECT::EMRDELETEOBJECT
EMRDELETEOBJECT(HGDIOBJ object)
Definition libemf.h:2749
EMF::EMRDELETEOBJECT::size
int size(void) const
Definition libemf.h:2774
EMF::EMRDELETEOBJECT::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.cpp:555
EMF::EMRELLIPSE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3178
EMF::EMRELLIPSE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3164
EMF::EMRELLIPSE::EMRELLIPSE
EMRELLIPSE(INT left, INT top, INT right, INT bottom)
Definition libemf.h:3144
EMF::EMRELLIPSE::size
int size(void) const
Definition libemf.h:3172
EMF::EMRELLIPSE::EMRELLIPSE
EMRELLIPSE(DATASTREAM &ds)
Definition libemf.h:3157
EMF::EMRENDPATH::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5865
EMF::EMRENDPATH::size
int size(void) const
Definition libemf.h:5873
EMF::EMRENDPATH::EMRENDPATH
EMRENDPATH(void)
Definition libemf.h:5849
EMF::EMRENDPATH::EMRENDPATH
EMRENDPATH(DATASTREAM &ds)
Definition libemf.h:5858
EMF::EMRENDPATH::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5879
EMF::EMREOF::size
int size(void) const
Definition libemf.h:1711
EMF::EMREOF::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:1703
EMF::EMREOF::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:1717
EMF::EMREOF::EMREOF
EMREOF(DATASTREAM &ds)
Definition libemf.h:1695
EMF::EMREOF::EMREOF
EMREOF(void)
Definition libemf.h:1682
EMF::EMREXTCREATEFONTINDIRECTW
EMF Font.
Definition libemf.h:5439
EMF::EMREXTCREATEFONTINDIRECTW::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5454
EMF::EMREXTCREATEFONTINDIRECTW::size
int size(void) const
Definition libemf.h:5467
EMF::EMREXTCREATEFONTINDIRECTW::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.cpp:666
EMF::EMREXTCREATEFONTINDIRECTW::EMREXTCREATEFONTINDIRECTW
EMREXTCREATEFONTINDIRECTW(FONT *font, HGDIOBJ handle)
Definition libemf.cpp:652
EMF::EMREXTCREATEPEN
EMF Extended Pen.
Definition libemf.h:5310
EMF::EMREXTCREATEPEN::size
int size(void) const
Definition libemf.h:5333
EMF::EMREXTCREATEPEN::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.cpp:600
EMF::EMREXTCREATEPEN::EMREXTCREATEPEN
EMREXTCREATEPEN(EXTPEN *pen, HGDIOBJ handle)
Definition libemf.cpp:588
EMF::EMREXTCREATEPEN::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5325
EMF::EMREXTTEXTOUTA::EMREXTTEXTOUTA
EMREXTTEXTOUTA(DATASTREAM &ds)
Definition libemf.h:4722
EMF::EMREXTTEXTOUTA::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:4772
EMF::EMREXTTEXTOUTA::~EMREXTTEXTOUTA
~EMREXTTEXTOUTA()
Definition libemf.h:4764
EMF::EMREXTTEXTOUTA::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:4789
EMF::EMREXTTEXTOUTA::size
int size(void) const
Definition libemf.h:4783
EMF::EMREXTTEXTOUTA::EMREXTTEXTOUTA
EMREXTTEXTOUTA(const RECTL *bounds, DWORD graphicsMode, FLOAT xScale, FLOAT yScale, const PEMRTEXT text, LPCSTR string, const INT *dx)
Definition libemf.h:4664
EMF::EMREXTTEXTOUTW::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5020
EMF::EMREXTTEXTOUTW::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5037
EMF::EMREXTTEXTOUTW::~EMREXTTEXTOUTW
~EMREXTTEXTOUTW()
Definition libemf.h:5012
EMF::EMREXTTEXTOUTW::EMREXTTEXTOUTW
EMREXTTEXTOUTW(const RECTL *bounds, DWORD graphicsMode, FLOAT xScale, FLOAT yScale, const PEMRTEXT text, LPCWSTR string, const INT *dx)
Definition libemf.h:4912
EMF::EMREXTTEXTOUTW::size
int size(void) const
Definition libemf.h:5031
EMF::EMREXTTEXTOUTW::EMREXTTEXTOUTW
EMREXTTEXTOUTW(DATASTREAM &ds)
Definition libemf.h:4970
EMF::EMRFILLPATH::EMRFILLPATH
EMRFILLPATH(DATASTREAM &ds)
Definition libemf.h:5637
EMF::EMRFILLPATH::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5644
EMF::EMRFILLPATH::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5658
EMF::EMRFILLPATH::size
int size(void) const
Definition libemf.h:5652
EMF::EMRFILLPATH::EMRFILLPATH
EMRFILLPATH(const RECTL *bounds)
Definition libemf.h:5627
EMF::EMRLINETO::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2885
EMF::EMRLINETO::EMRLINETO
EMRLINETO(DATASTREAM &ds)
Definition libemf.h:2878
EMF::EMRLINETO::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2899
EMF::EMRLINETO::EMRLINETO
EMRLINETO(INT x, INT y)
Definition libemf.h:2867
EMF::EMRLINETO::size
int size(void) const
Definition libemf.h:2893
EMF::EMRMODIFYWORLDTRANSFORM::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2184
EMF::EMRMODIFYWORLDTRANSFORM::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2170
EMF::EMRMODIFYWORLDTRANSFORM::EMRMODIFYWORLDTRANSFORM
EMRMODIFYWORLDTRANSFORM(DATASTREAM &ds)
Definition libemf.h:2163
EMF::EMRMODIFYWORLDTRANSFORM::size
int size(void) const
Definition libemf.h:2178
EMF::EMRMODIFYWORLDTRANSFORM::EMRMODIFYWORLDTRANSFORM
EMRMODIFYWORLDTRANSFORM(const XFORM *transform, DWORD mode)
Definition libemf.h:2152
EMF::EMRMOVETOEX::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2840
EMF::EMRMOVETOEX::EMRMOVETOEX
EMRMOVETOEX(INT x, INT y)
Definition libemf.h:2808
EMF::EMRMOVETOEX::size
int size(void) const
Definition libemf.h:2834
EMF::EMRMOVETOEX::EMRMOVETOEX
EMRMOVETOEX(DATASTREAM &ds)
Definition libemf.h:2819
EMF::EMRMOVETOEX::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2826
EMF::EMRPOLYBEZIER16::size
int size(void) const
Definition libemf.h:4188
EMF::EMRPOLYBEZIER16::EMRPOLYBEZIER16
EMRPOLYBEZIER16(DATASTREAM &ds)
Definition libemf.h:4153
EMF::EMRPOLYBEZIER16::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:4194
EMF::EMRPOLYBEZIER16::~EMRPOLYBEZIER16
~EMRPOLYBEZIER16()
Definition libemf.h:4173
EMF::EMRPOLYBEZIER16::EMRPOLYBEZIER16
EMRPOLYBEZIER16(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:4130
EMF::EMRPOLYBEZIER16::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:4180
EMF::EMRPOLYBEZIER16::EMRPOLYBEZIER16
EMRPOLYBEZIER16(const RECTL *bounds, const POINT16 *points, INT n)
Definition libemf.h:4105
EMF::EMRPOLYBEZIERTO16::EMRPOLYBEZIERTO16
EMRPOLYBEZIERTO16(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:4345
EMF::EMRPOLYBEZIERTO16::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:4395
EMF::EMRPOLYBEZIERTO16::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:4409
EMF::EMRPOLYBEZIERTO16::EMRPOLYBEZIERTO16
EMRPOLYBEZIERTO16(DATASTREAM &ds)
Definition libemf.h:4368
EMF::EMRPOLYBEZIERTO16::size
int size(void) const
Definition libemf.h:4403
EMF::EMRPOLYBEZIERTO16::EMRPOLYBEZIERTO16
EMRPOLYBEZIERTO16(const RECTL *bounds, const POINT16 *points, INT n)
Definition libemf.h:4320
EMF::EMRPOLYBEZIERTO16::~EMRPOLYBEZIERTO16
~EMRPOLYBEZIERTO16()
Definition libemf.h:4388
EMF::EMRPOLYBEZIERTO::~EMRPOLYBEZIERTO
~EMRPOLYBEZIERTO()
Definition libemf.h:4268
EMF::EMRPOLYBEZIERTO::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:4289
EMF::EMRPOLYBEZIERTO::size
int size(void) const
Definition libemf.h:4283
EMF::EMRPOLYBEZIERTO::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:4275
EMF::EMRPOLYBEZIERTO::EMRPOLYBEZIERTO
EMRPOLYBEZIERTO(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:4225
EMF::EMRPOLYBEZIERTO::EMRPOLYBEZIERTO
EMRPOLYBEZIERTO(DATASTREAM &ds)
Definition libemf.h:4248
EMF::EMRPOLYBEZIER::EMRPOLYBEZIER
EMRPOLYBEZIER(DATASTREAM &ds)
Definition libemf.h:4033
EMF::EMRPOLYBEZIER::size
int size(void) const
Definition libemf.h:4068
EMF::EMRPOLYBEZIER::~EMRPOLYBEZIER
~EMRPOLYBEZIER()
Definition libemf.h:4053
EMF::EMRPOLYBEZIER::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:4060
EMF::EMRPOLYBEZIER::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:4074
EMF::EMRPOLYBEZIER::EMRPOLYBEZIER
EMRPOLYBEZIER(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:4010
EMF::EMRPOLYGON16::~EMRPOLYGON16
~EMRPOLYGON16()
Definition libemf.h:3584
EMF::EMRPOLYGON16::EMRPOLYGON16
EMRPOLYGON16(const RECTL *bounds, const POINT16 *points, INT16 n)
Definition libemf.h:3541
EMF::EMRPOLYGON16::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3591
EMF::EMRPOLYGON16::size
int size(void) const
Definition libemf.h:3599
EMF::EMRPOLYGON16::EMRPOLYGON16
EMRPOLYGON16(DATASTREAM &ds)
Definition libemf.h:3564
EMF::EMRPOLYGON16::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3605
EMF::EMRPOLYGON16::EMRPOLYGON16
EMRPOLYGON16(const RECTL *bounds, const POINT *points, INT16 n)
Definition libemf.h:3516
EMF::EMRPOLYGON::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3485
EMF::EMRPOLYGON::size
int size(void) const
Definition libemf.h:3479
EMF::EMRPOLYGON::EMRPOLYGON
EMRPOLYGON(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:3421
EMF::EMRPOLYGON::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3471
EMF::EMRPOLYGON::EMRPOLYGON
EMRPOLYGON(DATASTREAM &ds)
Definition libemf.h:3444
EMF::EMRPOLYGON::~EMRPOLYGON
~EMRPOLYGON()
Definition libemf.h:3464
EMF::EMRPOLYLINE16::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3376
EMF::EMRPOLYLINE16::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3390
EMF::EMRPOLYLINE16::EMRPOLYLINE16
EMRPOLYLINE16(const RECTL *bounds, const POINT16 *points, INT n)
Definition libemf.h:3301
EMF::EMRPOLYLINE16::EMRPOLYLINE16
EMRPOLYLINE16(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:3326
EMF::EMRPOLYLINE16::EMRPOLYLINE16
EMRPOLYLINE16(DATASTREAM &ds)
Definition libemf.h:3356
EMF::EMRPOLYLINE16::size
int size(void) const
Definition libemf.h:3384
EMF::EMRPOLYLINE16::~EMRPOLYLINE16
~EMRPOLYLINE16()
Definition libemf.h:3348
EMF::EMRPOLYLINETO16::EMRPOLYLINETO16
EMRPOLYLINETO16(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:4560
EMF::EMRPOLYLINETO16::EMRPOLYLINETO16
EMRPOLYLINETO16(DATASTREAM &ds)
Definition libemf.h:4583
EMF::EMRPOLYLINETO16::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:4610
EMF::EMRPOLYLINETO16::~EMRPOLYLINETO16
~EMRPOLYLINETO16()
Definition libemf.h:4603
EMF::EMRPOLYLINETO16::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:4624
EMF::EMRPOLYLINETO16::EMRPOLYLINETO16
EMRPOLYLINETO16(const RECTL *bounds, const POINT16 *points, INT n)
Definition libemf.h:4535
EMF::EMRPOLYLINETO16::size
int size(void) const
Definition libemf.h:4618
EMF::EMRPOLYLINETO::EMRPOLYLINETO
EMRPOLYLINETO(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:4440
EMF::EMRPOLYLINETO::~EMRPOLYLINETO
~EMRPOLYLINETO()
Definition libemf.h:4483
EMF::EMRPOLYLINETO::EMRPOLYLINETO
EMRPOLYLINETO(DATASTREAM &ds)
Definition libemf.h:4463
EMF::EMRPOLYLINETO::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:4504
EMF::EMRPOLYLINETO::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:4490
EMF::EMRPOLYLINETO::size
int size(void) const
Definition libemf.h:4498
EMF::EMRPOLYLINE::size
int size(void) const
Definition libemf.h:3264
EMF::EMRPOLYLINE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3256
EMF::EMRPOLYLINE::EMRPOLYLINE
EMRPOLYLINE(const RECTL *bounds, const POINT *points, INT n)
Definition libemf.h:3207
EMF::EMRPOLYLINE::~EMRPOLYLINE
~EMRPOLYLINE()
Definition libemf.h:3229
EMF::EMRPOLYLINE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3270
EMF::EMRPOLYLINE::EMRPOLYLINE
EMRPOLYLINE(DATASTREAM &ds)
Definition libemf.h:3237
EMF::EMRPOLYPOLYGON16::size
int size(void) const
Definition libemf.h:3944
EMF::EMRPOLYPOLYGON16::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3935
EMF::EMRPOLYPOLYGON16::EMRPOLYPOLYGON16
EMRPOLYPOLYGON16(const RECTL *bounds, const POINT16 *points, const INT *counts, UINT16 polygons)
Definition libemf.h:3848
EMF::EMRPOLYPOLYGON16::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3950
EMF::EMRPOLYPOLYGON16::EMRPOLYPOLYGON16
EMRPOLYPOLYGON16(DATASTREAM &ds)
Definition libemf.h:3894
EMF::EMRPOLYPOLYGON16::EMRPOLYPOLYGON16
EMRPOLYPOLYGON16(const RECTL *bounds, const POINT *points, const INT *counts, UINT polygons)
Definition libemf.h:3807
EMF::EMRPOLYPOLYGON16::~EMRPOLYPOLYGON16
~EMRPOLYPOLYGON16()
Definition libemf.h:3885
EMF::EMRPOLYPOLYGON::EMRPOLYPOLYGON
EMRPOLYPOLYGON(DATASTREAM &ds)
Definition libemf.h:3684
EMF::EMRPOLYPOLYGON::EMRPOLYPOLYGON
EMRPOLYPOLYGON(const RECTL *bounds, const POINT *points, const INT *counts, UINT polygons)
Definition libemf.h:3638
EMF::EMRPOLYPOLYGON::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3726
EMF::EMRPOLYPOLYGON::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3741
EMF::EMRPOLYPOLYGON::size
int size(void) const
Definition libemf.h:3735
EMF::EMRPOLYPOLYGON::~EMRPOLYPOLYGON
~EMRPOLYPOLYGON()
Definition libemf.h:3675
EMF::EMRRECTANGLE::EMRRECTANGLE
EMRRECTANGLE(DATASTREAM &ds)
Definition libemf.h:3093
EMF::EMRRECTANGLE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:3100
EMF::EMRRECTANGLE::size
int size(void) const
Definition libemf.h:3108
EMF::EMRRECTANGLE::EMRRECTANGLE
EMRRECTANGLE(INT left, INT top, INT right, INT bottom)
Definition libemf.h:3080
EMF::EMRRECTANGLE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:3114
EMF::EMRRESTOREDC::EMRRESTOREDC
EMRRESTOREDC(INT n)
Definition libemf.h:6012
EMF::EMRRESTOREDC::EMRRESTOREDC
EMRRESTOREDC(DATASTREAM &ds)
Definition libemf.h:6022
EMF::EMRRESTOREDC::size
int size(void) const
Definition libemf.h:6037
EMF::EMRRESTOREDC::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:6043
EMF::EMRRESTOREDC::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:6029
EMF::EMRSAVEDC::EMRSAVEDC
EMRSAVEDC(DATASTREAM &ds)
Definition libemf.h:5967
EMF::EMRSAVEDC::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5988
EMF::EMRSAVEDC::size
int size(void) const
Definition libemf.h:5982
EMF::EMRSAVEDC::EMRSAVEDC
EMRSAVEDC(void)
Definition libemf.h:5958
EMF::EMRSAVEDC::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5974
EMF::EMRSCALEVIEWPORTEXTEX::EMRSCALEVIEWPORTEXTEX
EMRSCALEVIEWPORTEXTEX(DATASTREAM &ds)
Definition libemf.h:1946
EMF::EMRSCALEVIEWPORTEXTEX::size
int size(void) const
Definition libemf.h:1961
EMF::EMRSCALEVIEWPORTEXTEX::EMRSCALEVIEWPORTEXTEX
EMRSCALEVIEWPORTEXTEX(LONG x_num, LONG x_den, LONG y_num, LONG y_den)
Definition libemf.h:1933
EMF::EMRSCALEVIEWPORTEXTEX::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:1967
EMF::EMRSCALEVIEWPORTEXTEX::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:1953
EMF::EMRSCALEWINDOWEXTEX::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2107
EMF::EMRSCALEWINDOWEXTEX::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2093
EMF::EMRSCALEWINDOWEXTEX::size
int size(void) const
Definition libemf.h:2101
EMF::EMRSCALEWINDOWEXTEX::EMRSCALEWINDOWEXTEX
EMRSCALEWINDOWEXTEX(DATASTREAM &ds)
Definition libemf.h:2086
EMF::EMRSCALEWINDOWEXTEX::EMRSCALEWINDOWEXTEX
EMRSCALEWINDOWEXTEX(LONG x_num, LONG x_den, LONG y_num, LONG y_den)
Definition libemf.h:2073
EMF::EMRSELECTOBJECT::EMRSELECTOBJECT
EMRSELECTOBJECT(HGDIOBJ object)
Definition libemf.h:2691
EMF::EMRSELECTOBJECT::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.cpp:540
EMF::EMRSELECTOBJECT::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2708
EMF::EMRSELECTOBJECT::EMRSELECTOBJECT
EMRSELECTOBJECT(DATASTREAM &ds)
Definition libemf.h:2701
EMF::EMRSELECTOBJECT::size
int size(void) const
Definition libemf.h:2716
EMF::EMRSETBKCOLOR::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2456
EMF::EMRSETBKCOLOR::size
int size(void) const
Definition libemf.h:2450
EMF::EMRSETBKCOLOR::EMRSETBKCOLOR
EMRSETBKCOLOR(COLORREF color)
Definition libemf.h:2425
EMF::EMRSETBKCOLOR::EMRSETBKCOLOR
EMRSETBKCOLOR(DATASTREAM &ds)
Definition libemf.h:2435
EMF::EMRSETBKCOLOR::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2442
EMF::EMRSETBKMODE::EMRSETBKMODE
EMRSETBKMODE(DWORD mode)
Definition libemf.h:2483
EMF::EMRSETBKMODE::size
int size(void) const
Definition libemf.h:2508
EMF::EMRSETBKMODE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2500
EMF::EMRSETBKMODE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2514
EMF::EMRSETBKMODE::EMRSETBKMODE
EMRSETBKMODE(DATASTREAM &ds)
Definition libemf.h:2493
EMF::EMRSETMAPMODE::EMRSETMAPMODE
EMRSETMAPMODE(DWORD mode)
Definition libemf.h:2618
EMF::EMRSETMAPMODE::EMRSETMAPMODE
EMRSETMAPMODE(DATASTREAM &ds)
Definition libemf.h:2628
EMF::EMRSETMAPMODE::size
int size(void) const
Definition libemf.h:2643
EMF::EMRSETMAPMODE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2635
EMF::EMRSETMAPMODE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2649
EMF::EMRSETMETARGN::EMRSETMETARGN
EMRSETMETARGN(DATASTREAM &ds)
Definition libemf.h:6082
EMF::EMRSETMETARGN::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:6103
EMF::EMRSETMETARGN::EMRSETMETARGN
EMRSETMETARGN(void)
Definition libemf.h:6073
EMF::EMRSETMETARGN::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:6089
EMF::EMRSETMETARGN::size
int size(void) const
Definition libemf.h:6097
EMF::EMRSETMITERLIMIT::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:6322
EMF::EMRSETMITERLIMIT::EMRSETMITERLIMIT
EMRSETMITERLIMIT(FLOAT limit)
Definition libemf.h:6303
EMF::EMRSETMITERLIMIT::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:6336
EMF::EMRSETMITERLIMIT::size
int size(void) const
Definition libemf.h:6330
EMF::EMRSETMITERLIMIT::EMRSETMITERLIMIT
EMRSETMITERLIMIT(DATASTREAM &ds)
Definition libemf.h:6313
EMF::EMRSETPIXELV::EMRSETPIXELV
EMRSETPIXELV(DATASTREAM &ds)
Definition libemf.h:5202
EMF::EMRSETPIXELV::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5223
EMF::EMRSETPIXELV::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5209
EMF::EMRSETPIXELV::EMRSETPIXELV
EMRSETPIXELV(INT x, INT y, COLORREF color)
Definition libemf.h:5190
EMF::EMRSETPIXELV::size
int size(void) const
Definition libemf.h:5217
EMF::EMRSETPOLYFILLMODE::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2567
EMF::EMRSETPOLYFILLMODE::EMRSETPOLYFILLMODE
EMRSETPOLYFILLMODE(DATASTREAM &ds)
Definition libemf.h:2560
EMF::EMRSETPOLYFILLMODE::size
int size(void) const
Definition libemf.h:2575
EMF::EMRSETPOLYFILLMODE::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2581
EMF::EMRSETPOLYFILLMODE::EMRSETPOLYFILLMODE
EMRSETPOLYFILLMODE(DWORD mode)
Definition libemf.h:2550
EMF::EMRSETTEXTALIGN::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2313
EMF::EMRSETTEXTALIGN::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2299
EMF::EMRSETTEXTALIGN::size
int size(void) const
Definition libemf.h:2307
EMF::EMRSETTEXTALIGN::EMRSETTEXTALIGN
EMRSETTEXTALIGN(DATASTREAM &ds)
Definition libemf.h:2292
EMF::EMRSETTEXTALIGN::EMRSETTEXTALIGN
EMRSETTEXTALIGN(UINT mode)
Definition libemf.h:2282
EMF::EMRSETTEXTCOLOR::EMRSETTEXTCOLOR
EMRSETTEXTCOLOR(DATASTREAM &ds)
Definition libemf.h:2378
EMF::EMRSETTEXTCOLOR::EMRSETTEXTCOLOR
EMRSETTEXTCOLOR(COLORREF color)
Definition libemf.h:2368
EMF::EMRSETTEXTCOLOR::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2385
EMF::EMRSETTEXTCOLOR::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2399
EMF::EMRSETTEXTCOLOR::size
int size(void) const
Definition libemf.h:2393
EMF::EMRSETVIEWPORTEXTEX::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:1902
EMF::EMRSETVIEWPORTEXTEX::size
int size(void) const
Definition libemf.h:1896
EMF::EMRSETVIEWPORTEXTEX::EMRSETVIEWPORTEXTEX
EMRSETVIEWPORTEXTEX(INT cx, INT cy)
Definition libemf.h:1870
EMF::EMRSETVIEWPORTEXTEX::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:1888
EMF::EMRSETVIEWPORTEXTEX::EMRSETVIEWPORTEXTEX
EMRSETVIEWPORTEXTEX(DATASTREAM &ds)
Definition libemf.h:1881
EMF::EMRSETVIEWPORTORGEX::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:1778
EMF::EMRSETVIEWPORTORGEX::EMRSETVIEWPORTORGEX
EMRSETVIEWPORTORGEX(INT x, INT y)
Definition libemf.h:1746
EMF::EMRSETVIEWPORTORGEX::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:1764
EMF::EMRSETVIEWPORTORGEX::EMRSETVIEWPORTORGEX
EMRSETVIEWPORTORGEX(DATASTREAM &ds)
Definition libemf.h:1757
EMF::EMRSETVIEWPORTORGEX::size
int size(void) const
Definition libemf.h:1772
EMF::EMRSETWINDOWEXTEX::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2042
EMF::EMRSETWINDOWEXTEX::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2028
EMF::EMRSETWINDOWEXTEX::EMRSETWINDOWEXTEX
EMRSETWINDOWEXTEX(DATASTREAM &ds)
Definition libemf.h:2021
EMF::EMRSETWINDOWEXTEX::EMRSETWINDOWEXTEX
EMRSETWINDOWEXTEX(INT cx, INT cy)
Definition libemf.h:2010
EMF::EMRSETWINDOWEXTEX::size
int size(void) const
Definition libemf.h:2036
EMF::EMRSETWINDOWORGEX::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:1841
EMF::EMRSETWINDOWORGEX::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:1827
EMF::EMRSETWINDOWORGEX::size
int size(void) const
Definition libemf.h:1835
EMF::EMRSETWINDOWORGEX::EMRSETWINDOWORGEX
EMRSETWINDOWORGEX(INT x, INT y)
Definition libemf.h:1809
EMF::EMRSETWINDOWORGEX::EMRSETWINDOWORGEX
EMRSETWINDOWORGEX(DATASTREAM &ds)
Definition libemf.h:1820
EMF::EMRSETWORLDTRANSFORM::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:2242
EMF::EMRSETWORLDTRANSFORM::EMRSETWORLDTRANSFORM
EMRSETWORLDTRANSFORM(DATASTREAM &ds)
Definition libemf.h:2235
EMF::EMRSETWORLDTRANSFORM::size
int size(void) const
Definition libemf.h:2250
EMF::EMRSETWORLDTRANSFORM::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:2256
EMF::EMRSETWORLDTRANSFORM::EMRSETWORLDTRANSFORM
EMRSETWORLDTRANSFORM(const XFORM *transform)
Definition libemf.h:2225
EMF::EMRSTROKEANDFILLPATH::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5770
EMF::EMRSTROKEANDFILLPATH::EMRSTROKEANDFILLPATH
EMRSTROKEANDFILLPATH(DATASTREAM &ds)
Definition libemf.h:5749
EMF::EMRSTROKEANDFILLPATH::EMRSTROKEANDFILLPATH
EMRSTROKEANDFILLPATH(const RECTL *bounds)
Definition libemf.h:5739
EMF::EMRSTROKEANDFILLPATH::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5756
EMF::EMRSTROKEANDFILLPATH::size
int size(void) const
Definition libemf.h:5764
EMF::EMRSTROKEPATH::EMRSTROKEPATH
EMRSTROKEPATH(const RECTL *bounds)
Definition libemf.h:5683
EMF::EMRSTROKEPATH::size
int size(void) const
Definition libemf.h:5708
EMF::EMRSTROKEPATH::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:5714
EMF::EMRSTROKEPATH::EMRSTROKEPATH
EMRSTROKEPATH(DATASTREAM &ds)
Definition libemf.h:5693
EMF::EMRSTROKEPATH::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:5700
EMF::ENHMETAHEADER
Enhanced Metafile Header Record.
Definition libemf.h:1424
EMF::ENHMETAHEADER::serialize
bool serialize(DATASTREAM ds)
Definition libemf.h:1512
EMF::ENHMETAHEADER::size
int size(void) const
Definition libemf.h:1572
EMF::ENHMETAHEADER::ENHMETAHEADER
ENHMETAHEADER(LPCWSTR description=0)
Definition libemf.h:1436
EMF::ENHMETAHEADER::unserialize
bool unserialize(DATASTREAM ds)
Definition libemf.h:1527
EMF::ENHMETAHEADER::~ENHMETAHEADER
~ENHMETAHEADER()
Definition libemf.h:1504
EMF::ENHMETAHEADER::execute
void execute(METAFILEDEVICECONTEXT *source, HDC dc) const
Definition libemf.h:1578
EMF::EXTPEN
Extended Graphics Pen.
Definition libemf.h:6155
EMF::EXTPEN::EXTPEN
EXTPEN(const EXTLOGPEN *lpen)
Definition libemf.h:6160
EMF::EXTPEN::newEMR
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition libemf.h:6180
EMF::EXTPEN::getType
OBJECTTYPE getType(void) const
Definition libemf.h:6173
EMF::FONT
Graphics Font.
Definition libemf.h:6223
EMF::FONT::FONT
FONT(const LOGFONTW *lfont)
Definition libemf.h:6228
EMF::FONT::newEMR
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition libemf.h:6253
EMF::FONT::getType
OBJECTTYPE getType(void) const
Definition libemf.h:6246
EMF::GLOBALOBJECTS::new_extcreatefontindirectw
static EMF::METARECORD * new_extcreatefontindirectw(DATASTREAM &ds)
Create a new EXTCREATEFONTINDIRECTW record.
Definition libemf.cpp:477
EMF::GLOBALOBJECTS::new_exttextoutw
static EMF::METARECORD * new_exttextoutw(DATASTREAM &ds)
Create a new EXTTEXTOUTW record.
Definition libemf.cpp:452
EMF::GLOBALOBJECTS::new_arc
static EMF::METARECORD * new_arc(DATASTREAM &ds)
Create a new ARC record.
Definition libemf.cpp:367
EMF::GLOBALOBJECTS::new_polypolygon16
static EMF::METARECORD * new_polypolygon16(DATASTREAM &ds)
Create a new POLYPOLYGON16 record.
Definition libemf.cpp:412
EMF::GLOBALOBJECTS::new_modifyworldtransform
static EMF::METARECORD * new_modifyworldtransform(DATASTREAM &ds)
Create a new MODIFYWORLDTRANSFORM record.
Definition libemf.cpp:307
EMF::GLOBALOBJECTS::new_createbrushindirect
static EMF::METARECORD * new_createbrushindirect(DATASTREAM &ds)
Create a new CREATEBRUSHINDIRECT record.
Definition libemf.cpp:472
EMF::GLOBALOBJECTS::new_ellipse
static EMF::METARECORD * new_ellipse(DATASTREAM &ds)
Create a new ELLIPSE record.
Definition libemf.cpp:382
EMF::GLOBALOBJECTS::new_savedc
static EMF::METARECORD * new_savedc(DATASTREAM &ds)
Create a new SAVEDC record.
Definition libemf.cpp:512
EMF::GLOBALOBJECTS::new_polybezierto
static EMF::METARECORD * new_polybezierto(DATASTREAM &ds)
Create a new POLYBEZIERTO record.
Definition libemf.cpp:427
EMF::GLOBALOBJECTS::new_createpen
static EMF::METARECORD * new_createpen(DATASTREAM &ds)
Create a new CREATEPEN record.
Definition libemf.cpp:462
EMF::GLOBALOBJECTS::new_exttextouta
static EMF::METARECORD * new_exttextouta(DATASTREAM &ds)
Create a new EXTTEXTOUTA record.
Definition libemf.cpp:447
EMF::GLOBALOBJECTS::new_scaleviewportextex
static EMF::METARECORD * new_scaleviewportextex(DATASTREAM &ds)
Create a new SCALEVIEWPORTEXTEX record.
Definition libemf.cpp:297
EMF::GLOBALOBJECTS::new_extcreatepen
static EMF::METARECORD * new_extcreatepen(DATASTREAM &ds)
Create a new EXTCREATEPEN record.
Definition libemf.cpp:467
EMF::GLOBALOBJECTS::new_setviewportorgex
static EMF::METARECORD * new_setviewportorgex(DATASTREAM &ds)
Create a new EMRSETVIEWPORTORGEX record.
Definition libemf.cpp:277
EMF::GLOBALOBJECTS::new_setmiterlimit
static EMF::METARECORD * new_setmiterlimit(DATASTREAM &ds)
Create a new SETMITERLIMIT record.
Definition libemf.cpp:527
EMF::GLOBALOBJECTS::end
auto end(void) const
Definition libemf.h:1305
EMF::GLOBALOBJECTS::new_setbkmode
static EMF::METARECORD * new_setbkmode(DATASTREAM &ds)
Create a new SETBKMODE record.
Definition libemf.cpp:332
EMF::GLOBALOBJECTS::newRecord
METARECORDCTOR newRecord(DWORD iType) const
Definition libemf.cpp:262
EMF::GLOBALOBJECTS::new_polyline
static EMF::METARECORD * new_polyline(DATASTREAM &ds)
Create a new POLYLINE record.
Definition libemf.cpp:387
EMF::GLOBALOBJECTS::new_setviewportextex
static EMF::METARECORD * new_setviewportextex(DATASTREAM &ds)
Create a new EMRSETVIEWPORTEXTEX record.
Definition libemf.cpp:287
EMF::GLOBALOBJECTS::new_deleteobject
static EMF::METARECORD * new_deleteobject(DATASTREAM &ds)
Create a new DELETEOBJECT record.
Definition libemf.cpp:352
EMF::GLOBALOBJECTS::new_polylineto
static EMF::METARECORD * new_polylineto(DATASTREAM &ds)
Create a new POLYLINETO record.
Definition libemf.cpp:437
EMF::GLOBALOBJECTS::new_polylineto16
static EMF::METARECORD * new_polylineto16(DATASTREAM &ds)
Create a new POLYLINETO16 record.
Definition libemf.cpp:442
EMF::GLOBALOBJECTS::new_settextalign
static EMF::METARECORD * new_settextalign(DATASTREAM &ds)
Create a new SETTEXTALIGN record.
Definition libemf.cpp:317
EMF::GLOBALOBJECTS::remove
void remove(const OBJECT *object)
Definition libemf.cpp:248
EMF::GLOBALOBJECTS::new_polybezier16
static EMF::METARECORD * new_polybezier16(DATASTREAM &ds)
Create a new POLYBEZIER16 record.
Definition libemf.cpp:422
EMF::GLOBALOBJECTS::begin
auto begin(void) const
Definition libemf.h:1300
EMF::GLOBALOBJECTS::new_polypolygon
static EMF::METARECORD * new_polypolygon(DATASTREAM &ds)
Create a new POLYPOLYGON record.
Definition libemf.cpp:407
EMF::GLOBALOBJECTS::new_setwindowextex
static EMF::METARECORD * new_setwindowextex(DATASTREAM &ds)
Create a new EMRSETWINDOWEXTEX record.
Definition libemf.cpp:292
EMF::GLOBALOBJECTS::new_polyline16
static EMF::METARECORD * new_polyline16(DATASTREAM &ds)
Create a new POLYLINE16 record.
Definition libemf.cpp:392
EMF::GLOBALOBJECTS::new_endpath
static EMF::METARECORD * new_endpath(DATASTREAM &ds)
Create a new ENDPATH record.
Definition libemf.cpp:502
EMF::GLOBALOBJECTS::new_setpixelv
static EMF::METARECORD * new_setpixelv(DATASTREAM &ds)
Create a new SETPIXELV record.
Definition libemf.cpp:457
EMF::GLOBALOBJECTS::new_restoredc
static EMF::METARECORD * new_restoredc(DATASTREAM &ds)
Create a new RESTOREDC record.
Definition libemf.cpp:517
EMF::GLOBALOBJECTS::new_beginpath
static EMF::METARECORD * new_beginpath(DATASTREAM &ds)
Create a new BEGINPATH record.
Definition libemf.cpp:497
EMF::GLOBALOBJECTS::new_scalewindowextex
static EMF::METARECORD * new_scalewindowextex(DATASTREAM &ds)
Create a new SCALEWINDOWEXTEX record.
Definition libemf.cpp:302
EMF::GLOBALOBJECTS::new_setmapmode
static EMF::METARECORD * new_setmapmode(DATASTREAM &ds)
Create a new SETMAPMODE record.
Definition libemf.cpp:342
EMF::GLOBALOBJECTS::new_polybezierto16
static EMF::METARECORD * new_polybezierto16(DATASTREAM &ds)
Create a new POLYBEZIERTO16 record.
Definition libemf.cpp:432
EMF::GLOBALOBJECTS::new_eof
static EMF::METARECORD * new_eof(DATASTREAM &ds)
Create a new EMREOF record.
Definition libemf.cpp:272
EMF::GLOBALOBJECTS::new_setbkcolor
static EMF::METARECORD * new_setbkcolor(DATASTREAM &ds)
Create a new SETBKCOLOR record.
Definition libemf.cpp:327
EMF::GLOBALOBJECTS::new_setworldtransform
static EMF::METARECORD * new_setworldtransform(DATASTREAM &ds)
Create a new SETWORLDTRANSFORM record.
Definition libemf.cpp:312
EMF::GLOBALOBJECTS::new_setwindoworgex
static EMF::METARECORD * new_setwindoworgex(DATASTREAM &ds)
Create a new EMRSETWINDOWORGEX record.
Definition libemf.cpp:282
EMF::GLOBALOBJECTS::new_strokeandfillpath
static EMF::METARECORD * new_strokeandfillpath(DATASTREAM &ds)
Create a new STROKEANDFILLPATH record.
Definition libemf.cpp:492
EMF::GLOBALOBJECTS::add
HGDIOBJ add(OBJECT *object)
Definition libemf.cpp:193
EMF::GLOBALOBJECTS::new_polygon
static EMF::METARECORD * new_polygon(DATASTREAM &ds)
Create a new POLYGON record.
Definition libemf.cpp:397
EMF::GLOBALOBJECTS::new_strokepath
static EMF::METARECORD * new_strokepath(DATASTREAM &ds)
Create a new STROKEPATH record.
Definition libemf.cpp:487
EMF::GLOBALOBJECTS::new_polygon16
static EMF::METARECORD * new_polygon16(DATASTREAM &ds)
Create a new POLYGON16 record.
Definition libemf.cpp:402
EMF::GLOBALOBJECTS::new_fillpath
static EMF::METARECORD * new_fillpath(DATASTREAM &ds)
Create a new FILLPATH record.
Definition libemf.cpp:482
EMF::GLOBALOBJECTS::new_arcto
static EMF::METARECORD * new_arcto(DATASTREAM &ds)
Create a new ARCTO record.
Definition libemf.cpp:372
EMF::GLOBALOBJECTS::new_lineto
static EMF::METARECORD * new_lineto(DATASTREAM &ds)
Create a new LINETO record.
Definition libemf.cpp:362
EMF::GLOBALOBJECTS::new_setpolyfillmode
static EMF::METARECORD * new_setpolyfillmode(DATASTREAM &ds)
Create a new SETPOLYFILLMODE record.
Definition libemf.cpp:337
EMF::GLOBALOBJECTS::new_settextcolor
static EMF::METARECORD * new_settextcolor(DATASTREAM &ds)
Create a new SETTEXTCOLOR record.
Definition libemf.cpp:322
EMF::GLOBALOBJECTS::new_rectangle
static EMF::METARECORD * new_rectangle(DATASTREAM &ds)
Create a new RECTANGLE record.
Definition libemf.cpp:377
EMF::GLOBALOBJECTS::new_movetoex
static EMF::METARECORD * new_movetoex(DATASTREAM &ds)
Create a new MOVETOEX record.
Definition libemf.cpp:357
EMF::GLOBALOBJECTS::new_closefigure
static EMF::METARECORD * new_closefigure(DATASTREAM &ds)
Create a new CLOSEFIGURE record.
Definition libemf.cpp:507
EMF::GLOBALOBJECTS::new_polybezier
static EMF::METARECORD * new_polybezier(DATASTREAM &ds)
Create a new POLYBEZIER record.
Definition libemf.cpp:417
EMF::GLOBALOBJECTS::new_selectobject
static EMF::METARECORD * new_selectobject(DATASTREAM &ds)
Create a new SELECTOBJECT record.
Definition libemf.cpp:347
EMF::GLOBALOBJECTS::new_setmetargn
static EMF::METARECORD * new_setmetargn(DATASTREAM &ds)
Create a new SETMETARGN record.
Definition libemf.cpp:522
EMF::GLOBALOBJECTS::find
OBJECT * find(const HGDIOBJ handle)
Definition libemf.cpp:225
EMF::GRAPHICSOBJECT
A global graphics object.
Definition libemf.h:1253
EMF::GRAPHICSOBJECT::contexts
std::map< HDC, HGDIOBJ > contexts
Definition libemf.h:1261
EMF::GRAPHICSOBJECT::newEMR
virtual METARECORD * newEMR(HDC dc, HGDIOBJ handle)=0
EMF::GRAPHICSOBJECT::~GRAPHICSOBJECT
virtual ~GRAPHICSOBJECT()
GRAPHICSOBJECTs has a virtual destructor.
Definition libemf.h:1256
EMF::METAFILEDEVICECONTEXT
Graphics Device Context.
Definition libemf.h:6360
EMF::METAFILEDEVICECONTEXT::clearHandle
void clearHandle(DWORD handle)
Definition libemf.h:6556
EMF::METAFILEDEVICECONTEXT::getType
OBJECTTYPE getType(void) const
Definition libemf.h:6534
EMF::METAFILEDEVICECONTEXT::appendHandle
void appendHandle(METARECORD *record)
Definition libemf.h:6579
EMF::METAFILEDEVICECONTEXT::header
ENHMETAHEADER * header
Definition libemf.h:6462
EMF::METAFILEDEVICECONTEXT::polyfill_mode
INT polyfill_mode
The current polygon fill mode.
Definition libemf.h:6486
EMF::METAFILEDEVICECONTEXT::window_org
POINT window_org
The origin of the window.
Definition libemf.h:6473
EMF::METAFILEDEVICECONTEXT::deleteMetafile
void deleteMetafile(void)
Definition libemf.h:6590
EMF::METAFILEDEVICECONTEXT::fp
::FILE * fp
Definition libemf.h:6453
EMF::METAFILEDEVICECONTEXT::pen
PEN * pen
The current pen.
Definition libemf.h:6478
EMF::METAFILEDEVICECONTEXT::font
FONT * font
The current font.
Definition libemf.h:6480
EMF::METAFILEDEVICECONTEXT::brush
BRUSH * brush
The current brush.
Definition libemf.h:6479
EMF::METAFILEDEVICECONTEXT::viewport_ext
SIZEL viewport_ext
The extent of the viewport.
Definition libemf.h:6470
EMF::METAFILEDEVICECONTEXT::update_frame
bool update_frame
Update the frame automatically?
Definition libemf.h:6474
EMF::METAFILEDEVICECONTEXT::resolution
SIZEL resolution
The resolution in DPI of the reference DC.
Definition libemf.h:6469
EMF::METAFILEDEVICECONTEXT::text_alignment
UINT text_alignment
The current text alignment.
Definition libemf.h:6482
EMF::METAFILEDEVICECONTEXT::~METAFILEDEVICECONTEXT
virtual ~METAFILEDEVICECONTEXT()
Definition libemf.h:6524
EMF::METAFILEDEVICECONTEXT::appendRecord
void appendRecord(METARECORD *record)
Definition libemf.h:6567
EMF::METAFILEDEVICECONTEXT::miter_limit
FLOAT miter_limit
The current miter length limit.
Definition libemf.h:6488
EMF::METAFILEDEVICECONTEXT::min_device_point
POINT min_device_point
The lft/top-most painted point in device units.
Definition libemf.h:6475
EMF::METAFILEDEVICECONTEXT::mergePoint
void mergePoint(const LONG &x, const LONG &y)
Definition libemf.h:6601
EMF::METAFILEDEVICECONTEXT::point
POINT point
The current point.
Definition libemf.h:6477
EMF::METAFILEDEVICECONTEXT::map_mode
INT map_mode
The current mapping mode.
Definition libemf.h:6487
EMF::METAFILEDEVICECONTEXT::bk_color
COLORREF bk_color
The current background color.
Definition libemf.h:6484
EMF::METAFILEDEVICECONTEXT::ds
DATASTREAM ds
Definition libemf.h:6458
EMF::METAFILEDEVICECONTEXT::handles
std::vector< bool > handles
Definition libemf.h:6495
EMF::METAFILEDEVICECONTEXT::max_device_point
POINT max_device_point
The rgt/btm-most painted point in device units.
Definition libemf.h:6476
EMF::METAFILEDEVICECONTEXT::METAFILEDEVICECONTEXT
METAFILEDEVICECONTEXT(FILE *fp_, const RECT *size, LPCWSTR description_w)
Definition libemf.h:6514
EMF::METAFILEDEVICECONTEXT::text_color
COLORREF text_color
The current text foreground color.
Definition libemf.h:6483
EMF::METAFILEDEVICECONTEXT::palette
PALETTE * palette
The current palette.
Definition libemf.h:6481
EMF::METAFILEDEVICECONTEXT::viewport_org
POINT viewport_org
The origin of the viewport.
Definition libemf.h:6471
EMF::METAFILEDEVICECONTEXT::window_ext
SIZEL window_ext
The extent of the window.
Definition libemf.h:6472
EMF::METAFILEDEVICECONTEXT::bk_mode
INT bk_mode
The current background mode.
Definition libemf.h:6485
EMF::METAFILEDEVICECONTEXT::records
std::vector< EMF::METARECORD * > records
Definition libemf.h:6466
EMF::METAFILEDEVICECONTEXT::mergePoint
void mergePoint(const POINT &p)
Definition libemf.h:6612
EMF::METAFILEDEVICECONTEXT::emf_handles
std::map< HGDIOBJ, HGDIOBJ > emf_handles
Definition libemf.h:6502
EMF::METAFILEDEVICECONTEXT::nextHandle
DWORD nextHandle(void)
Definition libemf.h:6539
EMF::METARECORD
The base class of all metafile records.
Definition libemf.h:989
EMF::METARECORD::size
virtual int size(void) const =0
EMF::METARECORD::~METARECORD
virtual ~METARECORD()
Definition libemf.h:1016
EMF::METARECORD::execute
virtual void execute(METAFILEDEVICECONTEXT *source, HDC dc) const =0
EMF::METARECORD::serialize
virtual bool serialize(DATASTREAM ds)=0
EMF::OBJECT
Global GDI object.
Definition libemf.h:1231
EMF::OBJECT::OBJECT
OBJECT(void)
Definition libemf.h:1240
EMF::OBJECT::getType
virtual OBJECTTYPE getType(void) const =0
EMF::OBJECT::handle
HGDIOBJ handle
Definition libemf.h:1233
EMF::OBJECT::~OBJECT
virtual ~OBJECT()
OBJECTs have a virtual destructor.
Definition libemf.h:1235
EMF::PALETTE
Graphics Palette.
Definition libemf.h:6264
EMF::PALETTE::getType
OBJECTTYPE getType(void) const
Definition libemf.h:6280
EMF::PALETTE::newEMR
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition libemf.h:6287
EMF::PALETTE::PALETTE
PALETTE(const LOGPALETTE *lpalette)
Definition libemf.h:6269
EMF::PEN
Graphics Pen.
Definition libemf.h:6123
EMF::PEN::PEN
PEN(const LOGPEN *lpen)
Definition libemf.h:6128
EMF::PEN::newEMR
METARECORD * newEMR(HDC dc, HGDIOBJ emf_handle)
Definition libemf.h:6144
EMF::PEN::getType
OBJECTTYPE getType(void) const
Definition libemf.h:6137
EMF::BYTEARRAY
Represent a byte array in a simple way.
Definition libemf.h:127
EMF::BYTEARRAY::n_
const int n_
Number of bytes in array.
Definition libemf.h:129
EMF::BYTEARRAY::array_
BYTE *const array_
Array of unsigned bytes.
Definition libemf.h:128
EMF::BYTEARRAY::BYTEARRAY
BYTEARRAY(BYTE *const array, const int n)
Definition libemf.h:135
EMF::CHARSTR
Represent an ASCII character string in a simple way.
Definition libemf.h:110
EMF::CHARSTR::length_
const int length_
Number of single byte characters in array.
Definition libemf.h:112
EMF::CHARSTR::CHARSTR
CHARSTR(CHAR *const string, const int length)
Definition libemf.h:118
EMF::CHARSTR::string_
CHAR *const string_
Array of single byte characters.
Definition libemf.h:111
EMF::DWORDARRAY
Represent an array of double word integers in a simple way.
Definition libemf.h:191
EMF::DWORDARRAY::dwords_
DWORD *const dwords_
Array of double words.
Definition libemf.h:192
EMF::DWORDARRAY::n_
const DWORD n_
Number of double words in array.
Definition libemf.h:193
EMF::DWORDARRAY::DWORDARRAY
DWORDARRAY(DWORD *const dwords, const DWORD n)
Definition libemf.h:199
EMF::INTARRAY
Represent an array of integers in a simple way.
Definition libemf.h:175
EMF::INTARRAY::ints_
INT *const ints_
Array of ints.
Definition libemf.h:176
EMF::INTARRAY::n_
const DWORD n_
Number of ints in array.
Definition libemf.h:177
EMF::INTARRAY::INTARRAY
INTARRAY(INT *const ints, const DWORD n)
Definition libemf.h:183
EMF::PADDING
All metafile records must be padded out to a multiple of 4 bytes.
Definition libemf.h:207
EMF::PADDING::padding_
static const char padding_[4]
Pad with '\0's.
Definition libemf.h:208
EMF::PADDING::PADDING
PADDING(const int size)
Definition libemf.h:214
EMF::PADDING::size_
const int size_
Number of bytes of padding.
Definition libemf.h:209
EMF::POINT16ARRAY
Represent an array of 16-bit point in a simple way.
Definition libemf.h:159
EMF::POINT16ARRAY::points_
POINT16 *const points_
Array of POINT16s.
Definition libemf.h:160
EMF::POINT16ARRAY::n_
const DWORD n_
Number of POINT16s in array.
Definition libemf.h:161
EMF::POINT16ARRAY::POINT16ARRAY
POINT16ARRAY(POINT16 *const points, const DWORD n)
Definition libemf.h:167
EMF::POINTLARRAY
Represent an array of points in a simple way.
Definition libemf.h:143
EMF::POINTLARRAY::n_
const DWORD n_
Number of POINTLs in array.
Definition libemf.h:145
EMF::POINTLARRAY::points_
POINTL *const points_
Array of POINTLs.
Definition libemf.h:144
EMF::POINTLARRAY::POINTLARRAY
POINTLARRAY(POINTL *const points, const DWORD n)
Definition libemf.h:151
EMF::WCHARSTR
Represent a wide (UNICODE) character string in a simple way.
Definition libemf.h:92
EMF::WCHARSTR::length_
const int length_
Number of WCHARs in string.
Definition libemf.h:94
EMF::WCHARSTR::WCHARSTR
WCHARSTR(WCHAR *const string, const int length)
Definition libemf.h:100
EMF::WCHARSTR::string_
WCHAR *const string_
String of WCHARs.
Definition libemf.h:93