summaryrefslogtreecommitdiff
path: root/svtools/source/filter.vcl/wmf
diff options
context:
space:
mode:
Diffstat (limited to 'svtools/source/filter.vcl/wmf')
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.cxx1207
-rw-r--r--svtools/source/filter.vcl/wmf/emfwr.hxx129
-rw-r--r--svtools/source/filter.vcl/wmf/enhwmf.cxx1077
-rw-r--r--svtools/source/filter.vcl/wmf/makefile.mk97
-rw-r--r--svtools/source/filter.vcl/wmf/winmtf.cxx1262
-rw-r--r--svtools/source/filter.vcl/wmf/winmtf.hxx687
-rw-r--r--svtools/source/filter.vcl/wmf/winwmf.cxx886
-rw-r--r--svtools/source/filter.vcl/wmf/wmf.cxx147
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.cxx1787
-rw-r--r--svtools/source/filter.vcl/wmf/wmfwr.hxx245
10 files changed, 7524 insertions, 0 deletions
diff --git a/svtools/source/filter.vcl/wmf/emfwr.cxx b/svtools/source/filter.vcl/wmf/emfwr.cxx
new file mode 100644
index 000000000000..3e504f830b0e
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/emfwr.cxx
@@ -0,0 +1,1207 @@
+/*************************************************************************
+ *
+ * $RCSfile: emfwr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "emfwr.hxx"
+#include <vcl/salbtype.hxx>
+
+// -----------
+// - Defines -
+// -----------
+
+#define WIN_EMR_HEADER 1
+#define WIN_EMR_POLYBEZIER 2
+#define WIN_EMR_POLYGON 3
+#define WIN_EMR_POLYLINE 4
+#define WIN_EMR_POLYBEZIERTO 5
+#define WIN_EMR_POLYLINETO 6
+#define WIN_EMR_POLYPOLYLINE 7
+#define WIN_EMR_POLYPOLYGON 8
+#define WIN_EMR_SETWINDOWEXTEX 9
+#define WIN_EMR_SETWINDOWORGEX 10
+#define WIN_EMR_SETVIEWPORTEXTEX 11
+#define WIN_EMR_SETVIEWPORTORGEX 12
+#define WIN_EMR_SETBRUSHORGEX 13
+#define WIN_EMR_EOF 14
+#define WIN_EMR_SETPIXELV 15
+#define WIN_EMR_SETMAPPERFLAGS 16
+#define WIN_EMR_SETMAPMODE 17
+#define WIN_EMR_SETBKMODE 18
+#define WIN_EMR_SETPOLYFILLMODE 19
+#define WIN_EMR_SETROP2 20
+#define WIN_EMR_SETSTRETCHBLTMODE 21
+#define WIN_EMR_SETTEXTALIGN 22
+#define WIN_EMR_SETCOLORADJUSTMENT 23
+#define WIN_EMR_SETTEXTCOLOR 24
+#define WIN_EMR_SETBKCOLOR 25
+#define WIN_EMR_OFFSETCLIPRGN 26
+#define WIN_EMR_MOVETOEX 27
+#define WIN_EMR_SETMETARGN 28
+#define WIN_EMR_EXCLUDECLIPRECT 29
+#define WIN_EMR_INTERSECTCLIPRECT 30
+#define WIN_EMR_SCALEVIEWPORTEXTEX 31
+#define WIN_EMR_SCALEWINDOWEXTEX 32
+#define WIN_EMR_SAVEDC 33
+#define WIN_EMR_RESTOREDC 34
+#define WIN_EMR_SETWORLDTRANSFORM 35
+#define WIN_EMR_MODIFYWORLDTRANSFORM 36
+#define WIN_EMR_SELECTOBJECT 37
+#define WIN_EMR_CREATEPEN 38
+#define WIN_EMR_CREATEBRUSHINDIRECT 39
+#define WIN_EMR_DELETEOBJECT 40
+#define WIN_EMR_ANGLEARC 41
+#define WIN_EMR_ELLIPSE 42
+#define WIN_EMR_RECTANGLE 43
+#define WIN_EMR_ROUNDRECT 44
+#define WIN_EMR_ARC 45
+#define WIN_EMR_CHORD 46
+#define WIN_EMR_PIE 47
+#define WIN_EMR_SELECTPALETTE 48
+#define WIN_EMR_CREATEPALETTE 49
+#define WIN_EMR_SETPALETTEENTRIES 50
+#define WIN_EMR_RESIZEPALETTE 51
+#define WIN_EMR_REALIZEPALETTE 52
+#define WIN_EMR_EXTFLOODFILL 53
+#define WIN_EMR_LINETO 54
+#define WIN_EMR_ARCTO 55
+#define WIN_EMR_POLYDRAW 56
+#define WIN_EMR_SETARCDIRECTION 57
+#define WIN_EMR_SETMITERLIMIT 58
+#define WIN_EMR_BEGINPATH 59
+#define WIN_EMR_ENDPATH 60
+#define WIN_EMR_CLOSEFIGURE 61
+#define WIN_EMR_FILLPATH 62
+#define WIN_EMR_STROKEANDFILLPATH 63
+#define WIN_EMR_STROKEPATH 64
+#define WIN_EMR_FLATTENPATH 65
+#define WIN_EMR_WIDENPATH 66
+#define WIN_EMR_SELECTCLIPPATH 67
+#define WIN_EMR_ABORTPATH 68
+
+#define WIN_EMR_GDICOMMENT 70
+#define WIN_EMR_FILLRGN 71
+#define WIN_EMR_FRAMERGN 72
+#define WIN_EMR_INVERTRGN 73
+#define WIN_EMR_PAINTRGN 74
+#define WIN_EMR_EXTSELECTCLIPRGN 75
+#define WIN_EMR_BITBLT 76
+#define WIN_EMR_STRETCHBLT 77
+#define WIN_EMR_MASKBLT 78
+#define WIN_EMR_PLGBLT 79
+#define WIN_EMR_SETDIBITSTODEVICE 80
+#define WIN_EMR_STRETCHDIBITS 81
+#define WIN_EMR_EXTCREATEFONTINDIRECTW 82
+#define WIN_EMR_EXTTEXTOUTA 83
+#define WIN_EMR_EXTTEXTOUTW 84
+#define WIN_EMR_POLYBEZIER16 85
+#define WIN_EMR_POLYGON16 86
+#define WIN_EMR_POLYLINE16 87
+#define WIN_EMR_POLYBEZIERTO16 88
+#define WIN_EMR_POLYLINETO16 89
+#define WIN_EMR_POLYPOLYLINE16 90
+#define WIN_EMR_POLYPOLYGON16 91
+#define WIN_EMR_POLYDRAW16 92
+#define WIN_EMR_CREATEMONOBRUSH 93
+#define WIN_EMR_CREATEDIBPATTERNBRUSHPT 94
+#define WIN_EMR_EXTCREATEPEN 95
+#define WIN_EMR_POLYTEXTOUTA 96
+#define WIN_EMR_POLYTEXTOUTW 97
+
+#define WIN_SRCCOPY 0x00CC0020L
+#define WIN_SRCPAINT 0x00EE0086L
+#define WIN_SRCAND 0x008800C6L
+#define WIN_SRCINVERT 0x00660046L
+
+#define HANDLE_INVALID 0xffffffff
+#define MAXHANDLES 65000
+
+#define LINE_SELECT 0x00000001
+#define FILL_SELECT 0x00000002
+#define TEXT_SELECT 0x00000004
+
+// -------------
+// - EMFWriter -
+// -------------
+
+BOOL EMFWriter::WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm,
+ PFilterCallback pCallback, void* pCallerData )
+{
+ const ULONG nHeaderPos = rOStm.Tell();
+
+ mpHandlesUsed = new BOOL[ MAXHANDLES ];
+ HMEMSET( mpHandlesUsed, 0, MAXHANDLES * sizeof( BOOL ) );
+ mnHandleCount = mnLastPercent = mnRecordPos = mnRecordCount = 0;
+ mnLineHandle = mnFillHandle = mnTextHandle = HANDLE_INVALID;
+ mbRecordOpen = FALSE;
+
+ mpStm = &rOStm;
+ mpCallback = pCallback;
+ mpCallerData = pCallerData;
+ maVDev.EnableOutput( FALSE );
+ maVDev.SetMapMode( rMtf.GetPrefMapMode() );
+
+ const Size aMtfSizePix( maVDev.LogicToPixel( rMtf.GetPrefSize(), rMtf.GetPrefMapMode() ) );
+ const Size aMtfSizeLog( maVDev.LogicToLogic( rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MAP_100TH_MM ) );
+
+ // seek over header
+ rOStm.SeekRel( 100 );
+
+ // write initial values
+ ImplBeginRecord( WIN_EMR_SETWINDOWORGEX );
+ (*mpStm) << (INT32) 0 << (INT32) 0;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETWINDOWEXTEX );
+ (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height();
+ ImplEndRecord();
+
+ ImplWriteRasterOp( ROP_OVERPAINT );
+
+ ImplBeginRecord( WIN_EMR_SETBKMODE );
+ (*mpStm) << (UINT32) 1; // TRANSPARENT
+ ImplEndRecord();
+
+ // write emf data
+ ImplWrite( rMtf );
+
+ // write header
+ const ULONG nEndPos = mpStm->Tell(); mpStm->Seek( nHeaderPos );
+
+ (*mpStm) << (UINT32) 0x00000001 << (UINT32) 100;
+ (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizePix.Width() - 1 ) << (INT32) ( aMtfSizePix.Height() - 1 );
+ (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) ( aMtfSizeLog.Width() - 1 ) << (INT32) ( aMtfSizeLog.Height() - 1 );
+ (*mpStm) << (UINT32) 0x464d4520 << (UINT32) 0x10000 << (UINT32) ( nEndPos - nHeaderPos );
+ (*mpStm) << (UINT32) mnRecordCount << (UINT16) ( mnHandleCount + 1 ) << (UINT16) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0;
+ (*mpStm) << (INT32) aMtfSizePix.Width() << (INT32) aMtfSizePix.Height();
+ (*mpStm) << (INT32) ( aMtfSizeLog.Width() / 100 ) << (INT32) ( aMtfSizeLog.Height() / 100 );
+ (*mpStm) << (UINT32) 0 << (UINT32) 0 << (UINT32) 0;
+
+ mpStm->Seek( nEndPos );
+ delete[] mpHandlesUsed;
+
+ return( mpStm->GetError() == ERRCODE_NONE );
+}
+
+// -----------------------------------------------------------------------------
+
+ULONG EMFWriter::ImplAcquireHandle()
+{
+ ULONG nHandle = HANDLE_INVALID;
+
+ for( ULONG i = 0; i < MAXHANDLES && ( HANDLE_INVALID == nHandle ); i++ )
+ {
+ if( !mpHandlesUsed[ i ] )
+ {
+ mpHandlesUsed[ i ] = TRUE;
+
+ if( ( nHandle = i ) == mnHandleCount )
+ mnHandleCount++;
+ }
+ }
+
+ DBG_ASSERT( nHandle != HANDLE_INVALID, "No more handles available" );
+ return( nHandle != HANDLE_INVALID ? nHandle + 1 : HANDLE_INVALID );
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplReleaseHandle( ULONG nHandle )
+{
+ DBG_ASSERT( nHandle && ( nHandle < MAXHANDLES ), "Handle out of range" );
+ mpHandlesUsed[ nHandle - 1 ] = FALSE;
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplBeginRecord( ULONG nType )
+{
+ DBG_ASSERT( !mbRecordOpen, "Another record is already opened!" );
+
+ if( !mbRecordOpen )
+ {
+ mbRecordOpen = TRUE;
+ mnRecordPos = mpStm->Tell();
+
+ (*mpStm) << nType;
+ mpStm->SeekRel( 4 );
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplEndRecord()
+{
+ DBG_ASSERT( mbRecordOpen, "Record was not opened!" );
+
+ if( mbRecordOpen )
+ {
+ const ULONG nActPos = mpStm->Tell();
+
+ mpStm->Seek( mnRecordPos + 4 );
+ ( *mpStm ) << ( nActPos - mnRecordPos );
+ mpStm->Seek( nActPos );
+
+ mnRecordCount++;
+ mbRecordOpen = FALSE;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL EMFWriter::ImplPrepareHandleSelect( ULONG& rHandle, ULONG nSelectType )
+{
+ if( rHandle != HANDLE_INVALID )
+ {
+ UINT32 nStockObject = 0x80000000;
+
+ if( LINE_SELECT == nSelectType )
+ nStockObject |= 0x00000007;
+ else if( FILL_SELECT == nSelectType )
+ nStockObject |= 0x00000001;
+ else if( TEXT_SELECT == nSelectType )
+ nStockObject |= 0x0000000a;
+
+ // select stock object first
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ ( *mpStm ) << nStockObject;
+ ImplEndRecord();
+
+ // destroy handle of created object
+ ImplBeginRecord( WIN_EMR_DELETEOBJECT );
+ ( *mpStm ) << rHandle;
+ ImplEndRecord();
+
+ // mark handle as free
+ ImplReleaseHandle( rHandle );
+ }
+
+ rHandle = ImplAcquireHandle();
+
+ return( HANDLE_INVALID != rHandle );
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplCheckLineAttr()
+{
+ if( mbLineChanged && ImplPrepareHandleSelect( mnLineHandle, LINE_SELECT ) )
+ {
+ ULONG nStyle = maVDev.IsLineColor() ? 0 : 5;
+ ULONG nWidth = 0, nHeight = 0;
+
+ ImplBeginRecord( WIN_EMR_CREATEPEN );
+ (*mpStm) << mnLineHandle << nStyle << nWidth << nHeight;
+ ImplWriteColor( maVDev.GetLineColor() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ (*mpStm) << mnLineHandle;
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplCheckFillAttr()
+{
+ if( mbFillChanged && ImplPrepareHandleSelect( mnFillHandle, FILL_SELECT ) )
+ {
+ ULONG nStyle = maVDev.IsFillColor() ? 0 : 1;
+ ULONG nPatternStyle = 0;
+
+ ImplBeginRecord( WIN_EMR_CREATEBRUSHINDIRECT );
+ (*mpStm) << mnFillHandle << nStyle;
+ ImplWriteColor( maVDev.GetFillColor() );
+ (*mpStm) << nPatternStyle;
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ (*mpStm) << mnFillHandle;
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplCheckTextAttr()
+{
+ if( mbTextChanged && ImplPrepareHandleSelect( mnTextHandle, TEXT_SELECT ) )
+ {
+ const Font& rFont = maVDev.GetFont();
+ String aFontName( rFont.GetName() );
+ INT32 i, nWeight;
+ BYTE nPitchAndFamily;
+
+ ImplBeginRecord( WIN_EMR_EXTCREATEFONTINDIRECTW );
+ (*mpStm) << mnTextHandle;
+ ImplWriteExtent( rFont.GetSize().Height() );
+ ImplWriteExtent( rFont.GetSize().Width() );
+ (*mpStm) << (INT32) rFont.GetOrientation() << (INT32) rFont.GetOrientation();
+
+ switch( rFont.GetWeight() )
+ {
+ case WEIGHT_THIN: nWeight = 100; break;
+ case WEIGHT_ULTRALIGHT: nWeight = 200; break;
+ case WEIGHT_LIGHT: nWeight = 300; break;
+ case WEIGHT_SEMILIGHT: nWeight = 300; break;
+ case WEIGHT_NORMAL: nWeight = 400; break;
+ case WEIGHT_MEDIUM: nWeight = 500; break;
+ case WEIGHT_SEMIBOLD: nWeight = 600; break;
+ case WEIGHT_BOLD: nWeight = 700; break;
+ case WEIGHT_ULTRABOLD: nWeight = 800; break;
+ case WEIGHT_BLACK: nWeight = 900; break;
+ default: nWeight = 0; break;
+ }
+
+ (*mpStm) << nWeight;
+ (*mpStm) << (BYTE) ( ( ITALIC_NONE == rFont.GetItalic() ) ? 0 : 1 );
+ (*mpStm) << (BYTE) ( ( UNDERLINE_NONE == rFont.GetUnderline() ) ? 0 : 1 );
+ (*mpStm) << (BYTE) ( ( STRIKEOUT_NONE == rFont.GetStrikeout() ) ? 0 : 1 );
+ (*mpStm) << (BYTE) ( ( RTL_TEXTENCODING_SYMBOL == rFont.GetCharSet() ) ? 2 : 0 );
+ (*mpStm) << (BYTE) 0 << (BYTE) 0 << (BYTE) 0;
+
+ switch( rFont.GetPitch() )
+ {
+ case PITCH_FIXED: nPitchAndFamily = 0x01; break;
+ case PITCH_VARIABLE: nPitchAndFamily = 0x02; break;
+ default: nPitchAndFamily = 0x00; break;
+ }
+
+ switch( rFont.GetFamily() )
+ {
+ case FAMILY_DECORATIVE: nPitchAndFamily |= 0x50; break;
+ case FAMILY_MODERN: nPitchAndFamily |= 0x30; break;
+ case FAMILY_ROMAN: nPitchAndFamily |= 0x10; break;
+ case FAMILY_SCRIPT: nPitchAndFamily |= 0x40; break;
+ case FAMILY_SWISS: nPitchAndFamily |= 0x20; break;
+ default: break;
+ }
+
+ (*mpStm) << nPitchAndFamily;
+
+ for( i = 0; i < 32; i++ )
+ (*mpStm) << (sal_Unicode) ( ( i < aFontName.Len() ) ? aFontName.GetChar( i ) : 0 );
+
+ // dummy elfFullName
+ for( i = 0; i < 64; i++ )
+ (*mpStm) << (sal_Unicode) 0;
+
+ // dummy elfStyle
+ for( i = 0; i < 32; i++ )
+ (*mpStm) << (sal_Unicode) 0;
+
+ // dummy elfVersion, elfStyleSize, elfMatch, elfReserved
+ (*mpStm) << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 << (UINT32) 0 ;
+
+ // dummy elfVendorId
+ (*mpStm) << (UINT32) 0;
+
+ // dummy elfCulture
+ (*mpStm) << (UINT32) 0;
+
+ // dummy elfPanose
+ (*mpStm) << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0 << (BYTE) 0;
+
+ // fill record to get a record size divideable by 4
+ (*mpStm) << (UINT16) 0;
+
+ ImplEndRecord();
+
+ // TextAlign
+ UINT32 nTextAlign;
+
+ switch( rFont.GetAlign() )
+ {
+ case ALIGN_TOP: nTextAlign = 0; break;
+ case ALIGN_BOTTOM: nTextAlign = 8; break;
+ default: nTextAlign = 24; break;
+ }
+
+ ImplBeginRecord( WIN_EMR_SETTEXTALIGN );
+ (*mpStm) << nTextAlign;
+ ImplEndRecord();
+
+ // Text color
+ ImplBeginRecord( WIN_EMR_SETTEXTCOLOR );
+ ImplWriteColor( rFont.GetColor() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SELECTOBJECT );
+ (*mpStm) << mnTextHandle;
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteColor( const Color& rColor )
+{
+ UINT32 nCol = rColor.GetRed();
+
+ nCol |= ( (UINT32) rColor.GetGreen() ) << 8;
+ nCol |= ( (UINT32) rColor.GetBlue() ) << 16;
+
+ (*mpStm) << nCol;
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteRasterOp( RasterOp eRop )
+{
+ UINT32 nROP2;
+
+ switch( eRop )
+ {
+ case ROP_INVERT: nROP2 = 6; break;
+ case ROP_XOR: nROP2 = 7; break;
+ default: nROP2 = 13;break;
+ }
+
+ ImplBeginRecord( WIN_EMR_SETROP2 );
+ (*mpStm) << nROP2;
+ ImplEndRecord();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteExtent( long nExtent )
+{
+ const Size aSize( maVDev.LogicToPixel( Size( nExtent, nExtent ) ) );
+ (*mpStm) << (INT32) aSize.Width();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWritePoint( const Point& rPoint )
+{
+ const Point aPoint( maVDev.LogicToPixel( rPoint ) );
+
+ (*mpStm) << (INT32) aPoint.X() << (INT32) aPoint.Y();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteSize( const Size& rSize)
+{
+ const Size aSize( maVDev.LogicToPixel( rSize ) );
+
+ (*mpStm) << (INT32) aSize.Width() << (INT32) aSize.Height();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteRect( const Rectangle& rRect )
+{
+ const Rectangle aRect( maVDev.LogicToPixel( rRect ) );
+
+ (*mpStm) << aRect.Left() << aRect.Top() << aRect.Right() << aRect.Bottom();
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWritePolygonRecord( const Polygon& rPoly, BOOL bClose )
+{
+ if( rPoly.GetSize() )
+ {
+ if( bClose )
+ ImplCheckFillAttr();
+
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( bClose ? WIN_EMR_POLYGON : WIN_EMR_POLYLINE );
+ ImplWriteRect( rPoly.GetBoundRect() );
+ (*mpStm) << (UINT32) rPoly.GetSize();
+
+ for( USHORT i = 0; i < rPoly.GetSize(); i++ )
+ ImplWritePoint( rPoly[ i ] );
+
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly )
+{
+ const UINT32 nPolyCount = rPolyPoly.Count();
+
+ if( nPolyCount )
+ {
+ if( 1 == nPolyCount )
+ ImplWritePolygonRecord( rPolyPoly[ 0 ], TRUE );
+ else
+ {
+ UINT32 nTotalPoints = 0, i;
+
+ for( i = 0; i < nPolyCount; i++ )
+ nTotalPoints += rPolyPoly[ i ].GetSize();
+
+ if( nTotalPoints )
+ {
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_POLYPOLYGON );
+ ImplWriteRect( rPolyPoly.GetBoundRect() );
+ (*mpStm) << nPolyCount << nTotalPoints;
+
+ for( i = 0; i < nPolyCount; i++ )
+ (*mpStm) << (UINT32) rPolyPoly[ i ].GetSize();
+
+ for( i = 0; i < nPolyCount; i++ )
+ {
+ const Polygon& rPoly = rPolyPoly[ i ];
+
+ for( USHORT n = 0; n < rPoly.GetSize(); n++ )
+ ImplWritePoint( rPoly[ n ] );
+ }
+
+ ImplEndRecord();
+ }
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt,
+ const Size& rSz, UINT32 nROP )
+{
+ if( !!rBmp )
+ {
+ SvMemoryStream aMemStm( 65535, 65535 );
+ const Size aBmpSizePixel( rBmp.GetSizePixel() );
+
+ ImplBeginRecord( WIN_EMR_STRETCHDIBITS );
+ ImplWriteRect( Rectangle( rPt, rSz ) );
+ ImplWritePoint( rPt );
+ (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) aBmpSizePixel.Width() << (INT32) aBmpSizePixel.Height();
+
+ // write offset positions and sizes later
+ const ULONG nOffPos = mpStm->Tell();
+ mpStm->SeekRel( 16 );
+
+ (*mpStm) << (UINT32) 0 << ( ( ROP_XOR == maVDev.GetRasterOp() && WIN_SRCCOPY == nROP ) ? WIN_SRCINVERT : nROP );
+ ImplWriteSize( rSz );
+
+ rBmp.Write( aMemStm, TRUE, FALSE );
+
+ UINT32 nDIBSize = aMemStm.Tell(), nHeaderSize, nCompression, nColsUsed, nPalCount, nImageSize;
+ UINT16 nBitCount;
+
+ // get DIB parameters
+ aMemStm.Seek( 0 );
+ aMemStm >> nHeaderSize;
+ aMemStm.SeekRel( 10 );
+ aMemStm >> nBitCount >> nCompression >> nImageSize;
+ aMemStm.SeekRel( 8 );
+ aMemStm >> nColsUsed;
+
+ nPalCount = ( nBitCount <= 8 ) ? ( nColsUsed ? nColsUsed : ( 1 << (UINT32) nBitCount ) ) :
+ ( ( 3 == nCompression ) ? 12 : 0 );
+
+ mpStm->Write( aMemStm.GetData(), nDIBSize );
+
+ const ULONG nEndPos = mpStm->Tell();
+ mpStm->Seek( nOffPos );
+ (*mpStm) << (UINT32) 80 << (UINT32)( nHeaderSize + ( nPalCount << 2 ) );
+ (*mpStm) << (UINT32)( 80 + ( nHeaderSize + ( nPalCount << 2 ) ) ) << nImageSize;
+ mpStm->Seek( nEndPos );
+
+ ImplEndRecord();
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWriteTextRecord( const Point& rPos, const String rText, const long* pDXArray, UINT32 nWidth )
+{
+ UINT32 nLen = rText.Len(), i;
+
+ if( nLen )
+ {
+ sal_Int32 nNormWidth;
+ long* pOwnArray;
+ long* pDX;
+
+ // get text sizes
+ if( pDXArray )
+ {
+ pOwnArray = NULL;
+ nNormWidth = maVDev.GetTextWidth( rText );
+ pDX = (long*) pDXArray;
+ }
+ else
+ {
+ pOwnArray = new long[ nLen ];
+ nNormWidth = maVDev.GetTextArray( rText, pOwnArray );
+ pDX = pOwnArray;
+ }
+
+ if( nLen > 1 )
+ {
+ nNormWidth = pDX[ nLen - 2 ] + maVDev.GetTextWidth( rText.GetChar( nLen - 1 ) );
+
+ if( nWidth && nNormWidth && ( nWidth != nNormWidth ) )
+ {
+ const double fFactor = (double) nWidth / nNormWidth;
+
+ for( i = 0; i < ( nLen - 1 ); i++ )
+ pDX[ i ] = FRound( pDX[ i ] * fFactor );
+ }
+ }
+
+ // write text record
+ ImplBeginRecord( WIN_EMR_EXTTEXTOUTW );
+
+ ImplWriteRect( Rectangle( rPos, Size( nNormWidth, maVDev.GetTextHeight() ) ) );
+ (*mpStm) << (UINT32) 2; // GM_ADVANCED
+ (*mpStm) << (INT32) 0 << (INT32) 0;
+ ImplWritePoint( rPos );
+ (*mpStm) << (UINT32) nLen << (UINT32) 76 << (UINT32) 2;
+ (*mpStm) << (INT32) 0 << (INT32) 0 << (INT32) 0 << (INT32) 0;
+ (*mpStm) << (UINT32) ( 76 + ( nLen << 1 ) + ( (nLen & 1 ) ? 2 : 0 ) );
+
+ // write text
+ for( i = 0; i < nLen; i++ )
+ (*mpStm) << (sal_Unicode)rText.GetChar( i );
+
+ // padding word
+ if( nLen & 1 )
+ (*mpStm) << (UINT16) 0;
+
+ // write DX array
+ ImplWriteExtent( pDX[ 0 ] );
+
+ if( nLen > 1 )
+ {
+ for( i = 1; i < ( nLen - 1 ); i++ )
+ ImplWriteExtent( pDX[ i ] - pDX[ i - 1 ] );
+
+ ImplWriteExtent( pDX[ nLen - 2 ] / ( nLen - 1 ) );
+ }
+
+ ImplEndRecord();
+ delete[] pOwnArray;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void EMFWriter::ImplWrite( const GDIMetaFile& rMtf )
+{
+ for( ULONG i = 0, nCount = rMtf.GetActionCount(); i < nCount; i++ )
+ {
+ const MetaAction* pAction = rMtf.GetAction( i );
+ const USHORT nType = pAction->GetType();
+
+ switch( nType )
+ {
+ case( META_PIXEL_ACTION ):
+ {
+ const MetaPixelAction* pA = (const MetaPixelAction*) pAction;
+
+ ImplCheckLineAttr();
+ ImplBeginRecord( WIN_EMR_SETPIXELV );
+ ImplWritePoint( pA->GetPoint() );
+ ImplWriteColor( pA->GetColor() );
+ ImplEndRecord();
+ }
+ break;
+
+ case( META_POINT_ACTION ):
+ {
+ if( maVDev.IsLineColor() )
+ {
+ const MetaPointAction* pA = (const MetaPointAction*) pAction;
+
+ ImplCheckLineAttr();
+ ImplBeginRecord( WIN_EMR_SETPIXELV );
+ ImplWritePoint( pA->GetPoint() );
+ ImplWriteColor( maVDev.GetLineColor() );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_LINE_ACTION ):
+ {
+ if( maVDev.IsLineColor() )
+ {
+ const MetaLineAction* pA = (const MetaLineAction*) pAction;
+
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_MOVETOEX );
+ ImplWritePoint( pA->GetStartPoint() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_LINETO );
+ ImplWritePoint( pA->GetEndPoint() );
+ ImplEndRecord();
+
+ ImplBeginRecord( WIN_EMR_SETPIXELV );
+ ImplWritePoint( pA->GetEndPoint() );
+ ImplWriteColor( maVDev.GetLineColor() );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_RECT_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ const MetaRectAction* pA = (const MetaRectAction*) pAction;
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_RECTANGLE );
+ ImplWriteRect( pA->GetRect() );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_ROUNDRECT_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pAction;
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_ROUNDRECT );
+ ImplWriteRect( pA->GetRect() );
+ ImplWriteSize( Size( pA->GetHorzRound(), pA->GetVertRound() ) );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_ELLIPSE_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ const MetaEllipseAction* pA = (const MetaEllipseAction*) pAction;
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+
+ ImplBeginRecord( WIN_EMR_ELLIPSE );
+ ImplWriteRect( pA->GetRect() );
+ ImplEndRecord();
+ }
+ }
+ break;
+
+ case( META_ARC_ACTION ):
+ case( META_PIE_ACTION ):
+ case( META_CHORD_ACTION ):
+ case( META_POLYGON_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ {
+ Polygon aPoly;
+
+ switch( nType )
+ {
+ case( META_ARC_ACTION ):
+ {
+ const MetaArcAction* pA = (const MetaArcAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_ARC );
+ }
+ break;
+
+ case( META_PIE_ACTION ):
+ {
+ const MetaPieAction* pA = (const MetaPieAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_PIE );
+ }
+ break;
+
+ case( META_CHORD_ACTION ):
+ {
+ const MetaChordAction* pA = (const MetaChordAction*) pAction;
+ aPoly = Polygon( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint(), POLY_CHORD );
+ }
+ break;
+
+ case( META_POLYGON_ACTION ):
+ aPoly = ( (const MetaPolygonAction*) pAction )->GetPolygon();
+ break;
+ }
+
+ ImplWritePolygonRecord( aPoly, nType != META_ARC_ACTION );
+ }
+ }
+ break;
+
+ case( META_POLYLINE_ACTION ):
+ {
+ if( maVDev.IsLineColor() )
+ ImplWritePolygonRecord( ( (const MetaPolyLineAction*) pAction )->GetPolygon(), FALSE );
+ }
+ break;
+
+ case( META_POLYPOLYGON_ACTION ):
+ {
+ if( maVDev.IsLineColor() || maVDev.IsFillColor() )
+ ImplWritePolyPolygonRecord( ( (const MetaPolyPolygonAction*) pAction )->GetPolyPolygon() );
+ }
+ break;
+
+ case( META_GRADIENT_ACTION ):
+ {
+ const MetaGradientAction* pA = (const MetaGradientAction*) pAction;
+ GDIMetaFile aTmpMtf;
+
+ maVDev.AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
+ ImplWrite( aTmpMtf );
+ }
+ break;
+
+ case META_HATCH_ACTION:
+ {
+ const MetaHatchAction* pA = (const MetaHatchAction*) pAction;
+ GDIMetaFile aTmpMtf;
+
+ maVDev.AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
+ ImplWrite( aTmpMtf );
+ }
+ break;
+
+ case META_TRANSPARENT_ACTION:
+ {
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+ ImplWritePolyPolygonRecord( ( (MetaTransparentAction*) pAction )->GetPolyPolygon() );
+ }
+ break;
+
+ case META_FLOATTRANSPARENT_ACTION:
+ {
+ const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pAction;
+
+ GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
+ Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
+ const Size aSrcSize( aTmpMtf.GetPrefSize() );
+ const Point aDestPt( pA->GetPoint() );
+ const Size aDestSize( pA->GetSize() );
+ const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
+ const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
+ long nMoveX, nMoveY;
+
+ if( fScaleX != 1.0 || fScaleY != 1.0 )
+ {
+ aTmpMtf.Scale( fScaleX, fScaleY );
+ aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
+ }
+
+ nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
+
+ if( nMoveX || nMoveY )
+ aTmpMtf.Move( nMoveX, nMoveY );
+
+ ImplCheckFillAttr();
+ ImplCheckLineAttr();
+ ImplCheckTextAttr();
+ ImplWrite( aTmpMtf );
+ }
+ break;
+
+ case( META_EPS_ACTION ):
+ {
+ const MetaEPSAction* pA = (const MetaEPSAction*) pAction;
+ const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
+ sal_Bool bFound = sal_False;
+
+ for( ULONG i = 0, nCount = aGDIMetaFile.GetActionCount(); ( i < nCount ) && !bFound; i++ )
+ {
+ const MetaAction* pSubstAct = aGDIMetaFile.GetAction( i );
+
+ if( pSubstAct->GetType() == META_BMPSCALE_ACTION )
+ {
+ bFound = sal_True;
+ const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*) pAction;
+ ImplWriteBmpRecord( pBmpScaleAction->GetBitmap(), pBmpScaleAction->GetPoint(),
+ pBmpScaleAction->GetSize(), WIN_SRCCOPY );
+ }
+ }
+ }
+ break;
+
+ case META_BMP_ACTION:
+ {
+ const MetaBmpAction* pA = (const MetaBmpAction *) pAction;
+ ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetBitmap().GetSizePixel(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPSCALE_ACTION:
+ {
+ const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pAction;
+ ImplWriteBmpRecord( pA->GetBitmap(), pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPSCALEPART_ACTION:
+ {
+ const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pAction;
+ Bitmap aTmp( pA->GetBitmap() );
+
+ if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
+ ImplWriteBmpRecord( aTmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPEX_ACTION:
+ {
+ const MetaBmpExAction* pA = (const MetaBmpExAction *) pAction;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ ImplWriteBmpRecord( aMsk, pA->GetPoint(), aMsk.GetSizePixel(), WIN_SRCPAINT );
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCAND );
+ }
+ else
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), aBmp.GetSizePixel(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPEXSCALE_ACTION:
+ {
+ const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pAction;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ ImplWriteBmpRecord( aMsk, pA->GetPoint(), pA->GetSize(), WIN_SRCPAINT );
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCAND );
+ }
+ else
+ ImplWriteBmpRecord( aBmp, pA->GetPoint(), pA->GetSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_BMPEXSCALEPART_ACTION:
+ {
+ const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pAction;
+ BitmapEx aBmpEx( pA->GetBitmapEx() );
+ aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
+ Bitmap aBmp( aBmpEx.GetBitmap() );
+ Bitmap aMsk( aBmpEx.GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ ImplWriteBmpRecord( aMsk, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCPAINT );
+ ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCAND );
+ }
+ else
+ ImplWriteBmpRecord( aBmp, pA->GetDestPoint(), pA->GetDestSize(), WIN_SRCCOPY );
+ }
+ break;
+
+ case META_TEXT_ACTION:
+ {
+ const MetaTextAction* pA = (const MetaTextAction*) pAction;
+ const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetPoint(), aText, NULL, 0 );
+ }
+ break;
+
+ case META_TEXTRECT_ACTION:
+ {
+ const MetaTextRectAction* pA = (const MetaTextRectAction*) pAction;
+ const String aText( pA->GetText() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetRect().TopLeft(), aText, NULL, 0 );
+ }
+ break;
+
+ case META_TEXTARRAY_ACTION:
+ {
+ const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pAction;
+ const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetPoint(), aText, pA->GetDXArray(), 0 );
+ }
+ break;
+
+ case META_STRETCHTEXT_ACTION:
+ {
+ const MetaStretchTextAction* pA = (const MetaStretchTextAction*) pAction;
+ const String aText( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+
+ ImplCheckTextAttr();
+ ImplWriteTextRecord( pA->GetPoint(), aText, NULL, pA->GetWidth() );
+ }
+ break;
+
+ case( META_LINECOLOR_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ mbLineChanged = TRUE;
+ }
+ break;
+
+ case( META_FILLCOLOR_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ mbFillChanged = TRUE;
+ }
+ break;
+
+ case( META_TEXTCOLOR_ACTION ):
+ case( META_TEXTLINECOLOR_ACTION ):
+ case( META_TEXTFILLCOLOR_ACTION ):
+ case( META_TEXTALIGN_ACTION ):
+ case( META_FONT_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ mbTextChanged = TRUE;
+ }
+ break;
+
+ case( META_ISECTRECTCLIPREGION_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+
+ ImplBeginRecord( WIN_EMR_INTERSECTCLIPRECT );
+ ImplWriteRect( ( (MetaISectRectClipRegionAction*) pAction )->GetRect() );
+ ImplEndRecord();
+ }
+ break;
+
+ case( META_CLIPREGION_ACTION ):
+ case( META_ISECTREGIONCLIPREGION_ACTION ):
+ case( META_MOVECLIPREGION_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ }
+ break;
+
+ case( META_REFPOINT_ACTION ):
+ case( META_MAPMODE_ACTION ):
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ break;
+
+ case( META_PUSH_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+
+ ImplBeginRecord( WIN_EMR_SAVEDC );
+ ImplEndRecord();
+ }
+ break;
+
+ case( META_POP_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+
+ ImplBeginRecord( WIN_EMR_RESTOREDC );
+ (*mpStm) << (INT32) -1;
+ ImplEndRecord();
+
+ ImplWriteRasterOp( maVDev.GetRasterOp() );
+ mbLineChanged = mbFillChanged = mbTextChanged = TRUE;
+ }
+ break;
+
+ case( META_RASTEROP_ACTION ):
+ {
+ ( (MetaAction*) pAction )->Execute( &maVDev );
+ ImplWriteRasterOp( ( (MetaRasterOpAction*) pAction )->GetRasterOp() );
+ }
+ break;
+
+ case( META_MASK_ACTION ):
+ case( META_MASKSCALE_ACTION ):
+ case( META_MASKSCALEPART_ACTION ):
+ case( META_WALLPAPER_ACTION ):
+ case( META_TEXTLINE_ACTION ):
+ case( META_COMMENT_ACTION ):
+ case( META_GRADIENTEX_ACTION ):
+ {
+ // !!! >>> we don't want to support these actions
+ }
+ break;
+
+ default:
+ DBG_ERROR( ( ByteString( "SVGActionWriter::ImplWriteActions: unsupported MetaAction #" ) += ByteString( nType ) ).GetBuffer() );
+ break;
+ }
+ }
+}
diff --git a/svtools/source/filter.vcl/wmf/emfwr.hxx b/svtools/source/filter.vcl/wmf/emfwr.hxx
new file mode 100644
index 000000000000..f88edaeb92a6
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/emfwr.hxx
@@ -0,0 +1,129 @@
+/*************************************************************************
+ *
+ * $RCSfile: emfwr.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _EMFWR_HXX
+#define _EMFWR_HXX
+
+#include <tools/debug.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/virdev.hxx>
+#include "fltcall.hxx"
+
+// -------------
+// - EMFWriter -
+// -------------
+
+class EMFWriter
+{
+private:
+
+ VirtualDevice maVDev;
+ PFilterCallback mpCallback;
+ void* mpCallerData;
+ SvStream* mpStm;
+ BOOL* mpHandlesUsed;
+ ULONG mnHandleCount;
+ ULONG mnLastPercent;
+ ULONG mnRecordCount;
+ ULONG mnRecordPos;
+ BOOL mbRecordOpen;
+ BOOL mbLineChanged;
+ ULONG mnLineHandle;
+ BOOL mbFillChanged;
+ ULONG mnFillHandle;
+ BOOL mbTextChanged;
+ ULONG mnTextHandle;
+
+ void ImplBeginRecord( ULONG nType );
+ void ImplEndRecord();
+
+ ULONG ImplAcquireHandle();
+ void ImplReleaseHandle( ULONG nHandle );
+
+ BOOL ImplPrepareHandleSelect( ULONG& rHandle, ULONG nSelectType );
+ void ImplCheckLineAttr();
+ void ImplCheckFillAttr();
+ void ImplCheckTextAttr();
+
+ void ImplWriteColor( const Color& rColor );
+ void ImplWriteRasterOp( RasterOp eRop );
+ void ImplWriteExtent( long nExtent );
+ void ImplWritePoint( const Point& rPoint );
+ void ImplWriteSize( const Size& rSize);
+ void ImplWriteRect( const Rectangle& rRect );
+ void ImplWritePolygonRecord( const Polygon& rPoly, BOOL bClose );
+ void ImplWritePolyPolygonRecord( const PolyPolygon& rPolyPoly );
+ void ImplWriteBmpRecord( const Bitmap& rBmp, const Point& rPt, const Size& rSz, UINT32 nROP );
+ void ImplWriteTextRecord( const Point& rPos, const String rText, const long* pDXArray, UINT32 nWidth );
+
+ void ImplWrite( const GDIMetaFile& rMtf );
+
+public:
+
+ EMFWriter() {}
+
+ BOOL WriteEMF( const GDIMetaFile& rMtf, SvStream& rOStm,
+ PFilterCallback pCallback, void* pCallerData );
+};
+
+#endif // _EMFWR_HXX
diff --git a/svtools/source/filter.vcl/wmf/enhwmf.cxx b/svtools/source/filter.vcl/wmf/enhwmf.cxx
new file mode 100644
index 000000000000..ed2c10be2dd7
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/enhwmf.cxx
@@ -0,0 +1,1077 @@
+/*************************************************************************
+ *
+ * $RCSfile: enhwmf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "winmtf.hxx"
+
+//=========================== GDI-Array ===================================
+
+#define EMR_HEADER 1
+#define EMR_POLYBEZIER 2
+#define EMR_POLYGON 3
+#define EMR_POLYLINE 4
+#define EMR_POLYBEZIERTO 5
+#define EMR_POLYLINETO 6
+#define EMR_POLYPOLYLINE 7
+#define EMR_POLYPOLYGON 8
+#define EMR_SETWINDOWEXTEX 9
+#define EMR_SETWINDOWORGEX 10
+#define EMR_SETVIEWPORTEXTEX 11
+#define EMR_SETVIEWPORTORGEX 12
+#define EMR_SETBRUSHORGEX 13
+#define EMR_EOF 14
+#define EMR_SETPIXELV 15
+#define EMR_SETMAPPERFLAGS 16
+#define EMR_SETMAPMODE 17
+#define EMR_SETBKMODE 18
+#define EMR_SETPOLYFILLMODE 19
+#define EMR_SETROP2 20
+#define EMR_SETSTRETCHBLTMODE 21
+#define EMR_SETTEXTALIGN 22
+#define EMR_SETCOLORADJUSTMENT 23
+#define EMR_SETTEXTCOLOR 24
+#define EMR_SETBKCOLOR 25
+#define EMR_OFFSETCLIPRGN 26
+#define EMR_MOVETOEX 27
+#define EMR_SETMETARGN 28
+#define EMR_EXCLUDECLIPRECT 29
+#define EMR_INTERSECTCLIPRECT 30
+#define EMR_SCALEVIEWPORTEXTEX 31
+#define EMR_SCALEWINDOWEXTEX 32
+#define EMR_SAVEDC 33
+#define EMR_RESTOREDC 34
+#define EMR_SETWORLDTRANSFORM 35
+#define EMR_MODIFYWORLDTRANSFORM 36
+#define EMR_SELECTOBJECT 37
+#define EMR_CREATEPEN 38
+#define EMR_CREATEBRUSHINDIRECT 39
+#define EMR_DELETEOBJECT 40
+#define EMR_ANGLEARC 41
+#define EMR_ELLIPSE 42
+#define EMR_RECTANGLE 43
+#define EMR_ROUNDRECT 44
+#define EMR_ARC 45
+#define EMR_CHORD 46
+#define EMR_PIE 47
+#define EMR_SELECTPALETTE 48
+#define EMR_CREATEPALETTE 49
+#define EMR_SETPALETTEENTRIES 50
+#define EMR_RESIZEPALETTE 51
+#define EMR_REALIZEPALETTE 52
+#define EMR_EXTFLOODFILL 53
+#define EMR_LINETO 54
+#define EMR_ARCTO 55
+#define EMR_POLYDRAW 56
+#define EMR_SETARCDIRECTION 57
+#define EMR_SETMITERLIMIT 58
+#define EMR_BEGINPATH 59
+#define EMR_ENDPATH 60
+#define EMR_CLOSEFIGURE 61
+#define EMR_FILLPATH 62
+#define EMR_STROKEANDFILLPATH 63
+#define EMR_STROKEPATH 64
+#define EMR_FLATTENPATH 65
+#define EMR_WIDENPATH 66
+#define EMR_SELECTCLIPPATH 67
+#define EMR_ABORTPATH 68
+
+#define EMR_GDICOMMENT 70
+#define EMR_FILLRGN 71
+#define EMR_FRAMERGN 72
+#define EMR_INVERTRGN 73
+#define EMR_PAINTRGN 74
+#define EMR_EXTSELECTCLIPRGN 75
+#define EMR_BITBLT 76
+#define EMR_STRETCHBLT 77
+#define EMR_MASKBLT 78
+#define EMR_PLGBLT 79
+#define EMR_SETDIBITSTODEVICE 80
+#define EMR_STRETCHDIBITS 81
+#define EMR_EXTCREATEFONTINDIRECTW 82
+#define EMR_EXTTEXTOUTA 83
+#define EMR_EXTTEXTOUTW 84
+#define EMR_POLYBEZIER16 85
+#define EMR_POLYGON16 86
+#define EMR_POLYLINE16 87
+#define EMR_POLYBEZIERTO16 88
+#define EMR_POLYLINETO16 89
+#define EMR_POLYPOLYLINE16 90
+#define EMR_POLYPOLYGON16 91
+#define EMR_POLYDRAW16 92
+#define EMR_CREATEMONOBRUSH 93
+#define EMR_CREATEDIBPATTERNBRUSHPT 94
+#define EMR_EXTCREATEPEN 95
+#define EMR_POLYTEXTOUTA 96
+#define EMR_POLYTEXTOUTW 97
+#define EMR_SETICMMODE 98
+#define EMR_CREATECOLORSPACE 99
+#define EMR_SETCOLORSPACE 100
+#define EMR_DELETECOLORSPACE 101
+#define EMR_GLSRECORD 102
+#define EMR_GLSBOUNDEDRECORD 103
+#define EMR_PIXELFORMAT 104
+
+//-----------------------------------------------------------------------------------
+
+BOOL EnhWMFReader::ReadEnhWMF() // SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, PFilterCallback pcallback, void * pcallerdata)
+{
+ UINT32 nStretchBltMode = 0;
+ UINT32 nRecType, nRecSize, nNextPos;
+ UINT32 nWidth, nHeight, nPoints, nColor, nIndex;
+ UINT32 nDat32, nNom1, nDen1, nNom2, nDen2;
+ INT32 nX32, nY32, nx32, ny32;
+ INT16 nX16, nY16;
+
+ BOOL bFlag, bStatus = ReadHeader();
+
+ while( bStatus && nRecordCount-- )
+ {
+ *pWMF >> nRecType >> nRecSize;
+
+ if ( ( nRecSize < 8 ) || ( nRecSize & 3 ) ) // Parameter sind immer durch 4 teilbar
+ {
+ bStatus = FALSE;
+ break;
+ }
+ nNextPos = pWMF->Tell() + ( nRecSize - 8 );
+
+ if( aBmpSaveList.Count() && ( nRecType != EMR_STRETCHBLT ) && ( nRecType != EMR_STRETCHDIBITS ) )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+
+ bFlag = FALSE;
+
+ switch( nRecType )
+ {
+ case EMR_HEADER : // wir haben schon laengst einen header eingelesen
+ break;
+
+ case EMR_POLYBEZIER :
+ break;
+
+ case EMR_POLYGON :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ Polygon aPoly( (UINT16)nPoints );
+ for( UINT16 k = 0; k < (UINT16)nPoints; k++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ aPoly[ k ] = Point( nX32, nY32 );
+ }
+ pOut->DrawPolygon( aPoly );
+ }
+ break;
+
+ case EMR_POLYBEZIERTO :
+ break;
+
+ case EMR_POLYLINETO :
+ bFlag = TRUE;
+ case EMR_POLYLINE :
+ {
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> nPoints;
+ UINT16 i = 0;
+ if ( bFlag )
+ {
+ i++;
+ nPoints++;
+ }
+ Polygon aPolygon( (UINT16)nPoints );
+ for ( ; i < (UINT16)nPoints; i++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ aPolygon[ i ] = Point( nX32, nY32 );
+ }
+ pOut->DrawPolyLine( aPolygon, bFlag );
+ }
+ break;
+
+ case EMR_POLYPOLYLINE :
+ {
+ UINT16* pnPoints;
+
+ INT32 i, nPoly;
+ pWMF->SeekRel( 0x10 );
+
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> i;
+
+ // Anzahl der Punkte eines jeden Polygons holen, Gesammtzahl der Punkte ermitteln:
+ pnPoints = new UINT16[ nPoly ];
+
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+
+ // Polygonpunkte holen:
+
+ for ( i = 0; i < nPoly; i++ )
+ {
+ Polygon aPoly( pnPoints[ i ] );
+ for( UINT16 k = 0; k < pnPoints[ i ]; k++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ aPoly[ k ] = Point( nX32, nY32 );
+ }
+ pOut->DrawPolyLine( aPoly, FALSE );
+ }
+ delete pnPoints;
+ }
+ break;
+
+ case EMR_POLYPOLYGON :
+ {
+ UINT16* pnPoints;
+ Point* pPtAry;
+
+ INT32 i, nPoly, nGesPoints;
+ pWMF->SeekRel( 0x10 );
+
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> nGesPoints;
+
+ // Anzahl der Punkte eines jeden Polygons holen, Gesammtzahl der Punkte ermitteln:
+ pnPoints = new UINT16[ nPoly ];
+
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+ // Polygonpunkte holen:
+ pPtAry = (Point*) new char[ nGesPoints * sizeof(Point) ];
+
+ for ( i = 0; i < nGesPoints; i++ )
+ {
+ *pWMF >> nX32 >> nY32;
+ pPtAry[ i ] = Point( nX32, nY32 );
+ }
+ // PolyPolygon Actions erzeugen
+ PolyPolygon aPolyPoly( (UINT16)nPoly, pnPoints, pPtAry );
+
+ pOut->DrawPolyPolygon( aPolyPoly );
+ delete (char*) pPtAry;
+ delete pnPoints;
+ }
+ break;
+
+ case EMR_SETWINDOWEXTEX :
+ { // #75383#
+ *pWMF >> nWidth >> nHeight;
+ if( nWidth > 1 && nHeight > 1 )
+ pOut->SetWinExt( Size( nWidth, nHeight ) );
+ }
+ break;
+
+ case EMR_SETWINDOWORGEX :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->SetWinOrg( Point( nX32, nY32 ) );
+ }
+ break;
+
+ case EMR_SETVIEWPORTEXTEX :
+ case EMR_SETVIEWPORTORGEX :
+ break;
+
+ case EMR_SCALEVIEWPORTEXTEX :
+ {
+ *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2;
+ pOut->ScaleDevExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
+ }
+ break;
+
+ case EMR_SCALEWINDOWEXTEX :
+ {
+ *pWMF >> nNom1 >> nDen1 >> nNom2 >> nDen2;
+ pOut->ScaleWinExt( (double)nNom1 / nDen1, (double)nNom2 / nDen2 );
+ }
+ break;
+
+ case EMR_SETBRUSHORGEX :
+ break;
+ case EMR_EOF :
+ nRecordCount = 0; // #76846#
+ break;
+
+ case EMR_SETPIXELV :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->DrawPixel( Point( nX32, nY32 ), ReadColor() );
+ }
+ break;
+
+ case EMR_SETMAPPERFLAGS :
+ break;
+
+ case EMR_SETMAPMODE :
+ {
+ UINT32 nMapMode;
+ *pWMF >> nMapMode;
+ if ( nMapMode )
+ break;
+ }
+ break;
+
+ case EMR_SETBKMODE :
+ {
+ *pWMF >> nDat32;
+ pOut->SetBkMode( nDat32 );
+ }
+ break;
+
+ case EMR_SETPOLYFILLMODE :
+ break;
+
+ case EMR_SETROP2 :
+ {
+ *pWMF >> nDat32;
+ pOut->SetRasterOp( nDat32 );
+ }
+ break;
+
+ case EMR_SETSTRETCHBLTMODE :
+ {
+ *pWMF >> nStretchBltMode;
+ }
+ break;
+
+ case EMR_SETTEXTALIGN :
+ {
+ *pWMF >> nDat32;
+ pOut->SetTextAlign( nDat32 );
+ }
+ break;
+
+ case EMR_SETCOLORADJUSTMENT :
+ break;
+
+ case EMR_SETTEXTCOLOR :
+ {
+ pOut->SetTextColor( ReadColor() );
+ }
+ break;
+
+ case EMR_SETBKCOLOR :
+ {
+ pOut->SetBkColor( ReadColor() );
+ }
+ break;
+
+ case EMR_OFFSETCLIPRGN :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->MoveClipRegion( Size( nX32, nY32 ) );
+ }
+ break;
+
+ case EMR_MOVETOEX :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->MoveTo( Point( nX32, nY32 ) );
+ }
+ break;
+
+ case EMR_SETMETARGN :
+ case EMR_EXCLUDECLIPRECT :
+ break;
+
+ case EMR_INTERSECTCLIPRECT :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
+ pOut->IntersectClipRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
+ }
+ break;
+
+ case EMR_SAVEDC :
+ {
+ pOut->Push();
+ }
+ break;
+
+ case EMR_RESTOREDC :
+ {
+ pOut->Pop();
+ }
+ break;
+
+ case EMR_SETWORLDTRANSFORM :
+ {
+ XForm aTempXForm;
+ *pWMF >> aTempXForm.eM11 >> aTempXForm.eM12 >> aTempXForm.eM21 >> aTempXForm.eM22 >> aTempXForm.eDx >> aTempXForm.eDy;
+ pOut->SetWorldTransform( aTempXForm );
+ }
+ break;
+
+ case EMR_MODIFYWORLDTRANSFORM :
+ {
+ UINT32 nMode;
+ XForm aTempXForm;
+ *pWMF >> aTempXForm.eM11 >> aTempXForm.eM12 >> aTempXForm.eM21 >> aTempXForm.eM22 >> aTempXForm.eDx >> aTempXForm.eDy >> nMode;
+ pOut->ModifyWorldTransform( aTempXForm, nMode );
+ }
+ break;
+
+ case EMR_SELECTOBJECT :
+ {
+ *pWMF >> nIndex;
+ pOut->SelectObject( nIndex );
+ }
+ break;
+
+ case EMR_CREATEPEN :
+ {
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+
+ LineInfo aLineInfo;
+ UINT32 nStyle;
+ Size aSize;
+
+ *pWMF >> nStyle >> aSize.Width() >> aSize.Height();
+
+ if ( aSize.Width() )
+ aLineInfo.SetWidth( aSize.Width() );
+
+ BOOL bTransparent = FALSE;
+ UINT16 nDashCount = 0;
+ UINT16 nDotCount = 0;
+ switch( nStyle )
+ {
+ case PS_DASHDOTDOT :
+ nDotCount++;
+ case PS_DASHDOT :
+ nDashCount++;
+ case PS_DOT :
+ nDotCount++;
+ break;
+ case PS_DASH :
+ nDashCount++;
+ break;
+ case PS_NULL :
+ bTransparent = TRUE;
+ aLineInfo.SetStyle( LINE_NONE );
+ break;
+ default :
+ case PS_INSIDEFRAME :
+ case PS_SOLID :
+ aLineInfo.SetStyle( LINE_SOLID );
+ }
+ if ( nDashCount | nDotCount )
+ {
+ aLineInfo.SetStyle( LINE_DASH );
+ aLineInfo.SetDashCount( nDashCount );
+ aLineInfo.SetDotCount( nDotCount );
+ }
+ pOut->CreateObject( nIndex, GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
+ }
+ }
+ break;
+ case EMR_CREATEBRUSHINDIRECT :
+ {
+ UINT32 nStyle;
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ *pWMF >> nStyle;
+ pOut->CreateObject( nIndex, GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? TRUE : FALSE ) );
+ }
+ }
+ break;
+ case EMR_DELETEOBJECT :
+ {
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ pOut->DeleteObject( nIndex );
+ }
+ break;
+
+ case EMR_ANGLEARC :
+ break;
+
+ case EMR_ELLIPSE :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
+ pOut->DrawEllipse( ReadRectangle( nX32, nY32, nx32, ny32 ) );
+ }
+ break;
+
+ case EMR_RECTANGLE :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32;
+ pOut->DrawRect( ReadRectangle( nX32, nY32, nx32, ny32 ) );
+ }
+ break;
+
+ case EMR_ROUNDRECT :
+ {
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nWidth >> nHeight;
+ Size aSize( Size( nWidth, nHeight ) );
+ pOut->DrawRoundRect( ReadRectangle( nX32, nY32, nx32, ny32 ), aSize );
+ }
+ break;
+
+ case EMR_ARC :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
+ }
+ break;
+
+ case EMR_CHORD :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ pOut->DrawChord( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
+ }
+ break;
+
+ case EMR_PIE :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ pOut->DrawPie( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ) );
+ }
+ break;
+
+ case EMR_SELECTPALETTE :
+ case EMR_CREATEPALETTE :
+ case EMR_SETPALETTEENTRIES :
+ case EMR_RESIZEPALETTE :
+ case EMR_REALIZEPALETTE :
+ case EMR_EXTFLOODFILL :
+ break;
+
+ case EMR_LINETO :
+ {
+ *pWMF >> nX32 >> nY32;
+ pOut->LineTo( Point( nX32, nY32 ) );
+ }
+ break;
+
+ case EMR_ARCTO :
+ {
+ UINT32 nStartX, nStartY, nEndX, nEndY;
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nStartX >> nStartY >> nEndX >> nEndY;
+ pOut->DrawArc( ReadRectangle( nX32, nY32, nx32, ny32 ), Point( nStartX, nStartY ), Point( nEndX, nEndY ), TRUE );
+ }
+ break;
+ case EMR_POLYDRAW :
+ case EMR_SETARCDIRECTION :
+ case EMR_SETMITERLIMIT :
+ case EMR_BEGINPATH :
+ case EMR_ENDPATH :
+ case EMR_CLOSEFIGURE :
+ case EMR_FILLPATH :
+ case EMR_STROKEANDFILLPATH :
+ case EMR_STROKEPATH :
+ case EMR_FLATTENPATH :
+ case EMR_WIDENPATH :
+ case EMR_SELECTCLIPPATH :
+ case EMR_ABORTPATH :
+
+ case EMR_GDICOMMENT :
+ case EMR_FILLRGN :
+ case EMR_FRAMERGN :
+ case EMR_INVERTRGN :
+ case EMR_PAINTRGN :
+ case EMR_EXTSELECTCLIPRGN :
+ break;
+ case EMR_BITBLT :
+ {
+ UINT32 nRasterOp;
+ Size aDestExt;
+ Point aDestOrg;
+ Bitmap aBmp;
+
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> nX32 >> nY32 >> nx32 >> ny32 >> nRasterOp;
+ aDestOrg = Point( nX32, nY32 );
+ aDestExt = Size( nx32, ny32 );
+ *pWMF >> nX32 >> nY32 >> nColor;
+
+ UINT32 nNewRop = R2_BLACK;
+ switch( nRasterOp )
+ {
+ case DSTINVERT :
+ nNewRop = R2_NOT;
+ break;
+ case 0x00990066 :
+ case SRCINVERT:
+ nNewRop = R2_XORPEN;
+ break;
+ case BLACKNESS :
+ nColor = 0;
+ break;
+ case WHITENESS :
+ nColor = 0xffffff;
+ break;
+ }
+ pOut->Push();
+ UINT32 nOldRop = pOut->SetRasterOp( nNewRop );
+ pOut->DrawRect( Rectangle( aDestOrg, aDestExt ) );
+ pOut->SetRasterOp( nOldRop );
+ pOut->Pop();
+ }
+ break;
+
+ case EMR_STRETCHBLT :
+ {
+ INT32 xDest, yDest, cxDest, cyDest, xSrc, ySrc, cxSrc, cySrc;
+ UINT32 dwRop, iUsageSrc, offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc;
+ XForm xformSrc;
+
+ UINT32 nStartPos = pWMF->Tell() - 8;
+
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> xDest >> yDest >> cxDest >> cyDest >> dwRop >> xSrc >> ySrc >> xformSrc.eM11 >> xformSrc.eM12 >>
+ xformSrc.eM21 >> xformSrc.eM22 >> xformSrc.eDx >> xformSrc.eDy >> nColor >> iUsageSrc >> offBmiSrc >>
+ cbBmiSrc >> offBitsSrc >> cbBitsSrc >> cxSrc >> cySrc;
+
+ if ( offBmiSrc )
+ {
+ Bitmap aBitmap;
+ Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
+
+ UINT32 nSize = cbBmiSrc + cbBitsSrc + 14;
+ char* pBuf = new char[ nSize ];
+ SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
+ aTmp.ObjectOwnsMemory( TRUE );
+ aTmp << (BYTE)'B'
+ << (BYTE)'M'
+ << (UINT32)cbBitsSrc
+ << (UINT16)0
+ << (UINT16)0
+ << (UINT32)cbBmiSrc + 14;
+ pWMF->Seek( nStartPos + offBmiSrc );
+ pWMF->Read( pBuf + 14, cbBmiSrc );
+ pWMF->Seek( nStartPos + offBitsSrc );
+ pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
+ aTmp.Seek( 0 );
+ aBitmap.Read( aTmp, TRUE );
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ }
+ else
+ {
+ if( aBmpSaveList.Count() )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+
+ Point aDestOrg = Point( xDest, yDest );
+ Size aDestExt = Size( cxDest, cyDest );
+
+ UINT32 nNewRop = R2_BLACK;
+ switch( dwRop )
+ {
+ case DSTINVERT :
+ nNewRop = R2_NOT;
+ break;
+ case 0x00990066 :
+ case SRCINVERT:
+ nNewRop = R2_XORPEN;
+ break;
+ case BLACKNESS :
+ nColor = 0;
+ break;
+ case WHITENESS :
+ nColor = 0xffffff;
+ break;
+ }
+ pOut->Push();
+ UINT32 nOldRop = pOut->SetRasterOp( nNewRop );
+ pOut->DrawRect( Rectangle( aDestOrg, aDestExt ), FALSE );
+ pOut->SetRasterOp( nOldRop );
+ pOut->Pop();
+ }
+ }
+ break;
+
+ case EMR_STRETCHDIBITS :
+ {
+ INT32 xDest, yDest, xSrc, ySrc, cxSrc, cySrc, cxDest, cyDest;
+ UINT32 offBmiSrc, cbBmiSrc, offBitsSrc, cbBitsSrc, iUsageSrc, dwRop;
+ UINT32 nStartPos = pWMF->Tell() - 8;
+
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> xDest >> yDest >> xSrc >> ySrc >> cxSrc >> cySrc >> offBmiSrc >> cbBmiSrc >> offBitsSrc
+ >> cbBitsSrc >> iUsageSrc >> dwRop >> cxDest >> cyDest;
+
+ Bitmap aBitmap;
+ Rectangle aRect( Point( xDest, yDest ), Size( cxDest+1, cyDest+1 ) );
+
+ UINT32 nSize = cbBmiSrc + cbBitsSrc + 14;
+ char* pBuf = new char[ nSize ];
+ SvMemoryStream aTmp( pBuf, nSize, STREAM_READ | STREAM_WRITE );
+ aTmp.ObjectOwnsMemory( TRUE );
+ aTmp << (BYTE)'B'
+ << (BYTE)'M'
+ << (UINT32)cbBitsSrc
+ << (UINT16)0
+ << (UINT16)0
+ << (UINT32)cbBmiSrc + 14;
+ pWMF->Seek( nStartPos + offBmiSrc );
+ pWMF->Read( pBuf + 14, cbBmiSrc );
+ pWMF->Seek( nStartPos + offBitsSrc );
+ pWMF->Read( pBuf + 14 + cbBmiSrc, cbBitsSrc );
+ aTmp.Seek( 0 );
+ aBitmap.Read( aTmp, TRUE );
+ aBmpSaveList.Insert( new BSaveStruct( aBitmap, aRect, dwRop ), LIST_APPEND );
+ }
+ break;
+
+ case EMR_MASKBLT :
+ case EMR_PLGBLT :
+ case EMR_SETDIBITSTODEVICE :
+ break;
+
+ case EMR_EXTCREATEFONTINDIRECTW :
+ {
+ *pWMF >> nIndex;
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ LOGFONTW aLogFont;
+ *pWMF >> aLogFont.lfHeight >> aLogFont.lfWidth >> aLogFont.lfEscapement >> aLogFont.lfOrientation >> aLogFont.lfWeight >> aLogFont.lfItalic
+ >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision >> aLogFont.lfClipPrecision
+ >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily;
+
+ for ( int i = 0; i < LF_FACESIZE; i++ )
+ {
+ UINT16 nChar;
+ *pWMF >> nChar;
+ aLogFont.lfFaceName[ i ] = (BYTE)nChar;
+ }
+ pOut->CreateObject( nIndex, GDI_FONT, new WinMtfFontStyle( aLogFont ) );
+ }
+ }
+ break;
+ case EMR_EXTTEXTOUTA :
+ bFlag = TRUE;
+ case EMR_EXTTEXTOUTW :
+ {
+ INT32 nLeft, nTop, nRight, nBottom, ptlReferenceX, ptlReferenceY, nGfxMode, nXScale, nYScale;
+ UINT32 nCurPos, nLen, nOffString, nOptions, offDx;
+
+ nCurPos = pWMF->Tell() - 8;
+
+ *pWMF >> nLeft >> nTop >> nRight >> nBottom >> nGfxMode >> nXScale >> nYScale
+ >> ptlReferenceX >> ptlReferenceY >> nLen >> nOffString >> nOptions;
+
+ pWMF->SeekRel( 0x10 );
+ *pWMF >> offDx;
+
+ Point aPos;
+
+ if ( nGfxMode != GM_COMPATIBLE )
+ aPos = Point( nLeft, nTop );
+ else
+ aPos = Point( ptlReferenceX, ptlReferenceY );
+
+ UINT32 nSize = nLen;
+
+ if ( nLen )
+ {
+ if ( !bFlag )
+ nSize <<= 1;
+
+ BYTE* pBuf = new BYTE[ nSize + 1 ];
+
+ pWMF->Seek( nCurPos + nOffString );
+ pWMF->Read( pBuf, nSize );
+
+ String aText;
+ if( bFlag )
+ aText = String( (char*)pBuf, (USHORT)nLen, pOut->GetCharSet() );
+ else
+ {
+ #ifdef __BIGENDIAN
+ pBuf += nSize;
+ BYTE nTemp;
+ for( UINT32 i = 0; i < nLen; i++ )
+ {
+ pBuf -= 2;
+ pBuf[ 2 ] = *pBuf;
+ }
+ pBuf++;
+ #endif
+ aText = String( (sal_Unicode*)pBuf, (xub_StrLen)nLen );
+ }
+ #ifdef __BIGENDIAN
+ pBuf--;
+ #endif
+ delete[] pBuf;
+ pOut->DrawText( aPos, aText );
+ }
+ }
+ break;
+
+ case EMR_POLYBEZIERTO16 :
+ bFlag = TRUE;
+ case EMR_POLYBEZIER16 :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ UINT16 i = 0;
+ if ( bFlag )
+ {
+ i++;
+ nPoints++;
+ }
+ Polygon aPoly( (UINT16)nPoints );
+ for( ; i < (UINT16)nPoints; i++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPoly[ i ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolyBezier( aPoly, bFlag ); // Line( aPoly, bFlag );
+ }
+ break;
+ case EMR_POLYGON16 :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ Polygon aPoly( (UINT16)nPoints );
+ for( UINT16 k = 0; k < (UINT16)nPoints; k++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPoly[ k ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolygon( aPoly );
+ }
+ break;
+ case EMR_POLYLINETO16 :
+ bFlag = TRUE;
+ case EMR_POLYLINE16 :
+ {
+ pWMF->SeekRel( 16 );
+ *pWMF >> nPoints;
+ UINT16 i = 0;
+ if ( bFlag )
+ {
+ i++;
+ nPoints++;
+ }
+
+ Polygon aPoly( (UINT16)nPoints );
+ for( ; i < (UINT16)nPoints; i++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPoly[ i ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolyLine( aPoly, bFlag );
+ }
+ break;
+
+ case EMR_POLYPOLYLINE16 :
+ {
+ UINT16* pnPoints;
+
+ INT32 i, nPoly, nGesPoints;
+ pWMF->SeekRel( 0x10 );
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> nGesPoints;
+ // Anzahl der Punkte eines jeden Polygons holen, Gesammtzahl der Punkte ermitteln:
+ pnPoints = new UINT16[ nPoly ];
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+ // Polygonpunkte holen:
+ for ( i = 0; i < nPoly; i++ )
+ {
+ Polygon aPolygon( pnPoints[ i ] );
+ for ( UINT16 k = 0; k < pnPoints[ i ]; k++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ aPolygon[ k ] = Point( nX16, nY16 );
+ }
+ pOut->DrawPolyLine( aPolygon );
+ }
+ delete pnPoints;
+ }
+ break;
+
+ case EMR_POLYPOLYGON16 :
+ {
+ UINT16* pnPoints;
+ Point* pPtAry;
+
+ INT32 i, nPoly, nGesPoints;
+ pWMF->SeekRel( 0x10 );
+ // Anzahl der Polygone:
+ *pWMF >> nPoly >> nGesPoints;
+ // Anzahl der Punkte eines jeden Polygons holen, Gesammtzahl der Punkte ermitteln:
+ pnPoints = new UINT16[ nPoly ];
+ for ( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> nPoints;
+ pnPoints[ i ] = (UINT16)nPoints;
+ }
+ // Polygonpunkte holen:
+ pPtAry = (Point*) new char[ nGesPoints * sizeof(Point) ];
+ for ( i = 0; i < nGesPoints; i++ )
+ {
+ *pWMF >> nX16 >> nY16;
+ pPtAry[ i ] = Point( nX16, nY16 );
+ }
+
+ // PolyPolygon Actions erzeugen
+ PolyPolygon aPolyPoly( (UINT16)nPoly, pnPoints, pPtAry );
+ pOut->DrawPolyPolygon( aPolyPoly );
+ delete (char*) pPtAry;
+ delete pnPoints;
+ };
+ break;
+ case EMR_POLYDRAW16 :
+ break;
+ case EMR_CREATEMONOBRUSH :
+ case EMR_CREATEDIBPATTERNBRUSHPT :
+ case EMR_EXTCREATEPEN :
+ case EMR_POLYTEXTOUTA :
+ case EMR_POLYTEXTOUTW :
+ case EMR_SETICMMODE :
+ break;
+ case EMR_CREATECOLORSPACE :
+ case EMR_SETCOLORSPACE :
+ case EMR_DELETECOLORSPACE :
+ break;
+ case EMR_GLSRECORD :
+ case EMR_GLSBOUNDEDRECORD :
+ case EMR_PIXELFORMAT :
+ break;
+
+ default :
+// bStatus = FALSE;
+ break;
+ }
+ pWMF->Seek( nNextPos );
+ }
+ if( aBmpSaveList.Count() )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+
+ if ( bStatus )
+ pWMF->Seek(nEndPos);
+
+ return bStatus;
+};
+
+//-----------------------------------------------------------------------------------
+
+BOOL EnhWMFReader::ReadHeader()
+{
+ Rectangle aPlaceableBound;
+ UINT32 nUINT32, nHeaderSize, nPalEntries;
+ INT32 nLeft, nTop, nRight, nBottom;
+ INT32 nPixX, nPixY, nMillX, nMillY;
+
+ // METAFILEHEADER SPARE ICH MIR HIER
+ // Einlesen des METAHEADER
+ *pWMF >> nUINT32 >> nHeaderSize;
+ if ( nUINT32 != 1 ) // Typ
+ return FALSE;
+
+ // bound size
+ pWMF->SeekRel( 16 );
+
+ // picture frame size
+ *pWMF >> nLeft >> nTop >> nRight >> nBottom;
+ aPlaceableBound.Left() = nLeft;
+ aPlaceableBound.Top() = nTop;
+ aPlaceableBound.Right() = nRight;
+ aPlaceableBound.Bottom() = nBottom;
+
+ *pWMF >> nUINT32; // signature
+
+ if ( nUINT32 != 0x464d4520 )
+ return FALSE;
+
+ *pWMF >> nUINT32; // nVersion
+ *pWMF >> nEndPos; // size of metafile
+ nEndPos += nStartPos;
+ *pWMF >> nRecordCount;
+
+ if ( !nRecordCount )
+ return FALSE;
+
+ pWMF->SeekRel( 0xc );
+ *pWMF >> nPalEntries >> nPixX >> nPixY >> nMillX >> nMillY;
+
+ pOut->SetDevExt( aPlaceableBound.GetSize() );
+ pOut->SetWinOrg( Point( FRound( ( (double) aPlaceableBound.Left() * nPixX ) / ( nMillX * 100.0 ) ),
+ FRound( ( (double) aPlaceableBound.Top() * nPixY ) / ( nMillY * 100.0 ) ) ) );
+ pOut->SetWinExt( Size( FRound( ( (double) aPlaceableBound.GetWidth() * nPixX ) / ( nMillX * 100.0 ) ),
+ FRound( ( (double) aPlaceableBound.GetHeight() * nPixY ) / ( nMillY * 100.0 ) ) ) );
+ pWMF->Seek( nStartPos + nHeaderSize );
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------------
+
+Rectangle EnhWMFReader::ReadRectangle( INT32 x1, INT32 y1, INT32 x2, INT32 y2 )
+{
+ Point aTL ( Point( x1, y1 ) );
+ Point aBR( Point( --x2, --y2 ) );
+ return Rectangle( aTL, aBR );
+}
+
diff --git a/svtools/source/filter.vcl/wmf/makefile.mk b/svtools/source/filter.vcl/wmf/makefile.mk
new file mode 100644
index 000000000000..090588e12bdf
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/makefile.mk
@@ -0,0 +1,97 @@
+#*************************************************************************
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.1.1.1 $
+#
+# last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+#
+# The Contents of this file are made available subject to the terms of
+# either of the following licenses
+#
+# - GNU Lesser General Public License Version 2.1
+# - Sun Industry Standards Source License Version 1.1
+#
+# Sun Microsystems Inc., October, 2000
+#
+# GNU Lesser General Public License Version 2.1
+# =============================================
+# Copyright 2000 by Sun Microsystems, Inc.
+# 901 San Antonio Road, Palo Alto, CA 94303, USA
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License version 2.1, as published by the Free Software Foundation.
+#
+# 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
+#
+#
+# Sun Industry Standards Source License Version 1.1
+# =================================================
+# The contents of this file are subject to the Sun Industry Standards
+# Source License Version 1.1 (the "License"); You may not use this file
+# except in compliance with the License. You may obtain a copy of the
+# License at http://www.openoffice.org/license.html.
+#
+# Software provided under this License is provided on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+# WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+# MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+# See the License for the specific provisions governing your rights and
+# obligations concerning the Software.
+#
+# The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+#
+# Copyright: 2000 by Sun Microsystems, Inc.
+#
+# All Rights Reserved.
+#
+# Contributor(s): _______________________________________
+#
+#
+#
+#*************************************************************************
+
+PRJ=..$/..$/..
+
+PRJNAME=SVTOOLS
+TARGET=wmf
+VERSION=$(UPD)
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : svpre.mk
+.INCLUDE : settings.mk
+.INCLUDE : sv.mk
+
+.IF "$(GUI)"=="WIN"
+LINKFLAGS=$(LINKFLAGS) /PACKC:32768
+.ENDIF
+
+# --- Files --------------------------------------------------------
+
+CXXFILES= wmf.cxx \
+ winmtf.cxx \
+ winwmf.cxx \
+ enhwmf.cxx \
+ emfwr.cxx \
+ wmfwr.cxx
+
+SLOFILES= $(SLO)$/wmf.obj \
+ $(SLO)$/winmtf.obj \
+ $(SLO)$/winwmf.obj \
+ $(SLO)$/enhwmf.obj \
+ $(SLO)$/emfwr.obj \
+ $(SLO)$/wmfwr.obj
+
+# --- Targets -------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/svtools/source/filter.vcl/wmf/winmtf.cxx b/svtools/source/filter.vcl/wmf/winmtf.cxx
new file mode 100644
index 000000000000..e00ff00c7c78
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/winmtf.cxx
@@ -0,0 +1,1262 @@
+/*************************************************************************
+ *
+ * $RCSfile: winmtf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+
+#include "winmtf.hxx"
+#include <vcl/metaact.hxx>
+
+// ------------------------------------------------------------------------
+
+WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont )
+{
+ Size aFontSize( Size( 0, rFont.lfHeight ) );
+
+ aFont.SetName( UniString( (char*)rFont.lfFaceName, RTL_TEXTENCODING_UTF8 ) );
+ aFont.SetSize( aFontSize );
+
+ CharSet eCharSet;
+ switch ( rFont.lfCharSet )
+ {
+ case ANSI_CHARSET:
+ eCharSet = RTL_TEXTENCODING_MS_1252;
+ break;
+
+ case SYMBOL_CHARSET:
+ eCharSet = RTL_TEXTENCODING_SYMBOL;
+ break;
+
+ case OEM_CHARSET:
+ case DEFAULT_CHARSET:
+ case SHIFTJIS_CHARSET:
+ case HANGEUL_CHARSET:
+ case CHINESEBIG5_CHARSET:
+ default:
+ eCharSet = gsl_getSystemTextEncoding();
+ break;
+ }
+ aFont.SetCharSet( eCharSet );
+
+ FontFamily eFamily;
+ switch ( rFont.lfPitchAndFamily & 0xf0 )
+ {
+ case FF_ROMAN:
+ eFamily = FAMILY_ROMAN;
+ break;
+
+ case FF_SWISS:
+ eFamily = FAMILY_SWISS;
+ break;
+
+ case FF_MODERN:
+ eFamily = FAMILY_MODERN;
+ break;
+
+ case FF_SCRIPT:
+ eFamily = FAMILY_SCRIPT;
+ break;
+
+ case FF_DECORATIVE:
+ eFamily = FAMILY_DECORATIVE;
+ break;
+
+ default:
+ eFamily = FAMILY_DONTKNOW;
+ break;
+ }
+ aFont.SetFamily( eFamily );
+
+ FontPitch ePitch;
+ switch ( rFont.lfPitchAndFamily & 0x0f )
+ {
+ case FIXED_PITCH:
+ ePitch = PITCH_FIXED;
+ break;
+
+ case DEFAULT_PITCH:
+ case VARIABLE_PITCH:
+ default:
+ ePitch = PITCH_VARIABLE;
+ break;
+ }
+ aFont.SetPitch( ePitch );
+
+ FontWeight eWeight;
+ if( rFont.lfWeight <= FW_THIN )
+ eWeight = WEIGHT_THIN;
+ else if( rFont.lfWeight <= FW_ULTRALIGHT )
+ eWeight = WEIGHT_ULTRALIGHT;
+ else if( rFont.lfWeight <= FW_LIGHT )
+ eWeight = WEIGHT_LIGHT;
+ else if( rFont.lfWeight < FW_MEDIUM )
+ eWeight = WEIGHT_NORMAL;
+ else if( rFont.lfWeight == FW_MEDIUM )
+ eWeight = WEIGHT_MEDIUM;
+ else if( rFont.lfWeight <= FW_SEMIBOLD )
+ eWeight = WEIGHT_SEMIBOLD;
+ else if( rFont.lfWeight <= FW_BOLD )
+ eWeight = WEIGHT_BOLD;
+ else if( rFont.lfWeight <= FW_ULTRABOLD )
+ eWeight = WEIGHT_ULTRABOLD;
+ else
+ eWeight = WEIGHT_BLACK;
+ aFont.SetWeight( eWeight );
+
+ if( rFont.lfItalic )
+ aFont.SetItalic( ITALIC_NORMAL );
+
+ if( rFont.lfUnderline )
+ aFont.SetUnderline( UNDERLINE_SINGLE );
+
+ if( rFont.lfStrikeOut )
+ aFont.SetStrikeout( STRIKEOUT_SINGLE );
+
+ if ( rFont.lfOrientation )
+ aFont.SetOrientation( (short)rFont.lfOrientation );
+ else
+ aFont.SetOrientation( (short)rFont.lfEscapement );
+};
+
+// ------------------------------------------------------------------------
+
+WinMtf::WinMtf( WinMtfOutput* pWinMtfOutput, SvStream& rStreamWMF, PFilterCallback pcallback, void * pcallerdata ) :
+ pOut ( pWinMtfOutput ),
+ pCallback ( pcallback ),
+ pCallerData ( pcallerdata ),
+ pWMF ( &rStreamWMF )
+{
+ SvLockBytes *pLB = pWMF->GetLockBytes();
+ if ( pLB )
+ pLB->SetSynchronMode( TRUE );
+
+ nStartPos = pWMF->Tell();
+
+ pOut->SetDevOrg( Point() );
+}
+
+// ------------------------------------------------------------------------
+
+WinMtf::~WinMtf()
+{
+ delete pOut;
+}
+
+// ------------------------------------------------------------------------
+
+BOOL WinMtf::Callback( USHORT nPercent )
+{
+ if ( pCallback != NULL )
+ {
+ if( (*pCallback)( pCallerData, nPercent ) )
+ {
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+// ------------------------------------------------------------------------
+
+Color WinMtf::ReadColor()
+{
+ UINT32 nColor;
+ *pWMF >> nColor;
+ return Color( (BYTE)nColor, (BYTE)( nColor >> 8 ), (BYTE)( nColor >> 16 ) );
+};
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+WinMtfOutput::WinMtfOutput() :
+ mnActTextAlign ( TA_LEFT | TA_TOP | TA_NOUPDATECP ),
+ mnBkMode ( OPAQUE ),
+ maBkColor ( COL_WHITE ),
+ mbNopMode ( FALSE ),
+ mbFontChanged ( FALSE ),
+ maActPos ( Point() ),
+ meRasterOp ( ROP_OVERPAINT ),
+ mnEntrys ( 16 )
+{
+ maFont.SetCharSet( gsl_getSystemTextEncoding() );
+ mpGDIObj = new GDIObj*[ mnEntrys ];
+ for ( UINT32 i = 0; i < mnEntrys; i++ )
+ {
+ mpGDIObj[ i ] = NULL;
+ }
+};
+
+//-----------------------------------------------------------------------------------
+
+WinMtfOutput::~WinMtfOutput()
+{
+ while( maSaveStack.Count() )
+ delete maSaveStack.Pop();
+
+ for ( UINT32 i = 0; i < mnEntrys; i++ )
+ {
+ delete mpGDIObj[ i ];
+ }
+ delete mpGDIObj;
+};
+
+//-----------------------------------------------------------------------------------
+
+Point WinMtfOutput::ImplMap( const Point& rPt )
+{
+ if( mnWinExtX && mnWinExtY )
+ {
+ return Point( FRound( ( ( (double) rPt.X() - mnWinOrgX ) * mnDevWidth / mnWinExtX + mnDevOrgX ) * maXForm.eM11 ),
+ FRound( ( ( (double) rPt.Y() - mnWinOrgY ) * mnDevHeight / mnWinExtY + mnDevOrgY ) * maXForm.eM12 ) );
+ }
+ else
+ return Point();
+};
+
+// ------------------------------------------------------------------------
+
+Size WinMtfOutput::ImplMap( const Size& rSz )
+{
+ if( mnWinExtX && mnWinExtY )
+ {
+ return Size( FRound( ( (double) rSz.Width() * mnDevWidth / mnWinExtX ) * maXForm.eM11 ),
+ FRound( ( (double) rSz.Height() * mnDevHeight / mnWinExtY ) * maXForm.eM12 ) );
+ }
+ else
+ return Size();
+}
+
+//-----------------------------------------------------------------------------------
+
+Rectangle WinMtfOutput::ImplMap( const Rectangle& rRect )
+{
+ return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ImplMap( Font& rFont )
+{
+ // !!! HACK: Wir setzen die Breite jetzt immer auf Null,
+ // da OS die Breite unterschiedlich interpretieren;
+ // muss spaeter in SV portabel gemacht werden ( KA 08.02.96 )
+ Size aFontSize = ImplMap ( rFont.GetSize() );
+
+ if( aFontSize.Height() < 0 )
+ aFontSize.Height() *= -1;
+
+ rFont.SetSize( Size( 0, aFontSize.Height() ) );
+
+ if( ( mnWinExtX * mnWinExtY ) < 0 )
+ rFont.SetOrientation( 3600 - rFont.GetOrientation() );
+}
+
+//-----------------------------------------------------------------------------------
+
+Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
+{
+ UINT16 nPoints = rPolygon.GetSize();
+ for ( UINT16 i = 0; i < nPoints; i++ )
+ {
+ rPolygon[ i ] = ImplMap( rPolygon[ i ] );
+ }
+ return rPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
+PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
+{
+ UINT16 nPolys = rPolyPolygon.Count();
+ for ( UINT16 i = 0; i < nPolys; ImplMap( rPolyPolygon[ i++ ] ) );
+ return rPolyPolygon;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SelectObject( INT32 nIndex )
+{
+ GDIObj* pGDIObj = NULL;
+
+ if ( nIndex & ENHMETA_STOCK_OBJECT )
+ pGDIObj = new GDIObj();
+ else
+ {
+ nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
+
+ if ( (UINT32)nIndex < mnEntrys )
+ pGDIObj = mpGDIObj[ nIndex ];
+ }
+
+ if( pGDIObj == NULL )
+ return;
+
+ if ( nIndex & ENHMETA_STOCK_OBJECT )
+ {
+ UINT16 nStockId = (BYTE)nIndex;
+ switch( nStockId )
+ {
+ case WHITE_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ) ) );
+ }
+ break;
+ case LTGRAY_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_LIGHTGRAY ) ) );
+ }
+ break;
+ case GRAY_BRUSH :
+ case DKGRAY_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_GRAY ) ) );
+ }
+ break;
+ case BLACK_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_BLACK ) ) );
+ }
+ break;
+ case NULL_BRUSH :
+ {
+ pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_TRANSPARENT ), TRUE ) );
+ }
+ break;
+ case WHITE_PEN :
+ {
+ pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_WHITE ) ) );
+ }
+ break;
+ case BLACK_PEN :
+ {
+ pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_BLACK ) ) );
+ }
+ break;
+ case NULL_PEN :
+ {
+ pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_TRANSPARENT ), TRUE ) );
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ if ( pGDIObj->pStyle )
+ {
+ switch( pGDIObj->eType )
+ {
+ case GDI_PEN :
+ maLineStyle = (WinMtfLineStyle*)pGDIObj->pStyle;
+ break;
+ case GDI_BRUSH :
+ maFillStyle = (WinMtfFillStyle*)pGDIObj->pStyle;
+ break;
+ case GDI_FONT :
+ {
+ maFont = ((WinMtfFontStyle*)pGDIObj->pStyle)->aFont;
+ if ( ( mnActTextAlign & TA_BASELINE) == TA_BASELINE )
+ maFont.SetAlign( ALIGN_BASELINE );
+ else if( ( mnActTextAlign & TA_BOTTOM) == TA_BOTTOM )
+ maFont.SetAlign( ALIGN_BOTTOM );
+ else
+ maFont.SetAlign( ALIGN_TOP );
+
+ if( mnBkMode == TRANSPARENT )
+ maFont.SetTransparent( TRUE );
+ else
+ {
+ maFont.SetFillColor( maBkColor );
+ maFont.SetTransparent( FALSE );
+ }
+ maFont.SetColor( maTextColor );
+ mbFontChanged = TRUE;
+ }
+ break;
+ }
+ }
+ if ( nIndex & ENHMETA_STOCK_OBJECT )
+ delete pGDIObj;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::Push( BOOL bWinExtSet )
+{
+ SaveStruct* pSave = new SaveStruct;
+
+ pSave->aActPos = maActPos;
+ pSave->nActTextAlign = mnActTextAlign;
+ pSave->nBkMode = mnBkMode;
+ pSave->aBkColor = maBkColor;
+ pSave->bWinExtSet = bWinExtSet;
+ pSave->aLineStyle = maLineStyle;
+ pSave->aFillStyle = maFillStyle;
+ pSave->aTextColor = maTextColor;
+ pSave->aFont = maFont;
+ pSave->bFontChanged = mbFontChanged;
+
+ if ( bWinExtSet )
+ {
+ pSave->nWinOrgX = mnWinOrgX;
+ pSave->nWinOrgY = mnWinOrgY;
+ pSave->nWinExtX = mnWinExtX;
+ pSave->nWinExtY = mnWinExtY;
+ pSave->nDevOrgX = mnDevOrgX;
+ pSave->nDevOrgY = mnDevOrgY;
+ pSave->nDevWidth = mnDevWidth;
+ pSave->nDevHeight = mnDevHeight;
+ }
+ maSaveStack.Push( pSave );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::Pop()
+{
+ // Die aktuellen Daten vom Stack holen
+ if( maSaveStack.Count() )
+ {
+ // Die aktuelle Daten auf dem Stack sichern
+ SaveStruct* pSave = maSaveStack.Pop();
+
+ mnBkMode = pSave->nBkMode;
+ maBkColor = pSave->aBkColor;
+ maActPos = pSave->aActPos;
+ mnActTextAlign = pSave->nActTextAlign;
+ maLineStyle = pSave->aLineStyle;
+ maFillStyle = pSave->aFillStyle;
+ maTextColor = pSave->aTextColor;
+ maFont = pSave->aFont;
+ mbFontChanged = pSave->bFontChanged;
+
+ if ( pSave->bWinExtSet )
+ {
+ mnWinOrgX = pSave->nWinOrgX;
+ mnWinOrgY = pSave->nWinOrgY;
+ mnWinExtX = pSave->nWinExtX;
+ mnWinExtY = pSave->nWinExtY;
+ mnDevOrgX = pSave->nDevOrgX;
+ mnDevOrgY = pSave->nDevOrgY;
+ mnDevWidth = pSave->nDevWidth;
+ mnDevHeight = pSave->nDevHeight;
+ }
+ delete pSave;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetBkMode( UINT32 nMode )
+{
+ maFont.SetTransparent( ( mnBkMode = nMode ) == TRANSPARENT );
+ mbFontChanged = TRUE;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetBkColor( const Color& rColor )
+{
+ maBkColor = rColor;
+ maFont.SetFillColor( rColor );
+ maFont.SetTransparent( mnBkMode == TRANSPARENT );
+ mbFontChanged = TRUE;
+}
+
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetTextColor( const Color& rColor )
+{
+ maTextColor = rColor;
+ maFont.SetColor( rColor );
+ mbFontChanged = TRUE;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::SetTextAlign( UINT32 nAlign )
+{
+ mnActTextAlign = nAlign;
+
+ if ( ( mnActTextAlign & TA_BASELINE ) == TA_BASELINE )
+ maFont.SetAlign( ALIGN_BASELINE );
+ else if( ( mnActTextAlign & TA_BOTTOM ) == TA_BOTTOM )
+ maFont.SetAlign( ALIGN_BOTTOM );
+ else
+ maFont.SetAlign( ALIGN_TOP );
+
+ mbFontChanged = TRUE;
+}
+
+//-----------------------------------------------------------------------------------
+
+UINT32 WinMtfOutput::SetRasterOp( UINT32 nROP2 )
+{
+ UINT32 nRetROP = mnRop;
+ if ( nROP2 != mnRop )
+ {
+ mnRop = nROP2;
+ static WinMtfFillStyle aNopFillStyle;
+ static WinMtfLineStyle aNopLineStyle;
+
+ if ( mbNopMode && ( nROP2 != R2_NOP ) )
+ { // beim uebergang von R2_NOP auf anderen Modus
+ // gesetzten Pen und Brush aktivieren
+ maFillStyle = aNopFillStyle;
+ maLineStyle = aNopLineStyle;
+ mbNopMode = FALSE;
+ }
+ switch( nROP2 )
+ {
+ case R2_NOT:
+ meRasterOp = ROP_INVERT;
+ break;
+
+ case R2_XORPEN:
+ meRasterOp = ROP_XOR;
+ break;
+
+ case R2_NOP:
+ {
+ meRasterOp = ROP_OVERPAINT;
+ if( mbNopMode = FALSE )
+ {
+ aNopFillStyle = maFillStyle;
+ aNopLineStyle = maLineStyle;
+ maFillStyle = WinMtfFillStyle( Color( COL_TRANSPARENT ), TRUE );
+ maLineStyle = WinMtfLineStyle( Color( COL_TRANSPARENT ), TRUE );
+ mbNopMode = TRUE;
+ }
+ }
+ break;
+
+ default:
+ meRasterOp = ROP_OVERPAINT;
+ break;
+ }
+ }
+ return nRetROP;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::ImplResizeObjectArry( UINT32 nNewEntrys )
+{
+ GDIObj** pGDIObj = new GDIObj*[ mnEntrys << 1 ];
+ UINT32 nIndex;
+ for ( nIndex = 0; nIndex < mnEntrys; nIndex++ )
+ pGDIObj[ nIndex ] = mpGDIObj[ nIndex ];
+ for ( mnEntrys = nNewEntrys; nIndex < mnEntrys; pGDIObj[ nIndex++ ] = NULL );
+ delete mpGDIObj, mpGDIObj = pGDIObj;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::CreateObject( GDIObjectType eType, void* pStyle )
+{
+ if ( pStyle )
+ {
+ if ( eType == GDI_FONT )
+ ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
+ else if ( eType == GDI_PEN )
+ {
+ Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
+ if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
+ {
+ aSize.Width() += 1;
+ long nDotLen = ImplMap( aSize ).Width();
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
+ }
+ }
+ }
+ UINT32 nIndex;
+ for ( nIndex = 0; nIndex < mnEntrys; nIndex++ )
+ {
+ if ( mpGDIObj[ nIndex ] == NULL )
+ break;
+ }
+ if ( nIndex == mnEntrys )
+ ImplResizeObjectArry( mnEntrys << 1 );
+
+ mpGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::CreateObject( INT32 nIndex, GDIObjectType eType, void* pStyle )
+{
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
+ if ( pStyle )
+ {
+ if ( eType == GDI_FONT )
+ ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
+ else if ( eType == GDI_PEN )
+ {
+ Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
+ if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
+ {
+ aSize.Width() += 1;
+ long nDotLen = ImplMap( aSize ).Width();
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
+ ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
+ }
+ }
+ }
+ if ( (UINT32)nIndex >= mnEntrys )
+ ImplResizeObjectArry( nIndex + 16 );
+
+ if ( mpGDIObj[ nIndex ] != NULL )
+ delete mpGDIObj[ nIndex ];
+
+ mpGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
+ }
+ else
+ delete pStyle;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DeleteObject( INT32 nIndex )
+{
+ if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
+ {
+ nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
+ delete mpGDIObj[ nIndex ], mpGDIObj[ nIndex ] = NULL;
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfOutput::DrawText( Point& rPosition, String& rText, INT32* pDXArry )
+{
+ rPosition = ImplMap( rPosition );
+
+ if ( pDXArry )
+ {
+ INT32 i, nSum, nLen = rText.Len();
+
+ for( i = 0, nSum = 0; i < nLen; i++ )
+ {
+ INT32 nTemp = ImplMap( Size( pDXArry[ i ], 0 ) ).Width();
+ nSum += nTemp;
+ pDXArry[ i ] = nSum;
+ }
+ }
+}
+
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+//-----------------------------------------------------------------------------------
+
+WinMtfMetaOutput::WinMtfMetaOutput( GDIMetaFile& rGDIMetaFile ) : WinMtfOutput()
+{
+ maLatestLineStyle.aLineColor = Color( 0x12, 0x34, 0x56 );
+ maLatestFillStyle.aFillColor = Color( 0x12, 0x34, 0x56 );
+ mpGDIMetaFile = &rGDIMetaFile;
+ mnPushPopCount = 0;
+
+ mnRop = R2_BLACK + 1;
+ SetRasterOp( R2_BLACK );
+};
+
+//-----------------------------------------------------------------------------------
+
+WinMtfMetaOutput::~WinMtfMetaOutput()
+{
+ while( mnPushPopCount > 0 )
+ {
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ mnPushPopCount--;
+ }
+ mpGDIMetaFile->SetPrefMapMode( MAP_100TH_MM );
+ mpGDIMetaFile->SetPrefSize( Size( mnDevWidth, mnDevHeight ) );
+};
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::UpdateLineStyle()
+{
+ if (!( maLatestLineStyle == maLineStyle ) )
+ {
+ maLatestLineStyle = maLineStyle;
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::UpdateFillStyle()
+{
+ if (!( maLatestFillStyle == maFillStyle ) )
+ {
+ maLatestFillStyle = maFillStyle;
+ mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+UINT32 WinMtfMetaOutput::SetRasterOp( UINT32 nRasterOp )
+{
+ UINT32 nRetROP = WinMtfOutput::SetRasterOp( nRasterOp );
+ if ( nRetROP != nRasterOp )
+ mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
+ return nRetROP;
+};
+
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawPixel( const Point& rSource, const Color& rColor )
+{
+ mpGDIMetaFile->AddAction( new MetaPixelAction( ImplMap( rSource), rColor ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::LineTo( const Point& rPoint )
+{
+ Point aDest( ImplMap( rPoint ) );
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaLineAction( maActPos, aDest, maLineStyle.aLineInfo ) );
+ maActPos = aDest;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawLine( const Point& rSource, const Point& rDest )
+{
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaLineAction( ImplMap( rSource), ImplMap( rDest ), maLineStyle.aLineInfo ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawRect( const Rectangle& rRect, BOOL bEdge )
+{
+ UpdateFillStyle();
+ if ( bEdge )
+ {
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, FALSE ) );
+ mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect ) ),maLineStyle.aLineInfo ) );
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
+ }
+ }
+ else
+ {
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( Color(), FALSE ) );
+ mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawRoundRect( const Rectangle& rRect, const Size& rSize )
+{
+ UpdateLineStyle();
+ UpdateFillStyle();
+ mpGDIMetaFile->AddAction( new MetaRoundRectAction( ImplMap( rRect ), labs( ImplMap( rSize ).Width() ), labs( ImplMap( rSize ).Height() ) ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawEllipse( const Rectangle& rRect )
+{
+ UpdateFillStyle();
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ Point aCenter( ImplMap( rRect.Center() ) );
+ Size aRad( ImplMap( Size( rRect.GetWidth() / 2, rRect.GetHeight() / 2 ) ) );
+
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, FALSE ) );
+ mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, BOOL bTo )
+{
+ UpdateLineStyle();
+ UpdateFillStyle();
+
+ Rectangle aRect( ImplMap( rRect ) );
+ Point aStart( ImplMap( rStart ) );
+ Point aEnd( ImplMap( rEnd ) );
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_ARC ), maLineStyle.aLineInfo ) );
+ else
+ mpGDIMetaFile->AddAction( new MetaArcAction( aRect, aStart, aEnd ) );
+
+ if ( bTo )
+ maActPos = aEnd;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawPie( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
+{
+ UpdateFillStyle();
+
+ Rectangle aRect( ImplMap( rRect ) );
+ Point aStart( ImplMap( rStart ) );
+ Point aEnd( ImplMap( rEnd ) );
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, FALSE ) );
+ mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_PIE ), maLineStyle.aLineInfo ) );
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawChord( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
+{
+ UpdateFillStyle();
+
+ Rectangle aRect( ImplMap( rRect ) );
+ Point aStart( ImplMap( rStart ) );
+ Point aEnd( ImplMap( rEnd ) );
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, FALSE ) );
+ mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_CHORD ), maLineStyle.aLineInfo ) );
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawPolygon( Polygon& rPolygon )
+{
+ UpdateFillStyle();
+
+ if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
+ {
+ USHORT nCount = rPolygon.GetSize();
+ if ( nCount )
+ {
+ if ( rPolygon[ nCount - 1 ] != rPolygon[ 0 ] )
+ {
+ Point aPoint( rPolygon[ 0 ] );
+ rPolygon.Insert( nCount, aPoint );
+ }
+ }
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, FALSE ) );
+ mpGDIMetaFile->AddAction( new MetaPolygonAction( ImplMap( rPolygon ) ) );
+ mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ }
+ else
+ {
+ UpdateLineStyle();
+ mpGDIMetaFile->AddAction( new MetaPolygonAction( ImplMap( rPolygon ) ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon )
+{
+ UpdateLineStyle();
+ UpdateFillStyle();
+ mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( ImplMap( rPolyPolygon ) ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawPolyLine( Polygon& rPolygon, BOOL bTo )
+{
+ UpdateLineStyle();
+ ImplMap( rPolygon );
+ if ( bTo )
+ {
+ rPolygon[ 0 ] = maActPos;
+ maActPos = rPolygon[ rPolygon.GetSize() - 1 ];
+ }
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawPolyBezier( Polygon& rPolygon, BOOL bTo )
+{
+ UpdateLineStyle();
+ UINT16 nPoints = rPolygon.GetSize();
+ if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) )
+ {
+ ImplMap( rPolygon );
+ if ( bTo )
+ {
+ rPolygon[ 0 ] = maActPos;
+ maActPos = rPolygon[ nPoints - 1 ];
+ }
+ // create bezier polygon
+ const USHORT nSegPoints = 25;
+ const USHORT nSegments = ( ( nPoints - 4 ) / 3 ) + 1;
+ Polygon aBezPoly( nSegments * nSegPoints );
+
+ USHORT nSeg, nBezPos, nStartPos;
+ for( nSeg = 0, nBezPos = 0, nStartPos = 0; nSeg < nSegments; nSeg++, nStartPos += 3 )
+ {
+ const Polygon aSegPoly( rPolygon[ nStartPos ], rPolygon[ nStartPos + 1 ],
+ rPolygon[ nStartPos + 3 ], rPolygon[ nStartPos + 2 ],
+ nSegPoints );
+ for( USHORT nSegPos = 0; nSegPos < nSegPoints; )
+ aBezPoly[ nBezPos++ ] = aSegPoly[ nSegPos++ ];
+ }
+
+ if( nBezPos != aBezPoly.GetSize() )
+ aBezPoly.SetSize( nBezPos );
+ mpGDIMetaFile->AddAction( new MetaPolyLineAction( aBezPoly, maLineStyle.aLineInfo ) );
+ }
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::DrawText( Point& rPosition, String& rText, INT32* pDXArry )
+{
+ WinMtfOutput::DrawText( rPosition, rText, pDXArry );
+
+ if( mbFontChanged )
+ {
+ mpGDIMetaFile->AddAction( new MetaFontAction( maFont ) );
+ mpGDIMetaFile->AddAction( new MetaTextAlignAction( maFont.GetAlign() ) );
+ mpGDIMetaFile->AddAction( new MetaTextColorAction( maFont.GetColor() ) );
+ mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
+ mbFontChanged = FALSE;
+ }
+
+ if( mnActTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) )
+ {
+ VirtualDevice aVDev;
+ sal_Int32 nTextWidth;
+
+ aVDev.SetMapMode( MapMode( MAP_100TH_MM ) );
+ aVDev.SetFont( maFont );
+
+ if( pDXArry )
+ {
+ UINT32 nLen = rText.Len();
+ nTextWidth = aVDev.GetTextWidth( rText.GetChar( nLen - 1 ) );
+ if( nLen > 1 )
+ nTextWidth += pDXArry[ nLen - 2 ];
+ }
+ else
+ nTextWidth = aVDev.GetTextWidth( rText );
+
+ if( mnActTextAlign & TA_UPDATECP )
+ rPosition = maActPos;
+
+ if( mnActTextAlign & TA_RIGHT_CENTER )
+ rPosition.X() -= ( ( mnActTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : ( nTextWidth >> 1 );
+
+ if( mnActTextAlign & TA_UPDATECP )
+ maActPos.X() = rPosition.X() + nTextWidth;
+ }
+
+ if( pDXArry )
+ mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDXArry, 0, STRING_LEN ) );
+ else
+ mpGDIMetaFile->AddAction( new MetaTextAction( rPosition, rText, 0, STRING_LEN ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::ResolveBitmapActions( List& rSaveList )
+{
+ for( ULONG i = 0, nCount = rSaveList.Count(); i < nCount; i++ )
+ {
+ BSaveStruct* pSave1 = (BSaveStruct*) rSaveList.GetObject( i );
+ BOOL bDrawn = FALSE;
+
+ UpdateFillStyle();
+
+ if( i < ( nCount - 1 ) )
+ {
+ BSaveStruct* pSave2 = (BSaveStruct*) rSaveList.GetObject( i + 1 );
+
+ if( ( pSave1->aOutRect == pSave2->aOutRect ) &&
+ ( pSave1->nWinRop == SRCPAINT) && ( pSave2->nWinRop == SRCAND ) )
+ {
+ Bitmap aMask( pSave1->aBmp ); aMask.Invert();
+ BitmapEx aBmpEx( pSave2->aBmp, aMask );
+ mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( ImplMap( pSave1->aOutRect.TopLeft() ), ImplMap( pSave1->aOutRect.GetSize() ), aBmpEx ) );
+ bDrawn = TRUE;
+ i++;
+ delete pSave2;
+ }
+ }
+ if( !bDrawn )
+ {
+ UINT32 nNewROP, nOldROP;
+ switch( pSave1->nWinRop )
+ {
+ case DSTINVERT: nNewROP = R2_NOT; break;
+ case SRCINVERT: nNewROP = R2_XORPEN; break;
+ default: nNewROP = R2_BLACK; break;
+ }
+ nOldROP = SetRasterOp( nNewROP );
+ mpGDIMetaFile->AddAction( new MetaBmpScaleAction( ImplMap( pSave1->aOutRect.TopLeft() ), ImplMap( pSave1->aOutRect.GetSize() ), pSave1->aBmp ) );
+ SetRasterOp( nOldROP );
+ }
+ delete pSave1;
+ }
+ rSaveList.Clear();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::IntersectClipRect( const Rectangle& rRect )
+{
+ mpGDIMetaFile->AddAction( new MetaISectRectClipRegionAction( ImplMap( rRect ) ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::MoveClipRegion( const Size& rSize )
+{
+ Size aSize( ImplMap( rSize ) );
+ mpGDIMetaFile->AddAction( new MetaMoveClipRegionAction( aSize.Width(), aSize.Height() ) );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::SetDevOrg( const Point& rPoint )
+{
+ mnDevOrgX = rPoint.X();
+ mnDevOrgY = rPoint.Y();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::SetDevOrgOffset( INT32 nXAdd, INT32 nYAdd )
+{
+ mnDevOrgX += nXAdd;
+ mnDevOrgY += nYAdd;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::SetDevExt( const Size& rSize )
+{
+ mnDevWidth = rSize.Width();
+ mnDevHeight = rSize.Height();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::ScaleDevExt( double fX, double fY )
+{
+ mnDevWidth = FRound( mnDevWidth * fX );
+ mnDevHeight = FRound( mnDevHeight * fY );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::SetWinOrg( const Point& rPoint )
+{
+ mnWinOrgX = rPoint.X();
+ mnWinOrgY = rPoint.Y();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::SetWinOrgOffset( INT32 nXAdd, INT32 nYAdd )
+{
+ mnWinOrgX += nXAdd;
+ mnWinOrgY += nYAdd;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::SetWinExt( const Size& rSize )
+{
+ mnWinExtX = rSize.Width();
+ mnWinExtY = rSize.Height();
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::ScaleWinExt( double fX, double fY )
+{
+ mnWinExtX = FRound( mnWinExtX * fX );
+ mnWinExtY = FRound( mnWinExtY * fY );
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::SetWorldTransform( const XForm& rXForm )
+{
+ maXForm.eM11 = rXForm.eM11;
+ maXForm.eM12 = rXForm.eM12;
+ maXForm.eM21 = rXForm.eM21;
+ maXForm.eM22 = rXForm.eM22;
+ maXForm.eDx = rXForm.eDx;
+ maXForm.eDy = rXForm.eDy;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::ModifyWorldTransform( const XForm& rXForm, UINT32 nMode )
+{
+ switch( nMode )
+ {
+ case MWT_IDENTITY :
+ {
+ maXForm.eM11 = maXForm.eM12 = maXForm.eM21 = maXForm.eM22 = 1.0f;
+ maXForm.eDx = maXForm.eDx = 0.0f;
+ }
+ break;
+
+ case MWT_LEFTMULTIPLY :
+ case MWT_RIGHTMULTIPLY :
+ break;
+ }
+ }
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::Push( BOOL bExtSet )
+{
+ WinMtfOutput::Push( bExtSet );
+ // bei SaveDC muessen wir die verzoegerte Selektion
+ // von Objekten umgehen, damit beim RestoreDC wieder
+ // die richtigen Objekte selektiert werden
+ UpdateLineStyle();
+ UpdateFillStyle();
+ if( mbFontChanged )
+ {
+ mpGDIMetaFile->AddAction( new MetaFontAction( maFont ) );
+ mpGDIMetaFile->AddAction( new MetaTextAlignAction( maFont.GetAlign() ) );
+ mpGDIMetaFile->AddAction( new MetaTextColorAction( maFont.GetColor() ) );
+ mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
+ mbFontChanged = FALSE;
+ }
+ mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_ALL ) );
+ mnPushPopCount++;
+}
+
+//-----------------------------------------------------------------------------------
+
+void WinMtfMetaOutput::Pop()
+{
+ WinMtfOutput::Pop();
+ maLatestLineStyle = maLineStyle;
+ maLatestFillStyle = maFillStyle;
+ if( mnPushPopCount > 0 )
+ {
+ mpGDIMetaFile->AddAction( new MetaPopAction() );
+ mnPushPopCount--;
+ }
+}
+
diff --git a/svtools/source/filter.vcl/wmf/winmtf.hxx b/svtools/source/filter.vcl/wmf/winmtf.hxx
new file mode 100644
index 000000000000..2d129a55ab6b
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/winmtf.hxx
@@ -0,0 +1,687 @@
+/*************************************************************************
+ *
+ * $RCSfile: winmtf.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _WINMTF_HXX
+#define _WINMTF_HXX
+
+#include <math.h>
+#include <stdlib.h>
+#include <sot/object.hxx>
+#ifndef _TOOL_DEBUG_HXX
+#include <tools/debug.hxx>
+#endif
+#ifndef _STACK_HXX
+#include <tools/stack.hxx>
+#endif
+#ifndef _TOOLS_TABLE_HXX
+#include <tools/table.hxx>
+#endif
+#ifndef _DYNARY_HXX
+#include <tools/dynary.hxx>
+#endif
+#ifndef _SV_GRAPH_HXX
+#include <vcl/graph.hxx>
+#endif
+#ifndef _SV_VIRDEV_HXX
+#include <vcl/virdev.hxx>
+#endif
+#ifndef _SV_POLY_HXX
+#include <vcl/poly.hxx>
+#endif
+#ifndef _SV_FONT_HXX
+#include <vcl/font.hxx>
+#endif
+#ifndef _SV_BMPACC_HXX
+#include <vcl/bmpacc.hxx>
+#endif
+#ifndef _SV_LINEINFO_HXX
+#include <vcl/lineinfo.hxx>
+#endif
+#ifndef _FLTCALL_HXX
+#include <fltcall.hxx>
+#endif
+
+
+#define TRANSPARENT 1
+#define OPAQUE 2
+#define BKMODE_LAST 2
+
+/* xform stuff */
+#define MWT_IDENTITY 1
+#define MWT_LEFTMULTIPLY 2
+#define MWT_RIGHTMULTIPLY 3
+
+#define ENHMETA_STOCK_OBJECT 0x80000000
+
+/* Stock Logical Objects */
+#define WHITE_BRUSH 0
+#define LTGRAY_BRUSH 1
+#define GRAY_BRUSH 2
+#define DKGRAY_BRUSH 3
+#define BLACK_BRUSH 4
+#define NULL_BRUSH 5
+#define HOLLOW_BRUSH NULL_BRUSH
+#define WHITE_PEN 6
+#define BLACK_PEN 7
+#define NULL_PEN 8
+#define OEM_FIXED_FONT 10
+#define ANSI_FIXED_FONT 11
+#define ANSI_VAR_FONT 12
+#define SYSTEM_FONT 13
+#define DEVICE_DEFAULT_FONT 14
+#define DEFAULT_PALETTE 15
+#define SYSTEM_FIXED_FONT 16
+
+
+#define R2_BLACK 1
+#define R2_NOTMERGEPEN 2
+#define R2_MASKNOTPEN 3
+#define R2_NOTCOPYPEN 4
+#define R2_MASKPENNOT 5
+#define R2_NOT 6
+#define R2_XORPEN 7
+#define R2_NOTMASKPEN 8
+#define R2_MASKPEN 9
+#define R2_NOTXORPEN 10
+#define R2_NOP 11
+#define R2_MERGENOTPEN 12
+#define R2_COPYPEN 13
+#define R2_MERGEPENNOT 14
+#define R2_MERGEPEN 15
+#define R2_WHITE 16
+
+/* Mapping Modes */
+#define MM_TEXT 1
+#define MM_LOMETRIC 2
+#define MM_HIMETRIC 3
+#define MM_LOENGLISH 4
+#define MM_HIENGLISH 5
+#define MM_TWIPS 6
+#define MM_ISOTROPIC 7
+#define MM_ANISOTROPIC 8
+
+
+/* Graphics Modes */
+#define GM_COMPATIBLE 1
+#define GM_ADVANCED 2
+#define GM_LAST 2
+
+/* StretchBlt() Modes */
+#define BLACKONWHITE 1
+#define WHITEONBLACK 2
+#define COLORONCOLOR 3
+#define HALFTONE 4
+#define MAXSTRETCHBLTMODE 4
+#define STRETCH_ANDSCANS BLACKONWHITE
+#define STRETCH_ORSCANS WHITEONBLACK
+#define STRETCH_DELETESCANS COLORONCOLOR
+#define STRETCH_HALFTONE HALFTONE
+
+#define LF_FACESIZE 32
+
+struct LOGFONTW
+{
+ INT32 lfHeight;
+ INT32 lfWidth;
+ INT32 lfEscapement;
+ INT32 lfOrientation;
+ INT32 lfWeight;
+ BYTE lfItalic;
+ BYTE lfUnderline;
+ BYTE lfStrikeOut;
+ BYTE lfCharSet;
+ BYTE lfOutPrecision;
+ BYTE lfClipPrecision;
+ BYTE lfQuality;
+ BYTE lfPitchAndFamily;
+ BYTE lfFaceName[ LF_FACESIZE ];
+};
+
+#define TA_NOUPDATECP 0x0000
+#define TA_UPDATECP 0x0001
+#define TA_LEFT 0x0000
+#define TA_RIGHT 0x0002
+#define TA_CENTER 0x0006
+#define TA_RIGHT_CENTER (TA_RIGHT | TA_CENTER)
+#define TA_TOP 0x0000
+#define TA_BOTTOM 0x0008
+#define TA_BASELINE 0x0018
+
+#define SRCCOPY 0x00CC0020L
+#define SRCPAINT 0x00EE0086L
+#define SRCAND 0x008800C6L
+#define SRCINVERT 0x00660046L
+#define SRCERASE 0x00440328L
+#define NOTSRCCOPY 0x00330008L
+#define NOTSRCERASE 0x001100A6L
+#define MERGECOPY 0x00C000CAL
+#define MERGEPAINT 0x00BB0226L
+#define PATCOPY 0x00F00021L
+#define PATPAINT 0x00FB0A09L
+#define PATINVERT 0x005A0049L
+#define DSTINVERT 0x00550009L
+#define BLACKNESS 0x00000042L
+#define WHITENESS 0x00FF0062L
+
+#define PS_SOLID 0
+#define PS_DASH 1
+#define PS_DOT 2
+#define PS_DASHDOT 3
+#define PS_DASHDOTDOT 4
+#define PS_NULL 5
+#define PS_INSIDEFRAME 6
+
+#define ANSI_CHARSET 0
+#define DEFAULT_CHARSET 1
+#define SYMBOL_CHARSET 2
+#define SHIFTJIS_CHARSET 128
+#define HANGEUL_CHARSET 129
+#define CHINESEBIG5_CHARSET 136
+#define OEM_CHARSET 255
+
+#define DEFAULT_PITCH 0x00
+#define FIXED_PITCH 0x01
+#define VARIABLE_PITCH 0x02
+
+/* Font Families */
+#define FF_DONTCARE 0x00
+#define FF_ROMAN 0x10
+#define FF_SWISS 0x20
+#define FF_MODERN 0x30
+#define FF_SCRIPT 0x40
+#define FF_DECORATIVE 0x50
+
+#define FW_DONTCARE 0
+#define FW_THIN 100
+#define FW_EXTRALIGHT 200
+#define FW_LIGHT 300
+#define FW_NORMAL 400
+#define FW_MEDIUM 500
+#define FW_SEMIBOLD 600
+#define FW_BOLD 700
+#define FW_EXTRABOLD 800
+#define FW_HEAVY 900
+#define FW_ULTRALIGHT 200
+#define FW_REGULAR 400
+#define FW_DEMIBOLD 600
+#define FW_ULTRABOLD 800
+#define FW_BLACK 900
+
+#define BS_SOLID 0
+#define BS_NULL 1
+#define BS_HOLLOW 1
+#define BS_HATCHED 2
+#define BS_PATTERN 3
+#define BS_INDEXED 4
+#define BS_DIBPATTERN 5
+#define BS_DIBPATTERNPT 6
+#define BS_PATTERN8X8 7
+#define BS_DIBPATTERN8X8 8
+#define BS_MONOPATTERN 9
+
+#define W_HS_HORIZONTAL 0
+#define W_HS_VERTICAL 1
+#define W_HS_FDIAGONAL 2
+#define W_HS_BDIAGONAL 3
+#define W_HS_CROSS 4
+#define W_HS_DIAGCROSS 5
+
+//============================ WMFReader ==================================
+
+// -----------------------------------------------------------------------------
+
+struct WinMtfFontStyle
+{
+ Font aFont;
+
+ WinMtfFontStyle( LOGFONTW& rLogFont );
+};
+
+// -----------------------------------------------------------------------------
+
+struct WinMtfFillStyle
+{
+ Color aFillColor;
+ BOOL bTransparent;
+
+ WinMtfFillStyle() :
+ aFillColor ( Color( COL_BLACK ) ),
+ bTransparent( FALSE )
+ {
+ };
+
+ WinMtfFillStyle( const Color& rColor, BOOL bTrans = FALSE ) :
+ aFillColor ( rColor ),
+ bTransparent( bTrans )
+ {
+ };
+
+ BOOL operator==( const WinMtfFillStyle& rStyle )
+ { return ( ( aFillColor == rStyle.aFillColor ) && ( bTransparent == rStyle.bTransparent ) ); };
+ BOOL operator==( WinMtfFillStyle* pStyle )
+ { return ( ( aFillColor == pStyle->aFillColor ) && ( bTransparent == pStyle->bTransparent ) ); };
+ void operator=( const WinMtfFillStyle& rStyle ) { aFillColor = rStyle.aFillColor; bTransparent = rStyle.bTransparent; };
+ void operator=( WinMtfFillStyle* pStyle ) { aFillColor = pStyle->aFillColor; bTransparent = pStyle->bTransparent; };
+};
+
+// -----------------------------------------------------------------------------
+
+struct WinMtfLineStyle
+{
+ Color aLineColor;
+ LineInfo aLineInfo;
+ BOOL bTransparent;
+
+ WinMtfLineStyle() :
+ aLineColor ( COL_BLACK ),
+ bTransparent( FALSE ) {};
+
+ WinMtfLineStyle( const Color& rColor, BOOL bTrans = FALSE ) :
+ aLineColor ( rColor ),
+ bTransparent( bTrans ) {};
+
+ WinMtfLineStyle( const Color& rColor, const LineInfo rStyle, BOOL bTrans = FALSE ) :
+ aLineColor ( rColor ),
+ aLineInfo ( rStyle ),
+ bTransparent( bTrans ) {};
+
+ BOOL operator==( const WinMtfLineStyle& rStyle ) { return ( ( aLineColor == rStyle.aLineColor ) && ( bTransparent == rStyle.bTransparent ) && ( aLineInfo == rStyle.aLineInfo ) ); };
+ BOOL operator==( WinMtfLineStyle* pStyle ) { return ( ( aLineColor == pStyle->aLineColor ) && ( bTransparent == pStyle->bTransparent ) && ( aLineInfo == pStyle->aLineInfo ) ); };
+ void operator=( const WinMtfLineStyle& rStyle )
+ {
+ aLineColor = rStyle.aLineColor;
+ bTransparent = rStyle.bTransparent;
+ aLineInfo = rStyle.aLineInfo;
+ };
+
+ void operator=( WinMtfLineStyle* pStyle )
+ {
+ aLineColor = pStyle->aLineColor;
+ bTransparent = pStyle->bTransparent;
+ aLineInfo = pStyle->aLineInfo;
+ };
+};
+
+// -----------------------------------------------------------------------------
+
+struct SaveStruct
+{
+ UINT32 nBkMode;
+ BOOL bWinExtSet;
+ long nWinOrgX, nWinOrgY, nWinExtX, nWinExtY;
+ long nDevOrgX, nDevOrgY, nDevWidth, nDevHeight;
+ WinMtfLineStyle aLineStyle;
+ WinMtfFillStyle aFillStyle;
+ Color aBkColor;
+ Color aTextColor;
+ Point aActPos;
+ BOOL bFontChanged;
+ Font aFont;
+ UINT32 nActTextAlign;
+};
+
+DECLARE_STACK( SaveStack, SaveStruct* );
+
+// -----------------------------------------------------------------------------
+
+struct BSaveStruct
+{
+ Bitmap aBmp;
+ Rectangle aOutRect;
+ UINT32 nWinRop;
+
+ BSaveStruct( const Bitmap& rBmp, const Rectangle& rOutRect, UINT32 nRop ) :
+ aBmp( rBmp ), aOutRect( rOutRect ), nWinRop( nRop ){};
+};
+
+// -----------------------------------------------------------------------------
+
+enum GDIObjectType { GDI_DUMMY = 0, GDI_PEN = 1, GDI_BRUSH = 2, GDI_FONT = 3, GDI_PALETTE = 4, GDI_BITMAP = 5, GDI_REGION = 6 };
+
+struct GDIObj
+{
+ void* pStyle;
+ GDIObjectType eType;
+
+ GDIObj() :
+ pStyle ( NULL ),
+ eType ( GDI_DUMMY )
+ {
+ };
+
+ GDIObj( GDIObjectType eT, void* pS ) { pStyle = pS; eType = eT; };
+ void Set( GDIObjectType eT, void* pS ) { pStyle = pS; eType = eT; };
+ void Delete()
+ {
+ if ( pStyle )
+ {
+ switch ( eType )
+ {
+ case GDI_PEN :
+ delete (WinMtfLineStyle*)pStyle;
+ break;
+ case GDI_BRUSH :
+ delete (WinMtfFillStyle*)pStyle;
+ break;
+ case GDI_FONT :
+ delete (WinMtfFontStyle*)pStyle;
+ break;
+
+ default:
+ delete pStyle;
+ }
+ pStyle = NULL;
+ }
+ };
+
+ ~GDIObj()
+ {
+ Delete();
+ }
+};
+
+// -----------------------------------------------------------------------------
+
+struct XForm
+{
+ float eM11;
+ float eM12;
+ float eM21;
+ float eM22;
+ float eDx;
+ float eDy;
+ XForm()
+ {
+ eM11 = eM12 = eM21 = eM22 = 1.0f;
+ eDx = eDx = 0.0f;
+ };
+};
+
+// -----------------------------------------------------------------------------
+
+class WinMtfOutput
+{
+ protected:
+
+ GDIObj** mpGDIObj;
+ UINT32 mnEntrys;
+ UINT32 mnActTextAlign; // Aktuelle Textausrichtung (im MS-Windows-Format)
+ UINT32 mnBkMode; // Aktueller Modus, wie der Hintergrund uebermalt
+ Point maActPos; // wird. (ist gleich TRANSPARENT oder nicht)
+
+
+ BOOL mbFontChanged;
+ Font maFont;
+ WinMtfLineStyle maLineStyle;
+ WinMtfFillStyle maFillStyle;
+
+ Color maTextColor;
+ Color maBkColor;
+
+ UINT32 mnRop;
+ RasterOp meRasterOp;
+ BOOL mbNopMode;
+
+ SaveStack maSaveStack; // Stapel fuer aktuelle Zustaende bzw. DCs (Drawing-Contexts)
+
+ XForm maXForm;
+ long mnDevOrgX, mnDevOrgY;
+ long mnDevWidth, mnDevHeight;
+ long mnWinOrgX, mnWinOrgY; // aktuelles Window-Origin
+ long mnWinExtX, mnWinExtY; // aktuelles Window-Extent
+
+ Point ImplMap( const Point& rPt );
+ Size ImplMap( const Size& rSz );
+ Rectangle ImplMap( const Rectangle& rRectangle );
+ void ImplMap( Font& rFont );
+ Polygon& ImplMap( Polygon& rPolygon );
+ PolyPolygon& ImplMap( PolyPolygon& rPolyPolygon );
+ void ImplResizeObjectArry( UINT32 nNewEntry );
+
+ public:
+
+ virtual void SetDevOrg( const Point& rPoint ) {};
+ virtual void SetDevOrgOffset( INT32 nXAdd, INT32 nYAdd ){};
+ virtual void SetDevExt( const Size& rSize ){};
+ virtual void ScaleDevExt( double fX, double fY ){};
+
+ virtual void SetWinOrg( const Point& rPoint ){};
+ virtual void SetWinOrgOffset( INT32 nX, INT32 nY ){};
+ virtual void SetWinExt( const Size& rSize ){};
+ virtual void ScaleWinExt( double fX, double fY ){};
+
+ virtual void SetWorldTransform( const XForm& rXForm ){};
+ virtual void ModifyWorldTransform( const XForm& rXForm, UINT32 nMode ){};
+
+ virtual void Push( BOOL bWinExtSet = TRUE );
+ virtual void Pop();
+
+ void SetBkMode( UINT32 nMode );
+ void SetBkColor( const Color& rColor );
+ void SetTextColor( const Color& rColor );
+ void SetTextAlign( UINT32 nAlign );
+ virtual UINT32 SetRasterOp( UINT32 nRasterOp );
+ void CreateObject( GDIObjectType, void* pStyle = NULL );
+ void CreateObject( INT32 nIndex, GDIObjectType, void* pStyle = NULL );
+ void DeleteObject( INT32 nIndex );
+ void SelectObject( INT32 nIndex );
+ CharSet GetCharSet(){ return maFont.GetCharSet(); };
+
+ virtual void DrawPixel( const Point& rSource, const Color& rColor ){};
+ void MoveTo( const Point& rPoint ) { maActPos = ImplMap( rPoint ); };
+ virtual void LineTo( const Point& rPoint ){};
+ virtual void DrawLine( const Point& rSource, const Point& rDest ){};
+ virtual void DrawRect( const Rectangle& rRect, BOOL bEdge = TRUE ){};
+ virtual void DrawRoundRect( const Rectangle& rRect, const Size& rSize ){};
+ virtual void DrawEllipse( const Rectangle& rRect ){};
+ virtual void DrawArc( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle, BOOL bDrawTo = FALSE ){};
+ virtual void DrawPie( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle ){};
+ virtual void DrawChord( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle ){};
+ virtual void DrawPolygon( Polygon& rPolygon ){};
+ virtual void DrawPolyPolygon( PolyPolygon& rPolyPolygon ){};
+ virtual void DrawPolyLine( Polygon& rPolygon, BOOL bDrawTo = FALSE ){};
+ virtual void DrawPolyBezier( Polygon& rPolygin, BOOL bDrawTo = FALSE ){};
+ virtual void DrawText( Point& rPosition, String& rString, INT32* pDXArry = NULL );
+ virtual void ResolveBitmapActions( List& rSaveList ){};
+ virtual void IntersectClipRect( const Rectangle& rRectangle ){};
+ virtual void MoveClipRegion( const Size& rSize ){};
+
+ WinMtfOutput();
+ virtual ~WinMtfOutput();
+};
+
+// -----------------------------------------------------------------------------
+
+class WinMtfMetaOutput : public WinMtfOutput
+{
+ UINT32 mnPushPopCount; // hoehe des Stapels
+ GDIMetaFile* mpGDIMetaFile;
+ WinMtfLineStyle maLatestLineStyle;
+ WinMtfFillStyle maLatestFillStyle;
+
+ void UpdateLineStyle();
+ void UpdateFillStyle();
+
+ public:
+
+ virtual void SetDevOrg( const Point& rPoint );
+ virtual void SetDevOrgOffset( INT32 nXAdd, INT32 nYAdd );
+ virtual void SetDevExt( const Size& rSize );
+ virtual void ScaleDevExt( double fX, double fY );
+
+ virtual void SetWinOrg( const Point& rPoint );
+ virtual void SetWinOrgOffset( INT32 nX, INT32 nY );
+ virtual void SetWinExt( const Size& rSize );
+ virtual void ScaleWinExt( double fX, double fY );
+
+ virtual void SetWorldTransform( const XForm& rXForm );
+ virtual void ModifyWorldTransform( const XForm& rXForm, UINT32 nMode );
+
+ virtual void Push( BOOL bWinExtSet = TRUE );
+ virtual void Pop();
+
+ virtual UINT32 SetRasterOp( UINT32 nRasterOp );
+
+ virtual void LineTo( const Point& rPoint );
+ virtual void DrawPixel( const Point& rSource, const Color& rColor );
+ virtual void DrawLine( const Point& rSource, const Point& rDest );
+ virtual void DrawRect( const Rectangle& rRect, BOOL bEdge = TRUE );
+ virtual void DrawRoundRect( const Rectangle& rRect, const Size& rSize );
+ virtual void DrawEllipse( const Rectangle& rRect );
+ virtual void DrawArc( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle, BOOL bDrawTo = FALSE );
+ virtual void DrawPie( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle );
+ virtual void DrawChord( const Rectangle& rRect, const Point& rStartAngle, const Point& rEndAngle );
+ virtual void DrawPolygon( Polygon& rPolygon );
+ virtual void DrawPolyPolygon( PolyPolygon& rPolyPolygon );
+ virtual void DrawPolyLine( Polygon& rPolygon, BOOL bDrawTo = FALSE );
+ virtual void DrawPolyBezier( Polygon& rPolygin, BOOL bDrawTo = FALSE );
+ virtual void DrawText( Point& rPosition, String& rString, INT32* pDXArry = NULL );
+ virtual void ResolveBitmapActions( List& rSaveList );
+ virtual void IntersectClipRect( const Rectangle& rRectangle );
+ virtual void MoveClipRegion( const Size& rSize );
+
+
+ WinMtfMetaOutput( GDIMetaFile& rGDIMetaFile );
+ virtual ~WinMtfMetaOutput();
+};
+
+// -----------------------------------------------------------------------------
+
+class WinMtf
+{
+ protected:
+
+ WinMtfOutput* pOut; //
+ SvStream* pWMF; // Die einzulesende WMF/EMF-Datei
+
+ UINT32 nStartPos, nEndPos;
+ List aBmpSaveList;
+
+ PFilterCallback pCallback;
+ void* pCallerData;
+
+ // Sorgt dafuer, das aSampledBrush der aktuelle Brush des GDIMetaFiles ist.
+
+ Color ReadColor();
+ BOOL Callback( USHORT nPercent );
+
+ WinMtf( WinMtfOutput* pOut, SvStream& rStreamWMF, PFilterCallback pcallback, void * pcallerdata );
+ ~WinMtf();
+
+ public:
+
+};
+
+//============================ EMFReader ==================================
+
+class EnhWMFReader : public WinMtf
+{
+
+private:
+
+ INT32 nRecordCount;
+
+ BOOL ReadHeader();
+ Rectangle ReadRectangle( INT32, INT32, INT32, INT32 ); // Liesst und konvertiert ein Rechteck
+ void ImplExtTextOut( BOOL bWideCharakter );
+
+public:
+ EnhWMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile,
+ PFilterCallback pcallback, void * pcallerdata ) : WinMtf( new WinMtfMetaOutput( rGDIMetaFile ), rStreamWMF,
+ pcallback, pcallerdata ) {};
+
+ BOOL ReadEnhWMF();
+};
+
+//============================ WMFReader ==================================
+
+class WMFReader : public WinMtf
+{
+private:
+
+ BOOL bWinExtSet;
+ UINT16 nUnitsPerInch;
+
+ // Liesst den Kopf der WMF-Datei
+ BOOL ReadHeader();
+
+ // Liesst die Parameter des Rocords mit der Funktionsnummer nFunction.
+ void ReadRecordParams( USHORT nFunction );
+
+ Point ReadPoint(); // Liesst und konvertiert einen Punkt (erst X dann Y)
+ Point ReadYX(); // Liesst und konvertiert einen Punkt (erst Y dann X)
+ Rectangle ReadRectangle(); // Liesst und konvertiert ein Rechteck
+ Size ReadYXExt();
+ void ImplSetWMFSize( const Size& rSize );
+
+public:
+
+ WMFReader( SvStream& rStreamWMF, GDIMetaFile& rGDIMetaFile,
+ PFilterCallback pcallback, void * pcallerdata ) : WinMtf( new WinMtfMetaOutput( rGDIMetaFile ), rStreamWMF,
+ pcallback, pcallerdata ) {};
+
+ // Liesst aus dem Stream eine WMF-Datei und fuellt das GDIMetaFile
+ void ReadWMF();
+};
+
+#endif
+
+
diff --git a/svtools/source/filter.vcl/wmf/winwmf.cxx b/svtools/source/filter.vcl/wmf/winwmf.cxx
new file mode 100644
index 000000000000..6e352ae8ecfd
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/winwmf.cxx
@@ -0,0 +1,886 @@
+/*************************************************************************
+ *
+ * $RCSfile: winwmf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "winmtf.hxx"
+
+//====================== MS-Windows-defines ===============================
+
+#define W_META_SETBKCOLOR 0x0201
+#define W_META_SETBKMODE 0x0102
+#define W_META_SETMAPMODE 0x0103
+#define W_META_SETROP2 0x0104
+#define W_META_SETRELABS 0x0105
+#define W_META_SETPOLYFILLMODE 0x0106
+#define W_META_SETSTRETCHBLTMODE 0x0107
+#define W_META_SETTEXTCHAREXTRA 0x0108
+#define W_META_SETTEXTCOLOR 0x0209
+#define W_META_SETTEXTJUSTIFICATION 0x020A
+#define W_META_SETWINDOWORG 0x020B
+#define W_META_SETWINDOWEXT 0x020C
+#define W_META_SETVIEWPORTORG 0x020D
+#define W_META_SETVIEWPORTEXT 0x020E
+#define W_META_OFFSETWINDOWORG 0x020F
+#define W_META_SCALEWINDOWEXT 0x0410
+#define W_META_OFFSETVIEWPORTORG 0x0211
+#define W_META_SCALEVIEWPORTEXT 0x0412
+#define W_META_LINETO 0x0213
+#define W_META_MOVETO 0x0214
+#define W_META_EXCLUDECLIPRECT 0x0415
+#define W_META_INTERSECTCLIPRECT 0x0416
+#define W_META_ARC 0x0817
+#define W_META_ELLIPSE 0x0418
+#define W_META_FLOODFILL 0x0419
+#define W_META_PIE 0x081A
+#define W_META_RECTANGLE 0x041B
+#define W_META_ROUNDRECT 0x061C
+#define W_META_PATBLT 0x061D
+#define W_META_SAVEDC 0x001E
+#define W_META_SETPIXEL 0x041F
+#define W_META_OFFSETCLIPRGN 0x0220
+#define W_META_TEXTOUT 0x0521
+#define W_META_BITBLT 0x0922
+#define W_META_STRETCHBLT 0x0B23
+#define W_META_POLYGON 0x0324
+#define W_META_POLYLINE 0x0325
+#define W_META_ESCAPE 0x0626
+#define W_META_RESTOREDC 0x0127
+#define W_META_FILLREGION 0x0228
+#define W_META_FRAMEREGION 0x0429
+#define W_META_INVERTREGION 0x012A
+#define W_META_PAINTREGION 0x012B
+#define W_META_SELECTCLIPREGION 0x012C
+#define W_META_SELECTOBJECT 0x012D
+#define W_META_SETTEXTALIGN 0x012E
+#define W_META_DRAWTEXT 0x062F
+#define W_META_CHORD 0x0830
+#define W_META_SETMAPPERFLAGS 0x0231
+#define W_META_EXTTEXTOUT 0x0a32
+#define W_META_SETDIBTODEV 0x0d33
+#define W_META_SELECTPALETTE 0x0234
+#define W_META_REALIZEPALETTE 0x0035
+#define W_META_ANIMATEPALETTE 0x0436
+#define W_META_SETPALENTRIES 0x0037
+#define W_META_POLYPOLYGON 0x0538
+#define W_META_RESIZEPALETTE 0x0139
+#define W_META_DIBBITBLT 0x0940
+#define W_META_DIBSTRETCHBLT 0x0b41
+#define W_META_DIBCREATEPATTERNBRUSH 0x0142
+#define W_META_STRETCHDIB 0x0f43
+#define W_META_EXTFLOODFILL 0x0548
+#define W_META_RESETDC 0x014C
+#define W_META_STARTDOC 0x014D
+#define W_META_STARTPAGE 0x004F
+#define W_META_ENDPAGE 0x0050
+#define W_META_ABORTDOC 0x0052
+#define W_META_ENDDOC 0x005E
+#define W_META_DELETEOBJECT 0x01f0
+#define W_META_CREATEPALETTE 0x00f7
+#define W_META_CREATEBRUSH 0x00F8
+#define W_META_CREATEPATTERNBRUSH 0x01F9
+#define W_META_CREATEPENINDIRECT 0x02FA
+#define W_META_CREATEFONTINDIRECT 0x02FB
+#define W_META_CREATEBRUSHINDIRECT 0x02FC
+#define W_META_CREATEBITMAPINDIRECT 0x02FD
+#define W_META_CREATEBITMAP 0x06FE
+#define W_META_CREATEREGION 0x06FF
+
+//=================== Methoden von WMFReader ==============================
+
+inline Point WMFReader::ReadPoint()
+{
+ short nX, nY;
+ *pWMF >> nX >> nY;
+ return Point( nX, nY );
+}
+
+// ------------------------------------------------------------------------
+
+inline Point WMFReader::ReadYX()
+{
+ short nX, nY;
+ *pWMF >> nY >> nX;
+ return Point( nX, nY );
+}
+
+// ------------------------------------------------------------------------
+
+Rectangle WMFReader::ReadRectangle()
+{
+ Point aBR, aTL;
+ aBR = ReadYX();
+ aTL = ReadYX();
+ aBR.X()--;
+ aBR.Y()--;
+ return Rectangle( aTL, aBR );
+}
+
+// ------------------------------------------------------------------------
+
+Size WMFReader::ReadYXExt()
+{
+ short nW, nH;
+ *pWMF >> nH >> nW;
+ return Size( nW, nH );
+}
+
+// ------------------------------------------------------------------------
+
+void WMFReader::ReadRecordParams( USHORT nFunction )
+{
+ switch( nFunction )
+ {
+ case W_META_SETBKCOLOR:
+ {
+ pOut->SetBkColor( ReadColor() );
+ }
+ break;
+
+ case W_META_SETBKMODE:
+ {
+ USHORT nDat;
+ *pWMF >> nDat;
+ pOut->SetBkMode( nDat );
+ }
+ break;
+
+ // !!!
+ case W_META_SETMAPMODE:
+ {
+ short nMapMode;
+ *pWMF >> nMapMode;
+#ifdef DBG_ASSERT
+ if ( nMapMode != 8 ) // nur MM_ANISOTROPHIC == 8 wird unterstuetzt
+ {
+ DBG_ASSERT(0,"WMF-Import: MapMode ignored");
+ }
+#endif
+ }
+ break;
+
+ case W_META_SETROP2:
+ {
+ UINT16 nROP2;
+ *pWMF >> nROP2;
+ pOut->SetRasterOp( nROP2 );
+ }
+ break;
+
+ case W_META_SETTEXTCOLOR:
+ {
+ pOut->SetTextColor( ReadColor() );
+ }
+ break;
+
+ case W_META_SETWINDOWORG:
+ {
+ pOut->SetWinOrg( ReadYX() );
+ }
+ break;
+
+ case W_META_SETWINDOWEXT:
+ {
+ short nWidth, nHeight;
+ *pWMF >> nHeight >> nWidth;
+ ImplSetWMFSize( Size( nWidth, nHeight ) );
+ }
+ break;
+
+ case W_META_OFFSETWINDOWORG:
+ {
+ short nXAdd, nYAdd;
+ *pWMF >> nYAdd >> nXAdd;
+ pOut->SetWinOrgOffset( nXAdd, nYAdd );
+ }
+ break;
+
+ case W_META_SCALEWINDOWEXT:
+ {
+ short nXNum, nXDenom, nYNum, nYDenom;
+ *pWMF >> nYDenom >> nYNum >> nXDenom >> nXNum;
+ pOut->ScaleWinExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
+ }
+ break;
+
+ case W_META_SETVIEWPORTORG:
+ case W_META_SETVIEWPORTEXT:
+ break;
+
+ case W_META_OFFSETVIEWPORTORG:
+ {
+ short nXAdd, nYAdd;
+ *pWMF >> nYAdd >> nXAdd;
+ pOut->SetDevOrgOffset( nXAdd, nYAdd );
+ }
+ break;
+
+ case W_META_SCALEVIEWPORTEXT:
+ {
+ short nXNum, nXDenom, nYNum, nYDenom;
+ *pWMF >> nYDenom >> nYNum >> nXDenom >> nXNum;
+ pOut->ScaleDevExt( (double)nXNum / nXDenom, (double)nYNum / nYDenom );
+ }
+ break;
+
+ case W_META_LINETO:
+ {
+ pOut->LineTo( ReadYX() );
+ }
+ break;
+
+ case W_META_MOVETO:
+ {
+ pOut->MoveTo( ReadYX() );
+ }
+ break;
+
+ case W_META_INTERSECTCLIPRECT:
+ {
+ pOut->IntersectClipRect( ReadRectangle() );
+ }
+ break;
+
+ case W_META_RECTANGLE:
+ {
+ pOut->DrawRect( ReadRectangle() );
+ }
+ break;
+
+ case W_META_ROUNDRECT:
+ {
+ Size aSize( ReadYXExt() );
+ pOut->DrawRoundRect( ReadRectangle(), aSize );
+ }
+ break;
+
+ case W_META_ELLIPSE:
+ {
+ pOut->DrawEllipse( ReadRectangle() );
+ }
+ break;
+
+ case W_META_ARC:
+ {
+ Point aEnd( ReadYX() );
+ Point aStart( ReadYX() );
+ pOut->DrawArc( ReadRectangle(), aStart, aEnd );
+ }
+ break;
+
+ case W_META_PIE:
+ {
+ Point aEnd( ReadYX() );
+ Point aStart( ReadYX() );
+ pOut->DrawPie( ReadRectangle(), aStart, aEnd );
+ }
+ break;
+
+ case W_META_CHORD:
+ {
+ Point aEnd( ReadYX() );
+ Point aStart( ReadYX() );
+ pOut->DrawChord( ReadRectangle(), aStart, aEnd );
+ }
+ break;
+
+ case W_META_POLYGON:
+ {
+ USHORT i,nPoints;
+ *pWMF >> nPoints;
+ Polygon aPoly( nPoints );
+ for( i = 0; i < nPoints; i++ )
+ aPoly[ i ] = ReadPoint();
+ pOut->DrawPolygon( aPoly );
+ }
+ break;
+
+ case W_META_POLYPOLYGON:
+ {
+ USHORT i, nPoly, nPoints;
+ USHORT* pnPoints;
+ Point* pPtAry;
+ // Anzahl der Polygone:
+ *pWMF >> nPoly;
+ // Anzahl der Punkte eines jeden Polygons holen, Gesammtzahl der Punkte ermitteln:
+ pnPoints = new USHORT[ nPoly ];
+ nPoints = 0;
+ for( i = 0; i < nPoly; i++ )
+ {
+ *pWMF >> pnPoints[i];
+ nPoints += pnPoints[i];
+ }
+ // Polygonpunkte holen:
+ pPtAry = (Point*) new char[ nPoints * sizeof(Point) ];
+ for ( i = 0; i < nPoints; i++ )
+ pPtAry[ i ] = ReadPoint();
+ // PolyPolygon Actions erzeugen
+ PolyPolygon aPolyPoly( nPoly, pnPoints, pPtAry );
+ pOut->DrawPolyPolygon( aPolyPoly );
+ delete (char*) pPtAry;
+ delete pnPoints;
+ }
+ break;
+
+ case W_META_POLYLINE:
+ {
+ USHORT i,nPoints;
+ *pWMF >> nPoints;
+ Polygon aPoly( nPoints );
+ for( i = 0; i < nPoints; i++ )
+ aPoly[ i ] = ReadPoint();
+ pOut->DrawPolyLine( aPoly );
+ }
+ break;
+
+ case W_META_SAVEDC:
+ {
+ pOut->Push( bWinExtSet );
+ }
+ break;
+
+ case W_META_RESTOREDC:
+ {
+ pOut->Pop();
+ }
+ break;
+
+ case W_META_SETPIXEL:
+ {
+ const Color aColor = ReadColor();
+ pOut->DrawPixel( ReadYX(), aColor );
+ }
+ break;
+
+ case W_META_OFFSETCLIPRGN:
+ {
+ pOut->MoveClipRegion( ReadYXExt() );
+ }
+ break;
+
+ case W_META_TEXTOUT:
+ {
+ USHORT nLength;
+ *pWMF >> nLength;
+ if ( nLength )
+ {
+ char* pChar = new char[ ( nLength + 1 ) &~ 1 ];
+ pWMF->Read( pChar, ( nLength + 1 ) &~ 1 );
+ String aText( pChar, nLength, pOut->GetCharSet() );
+ delete pChar;
+ Point aPosition( ReadYX() );
+ pOut->DrawText( aPosition, aText );
+ }
+ }
+ break;
+
+ case W_META_EXTTEXTOUT:
+ {
+ USHORT i,nLen,nOptions,nData;
+ long nRecordSize,nRecSizeLeft, *pDXAry;
+ Point aPosition;
+ Rectangle aRect;
+
+ pWMF->SeekRel(-6);
+ *pWMF >> nRecordSize;
+ pWMF->SeekRel(2);
+ aPosition = ReadYX();
+ *pWMF >> nLen >> nOptions;
+ // Nur wenn der Text auch Zeichen enthaelt, macht die Ausgabe Sinn
+ if( nLen )
+ {
+ if( nOptions )
+ {
+ const Point aPt1( ReadPoint() );
+ const Point aPt2( ReadPoint() );
+ aRect = Rectangle( aPt1, aPt2 );
+ }
+ char* pChar = new char[ ( nLen + 1 ) &~ 1 ];
+ pWMF->Read( pChar, ( nLen + 1 ) &~ 1 );
+ String aText( pChar, nLen, pOut->GetCharSet() );
+ delete pChar;
+
+ nRecSizeLeft=(nRecordSize-7-(((long)nLen+1)>>1))<<1;
+
+ if( nOptions )
+ nRecSizeLeft-=8;
+
+ if( nRecSizeLeft >= (long) nLen )
+ {
+ pDXAry = new long[ nLen ];
+
+ for( i = 0; i < nLen; i++ )
+ {
+ *pWMF >> nData;
+ pDXAry[ i ] = nData;
+ }
+ pOut->DrawText( aPosition, aText, pDXAry );
+ delete[] pDXAry;
+ }
+ else
+ pOut->DrawText( aPosition, aText );
+ }
+ }
+ break;
+
+ case W_META_SELECTOBJECT:
+ {
+ INT16 nObjIndex;
+ *pWMF >> nObjIndex;
+ pOut->SelectObject( nObjIndex );
+ }
+ break;
+
+ case W_META_SETTEXTALIGN:
+ {
+ UINT16 nAlign;
+ *pWMF >> nAlign;
+ pOut->SetTextAlign( nAlign );
+ }
+ break;
+
+ case W_META_BITBLT:
+ case W_META_STRETCHBLT:
+ case W_META_DIBBITBLT:
+ case W_META_DIBSTRETCHBLT:
+ case W_META_STRETCHDIB:
+ {
+ long nWinROP;
+ short nSx, nSy, nSxe, nSye, nUsage;
+ Bitmap aBmp;
+
+ *pWMF >> nWinROP;
+
+ if( nFunction == W_META_STRETCHDIB )
+ *pWMF >> nUsage;
+
+ if( nFunction==W_META_STRETCHDIB || nFunction==W_META_STRETCHBLT || nFunction==W_META_DIBSTRETCHBLT )
+ *pWMF >> nSye >> nSxe;
+
+ *pWMF >> nSy >> nSx;
+
+ if( nFunction == W_META_STRETCHDIB || nFunction == W_META_DIBBITBLT || nFunction == W_META_DIBSTRETCHBLT )
+ {
+ switch( nWinROP )
+ {
+ case PATCOPY :
+ {
+ *pWMF >> nUsage; // i don't know anything of this parameter, so its called nUsage
+ Size aDestSize( ReadYXExt() );
+ pOut->DrawRect( Rectangle( ReadYX(), aDestSize ), FALSE );
+ }
+ break;
+ default :
+ {
+ Size aDestSize( ReadYXExt() );
+ Rectangle aDestRect( ReadYX(), aDestSize );
+ aBmp.Read( *pWMF, FALSE );
+ aBmpSaveList.Insert( new BSaveStruct( aBmp, aDestRect, nWinROP ), LIST_APPEND );
+ }
+ break;
+ }
+ }
+ else
+ {
+ if( aBmpSaveList.Count() )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+ }
+ }
+ break;
+
+ case W_META_DIBCREATEPATTERNBRUSH:
+ {
+ Bitmap aBmp;
+ BitmapReadAccess* pBmp;
+ UINT32 nRed = 0, nGreen = 0, nBlue = 0, nCount = 1;
+ UINT16 nFunction;
+
+ *pWMF >> nFunction >> nFunction;
+
+ aBmp.Read( *pWMF, FALSE );
+ pBmp = aBmp.AcquireReadAccess();
+ if ( pBmp )
+ {
+ for ( INT32 y = 0; y < pBmp->Height(); y++ )
+ {
+ for ( INT32 x = 0; x < pBmp->Width(); x++ )
+ {
+ const BitmapColor aColor( pBmp->GetColor( y, x ) );
+
+ nRed += aColor.GetRed();
+ nGreen += aColor.GetGreen();
+ nBlue += aColor.GetBlue();
+ }
+ }
+ nCount = pBmp->Height() * pBmp->Width();
+ if ( !nCount )
+ nCount++;
+ aBmp.ReleaseAccess( pBmp );
+ }
+ Color aColor( (BYTE)( nRed / nCount ), (BYTE)( nGreen / nCount ), (BYTE)( nBlue / nCount ) );
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( aColor, FALSE ) );
+ }
+ break;
+
+ case W_META_DELETEOBJECT:
+ {
+ INT16 nIndex;
+ *pWMF >> nIndex;
+ pOut->DeleteObject( nIndex );
+ }
+ break;
+
+ case W_META_CREATEPALETTE:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_CREATEBRUSH:
+ {
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), FALSE ) );
+ }
+ break;
+
+ case W_META_CREATEPATTERNBRUSH:
+ {
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ), FALSE ) );
+ }
+ break;
+
+ case W_META_CREATEPENINDIRECT:
+ {
+ LineInfo aLineInfo;
+ USHORT nStyle, nWidth, nHeight;
+
+ *pWMF >> nStyle >> nWidth >> nHeight;
+
+ if ( nWidth )
+ aLineInfo.SetWidth( nWidth );
+
+ BOOL bTransparent = FALSE;
+ UINT16 nDashCount = 0;
+ UINT16 nDotCount = 0;
+ switch( nStyle )
+ {
+ case PS_DASHDOTDOT :
+ nDotCount++;
+ case PS_DASHDOT :
+ nDashCount++;
+ case PS_DOT :
+ nDotCount++;
+ break;
+ case PS_DASH :
+ nDashCount++;
+ break;
+ case PS_NULL :
+ bTransparent = TRUE;
+ aLineInfo.SetStyle( LINE_NONE );
+ break;
+ default :
+ case PS_INSIDEFRAME :
+ case PS_SOLID :
+ aLineInfo.SetStyle( LINE_SOLID );
+ }
+ if ( nDashCount | nDotCount )
+ {
+ aLineInfo.SetStyle( LINE_DASH );
+ aLineInfo.SetDashCount( nDashCount );
+ aLineInfo.SetDotCount( nDotCount );
+ }
+ pOut->CreateObject( GDI_PEN, new WinMtfLineStyle( ReadColor(), aLineInfo, bTransparent ) );
+ }
+ break;
+
+ case W_META_CREATEBRUSHINDIRECT:
+ {
+ USHORT nStyle;
+ *pWMF >> nStyle;
+ pOut->CreateObject( GDI_BRUSH, new WinMtfFillStyle( ReadColor(), ( nStyle == BS_HOLLOW ) ? TRUE : FALSE ) );
+ }
+ break;
+
+ case W_META_CREATEFONTINDIRECT:
+ {
+ Size aFontSize;
+ INT16 lfEscapement, lfOrientation, lfWeight; // ( ehemals USHORT )
+
+ LOGFONTW aLogFont;
+ aFontSize = ReadYXExt();
+ *pWMF >> lfEscapement >> lfOrientation >> lfWeight
+ >> aLogFont.lfItalic >> aLogFont.lfUnderline >> aLogFont.lfStrikeOut >> aLogFont.lfCharSet >> aLogFont.lfOutPrecision
+ >> aLogFont.lfClipPrecision >> aLogFont.lfQuality >> aLogFont.lfPitchAndFamily;
+ pWMF->Read( aLogFont.lfFaceName, LF_FACESIZE );
+ aLogFont.lfWidth = aFontSize.Width();
+ aLogFont.lfHeight = aFontSize.Height();
+ aLogFont.lfEscapement = lfEscapement;
+ aLogFont.lfOrientation = lfOrientation;
+ aLogFont.lfWeight = lfWeight;
+ pOut->CreateObject( GDI_FONT, new WinMtfFontStyle( aLogFont ) );
+ }
+ break;
+
+ case W_META_CREATEBITMAPINDIRECT:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_CREATEBITMAP:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_CREATEREGION:
+ {
+ pOut->CreateObject( GDI_DUMMY );
+ }
+ break;
+
+ case W_META_SETRELABS:
+ case W_META_SETPOLYFILLMODE:
+ case W_META_SETSTRETCHBLTMODE:
+ case W_META_SETTEXTCHAREXTRA:
+ case W_META_SETTEXTJUSTIFICATION:
+ case W_META_EXCLUDECLIPRECT:
+ case W_META_FLOODFILL:
+ break;
+ case W_META_PATBLT:
+ {
+ UINT32 nROP, nOldROP;
+ *pWMF >> nROP;
+ Size aSize = ReadYXExt();
+ nOldROP = pOut->SetRasterOp( nROP );
+ pOut->DrawRect( Rectangle( ReadYX(), aSize ), FALSE );
+ pOut->SetRasterOp( nOldROP );
+ }
+ break;
+ case W_META_ESCAPE:
+ case W_META_FILLREGION:
+ case W_META_FRAMEREGION:
+ case W_META_INVERTREGION:
+ case W_META_PAINTREGION:
+ case W_META_SELECTCLIPREGION:
+ case W_META_DRAWTEXT:
+ case W_META_SETMAPPERFLAGS:
+ case W_META_SETDIBTODEV:
+ case W_META_SELECTPALETTE:
+ case W_META_REALIZEPALETTE:
+ case W_META_ANIMATEPALETTE:
+ case W_META_SETPALENTRIES:
+ case W_META_RESIZEPALETTE:
+ case W_META_EXTFLOODFILL:
+ case W_META_RESETDC:
+ case W_META_STARTDOC:
+ case W_META_STARTPAGE:
+ case W_META_ENDPAGE:
+ case W_META_ABORTDOC:
+ case W_META_ENDDOC:
+ break;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+BOOL WMFReader::ReadHeader()
+{
+ Rectangle aPlaceableBound;
+ ULONG nl;
+
+ // Einlesen des METAFILEHEADER, falls vorhanden
+ *pWMF >> nl;
+
+ if ( nl == 0x9ac6cdd7L )
+ {
+ INT16 nVal;
+
+ // hmf (Unused) ueberlesen wir
+ pWMF->SeekRel(2);
+
+ // BoundRect
+ *pWMF >> nVal; aPlaceableBound.Left() = nVal;
+ *pWMF >> nVal; aPlaceableBound.Top() = nVal;
+ *pWMF >> nVal; aPlaceableBound.Right() = nVal;
+ *pWMF >> nVal; aPlaceableBound.Bottom() = nVal;
+
+ // inch
+ *pWMF >> nUnitsPerInch;
+
+ // reserved
+ pWMF->SeekRel( 4 );
+
+ // checksum pruefen wir lieber nicht
+ pWMF->SeekRel( 2 );
+ }
+ else
+ {
+ // Unit wird bei den alten MTF's als MM_TEXT angenommen
+ nUnitsPerInch = 96;
+ pWMF->SeekRel( -4 ); // zurueck zum Anfang
+ }
+
+ // Einlesen des METAHEADER
+ *pWMF >> nl; // Typ und Headergroesse
+
+ if( nl != 0x00090001 )
+ {
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+ return FALSE;
+ }
+
+ pWMF->SeekRel( 2 ); // Version (von Windows)
+ pWMF->SeekRel( 4 ); // Size (der Datei in Words)
+ pWMF->SeekRel( 2 ); // NoObjects (Maximale Anzahl der gleichzeitigen Objekte)
+ pWMF->SeekRel( 4 ); // MaxRecord (Groesse des groessten Records in Words)
+ pWMF->SeekRel( 2 ); // NoParameters (Unused
+
+ pOut->SetWinOrg( aPlaceableBound.TopLeft() );
+
+ ImplSetWMFSize( aPlaceableBound.GetSize() );
+
+ return TRUE;
+}
+
+// ------------------------------------------------------------------------
+
+void WMFReader::ImplSetWMFSize( const Size& rSize )
+{
+ pOut->SetWinExt( rSize );
+
+ // try to calculate size of WMF
+ if( !bWinExtSet && rSize.Width() > 1 && rSize.Height() > 1 )
+ {
+ const Fraction aFrac( 1, nUnitsPerInch );
+ MapMode aWMFMap( MAP_INCH, Point(), aFrac, aFrac );
+ Size aSize100( OutputDevice::LogicToLogic( rSize, aWMFMap, MAP_100TH_MM ) );
+ pOut->SetDevExt( Size( labs( aSize100.Width() ), labs( aSize100.Height() ) ) );
+ bWinExtSet = TRUE;
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void WMFReader::ReadWMF() // SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile, PFilterCallback pcallback, void * pcallerdata)
+{
+ USHORT nFunction;
+ ULONG nRecSize;
+ ULONG nPos, nPercent, nLastPercent;
+
+ pOut->SetWinOrg( Point() );
+ pOut->SetWinExt( Size( 1, 1 ) );
+ pOut->SetDevExt( Size( 10000, 10000 ) );
+ bWinExtSet = FALSE;
+
+ nEndPos=pWMF->Seek( STREAM_SEEK_TO_END );
+ pWMF->Seek( nStartPos );
+ Callback( (USHORT) ( nLastPercent = 0 ) );
+
+ if ( ReadHeader() )
+ {
+
+ nPos = pWMF->Tell();
+
+ if( nEndPos - nStartPos )
+ {
+ while( TRUE )
+ {
+ nPercent = ( nPos - nStartPos ) * 100 / ( nEndPos - nStartPos );
+
+ if( nLastPercent + 4 <= nPercent )
+ {
+ if( Callback( (USHORT) nPercent ) )
+ break;
+
+ nLastPercent = nPercent;
+ }
+
+ *pWMF >> nRecSize >> nFunction;
+
+ if( pWMF->GetError() || ( nRecSize < 3 ) || ( nRecSize==3 && nFunction==0 ) || pWMF->IsEof() )
+ {
+
+ if( pWMF->IsEof() )
+ pWMF->SetError( SVSTREAM_FILEFORMAT_ERROR );
+
+ break;
+ }
+
+ if( aBmpSaveList.Count() &&
+ ( nFunction != W_META_STRETCHDIB ) &&
+ ( nFunction != W_META_DIBBITBLT ) &&
+ ( nFunction != W_META_DIBSTRETCHBLT ) )
+ {
+ pOut->ResolveBitmapActions( aBmpSaveList );
+ }
+
+ ReadRecordParams( nFunction );
+ pWMF->Seek( nPos += nRecSize * 2 );
+ }
+ }
+ else
+ pWMF->SetError( SVSTREAM_GENERALERROR );
+
+ if( !pWMF->GetError() && aBmpSaveList.Count() )
+ pOut->ResolveBitmapActions( aBmpSaveList );
+ }
+ if ( pWMF->GetError() )
+ pWMF->Seek( nStartPos );
+}
+
diff --git a/svtools/source/filter.vcl/wmf/wmf.cxx b/svtools/source/filter.vcl/wmf/wmf.cxx
new file mode 100644
index 000000000000..d085bfc45e21
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/wmf.cxx
@@ -0,0 +1,147 @@
+/*************************************************************************
+ *
+ * $RCSfile: wmf.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include "winmtf.hxx"
+#include "emfwr.hxx"
+#include "wmfwr.hxx"
+#include "wmf.hxx"
+
+// -----------------------------------------------------------------------------
+
+BOOL ConvertWMFToGDIMetaFile( SvStream & rStreamWMF, GDIMetaFile & rGDIMetaFile,
+ PFilterCallback pCallback, void * pCallerData)
+{
+ UINT32 nMetaType;
+ UINT32 nOrgPos = rStreamWMF.Tell();
+ UINT16 nOrigNumberFormat = rStreamWMF.GetNumberFormatInt();
+ rStreamWMF.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStreamWMF.Seek( 0x28 );
+ rStreamWMF >> nMetaType;
+ rStreamWMF.Seek( nOrgPos );
+ if ( nMetaType == 0x464d4520 )
+ {
+ if ( EnhWMFReader( rStreamWMF, rGDIMetaFile, pCallback, pCallerData ).ReadEnhWMF() == FALSE )
+ rStreamWMF.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ }
+ else
+ {
+ WMFReader( rStreamWMF, rGDIMetaFile, pCallback, pCallerData ).ReadWMF();
+ }
+ rStreamWMF.SetNumberFormatInt( nOrigNumberFormat );
+ return !rStreamWMF.GetError();
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ReadWindowMetafile( SvStream& rStream, GDIMetaFile& rMTF )
+{
+ UINT32 nMetaType;
+ UINT32 nOrgPos = rStream.Tell();
+ UINT16 nOrigNumberFormat = rStream.GetNumberFormatInt();
+ rStream.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
+ rStream.Seek( 0x28 );
+ rStream >> nMetaType;
+ rStream.Seek( nOrgPos );
+ if ( nMetaType == 0x464d4520 )
+ {
+ if ( EnhWMFReader( rStream, rMTF, NULL, NULL ).ReadEnhWMF() == FALSE )
+ rStream.SetError( SVSTREAM_FILEFORMAT_ERROR );
+ }
+ else
+ {
+ WMFReader( rStream, rMTF, NULL, NULL ).ReadWMF();
+ }
+ rStream.SetNumberFormatInt( nOrigNumberFormat );
+ return !rStream.GetError();
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ConvertGDIMetaFileToWMF( const GDIMetaFile & rMTF, SvStream & rTargetStream,
+ PFilterCallback pCallback, void * pCallerData,
+ BOOL bPlaceable)
+{
+ WMFWriter aWMFWriter;
+ return aWMFWriter.WriteWMF(rMTF,rTargetStream,pCallback,pCallerData,bPlaceable);
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL ConvertGDIMetaFileToEMF( const GDIMetaFile & rMTF, SvStream & rTargetStream,
+ PFilterCallback pCallback, void * pCallerData )
+{
+ EMFWriter aEMFWriter;
+ return aEMFWriter.WriteEMF( rMTF, rTargetStream, pCallback, pCallerData );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL WriteWindowMetafile( SvStream& rStream, const GDIMetaFile& rMTF )
+{
+ return WMFWriter().WriteWMF( rMTF, rStream, NULL, NULL );
+}
+
+// -----------------------------------------------------------------------------
+
+BOOL WriteWindowMetafileBits( SvStream& rStream, const GDIMetaFile& rMTF )
+{
+ return WMFWriter().WriteWMF( rMTF, rStream, NULL, NULL, FALSE );
+}
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.cxx b/svtools/source/filter.vcl/wmf/wmfwr.cxx
new file mode 100644
index 000000000000..ad860a457d7d
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/wmfwr.cxx
@@ -0,0 +1,1787 @@
+/*************************************************************************
+ *
+ * $RCSfile: wmfwr.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#include <vcl/salbtype.hxx>
+#include "wmfwr.hxx"
+
+//====================== MS-Windows-defines ===============================
+
+#define W_META_SETBKCOLOR 0x0201
+#define W_META_SETBKMODE 0x0102
+#define W_META_SETMAPMODE 0x0103
+#define W_META_SETROP2 0x0104
+#define W_META_SETRELABS 0x0105
+#define W_META_SETPOLYFILLMODE 0x0106
+#define W_META_SETSTRETCHBLTMODE 0x0107
+#define W_META_SETTEXTCHAREXTRA 0x0108
+#define W_META_SETTEXTCOLOR 0x0209
+#define W_META_SETTEXTJUSTIFICATION 0x020A
+#define W_META_SETWINDOWORG 0x020B
+#define W_META_SETWINDOWEXT 0x020C
+#define W_META_SETVIEWPORTORG 0x020D
+#define W_META_SETVIEWPORTEXT 0x020E
+#define W_META_OFFSETWINDOWORG 0x020F
+#define W_META_SCALEWINDOWEXT 0x0410
+#define W_META_OFFSETVIEWPORTORG 0x0211
+#define W_META_SCALEVIEWPORTEXT 0x0412
+#define W_META_LINETO 0x0213
+#define W_META_MOVETO 0x0214
+#define W_META_EXCLUDECLIPRECT 0x0415
+#define W_META_INTERSECTCLIPRECT 0x0416
+#define W_META_ARC 0x0817
+#define W_META_ELLIPSE 0x0418
+#define W_META_FLOODFILL 0x0419
+#define W_META_PIE 0x081A
+#define W_META_RECTANGLE 0x041B
+#define W_META_ROUNDRECT 0x061C
+#define W_META_PATBLT 0x061D
+#define W_META_SAVEDC 0x001E
+#define W_META_SETPIXEL 0x041F
+#define W_META_OFFSETCLIPRGN 0x0220
+#define W_META_TEXTOUT 0x0521
+#define W_META_BITBLT 0x0922
+#define W_META_STRETCHBLT 0x0B23
+#define W_META_POLYGON 0x0324
+#define W_META_POLYLINE 0x0325
+#define W_META_ESCAPE 0x0626
+#define W_META_RESTOREDC 0x0127
+#define W_META_FILLREGION 0x0228
+#define W_META_FRAMEREGION 0x0429
+#define W_META_INVERTREGION 0x012A
+#define W_META_PAINTREGION 0x012B
+#define W_META_SELECTCLIPREGION 0x012C
+#define W_META_SELECTOBJECT 0x012D
+#define W_META_SETTEXTALIGN 0x012E
+#define W_META_DRAWTEXT 0x062F
+#define W_META_CHORD 0x0830
+#define W_META_SETMAPPERFLAGS 0x0231
+#define W_META_EXTTEXTOUT 0x0a32
+#define W_META_SETDIBTODEV 0x0d33
+#define W_META_SELECTPALETTE 0x0234
+#define W_META_REALIZEPALETTE 0x0035
+#define W_META_ANIMATEPALETTE 0x0436
+#define W_META_SETPALENTRIES 0x0037
+#define W_META_POLYPOLYGON 0x0538
+#define W_META_RESIZEPALETTE 0x0139
+#define W_META_DIBBITBLT 0x0940
+#define W_META_DIBSTRETCHBLT 0x0b41
+#define W_META_DIBCREATEPATTERNBRUSH 0x0142
+#define W_META_STRETCHDIB 0x0f43
+#define W_META_EXTFLOODFILL 0x0548
+#define W_META_RESETDC 0x014C
+#define W_META_STARTDOC 0x014D
+#define W_META_STARTPAGE 0x004F
+#define W_META_ENDPAGE 0x0050
+#define W_META_ABORTDOC 0x0052
+#define W_META_ENDDOC 0x005E
+#define W_META_DELETEOBJECT 0x01f0
+#define W_META_CREATEPALETTE 0x00f7
+#define W_META_CREATEBRUSH 0x00F8
+#define W_META_CREATEPATTERNBRUSH 0x01F9
+#define W_META_CREATEPENINDIRECT 0x02FA
+#define W_META_CREATEFONTINDIRECT 0x02FB
+#define W_META_CREATEBRUSHINDIRECT 0x02FC
+#define W_META_CREATEBITMAPINDIRECT 0x02FD
+#define W_META_CREATEBITMAP 0x06FE
+#define W_META_CREATEREGION 0x06FF
+
+#define W_TRANSPARENT 1
+#define W_OPAQUE 2
+
+#define W_R2_BLACK 1
+#define W_R2_NOTMERGEPEN 2
+#define W_R2_MASKNOTPEN 3
+#define W_R2_NOTCOPYPEN 4
+#define W_R2_MASKPENNOT 5
+#define W_R2_NOT 6
+#define W_R2_XORPEN 7
+#define W_R2_NOTMASKPEN 8
+#define W_R2_MASKPEN 9
+#define W_R2_NOTXORPEN 10
+#define W_R2_NOP 11
+#define W_R2_MERGENOTPEN 12
+#define W_R2_COPYPEN 13
+#define W_R2_MERGEPENNOT 14
+#define W_R2_MERGEPEN 15
+#define W_R2_WHITE 16
+
+#define W_TA_NOUPDATECP 0x0000
+#define W_TA_UPDATECP 0x0001
+#define W_TA_LEFT 0x0000
+#define W_TA_RIGHT 0x0002
+#define W_TA_CENTER 0x0006
+#define W_TA_TOP 0x0000
+#define W_TA_BOTTOM 0x0008
+#define W_TA_BASELINE 0x0018
+
+#define W_SRCCOPY 0x00CC0020L
+#define W_SRCPAINT 0x00EE0086L
+#define W_SRCAND 0x008800C6L
+#define W_SRCINVERT 0x00660046L
+#define W_SRCERASE 0x00440328L
+#define W_NOTSRCCOPY 0x00330008L
+#define W_NOTSRCERASE 0x001100A6L
+#define W_MERGECOPY 0x00C000CAL
+#define W_MERGEPAINT 0x00BB0226L
+#define W_PATCOPY 0x00F00021L
+#define W_PATPAINT 0x00FB0A09L
+#define W_PATINVERT 0x005A0049L
+#define W_DSTINVERT 0x00550009L
+#define W_BLACKNESS 0x00000042L
+#define W_WHITENESS 0x00FF0062L
+
+#define W_PS_SOLID 0
+#define W_PS_DASH 1
+#define W_PS_DOT 2
+#define W_PS_DASHDOT 3
+#define W_PS_DASHDOTDOT 4
+#define W_PS_NULL 5
+#define W_PS_INSIDEFRAME 6
+
+#define W_LF_FACESIZE 32
+
+#define W_ANSI_CHARSET 0
+#define W_DEFAULT_CHARSET 1
+#define W_SYMBOL_CHARSET 2
+#define W_SHIFTJIS_CHARSET 128
+#define W_HANGEUL_CHARSET 129
+#define W_CHINESEBIG5_CHARSET 136
+#define W_OEM_CHARSET 255
+
+#define W_DEFAULT_PITCH 0x00
+#define W_FIXED_PITCH 0x01
+#define W_VARIABLE_PITCH 0x02
+
+#define W_FF_DONTCARE 0x00
+#define W_FF_ROMAN 0x10
+#define W_FF_SWISS 0x20
+#define W_FF_MODERN 0x30
+#define W_FF_SCRIPT 0x40
+#define W_FF_DECORATIVE 0x50
+
+#define W_FW_DONTCARE 0
+#define W_FW_THIN 100
+#define W_FW_EXTRALIGHT 200
+#define W_FW_LIGHT 300
+#define W_FW_NORMAL 400
+#define W_FW_MEDIUM 500
+#define W_FW_SEMIBOLD 600
+#define W_FW_BOLD 700
+#define W_FW_EXTRABOLD 800
+#define W_FW_HEAVY 900
+#define W_FW_ULTRALIGHT 200
+#define W_FW_REGULAR 400
+#define W_FW_DEMIBOLD 600
+#define W_FW_ULTRABOLD 800
+#define W_FW_BLACK 900
+
+#define W_BS_SOLID 0
+#define W_BS_HOLLOW 1
+#define W_BS_HATCHED 2
+#define W_BS_PATTERN 3
+#define W_BS_INDEXED 4
+#define W_BS_DIBPATTERN 5
+
+#define W_HS_HORIZONTAL 0
+#define W_HS_VERTICAL 1
+#define W_HS_FDIAGONAL 2
+#define W_HS_BDIAGONAL 3
+#define W_HS_CROSS 4
+#define W_HS_DIAGCROSS 5
+
+//========================== Methoden von WMFWriter ==========================
+
+void WMFWriter::MayCallback()
+{
+ ULONG nPercent;
+
+ // Wir gehen mal einfach so davon aus, dass 16386 Actions einer Bitmap entsprechen
+ // (in der Regel wird ein Metafile entweder nur Actions oder einige Bitmaps und fast
+ // keine Actions enthalten. Dann ist das Verhaeltnis ziemlich unwichtig)
+
+ nPercent=((nWrittenBitmaps<<14)+(nActBitmapPercent<<14)/100+nWrittenActions)
+ *100
+ /((nNumberOfBitmaps<<14)+nNumberOfActions);
+
+ if (nPercent>=nLastPercent+3) {
+ nLastPercent=nPercent;
+ if(pCallback!=NULL && nPercent<=100) {
+ if (((*pCallback)(pCallerData,(USHORT)nPercent))==TRUE) bStatus=FALSE;
+ }
+ }
+}
+
+
+void WMFWriter::CountActionsAndBitmaps( const GDIMetaFile & rMTF )
+{
+ ULONG nAction, nActionCount;
+
+ nActionCount = rMTF.GetActionCount();
+
+ for ( nAction=0; nAction<nActionCount; nAction++ )
+ {
+ MetaAction* pMA = rMTF.GetAction( nAction );
+
+ switch( pMA->GetType() )
+ {
+ case META_BMP_ACTION:
+ case META_BMPSCALE_ACTION:
+ case META_BMPSCALEPART_ACTION:
+ case META_BMPEX_ACTION:
+ case META_BMPEXSCALE_ACTION:
+ case META_BMPEXSCALEPART_ACTION:
+ nNumberOfBitmaps++;
+ break;
+ }
+ nNumberOfActions++;
+ }
+}
+
+
+void WMFWriter::WritePointXY(const Point & rPoint)
+{
+ Point aPt( pVirDev->LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aPt.X()) << ((short)aPt.Y());
+}
+
+
+void WMFWriter::WritePointYX(const Point & rPoint)
+{
+ Point aPt( pVirDev->LogicToLogic(rPoint,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aPt.Y()) << ((short)aPt.X());
+}
+
+
+void WMFWriter::WriteDX(long nDX)
+{
+ Size aSz( pVirDev->LogicToLogic(Size(nDX,0),aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aSz.Width());
+}
+
+
+void WMFWriter::WriteSize(const Size & rSize)
+{
+ Size aSz( pVirDev->LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aSz.Width()) << ((short)aSz.Height());
+}
+
+
+void WMFWriter::WriteHeightWidth(const Size & rSize)
+{
+ Size aSz( pVirDev->LogicToLogic(rSize,aSrcMapMode,aTargetMapMode) );
+ *pWMF << ((short)aSz.Height()) << ((short)aSz.Width());
+}
+
+
+void WMFWriter::WriteRectangle(const Rectangle & rRect)
+{
+ WritePointYX(Point(rRect.Right()+1,rRect.Bottom()+1));
+ WritePointYX(rRect.TopLeft());
+}
+
+
+void WMFWriter::WriteColor(const Color & rColor)
+{
+ *pWMF << (BYTE) rColor.GetRed() << (BYTE) rColor.GetGreen() << (BYTE) rColor.GetBlue() << (BYTE) 0;
+}
+
+
+void WMFWriter::WriteRecordHeader(ULONG nSizeWords, USHORT nType)
+{
+ nActRecordPos=pWMF->Tell();
+ if (nSizeWords>nMaxRecordSize) nMaxRecordSize=nSizeWords;
+ *pWMF << nSizeWords << nType;
+}
+
+
+void WMFWriter::UpdateRecordHeader()
+{
+ ULONG nPos,nSize;
+
+ nPos=pWMF->Tell(); nSize=nPos-nActRecordPos;
+ if ((nSize & 1)!=0) {
+ *pWMF << (BYTE)0;
+ nPos++; nSize++;
+ }
+ nSize/=2;
+ if (nSize>nMaxRecordSize) nMaxRecordSize=nSize;
+ pWMF->Seek(nActRecordPos);
+ *pWMF << nSize;
+ pWMF->Seek(nPos);
+}
+
+
+void WMFWriter::WMFRecord_Arc(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
+{
+ WriteRecordHeader(0x0000000b,W_META_ARC);
+ WritePointYX(rEndPt);
+ WritePointYX(rStartPt);
+ WriteRectangle(rRect);
+}
+
+void WMFWriter::WMFRecord_Chord(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
+{
+ WriteRecordHeader(0x0000000b,W_META_CHORD);
+ WritePointYX(rEndPt);
+ WritePointYX(rStartPt);
+ WriteRectangle(rRect);
+}
+
+
+void WMFWriter::WMFRecord_CreateBrushIndirect(const Color& rColor)
+{
+ WriteRecordHeader(0x00000007,W_META_CREATEBRUSHINDIRECT);
+
+ if( rColor==Color(COL_TRANSPARENT) )
+ *pWMF << (UINT16) W_BS_HOLLOW;
+ else
+ *pWMF << (UINT16) W_BS_SOLID;
+
+ WriteColor( rColor );
+ *pWMF << (UINT16) 0;
+}
+
+
+void WMFWriter::WMFRecord_CreateFontIndirect(const Font & rFont)
+{
+ USHORT nWeight,i;
+ BYTE nCharSet,nPitchFamily;
+
+ WriteRecordHeader(0x00000000,W_META_CREATEFONTINDIRECT);
+
+ WriteHeightWidth(Size(rFont.GetSize().Width(),-rFont.GetSize().Height()));
+
+ *pWMF << (short)rFont.GetOrientation() << (short)rFont.GetOrientation();
+
+ switch (rFont.GetWeight()) {
+ case WEIGHT_THIN: nWeight=W_FW_THIN; break;
+ case WEIGHT_ULTRALIGHT: nWeight=W_FW_ULTRALIGHT; break;
+ case WEIGHT_LIGHT: nWeight=W_FW_LIGHT; break;
+ case WEIGHT_SEMILIGHT: nWeight=W_FW_LIGHT; break;
+ case WEIGHT_NORMAL: nWeight=W_FW_NORMAL; break;
+ case WEIGHT_MEDIUM: nWeight=W_FW_MEDIUM; break;
+ case WEIGHT_SEMIBOLD: nWeight=W_FW_SEMIBOLD; break;
+ case WEIGHT_BOLD: nWeight=W_FW_BOLD; break;
+ case WEIGHT_ULTRABOLD: nWeight=W_FW_ULTRABOLD; break;
+ case WEIGHT_BLACK: nWeight=W_FW_BLACK; break;
+ default: nWeight=W_FW_DONTCARE;
+ }
+ *pWMF << nWeight;
+
+ if (rFont.GetItalic()==ITALIC_NONE) *pWMF << (BYTE)0; else *pWMF << (BYTE)1;
+ if (rFont.GetUnderline()==UNDERLINE_NONE) *pWMF << (BYTE)0; else *pWMF << (BYTE)1;
+ if (rFont.GetStrikeout()==STRIKEOUT_NONE) *pWMF << (BYTE)0; else *pWMF << (BYTE)1;
+
+ switch (rFont.GetCharSet())
+ {
+ case RTL_TEXTENCODING_SYMBOL : nCharSet = W_SYMBOL_CHARSET; break;
+ default: nCharSet = W_ANSI_CHARSET;
+ }
+ *pWMF << nCharSet;
+
+ *pWMF << (BYTE)0 << (BYTE)0 << (BYTE)0;
+
+ switch (rFont.GetPitch()) {
+ case PITCH_FIXED: nPitchFamily=W_FIXED_PITCH; break;
+ case PITCH_VARIABLE: nPitchFamily=W_VARIABLE_PITCH; break;
+ default: nPitchFamily=W_DEFAULT_PITCH;
+ }
+ switch (rFont.GetFamily()) {
+ case FAMILY_DECORATIVE: nPitchFamily|=W_FF_DECORATIVE; break;
+ case FAMILY_MODERN: nPitchFamily|=W_FF_MODERN; break;
+ case FAMILY_ROMAN: nPitchFamily|=W_FF_ROMAN; break;
+ case FAMILY_SCRIPT: nPitchFamily|=W_FF_SCRIPT; break;
+ case FAMILY_SWISS: nPitchFamily|=W_FF_SWISS; break;
+ default: nPitchFamily|=W_FF_DONTCARE;
+ }
+ *pWMF << nPitchFamily;
+
+ ByteString aFontName( rFont.GetName(), RTL_TEXTENCODING_UTF8 );
+ for ( i = 0; i < W_LF_FACESIZE; i++ )
+ {
+ if ( i < aFontName.Len() )
+ *pWMF << (BYTE)aFontName.GetChar( i );
+ else
+ *pWMF << (BYTE)0;
+ }
+
+ UpdateRecordHeader();
+}
+
+
+void WMFWriter::WMFRecord_CreatePenIndirect(const Color& rColor)
+{
+ WriteRecordHeader(0x00000008,W_META_CREATEPENINDIRECT);
+
+ if( rColor == Color( COL_TRANSPARENT ) )
+ *pWMF << (UINT16) W_PS_NULL;
+ else
+ *pWMF << (UINT16) W_PS_SOLID;
+
+ WriteSize( Size() );
+ WriteColor(rColor);
+}
+
+void WMFWriter::WMFRecord_CreatePenIndirect(const Color& rColor, const LineInfo& rLineInfo )
+{
+ WriteRecordHeader(0x00000008,W_META_CREATEPENINDIRECT);
+
+ USHORT nStyle = W_PS_SOLID;
+ switch( rLineInfo.GetStyle() )
+ {
+ case LINE_DASH :
+ {
+ if ( rLineInfo.GetDotCount() )
+ {
+ if ( !rLineInfo.GetDashCount() )
+ nStyle = W_PS_DOT;
+ else
+ {
+ if ( !rLineInfo.GetDotCount() == 1 )
+ nStyle = W_PS_DASHDOT;
+ else
+ nStyle = W_PS_DASHDOTDOT;
+ }
+ }
+ else
+ nStyle = W_PS_DASH;
+ }
+ break;
+ case LINE_NONE :
+ nStyle = W_PS_NULL;
+ break;
+ }
+ *pWMF << nStyle;
+
+ WriteSize( Size( rLineInfo.GetWidth(), 0 ) );
+ WriteColor( rColor );
+}
+
+void WMFWriter::WMFRecord_DeleteObject(USHORT nObjectHandle)
+{
+ WriteRecordHeader(0x00000004,W_META_DELETEOBJECT);
+ *pWMF << nObjectHandle;
+}
+
+
+void WMFWriter::WMFRecord_Ellipse(const Rectangle & rRect)
+{
+ WriteRecordHeader(0x00000007,W_META_ELLIPSE);
+ WriteRectangle(rRect);
+}
+
+
+void WMFWriter::WMFRecord_ExtTextOut(const Point & rPoint, const ByteString & rString, const long * pDXAry)
+{
+ USHORT nLen,i;
+
+ nLen=rString.Len();
+ if (nLen<=1 || pDXAry==NULL)
+ {
+ WMFRecord_TextOut(rPoint,rString);
+ return;
+ }
+
+ WriteRecordHeader(0,W_META_EXTTEXTOUT);
+ WritePointYX(rPoint);
+ *pWMF << nLen << (USHORT)0;
+
+ for ( i = 0; i < nLen; i++ )
+ *pWMF << (BYTE)rString.GetChar( i );
+ if ((nLen&1)!=0) *pWMF << (BYTE)0;
+ WriteDX(pDXAry[0]);
+ for (i=1; i<(nLen-1); i++) WriteDX(pDXAry[i]-pDXAry[i-1]);
+ WriteDX(pDXAry[nLen-2]/(nLen-1));
+ UpdateRecordHeader();
+}
+
+
+void WMFWriter::WMFRecord_ExtTextOut(const Point & rPoint, const ByteString & rString, ULONG nWidth)
+{
+ USHORT nLen,i;
+ long * pDXAry;
+ sal_Int32 nNormSize;
+
+ pVirDev->SetFont(aSrcFont);
+ nLen=rString.Len();
+ pDXAry=new long[nLen];
+ nNormSize = pVirDev->GetTextArray( UniString( rString, RTL_TEXTENCODING_UTF8 ),pDXAry );
+ if (nLen<=1 || nNormSize ==(long)nWidth )
+ {
+ WMFRecord_TextOut(rPoint,rString);
+ delete pDXAry;
+ return;
+ }
+ for (i=0; i<(nLen-1); i++) pDXAry[i]=pDXAry[i]*((long)nWidth)/nNormSize;
+ WMFRecord_ExtTextOut(rPoint,rString,pDXAry);
+ delete pDXAry;
+}
+
+
+void WMFWriter::WMFRecord_LineTo(const Point & rPoint)
+{
+ WriteRecordHeader(0x00000005,W_META_LINETO);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_MoveTo(const Point & rPoint)
+{
+ WriteRecordHeader(0x00000005,W_META_MOVETO);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_Pie(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt)
+{
+ WriteRecordHeader(0x0000000b,W_META_PIE);
+ WritePointYX(rEndPt);
+ WritePointYX(rStartPt);
+ WriteRectangle(rRect);
+}
+
+
+void WMFWriter::WMFRecord_Polygon(const Polygon & rPoly)
+{
+ USHORT nSize,i;
+ nSize=rPoly.GetSize();
+
+ WriteRecordHeader(((ULONG)nSize)*2+4,W_META_POLYGON);
+ *pWMF << nSize;
+ for (i=0; i<nSize; i++) WritePointXY(rPoly.GetPoint(i));
+}
+
+
+void WMFWriter::WMFRecord_PolyLine(const Polygon & rPoly)
+{
+ USHORT nSize,i;
+ nSize=rPoly.GetSize();
+
+ WriteRecordHeader(((ULONG)nSize)*2+4,W_META_POLYLINE);
+ *pWMF << nSize;
+ for (i=0; i<nSize; i++) WritePointXY(rPoly.GetPoint(i));
+}
+
+
+void WMFWriter::WMFRecord_PolyPolygon(const PolyPolygon & rPolyPoly)
+{
+ const Polygon * pPoly;
+ USHORT nCount,nSize,i,j;
+
+ WriteRecordHeader(0,W_META_POLYPOLYGON);
+ nCount=rPolyPoly.Count();
+ *pWMF << nCount;
+ for (i=0; i<nCount; i++) *pWMF << ((USHORT)(rPolyPoly.GetObject(i).GetSize()));
+ for (i=0; i<nCount; i++) {
+ pPoly=&(rPolyPoly.GetObject(i));
+ nSize=pPoly->GetSize();
+ for (j=0; j<nSize; j++) WritePointXY(pPoly->GetPoint(j));
+ }
+ UpdateRecordHeader();
+}
+
+
+void WMFWriter::WMFRecord_Rectangle(const Rectangle & rRect)
+{
+ WriteRecordHeader( 0x00000007,W_META_RECTANGLE );
+ WriteRectangle( rRect );
+}
+
+
+void WMFWriter::WMFRecord_RestoreDC()
+{
+ WriteRecordHeader(0x00000004,W_META_RESTOREDC);
+ *pWMF << (short)-1;
+}
+
+
+void WMFWriter::WMFRecord_RoundRect(const Rectangle & rRect, long nHorzRound, long nVertRound)
+{
+ WriteRecordHeader(0x00000009,W_META_ROUNDRECT);
+ WriteHeightWidth(Size(nHorzRound,nVertRound));
+ WriteRectangle(rRect);
+}
+
+
+void WMFWriter::WMFRecord_SaveDC()
+{
+ WriteRecordHeader(0x00000003,W_META_SAVEDC);
+}
+
+
+void WMFWriter::WMFRecord_SelectObject(USHORT nObjectHandle)
+{
+ WriteRecordHeader(0x00000004,W_META_SELECTOBJECT);
+ *pWMF << nObjectHandle;
+}
+
+
+void WMFWriter::WMFRecord_SetBkColor(const Color & rColor)
+{
+ WriteRecordHeader(0x00000005,W_META_SETBKCOLOR);
+ WriteColor(rColor);
+}
+
+
+void WMFWriter::WMFRecord_SetBkMode(BOOL bTransparent)
+{
+ WriteRecordHeader(0x00000004,W_META_SETBKMODE);
+ if (bTransparent==TRUE) *pWMF << (USHORT)W_TRANSPARENT;
+ else *pWMF << (USHORT)W_OPAQUE;
+}
+
+void WMFWriter::WMFRecord_SetStretchBltMode()
+{
+ WriteRecordHeader( 0x00000004, W_META_SETSTRETCHBLTMODE );
+ *pWMF << (USHORT) 3; // STRETCH_DELETESCANS
+}
+
+void WMFWriter::WMFRecord_SetPixel(const Point & rPoint, const Color & rColor)
+{
+ WriteRecordHeader(0x00000007,W_META_SETPIXEL);
+ WriteColor(rColor);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_SetROP2(RasterOp eROP)
+{
+ USHORT nROP2;
+
+ switch (eROP) {
+ case ROP_INVERT: nROP2=W_R2_NOT; break;
+ case ROP_XOR: nROP2=W_R2_XORPEN; break;
+ default: nROP2=W_R2_COPYPEN;
+ }
+ WriteRecordHeader(0x00000004,W_META_SETROP2);
+ *pWMF << nROP2;
+}
+
+
+void WMFWriter::WMFRecord_SetTextAlign(FontAlign eFontAlign)
+{
+ USHORT nAlign;
+
+ switch (eFontAlign) {
+ case ALIGN_TOP: nAlign=W_TA_TOP; break;
+ case ALIGN_BOTTOM: nAlign=W_TA_BOTTOM; break;
+ default: nAlign=W_TA_BASELINE;
+ }
+ nAlign|=W_TA_LEFT;
+ nAlign|=W_TA_NOUPDATECP;
+
+ WriteRecordHeader(0x00000004,W_META_SETTEXTALIGN);
+ *pWMF << nAlign;
+}
+
+
+void WMFWriter::WMFRecord_SetTextColor(const Color & rColor)
+{
+ WriteRecordHeader(0x00000005,W_META_SETTEXTCOLOR);
+ WriteColor(rColor);
+}
+
+
+void WMFWriter::WMFRecord_SetWindowExt(const Size & rSize)
+{
+ WriteRecordHeader(0x00000005,W_META_SETWINDOWEXT);
+ WriteHeightWidth(rSize);
+}
+
+
+void WMFWriter::WMFRecord_SetWindowOrg(const Point & rPoint)
+{
+ WriteRecordHeader(0x00000005,W_META_SETWINDOWORG);
+ WritePointYX(rPoint);
+}
+
+
+void WMFWriter::WMFRecord_StretchDIB( const Point & rPoint, const Size & rSize,
+ const Bitmap & rBitmap, ULONG nROP )
+{
+ ULONG nPosAnf,nPosEnd;
+
+ nActBitmapPercent=50;
+ MayCallback();
+
+ WriteRecordHeader(0x00000000,W_META_STRETCHDIB);
+
+ // Die Reihenfolge im Metafile soll jetzt sein:
+ // einige Parameter (laenge 22), dann die Bitmap ohne FILEHEADER.
+ // Da aber *pWMF << rBitmap einen FILEHEADER der Laenge 14
+ // erzeugt, schreiben wir zuerst die Bitmap an die richtige Position
+ // Und ueberschreiben hinterher den FILEHEADER mit den Parametern.
+ nPosAnf=pWMF->Tell(); // Position merken, wo Parameter hin sollen
+ *pWMF << (long)0 << (long)0; // 8 bytes auffuellen (diese 8 bytes +
+ // 14 bytes ueberfluessigen FILEHEADER
+ // = 22 bytes Parameter)
+ *pWMF << rBitmap; // Bitmap schreiben
+
+ // Parameter schreiben:
+ nPosEnd=pWMF->Tell();
+ pWMF->Seek(nPosAnf);
+
+ // Raster-Op bestimmen, falls nichts uebergeben wurde
+ if( !nROP )
+ {
+ switch( eSrcRasterOp )
+ {
+ case ROP_INVERT: nROP = W_DSTINVERT; break;
+ case ROP_XOR: nROP = W_SRCINVERT; break;
+ default: nROP = W_SRCCOPY;
+ }
+ }
+
+ *pWMF << nROP <<
+ (short) 0 <<
+ (short) rBitmap.GetSizePixel().Height() <<
+ (short) rBitmap.GetSizePixel().Width() <<
+ (short) 0 <<
+ (short) 0;
+
+ WriteHeightWidth(rSize);
+ WritePointYX(rPoint);
+ pWMF->Seek(nPosEnd);
+
+ UpdateRecordHeader();
+
+ nWrittenBitmaps++;
+ nActBitmapPercent=0;
+}
+
+
+void WMFWriter::WMFRecord_TextOut(const Point & rPoint, const ByteString & rString)
+{
+ USHORT nLen,i;
+
+ WriteRecordHeader(0,W_META_TEXTOUT);
+ nLen=rString.Len();
+ *pWMF << nLen;
+ for ( i = 0; i < nLen; i++ )
+ *pWMF << (BYTE)rString.GetChar( i );
+ if ((nLen&1)!=0) *pWMF << (BYTE)0;
+ WritePointYX(rPoint);
+ UpdateRecordHeader();
+}
+
+
+void WMFWriter::WMFRecord_EndOfFile()
+{
+ WriteRecordHeader(0x00000003,0x0000);
+}
+
+
+void WMFWriter::WMFRecord_IntersectClipRect( const Rectangle& rRect )
+{
+ WriteRecordHeader( 0x00000007, W_META_INTERSECTCLIPRECT );
+ WriteRectangle(rRect);
+}
+
+
+USHORT WMFWriter::AllocHandle()
+{
+ USHORT i;
+
+ for (i=0; i<MAXOBJECTHANDLES; i++) {
+ if (bHandleAllocated[i]==FALSE) {
+ bHandleAllocated[i]=TRUE;
+ return i;
+ }
+ }
+ bStatus=FALSE;
+ return 0xffff;
+}
+
+
+void WMFWriter::FreeHandle(USHORT nObjectHandle)
+{
+ if (nObjectHandle<MAXOBJECTHANDLES) bHandleAllocated[nObjectHandle]=FALSE;
+}
+
+
+void WMFWriter::CreateSelectDeletePen(const Color& rColor)
+{
+ USHORT nOldHandle;
+
+ nOldHandle=nDstPenHandle;
+ nDstPenHandle=AllocHandle();
+ WMFRecord_CreatePenIndirect(rColor);
+ WMFRecord_SelectObject(nDstPenHandle);
+ if (nOldHandle<MAXOBJECTHANDLES) {
+ WMFRecord_DeleteObject(nOldHandle);
+ FreeHandle(nOldHandle);
+ }
+}
+
+
+void WMFWriter::CreateSelectDeleteFont(const Font & rFont)
+{
+ USHORT nOldHandle;
+
+ nOldHandle=nDstFontHandle;
+ nDstFontHandle=AllocHandle();
+ WMFRecord_CreateFontIndirect(rFont);
+ WMFRecord_SelectObject(nDstFontHandle);
+ if (nOldHandle<MAXOBJECTHANDLES) {
+ WMFRecord_DeleteObject(nOldHandle);
+ FreeHandle(nOldHandle);
+ }
+}
+
+
+void WMFWriter::CreateSelectDeleteBrush(const Color& rColor)
+{
+ USHORT nOldHandle;
+
+ nOldHandle=nDstBrushHandle;
+ nDstBrushHandle=AllocHandle();
+ WMFRecord_CreateBrushIndirect(rColor);
+ WMFRecord_SelectObject(nDstBrushHandle);
+ if (nOldHandle<MAXOBJECTHANDLES) {
+ WMFRecord_DeleteObject(nOldHandle);
+ FreeHandle(nOldHandle);
+ }
+}
+
+
+void WMFWriter::SetAttrForLines()
+{
+
+ if (bAttrReadyForLines==TRUE) return;
+
+ if (bDstGraphicsInvalid || eDstROP2!=eSrcRasterOp) {
+ eDstROP2=eSrcRasterOp;
+ WMFRecord_SetROP2(eDstROP2);
+ }
+ if (bDstGraphicsInvalid || aDstLineColor!=aSrcLineColor) {
+ aDstLineColor=aSrcLineColor;
+ CreateSelectDeletePen(aDstLineColor);
+ }
+ if (bDstGraphicsInvalid || aDstFillColor!=aSrcFillColor) {
+ aDstFillColor=aSrcFillColor;
+ CreateSelectDeleteBrush(aDstFillColor);
+ }
+ if (bDstGraphicsInvalid || bDstIsClipping!=bSrcIsClipping ||
+ (bSrcIsClipping==TRUE && aDstClipRegion!=aSrcClipRegion)) {
+ bDstIsClipping=bSrcIsClipping;
+ aDstClipRegion=aSrcClipRegion;
+ if (bDstGraphicsInvalid==FALSE || bSrcIsClipping==TRUE) {
+ //...???...
+ }
+ }
+
+ bAttrReadyForLines=TRUE;
+ bAttrReadyForAreas=FALSE;
+ bAttrReadyForText=FALSE;
+ bDstGraphicsInvalid=FALSE;
+}
+
+
+void WMFWriter::SetAttrForAreas()
+{
+ if( aSrcFillColor == Color( COL_TRANSPARENT ) )
+ {
+ SetAttrForLines();
+ return;
+ }
+
+ if (bAttrReadyForAreas==TRUE) return;
+
+ if (bDstGraphicsInvalid || eDstROP2!=eSrcRasterOp) {
+ eDstROP2=eSrcRasterOp;
+ WMFRecord_SetROP2(eDstROP2);
+ }
+ if (bDstGraphicsInvalid || aDstLineColor!=aSrcLineColor) {
+ aDstLineColor=aSrcLineColor;
+ CreateSelectDeletePen(aDstLineColor);
+ }
+ if (bDstGraphicsInvalid || aDstFillColor!=aSrcFillColor) {
+ aDstFillColor=aSrcFillColor;
+ CreateSelectDeleteBrush(aDstFillColor);
+ }
+ if (bDstGraphicsInvalid || bDstIsClipping!=bSrcIsClipping ||
+ (bSrcIsClipping==TRUE && aDstClipRegion!=aSrcClipRegion)) {
+ bDstIsClipping=bSrcIsClipping;
+ aDstClipRegion=aSrcClipRegion;
+ if (bDstGraphicsInvalid==FALSE || bSrcIsClipping==TRUE) {
+ //...???...
+ }
+ }
+
+ bAttrReadyForAreas=TRUE;
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForText=FALSE;
+ bDstGraphicsInvalid=FALSE;
+}
+
+
+void WMFWriter::SetAttrForText()
+{
+ if (bAttrReadyForText==TRUE) return;
+
+ if (bDstGraphicsInvalid==FALSE) SetAttrForLines();
+
+ if (bDstTextInvalid || aDstTextColor!=aSrcFont.GetColor()) {
+ aDstTextColor=aSrcFont.GetColor();
+ WMFRecord_SetTextColor(aDstTextColor);
+ }
+ if (bDstTextInvalid || eDstTextAlign!=aSrcFont.GetAlign()) {
+ eDstTextAlign=aSrcFont.GetAlign();
+ WMFRecord_SetTextAlign(eDstTextAlign);
+ }
+ if (bDstTextInvalid || aDstFont!=aSrcFont) {
+ aDstFont=aSrcFont;
+ CreateSelectDeleteFont(aDstFont);
+ }
+
+ bAttrReadyForText=TRUE;
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ bDstTextInvalid=FALSE;
+}
+
+
+void WMFWriter::WriteRecords( const GDIMetaFile & rMTF )
+{
+ ULONG nA, nACount;
+ MetaAction* pMA;
+
+ if( bStatus )
+ {
+ nACount = rMTF.GetActionCount();
+
+ WMFRecord_SetStretchBltMode();
+
+ for( nA=0; nA<nACount; nA++ )
+ {
+ pMA = rMTF.GetAction( nA );
+
+ switch( pMA->GetType() )
+ {
+ case META_PIXEL_ACTION:
+ {
+ const MetaPixelAction* pA = (const MetaPixelAction *) pMA;
+ SetAttrForLines();
+ WMFRecord_SetPixel( pA->GetPoint(), pA->GetColor() );
+ }
+ break;
+
+ case META_POINT_ACTION:
+ {
+ const MetaPointAction* pA = (const MetaPointAction*) pMA;
+ const Point& rPt = pA->GetPoint();
+ SetAttrForLines();
+ WMFRecord_MoveTo( rPt);
+ WMFRecord_LineTo( rPt );
+ }
+ break;
+
+ case META_LINE_ACTION:
+ {
+ const MetaLineAction* pA = (const MetaLineAction *) pMA;
+ const LineInfo& rLineInfo = pA->GetLineInfo();
+ SetAttrForLines();
+ if ( rLineInfo.IsDefault() )
+ {
+ WMFRecord_MoveTo( pA->GetStartPoint() );
+ WMFRecord_LineTo( pA->GetEndPoint() );
+ }
+ else
+ {
+ USHORT nCurrentHandle = AllocHandle();
+ WMFRecord_CreatePenIndirect( aSrcLineColor, rLineInfo );
+ WMFRecord_SelectObject(nCurrentHandle);
+ WMFRecord_MoveTo( pA->GetStartPoint() );
+ WMFRecord_LineTo( pA->GetEndPoint() );
+ WMFRecord_DeleteObject(nCurrentHandle);
+ FreeHandle(nCurrentHandle);
+ WMFRecord_SelectObject(nDstPenHandle);
+ }
+ }
+ break;
+
+ case META_RECT_ACTION:
+ {
+ const MetaRectAction* pA = (const MetaRectAction*) pMA;
+ SetAttrForAreas();
+ WMFRecord_Rectangle( pA->GetRect() );
+ }
+ break;
+
+ case META_ROUNDRECT_ACTION:
+ {
+ const MetaRoundRectAction* pA = (const MetaRoundRectAction*) pMA;
+ SetAttrForAreas();
+ WMFRecord_RoundRect( pA->GetRect(), pA->GetHorzRound(), pA->GetVertRound() );
+ }
+ break;
+
+ case META_ELLIPSE_ACTION:
+ {
+ const MetaEllipseAction* pA = (const MetaEllipseAction*) pMA;
+ SetAttrForAreas();
+ WMFRecord_Ellipse( pA->GetRect() );
+ }
+ break;
+
+ case META_ARC_ACTION:
+ {
+ const MetaArcAction* pA = (const MetaArcAction*) pMA;
+ SetAttrForLines();
+ WMFRecord_Arc( pA->GetRect(),pA->GetStartPoint(),pA->GetEndPoint() );
+ }
+ break;
+
+ case META_PIE_ACTION:
+ {
+ const MetaPieAction* pA = (const MetaPieAction*) pMA;
+ SetAttrForAreas();
+ WMFRecord_Pie( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
+ }
+ break;
+
+
+ case META_CHORD_ACTION:
+ {
+ const MetaChordAction* pA = (const MetaChordAction*) pMA;
+ SetAttrForAreas();
+ WMFRecord_Chord( pA->GetRect(), pA->GetStartPoint(), pA->GetEndPoint() );
+ }
+ break;
+
+ case META_POLYLINE_ACTION:
+ {
+ const MetaPolyLineAction* pA = (const MetaPolyLineAction*) pMA;
+ const LineInfo& rLineInfo = pA->GetLineInfo();
+ SetAttrForLines();
+
+ if ( rLineInfo.IsDefault() )
+ WMFRecord_PolyLine( pA->GetPolygon() );
+ else
+ {
+ USHORT nCurrentHandle = AllocHandle();
+ WMFRecord_CreatePenIndirect( aSrcLineColor, rLineInfo );
+ WMFRecord_SelectObject(nCurrentHandle);
+ WMFRecord_PolyLine( pA->GetPolygon() );
+ WMFRecord_DeleteObject(nCurrentHandle);
+ FreeHandle(nCurrentHandle);
+ WMFRecord_SelectObject(nDstPenHandle);
+ }
+ }
+ break;
+
+ case META_POLYGON_ACTION:
+ {
+ const MetaPolygonAction* pA = (const MetaPolygonAction*) pMA;
+ SetAttrForAreas();
+ WMFRecord_Polygon( pA->GetPolygon() );
+ }
+ break;
+
+ case META_POLYPOLYGON_ACTION:
+ {
+ const MetaPolyPolygonAction* pA = (const MetaPolyPolygonAction*) pMA;
+ SetAttrForAreas();
+ WMFRecord_PolyPolygon( pA->GetPolyPolygon() );
+ }
+ break;
+
+ case META_TEXT_ACTION:
+ case META_TEXTRECT_ACTION:
+ {
+ const MetaTextAction * pA = (const MetaTextAction*) pMA;
+ String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+ rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
+ rtl_TextEncoding eTargetChrSet = RTL_TEXTENCODING_MS_1252;
+ if ( eChrSet == RTL_TEXTENCODING_DONTKNOW )
+ eChrSet = gsl_getSystemTextEncoding();
+ if ( eChrSet != RTL_TEXTENCODING_SYMBOL )
+ eTargetChrSet = RTL_TEXTENCODING_SYMBOL;
+ ByteString aStr( aTemp, eChrSet, eTargetChrSet );
+ SetAttrForText();
+ WMFRecord_TextOut( pA->GetPoint(), aStr );
+ }
+ break;
+
+ case META_TEXTARRAY_ACTION:
+ {
+ const MetaTextArrayAction* pA = (const MetaTextArrayAction*) pMA;
+
+ String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+ rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
+ rtl_TextEncoding eTargetChrSet = RTL_TEXTENCODING_MS_1252;
+ if ( eChrSet == RTL_TEXTENCODING_DONTKNOW )
+ eChrSet = gsl_getSystemTextEncoding();
+ if ( eChrSet != RTL_TEXTENCODING_SYMBOL )
+ eTargetChrSet = RTL_TEXTENCODING_SYMBOL;
+ ByteString aStr( aTemp, eChrSet, eTargetChrSet );
+ SetAttrForText();
+ WMFRecord_ExtTextOut( pA->GetPoint(), aStr,pA->GetDXArray() );
+ }
+ break;
+
+ case META_STRETCHTEXT_ACTION:
+ {
+ const MetaStretchTextAction* pA = (const MetaStretchTextAction *) pMA;
+ String aTemp( pA->GetText(), pA->GetIndex(), pA->GetLen() );
+ rtl_TextEncoding eChrSet = aSrcFont.GetCharSet();
+ rtl_TextEncoding eTargetChrSet = RTL_TEXTENCODING_MS_1252;
+ if ( eChrSet == RTL_TEXTENCODING_DONTKNOW )
+ eChrSet = gsl_getSystemTextEncoding();
+ if ( eChrSet != RTL_TEXTENCODING_SYMBOL )
+ eTargetChrSet = RTL_TEXTENCODING_SYMBOL;
+ ByteString aStr( aTemp, eChrSet, eTargetChrSet );
+ SetAttrForText();
+ WMFRecord_ExtTextOut( pA->GetPoint(),aStr,pA->GetWidth() );
+ }
+ break;
+
+ case META_BMP_ACTION:
+ {
+ const MetaBmpAction* pA = (const MetaBmpAction *) pMA;
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetBitmap().GetSizePixel(), pA->GetBitmap() );
+ }
+ break;
+
+ case META_BMPSCALE_ACTION:
+ {
+ const MetaBmpScaleAction* pA = (const MetaBmpScaleAction*) pMA;
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pA->GetBitmap() );
+ }
+ break;
+
+ case META_BMPSCALEPART_ACTION:
+ {
+ const MetaBmpScalePartAction* pA = (const MetaBmpScalePartAction*) pMA;
+ Bitmap aTmp( pA->GetBitmap() );
+
+ if( aTmp.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) ) )
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aTmp );
+ }
+
+ case META_BMPEX_ACTION:
+ {
+ const MetaBmpExAction* pA = (const MetaBmpExAction *) pMA;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ WMFRecord_StretchDIB( pA->GetPoint(), aMsk.GetSizePixel(), aBmp, W_SRCPAINT );
+ WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp, W_SRCAND );
+ }
+ else
+ WMFRecord_StretchDIB( pA->GetPoint(), aBmp.GetSizePixel(), aBmp );
+ }
+ break;
+
+ case META_BMPEXSCALE_ACTION:
+ {
+ const MetaBmpExScaleAction* pA = (const MetaBmpExScaleAction*) pMA;
+ Bitmap aBmp( pA->GetBitmapEx().GetBitmap() );
+ Bitmap aMsk( pA->GetBitmapEx().GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aMsk, W_SRCPAINT );
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp, W_SRCAND );
+ }
+ else
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), aBmp );
+ }
+ break;
+
+ case META_BMPEXSCALEPART_ACTION:
+ {
+ const MetaBmpExScalePartAction* pA = (const MetaBmpExScalePartAction*) pMA;
+ BitmapEx aBmpEx( pA->GetBitmapEx() );
+ aBmpEx.Crop( Rectangle( pA->GetSrcPoint(), pA->GetSrcSize() ) );
+ Bitmap aBmp( aBmpEx.GetBitmap() );
+ Bitmap aMsk( aBmpEx.GetMask() );
+
+ if( !!aMsk )
+ {
+ aBmp.Replace( aMsk, COL_WHITE );
+ aMsk.Invert();
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aMsk, W_SRCPAINT );
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp, W_SRCAND );
+ }
+ else
+ WMFRecord_StretchDIB( pA->GetDestPoint(), pA->GetDestSize(), aBmp );
+ }
+
+ case META_GRADIENT_ACTION:
+ {
+ const MetaGradientAction* pA = (const MetaGradientAction*) pMA;
+ GDIMetaFile aTmpMtf;
+
+ pVirDev->AddGradientActions( pA->GetRect(), pA->GetGradient(), aTmpMtf );
+ WriteRecords( aTmpMtf );
+ }
+ break;
+
+ case META_HATCH_ACTION:
+ {
+ const MetaHatchAction* pA = (const MetaHatchAction*) pMA;
+ GDIMetaFile aTmpMtf;
+
+ pVirDev->AddHatchActions( pA->GetPolyPolygon(), pA->GetHatch(), aTmpMtf );
+ WriteRecords( aTmpMtf );
+ }
+ break;
+
+ case META_WALLPAPER_ACTION:
+ {
+ const MetaWallpaperAction* pA = (const MetaWallpaperAction*) pMA;
+ const Color& rColor = pA->GetWallpaper().GetColor();
+ const Color aOldLineColor( aSrcLineColor );
+ const Color aOldFillColor( aSrcFillColor );
+
+ aSrcLineColor = rColor;
+ aSrcFillColor = rColor;
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ SetAttrForAreas();
+ WMFRecord_Rectangle( pA->GetRect() );
+ aSrcLineColor = aOldLineColor;
+ aSrcFillColor = aOldFillColor;
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ }
+ break;
+
+ case META_ISECTRECTCLIPREGION_ACTION:
+ {
+ const MetaISectRectClipRegionAction* pA = (const MetaISectRectClipRegionAction*) pMA;
+ WMFRecord_IntersectClipRect( pA->GetRect() );
+ }
+ break;
+
+ case META_LINECOLOR_ACTION:
+ {
+ const MetaLineColorAction* pA = (const MetaLineColorAction*) pMA;
+
+ if( pA->IsSetting() )
+ aSrcLineColor = pA->GetColor();
+ else
+ aSrcLineColor = Color( COL_TRANSPARENT );
+
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ }
+ break;
+
+ case META_FILLCOLOR_ACTION:
+ {
+ const MetaFillColorAction* pA = (const MetaFillColorAction*) pMA;
+
+ if( pA->IsSetting() )
+ aSrcFillColor = pA->GetColor();
+ else
+ aSrcFillColor = Color( COL_TRANSPARENT );
+
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ }
+ break;
+
+ case META_TEXTCOLOR_ACTION:
+ {
+ const MetaTextColorAction* pA = (const MetaTextColorAction*) pMA;
+ aSrcFont.SetColor( pA->GetColor() );
+ bAttrReadyForText = FALSE;
+ }
+ break;
+
+ case META_TEXTFILLCOLOR_ACTION:
+ {
+ const MetaTextFillColorAction* pA = (const MetaTextFillColorAction*) pMA;
+
+ if( pA->IsSetting() )
+ aSrcFont.SetFillColor( pA->GetColor() );
+ else
+ aSrcFont.SetFillColor( Color( COL_TRANSPARENT ) );
+
+ bAttrReadyForText = FALSE;
+ }
+ break;
+
+ case META_TEXTALIGN_ACTION:
+ {
+ const MetaTextAlignAction* pA = (const MetaTextAlignAction*) pMA;
+ WMFRecord_SetTextAlign( pA->GetTextAlign() );
+ }
+ break;
+
+
+ case META_MAPMODE_ACTION:
+ {
+ const MetaMapModeAction* pA = (const MetaMapModeAction*) pMA;
+
+ if (aSrcMapMode!=pA->GetMapMode())
+ {
+ if( pA->GetMapMode().GetMapUnit() == MAP_RELATIVE )
+ {
+ MapMode aMM = pA->GetMapMode();
+ Fraction aScaleX = aMM.GetScaleX();
+ Fraction aScaleY = aMM.GetScaleY();
+
+ Point aOrigin = aSrcMapMode.GetOrigin();
+ BigInt aX( aOrigin.X() );
+ aX *= BigInt( aScaleX.GetDenominator() );
+ if( aOrigin.X() >= 0 )
+ if( aScaleX.GetNumerator() >= 0 )
+ aX += BigInt( aScaleX.GetNumerator()/2 );
+ else
+ aX -= BigInt( (aScaleX.GetNumerator()+1)/2 );
+ else
+ if( aScaleX.GetNumerator() >= 0 )
+ aX -= BigInt( (aScaleX.GetNumerator()-1)/2 );
+ else
+ aX += BigInt( aScaleX.GetNumerator()/2 );
+ aX /= BigInt( aScaleX.GetNumerator() );
+ aOrigin.X() = (long)aX + aMM.GetOrigin().X();
+ BigInt aY( aOrigin.Y() );
+ aY *= BigInt( aScaleY.GetDenominator() );
+ if( aOrigin.Y() >= 0 )
+ if( aScaleY.GetNumerator() >= 0 )
+ aY += BigInt( aScaleY.GetNumerator()/2 );
+ else
+ aY -= BigInt( (aScaleY.GetNumerator()+1)/2 );
+ else
+ if( aScaleY.GetNumerator() >= 0 )
+ aY -= BigInt( (aScaleY.GetNumerator()-1)/2 );
+ else
+ aY += BigInt( aScaleY.GetNumerator()/2 );
+ aY /= BigInt( aScaleY.GetNumerator() );
+ aOrigin.Y() = (long)aY + aMM.GetOrigin().Y();
+ aSrcMapMode.SetOrigin( aOrigin );
+
+ aScaleX *= aSrcMapMode.GetScaleX();
+ aScaleY *= aSrcMapMode.GetScaleY();
+ aSrcMapMode.SetScaleX( aScaleX );
+ aSrcMapMode.SetScaleY( aScaleY );
+ }
+ else
+ aSrcMapMode=pA->GetMapMode();
+
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ bAttrReadyForText=FALSE;
+ bDstGraphicsInvalid=TRUE;
+ bDstTextInvalid=TRUE;
+ }
+ }
+ break;
+
+ case META_FONT_ACTION:
+ {
+ const MetaFontAction* pA = (const MetaFontAction*) pMA;
+ aSrcFont=pA->GetFont();
+ bAttrReadyForText=FALSE;
+ }
+ break;
+
+ case META_PUSH_ACTION:
+ {
+ WMFWriterAttrStackMember* pAt = new WMFWriterAttrStackMember;
+
+ pAt->aLineColor=aSrcLineColor;
+ pAt->aFillColor=aSrcFillColor;
+ pAt->eRasterOp=eSrcRasterOp;
+ pAt->aFont=aSrcFont;
+ pAt->aMapMode=aSrcMapMode;
+ pAt->aClipRegion=aSrcClipRegion;
+ pAt->pSucc=pAttrStack;
+ pAttrStack=pAt;
+
+ // Fuer das SaveDC muessen wir ggf. alle Objekte
+ // sofort selektieren, damit beim RestoreDC im ::Pop
+ // alles wieder richtig restauriert wird
+ SetAttrForLines();
+ SetAttrForAreas();
+ SetAttrForText();
+
+ // Das machen wir nur, um die ClipRegion nach einem evtl.
+ // IntersectClipRect wieder zuruecksetzen zu koennen
+ WMFRecord_SaveDC();
+ }
+ break;
+
+ case META_POP_ACTION:
+ {
+ WMFWriterAttrStackMember * pAt=pAttrStack;
+
+ if( pAt )
+ {
+ aSrcLineColor=pAt->aLineColor;
+ aSrcFillColor=pAt->aFillColor;
+ eSrcRasterOp=pAt->eRasterOp;
+ aSrcFont=pAt->aFont;
+ aSrcMapMode=pAt->aMapMode;
+ aSrcClipRegion=pAt->aClipRegion;
+ pAttrStack=pAt->pSucc;
+ delete pAt;
+
+ WMFRecord_RestoreDC();
+
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ bAttrReadyForText=FALSE;
+ bDstGraphicsInvalid=TRUE;
+ }
+ }
+ break;
+
+ case META_EPS_ACTION :
+ {
+ const MetaEPSAction* pA = (const MetaEPSAction*)pMA;
+ const GDIMetaFile aGDIMetaFile( pA->GetSubstitute() );
+
+ INT32 nCount = aGDIMetaFile.GetActionCount();
+ for ( INT32 i = 0; i < nCount; i++ )
+ {
+ const MetaAction* pMetaAct = aGDIMetaFile.GetAction( i );
+ if ( pMetaAct->GetType() == META_BMPSCALE_ACTION )
+ {
+ const MetaBmpScaleAction* pBmpScaleAction = (const MetaBmpScaleAction*)pMetaAct;
+ WMFRecord_StretchDIB( pA->GetPoint(), pA->GetSize(), pBmpScaleAction->GetBitmap() );
+ break;
+ }
+ }
+ }
+ break;
+
+ case META_RASTEROP_ACTION:
+ {
+ const MetaRasterOpAction* pA = (const MetaRasterOpAction*) pMA;
+ eSrcRasterOp=pA->GetRasterOp();
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ bAttrReadyForText=FALSE;
+ }
+ break;
+
+ case META_TRANSPARENT_ACTION:
+ {
+ SetAttrForAreas();
+ WMFRecord_PolyPolygon( ( (MetaTransparentAction*) pMA )->GetPolyPolygon() );
+ }
+ break;
+
+ case META_FLOATTRANSPARENT_ACTION:
+ {
+ const MetaFloatTransparentAction* pA = (const MetaFloatTransparentAction*) pMA;
+
+ GDIMetaFile aTmpMtf( pA->GetGDIMetaFile() );
+ Point aSrcPt( aTmpMtf.GetPrefMapMode().GetOrigin() );
+ const Size aSrcSize( aTmpMtf.GetPrefSize() );
+ const Point aDestPt( pA->GetPoint() );
+ const Size aDestSize( pA->GetSize() );
+ const double fScaleX = aSrcSize.Width() ? (double) aDestSize.Width() / aSrcSize.Width() : 1.0;
+ const double fScaleY = aSrcSize.Height() ? (double) aDestSize.Height() / aSrcSize.Height() : 1.0;
+ long nMoveX, nMoveY;
+
+ SetAttrForLines();
+ SetAttrForAreas();
+ SetAttrForText();
+
+ if( fScaleX != 1.0 || fScaleY != 1.0 )
+ {
+ aTmpMtf.Scale( fScaleX, fScaleY );
+ aSrcPt.X() = FRound( aSrcPt.X() * fScaleX ), aSrcPt.Y() = FRound( aSrcPt.Y() * fScaleY );
+ }
+
+ nMoveX = aDestPt.X() - aSrcPt.X(), nMoveY = aDestPt.Y() - aSrcPt.Y();
+
+ if( nMoveX || nMoveY )
+ aTmpMtf.Move( nMoveX, nMoveY );
+
+ WriteRecords( aTmpMtf );
+ }
+ break;
+
+ // Unsupported Actions
+ case META_MASK_ACTION:
+ case META_MASKSCALE_ACTION:
+ case META_MASKSCALEPART_ACTION:
+ {
+ DBG_ERROR( "Unsupported action: MetaMask...Action!" );
+ }
+ break;
+
+ case META_CLIPREGION_ACTION:
+ break;
+
+ case META_ISECTREGIONCLIPREGION_ACTION:
+ {
+ DBG_ERROR( "Unsupported action: MetaISectRegionClipRegionAction!" );
+ }
+ break;
+
+ case META_MOVECLIPREGION_ACTION:
+ {
+ DBG_ERROR( "Unsupported action: MetaMoveClipRegionAction!" );
+ }
+ break;
+ }
+
+ nWrittenActions++;
+ MayCallback();
+
+ if (pWMF->GetError())
+ bStatus=FALSE;
+
+ if(bStatus==FALSE)
+ break;
+ }
+ }
+}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::WriteHeader( const GDIMetaFile & rMTF, BOOL bPlaceable )
+{
+ if( bPlaceable )
+ {
+ USHORT nCheckSum, nValue;
+ Size aSize( pVirDev->LogicToLogic(Size(1,1),MapMode(MAP_INCH), aTargetMapMode) );
+ USHORT nUnitsPerInch = (USHORT) ( ( aSize.Width() + aSize.Height() ) >> 1 );
+
+ nCheckSum=0;
+ nValue=0xcdd7; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x9ac6; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=(USHORT) aTargetSize.Width(); nCheckSum^=nValue; *pWMF << nValue;
+ nValue=(USHORT) aTargetSize.Height(); nCheckSum^=nValue; *pWMF << nValue;
+ nValue=nUnitsPerInch; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ nValue=0x0000; nCheckSum^=nValue; *pWMF << nValue;
+ *pWMF << nCheckSum;
+ }
+
+ nMetafileHeaderPos=pWMF->Tell();
+ *pWMF << (USHORT)0x0001 // Typ: Datei
+ << (USHORT)0x0009 // Headerlaenge in Worten
+ << (USHORT)0x0300 // Version als BCD-Zahl
+ << (ULONG) 0x00000000 // Dateilaenge (ohne 1. Header), wird spaeter durch UpdateHeader() berichtigt
+ << (USHORT)MAXOBJECTHANDLES // Maximalezahl der gleichzeitigen Objekte
+ << (ULONG) 0x00000000 // Maximale Record-laenge, wird spaeter durch UpdateHeader() berichtigt
+ << (USHORT)0x0000; // Reserved
+}
+
+// ------------------------------------------------------------------------
+
+void WMFWriter::UpdateHeader()
+{
+ ULONG nPos,nFileSize;
+
+ nPos=pWMF->Tell(); // Endposition = Gesammtgroesse der Datei
+ nFileSize=nPos-nMetafileHeaderPos; // Groesse des 1. Headers abziehen
+ if ((nFileSize&1)!=0) { // ggf. auf ganze Worte aufrunden
+ *pWMF << (BYTE)0;
+ nPos++;
+ nFileSize++;
+ }
+ nFileSize>>=1; // In Anzahl Worte umrechnen
+ pWMF->Seek(nMetafileHeaderPos+6); // Zum Dateigroessen-Eintrag im zweiten Header
+ *pWMF << nFileSize; // Dateigroesse berichtigen
+ pWMF->SeekRel(2); // Zum Max-Record-Laenge-Eintrag im zweiten Header
+ *pWMF << nMaxRecordSize; // und berichtigen
+ pWMF->Seek(nPos);
+}
+
+// ------------------------------------------------------------------------
+
+BOOL WMFWriter::WriteWMF(const GDIMetaFile& rMTF, SvStream& rTargetStream,
+ PFilterCallback pcallback, void* pcallerdata,
+ BOOL bPlaceable)
+{
+ WMFWriterAttrStackMember * pAt;
+
+ bStatus=TRUE;
+ pVirDev = new VirtualDevice;
+ pCallback=pcallback;
+ pCallerData=pcallerdata;
+ nLastPercent=0;
+
+ pWMF=&rTargetStream;
+ pWMF->SetNumberFormatInt(NUMBERFORMAT_INT_LITTLEENDIAN);
+
+ nMaxRecordSize=0;
+
+ aSrcMapMode=rMTF.GetPrefMapMode();
+
+ if( bPlaceable )
+ {
+ aTargetMapMode = aSrcMapMode;
+ aTargetSize = rMTF.GetPrefSize();
+ nTargetDivisor = CalcSaveTargetMapMode(aTargetMapMode, aTargetSize);
+ aTargetSize.Width() /= nTargetDivisor;
+ aTargetSize.Height() /= nTargetDivisor;
+ }
+ else
+ {
+ aTargetMapMode = MapMode( MAP_INCH );
+
+ const long nUnit = pVirDev->LogicToPixel( Size( 1, 1 ), aTargetMapMode ).Width();
+ const Fraction aFrac( 1, nUnit );
+
+ aTargetMapMode.SetScaleX( aFrac );
+ aTargetMapMode.SetScaleY( aFrac );
+ aTargetSize = pVirDev->LogicToLogic( rMTF.GetPrefSize(), aSrcMapMode, aTargetMapMode );
+ }
+
+ pVirDev->SetMapMode( aTargetMapMode );
+
+ aSrcLineColor = Color( COL_BLACK );
+ aSrcFillColor = Color( COL_WHITE );
+ eSrcRasterOp=ROP_OVERPAINT;
+ aSrcFont=Font();
+ bSrcIsClipping=FALSE;
+ aSrcClipRegion=Region();
+ pAttrStack=NULL;
+
+ aDstLineColor = Color( COL_BLACK );
+ aDstFillColor = Color( COL_WHITE );
+ eDstROP2=ROP_OVERPAINT;
+ aDstTextColor=Color(COL_BLACK);
+ eDstTextAlign=ALIGN_BASELINE;
+ aDstFont=Font();
+ bDstIsClipping=FALSE;
+ aDstClipRegion=Region();
+
+ for (USHORT i=0; i<MAXOBJECTHANDLES; i++)
+ bHandleAllocated[i]=FALSE;
+
+ nDstPenHandle=0xffff;
+ nDstFontHandle=0xffff;
+ nDstBrushHandle=0xffff;
+
+ bDstTextInvalid=TRUE;
+ bDstGraphicsInvalid=TRUE;
+
+ bAttrReadyForLines=FALSE;
+ bAttrReadyForAreas=FALSE;
+ bAttrReadyForText=FALSE;
+
+ nNumberOfActions=0;
+ nNumberOfBitmaps=0;
+ nWrittenActions=0;
+ nWrittenBitmaps=0;
+ nActBitmapPercent=0;
+
+ CountActionsAndBitmaps(rMTF);
+
+ WriteHeader(rMTF,bPlaceable);
+ WMFRecord_SetWindowOrg(Point(0,0));
+ WMFRecord_SetWindowExt(rMTF.GetPrefSize());
+ WMFRecord_SetBkMode( TRUE );
+
+ // Write records
+ WriteRecords(rMTF);
+
+ WMFRecord_EndOfFile();
+ UpdateHeader();
+
+ while(pAttrStack)
+ {
+ pAt=pAttrStack;
+ pAttrStack=pAt->pSucc;
+ delete pAt;
+ }
+
+ delete pVirDev;
+
+ return bStatus;
+}
+
+// ------------------------------------------------------------------------
+
+USHORT WMFWriter::CalcSaveTargetMapMode(MapMode& rMapMode,
+ const Size& rPrefSize)
+{
+ Fraction aDivFrac(2, 1);
+ USHORT nDivisor = 1;
+
+ Size aSize = pVirDev->LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
+
+ while( nDivisor <= 64 && (aSize.Width() > 32767 || aSize.Height() > 32767) )
+ {
+ Fraction aFrac = rMapMode.GetScaleX();
+
+ aFrac *= aDivFrac;
+ rMapMode.SetScaleX(aFrac);
+ aFrac = rMapMode.GetScaleY();
+ aFrac *= aDivFrac;
+ rMapMode.SetScaleY(aFrac);
+ nDivisor <<= 1;
+ aSize = pVirDev->LogicToLogic( rPrefSize, aSrcMapMode, rMapMode );
+ }
+
+ return nDivisor;
+}
diff --git a/svtools/source/filter.vcl/wmf/wmfwr.hxx b/svtools/source/filter.vcl/wmf/wmfwr.hxx
new file mode 100644
index 000000000000..1ac7603c1ba9
--- /dev/null
+++ b/svtools/source/filter.vcl/wmf/wmfwr.hxx
@@ -0,0 +1,245 @@
+/*************************************************************************
+ *
+ * $RCSfile: wmfwr.hxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: hr $ $Date: 2000-09-18 16:59:00 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * 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
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef _WMFWR_HXX
+#define _WMFWR_HXX
+
+#include <tools/bigint.hxx>
+#include <tools/debug.hxx>
+#include <vcl/metaact.hxx>
+#include <vcl/graph.hxx>
+#include <vcl/gdimtf.hxx>
+#include <vcl/virdev.hxx>
+#include "fltcall.hxx"
+
+// -----------------------------------------------------------------------------
+
+#define MAXOBJECTHANDLES 16
+
+// -----------------------------------------------------------------------------
+
+struct WMFWriterAttrStackMember
+{
+ struct WMFWriterAttrStackMember * pSucc;
+ Color aLineColor;
+ Color aFillColor;
+ RasterOp eRasterOp;
+ Font aFont;
+ MapMode aMapMode;
+ Region aClipRegion;
+};
+
+// -------------
+// - WMFWriter -
+// -------------
+
+class WMFWriter
+{
+private:
+
+ BOOL bStatus;
+
+ PFilterCallback pCallback;
+ void* pCallerData;
+ ULONG nLastPercent; // Mit welcher Zahl pCallback zuletzt aufgerufen wurde.
+
+ SvStream* pWMF;
+ VirtualDevice* pVirDev;
+ MapMode aTargetMapMode;
+ Size aTargetSize;
+ USHORT nTargetDivisor;
+
+ ULONG nMetafileHeaderPos;
+ ULONG nMaxRecordSize; // in Worten
+ ULONG nActRecordPos;
+
+ // Aktuelle Attribute im Quell-Metafile:
+ Color aSrcLineColor;
+ Color aSrcFillColor;
+ RasterOp eSrcRasterOp;
+ Font aSrcFont;
+ MapMode aSrcMapMode;
+ BOOL bSrcIsClipping;
+ Region aSrcClipRegion;
+ WMFWriterAttrStackMember * pAttrStack;
+
+ // Aktuelle Attribute im Ziel-Metafile:
+ RasterOp eDstROP2;
+ Color aDstTextColor;
+ FontAlign eDstTextAlign;
+ Color aDstLineColor;
+ Color aDstFillColor;
+ Font aDstFont;
+ BOOL bDstIsClipping; // ???: derzeit unberuecksichtigt
+ Region aDstClipRegion; // ???: derzeit unberuecksichtigt
+ BOOL bHandleAllocated[MAXOBJECTHANDLES]; // Welche Handles vergeben sind
+ USHORT nDstPenHandle,nDstFontHandle,nDstBrushHandle; // Welche Handles die jeweiligen
+ // Selected-Objects besitzen
+ // 0xffff = keines:
+ BOOL bDstTextInvalid; // ist TRUE, wenn die Variablen aDstTextColor, eDstTextAlign
+ // und aDstFont nicht mit den Attributen im Ziel-Metafile
+ // uebereinstimmen (Das ist am Anfang der Fall)
+ BOOL bDstGraphicsInvalid; // dito fuer alle anderen Attribute
+
+ // Damit nicht bei jeder Operation alle Attribute verglichen werden muessen:
+ BOOL bAttrReadyForLines; // Ist TRUE, wenn die Attribute im Ziel-Metafile so
+ // gesetzt sind, dass Linien ausgegeben werden koennen.
+ BOOL bAttrReadyForAreas; // Ist TRUE, wenn die Attribute im Ziel-Metafile so
+ // gesetzt sind, dass gefuellte Polygone, Rechtecke etc.
+ // (einschliesslich Umrahmung) ausgegeben werden koennen.
+ BOOL bAttrReadyForText; // Ist TRUE, wenn die Attribute im Ziel-Metafile so
+ // gesetzt sind, dass Text ausgegeben werden kann.
+
+ ULONG nNumberOfActions; // Anzahl der Actions im GDIMetafile
+ ULONG nNumberOfBitmaps; // Anzahl der Bitmaps
+ ULONG nWrittenActions; // Anzahl der bereits verarbeiteten Actions beim Schreiben der Orders
+ ULONG nWrittenBitmaps; // Anzahl der bereits geschriebenen Bitmaps
+ ULONG nActBitmapPercent; // Wieviel Prozent die naechste Bitmap schon geschrieben ist.
+
+ void MayCallback();
+ // Berechnet anhand der obigen 5 Parameter eine Prozentzahl
+ // und macht dann ggf. einen Callback. Setzt bStatus auf FALSE wenn User abbrechen
+ // moechte.
+
+ void CountActionsAndBitmaps(const GDIMetaFile & rMTF);
+ // Zaehlt die Bitmaps und Actions (nNumberOfActions und nNumberOfBitmaps muessen
+ // zu Anfang auf 0 gesetzt werden, weil diese Methode rekursiv ist)
+
+ void WritePointXY(const Point & rPoint);
+ void WritePointYX(const Point & rPoint);
+ void WriteDX(long nDX);
+ void WriteSize(const Size & rSize);
+ void WriteHeightWidth(const Size & rSize);
+ void WriteRectangle(const Rectangle & rRect);
+ void WriteColor(const Color & rColor);
+
+ void WriteRecordHeader(ULONG nSizeWords, USHORT nType);
+ // nSizeWords ist die Groesse des gesammten Records in Anzahl Worte.
+ // Wenn nSizeWords unbekannt ist, dann 0 einsetzen (siehe UpdateRecordHeader()).
+
+ void UpdateRecordHeader();
+ // berichtig die Groesse des Records nach dem Schreiben der Parameter, wenn
+ // nSizeWords bei Aufruf von WriteRecordHeader(..) unbekannt war.
+ // fuegt ggf. noch ein BYTE 0 ein damit Anzahl Bytes immer gerade.
+
+ void WMFRecord_Arc(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
+ void WMFRecord_Chord(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
+ void WMFRecord_CreateBrushIndirect(const Color& rColor);
+ void WMFRecord_CreateFontIndirect(const Font & rFont);
+ void WMFRecord_CreatePenIndirect(const Color& rColor);
+ void WMFRecord_CreatePenIndirect(const Color& rColor, const LineInfo& rLineInfo );
+ void WMFRecord_DeleteObject(USHORT nObjectHandle);
+ void WMFRecord_Ellipse(const Rectangle & rRect);
+ void WMFRecord_ExtTextOut(const Point & rPoint, const ByteString & rString, const long * pDXAry);
+ void WMFRecord_ExtTextOut(const Point & rPoint, const ByteString & rString, ULONG nWidth);
+ void WMFRecord_LineTo(const Point & rPoint);
+ void WMFRecord_MoveTo(const Point & rPoint);
+ void WMFRecord_Pie(const Rectangle & rRect, const Point & rStartPt, const Point & rEndPt);
+ void WMFRecord_Polygon(const Polygon & rPoly);
+ void WMFRecord_PolyLine(const Polygon & rPoly);
+ void WMFRecord_PolyPolygon(const PolyPolygon & rPolyPoly);
+ void WMFRecord_Rectangle(const Rectangle & rRect);
+ void WMFRecord_RestoreDC();
+ void WMFRecord_RoundRect(const Rectangle & rRect, long nHorzRound, long nVertRound);
+ void WMFRecord_SaveDC();
+ void WMFRecord_SelectObject(USHORT nObjectHandle);
+ void WMFRecord_SetBkColor(const Color & rColor);
+ void WMFRecord_SetBkMode(BOOL bTransparent);
+ void WMFRecord_SetStretchBltMode();
+ void WMFRecord_SetPixel(const Point & rPoint, const Color & rColor);
+ void WMFRecord_SetROP2(RasterOp eROP);
+ void WMFRecord_SetTextAlign(FontAlign eFontAlign);
+ void WMFRecord_SetTextColor(const Color & rColor);
+ void WMFRecord_SetWindowExt(const Size & rSize);
+ void WMFRecord_SetWindowOrg(const Point & rPoint);
+ void WMFRecord_StretchDIB(const Point & rPoint, const Size & rSize, const Bitmap & rBitmap, ULONG nROP = 0UL );
+ void WMFRecord_TextOut(const Point & rPoint, const ByteString & rString);
+ void WMFRecord_EndOfFile();
+ void WMFRecord_IntersectClipRect( const Rectangle& rRect);
+
+ USHORT AllocHandle();
+ void FreeHandle(USHORT nObjectHandle);
+ void CreateSelectDeletePen(const Color& rColor);
+ void CreateSelectDeleteFont(const Font & rFont);
+ void CreateSelectDeleteBrush(const Color& rColor);
+
+ void SetAttrForLines(); // Setzt die Dst-Attribute fuer Linien
+ void SetAttrForAreas(); // Setzt die Dst-Attribute fuer gefuellte Dinge.
+ // Macht automatisch SetAttrForLines, wenn BrushStyle NULL
+ void SetAttrForText(); // Setzt die Dst-Attribute fuer Text-Ausgabe
+
+ void WriteRecords(const GDIMetaFile & rMTF);
+
+ void WriteHeader(const GDIMetaFile & rMTF, BOOL bPlaceable);
+ void UpdateHeader();
+
+ USHORT CalcSaveTargetMapMode(MapMode& rMapMode, const Size& rPrefSize);
+
+public:
+
+ WMFWriter() {}
+
+ BOOL WriteWMF(const GDIMetaFile & rMTF, SvStream & rTargetStream,
+ PFilterCallback pcallback, void * pcallerdata,
+ BOOL bPlaceable=TRUE);
+};
+
+#endif