diff options
Diffstat (limited to 'svtools/source/filter.vcl/wmf')
-rw-r--r-- | svtools/source/filter.vcl/wmf/emfwr.cxx | 1207 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/emfwr.hxx | 129 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/enhwmf.cxx | 1077 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/makefile.mk | 97 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winmtf.cxx | 1262 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winmtf.hxx | 687 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/winwmf.cxx | 886 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/wmf.cxx | 147 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/wmfwr.cxx | 1787 | ||||
-rw-r--r-- | svtools/source/filter.vcl/wmf/wmfwr.hxx | 245 |
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 |