1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir #include <vos/macros.hxx> 31*cdf0e10cSrcweir #include <rtl/crc.h> 32*cdf0e10cSrcweir #include <tools/stream.hxx> 33*cdf0e10cSrcweir #include <tools/vcompat.hxx> 34*cdf0e10cSrcweir #include <vcl/metaact.hxx> 35*cdf0e10cSrcweir #include <vcl/salbtype.hxx> 36*cdf0e10cSrcweir #include <vcl/outdev.hxx> 37*cdf0e10cSrcweir #include <vcl/window.hxx> 38*cdf0e10cSrcweir #ifndef _SV_CVTSVM_HXX 39*cdf0e10cSrcweir #include <vcl/cvtsvm.hxx> 40*cdf0e10cSrcweir #endif 41*cdf0e10cSrcweir #include <vcl/virdev.hxx> 42*cdf0e10cSrcweir #include <vcl/gdimtf.hxx> 43*cdf0e10cSrcweir #include <vcl/graphictools.hxx> 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir // ----------- 46*cdf0e10cSrcweir // - Defines - 47*cdf0e10cSrcweir // ----------- 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #define GAMMA( _def_cVal, _def_InvGamma ) ((sal_uInt8)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L)) 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir // -------------------------- 52*cdf0e10cSrcweir // - Color exchange structs - 53*cdf0e10cSrcweir // -------------------------- 54*cdf0e10cSrcweir 55*cdf0e10cSrcweir struct ImplColAdjustParam 56*cdf0e10cSrcweir { 57*cdf0e10cSrcweir sal_uInt8* pMapR; 58*cdf0e10cSrcweir sal_uInt8* pMapG; 59*cdf0e10cSrcweir sal_uInt8* pMapB; 60*cdf0e10cSrcweir }; 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir struct ImplBmpAdjustParam 63*cdf0e10cSrcweir { 64*cdf0e10cSrcweir short nLuminancePercent; 65*cdf0e10cSrcweir short nContrastPercent; 66*cdf0e10cSrcweir short nChannelRPercent; 67*cdf0e10cSrcweir short nChannelGPercent; 68*cdf0e10cSrcweir short nChannelBPercent; 69*cdf0e10cSrcweir double fGamma; 70*cdf0e10cSrcweir sal_Bool bInvert; 71*cdf0e10cSrcweir }; 72*cdf0e10cSrcweir 73*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 74*cdf0e10cSrcweir 75*cdf0e10cSrcweir struct ImplColConvertParam 76*cdf0e10cSrcweir { 77*cdf0e10cSrcweir MtfConversion eConversion; 78*cdf0e10cSrcweir }; 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir struct ImplBmpConvertParam 81*cdf0e10cSrcweir { 82*cdf0e10cSrcweir BmpConversion eConversion; 83*cdf0e10cSrcweir }; 84*cdf0e10cSrcweir 85*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir struct ImplColMonoParam 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir Color aColor; 90*cdf0e10cSrcweir }; 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir struct ImplBmpMonoParam 93*cdf0e10cSrcweir { 94*cdf0e10cSrcweir Color aColor; 95*cdf0e10cSrcweir }; 96*cdf0e10cSrcweir 97*cdf0e10cSrcweir // ----------------------------------------------------------------------------- 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir struct ImplColReplaceParam 100*cdf0e10cSrcweir { 101*cdf0e10cSrcweir sal_uLong* pMinR; 102*cdf0e10cSrcweir sal_uLong* pMaxR; 103*cdf0e10cSrcweir sal_uLong* pMinG; 104*cdf0e10cSrcweir sal_uLong* pMaxG; 105*cdf0e10cSrcweir sal_uLong* pMinB; 106*cdf0e10cSrcweir sal_uLong* pMaxB; 107*cdf0e10cSrcweir const Color* pDstCols; 108*cdf0e10cSrcweir sal_uLong nCount; 109*cdf0e10cSrcweir }; 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir struct ImplBmpReplaceParam 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir const Color* pSrcCols; 114*cdf0e10cSrcweir const Color* pDstCols; 115*cdf0e10cSrcweir sal_uLong nCount; 116*cdf0e10cSrcweir const sal_uLong* pTols; 117*cdf0e10cSrcweir }; 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir // --------- 121*cdf0e10cSrcweir // - Label - 122*cdf0e10cSrcweir // --------- 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir struct ImpLabel 125*cdf0e10cSrcweir { 126*cdf0e10cSrcweir String aLabelName; 127*cdf0e10cSrcweir sal_uLong nActionPos; 128*cdf0e10cSrcweir 129*cdf0e10cSrcweir ImpLabel( const String& rLabelName, sal_uLong _nActionPos ) : 130*cdf0e10cSrcweir aLabelName( rLabelName ), 131*cdf0e10cSrcweir nActionPos( _nActionPos ) {} 132*cdf0e10cSrcweir }; 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir // ------------- 135*cdf0e10cSrcweir // - LabelList - 136*cdf0e10cSrcweir // ------------- 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir class ImpLabelList : private List 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir public: 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir ImpLabelList() : List( 8, 4, 4 ) {} 143*cdf0e10cSrcweir ImpLabelList( const ImpLabelList& rList ); 144*cdf0e10cSrcweir ~ImpLabelList(); 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir void ImplInsert( ImpLabel* p ) { Insert( p, LIST_APPEND ); } 147*cdf0e10cSrcweir ImpLabel* ImplRemove( sal_uLong nPos ) { return (ImpLabel*) Remove( nPos ); } 148*cdf0e10cSrcweir void ImplReplace( ImpLabel* p ) { Replace( (void*)p ); } 149*cdf0e10cSrcweir ImpLabel* ImplFirst() { return (ImpLabel*) First(); } 150*cdf0e10cSrcweir ImpLabel* ImplNext() { return (ImpLabel*) Next(); } 151*cdf0e10cSrcweir ImpLabel* ImplGetLabel( sal_uLong nPos ) const { return (ImpLabel*) GetObject( nPos ); } 152*cdf0e10cSrcweir sal_uLong ImplGetLabelPos( const String& rLabelName ); 153*cdf0e10cSrcweir sal_uLong ImplCount() const { return Count(); } 154*cdf0e10cSrcweir }; 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir // ------------------------------------------------------------------------ 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir ImpLabelList::ImpLabelList( const ImpLabelList& rList ) : 159*cdf0e10cSrcweir List( rList ) 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() ) 162*cdf0e10cSrcweir ImplReplace( new ImpLabel( *pLabel ) ); 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir // ------------------------------------------------------------------------ 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir ImpLabelList::~ImpLabelList() 168*cdf0e10cSrcweir { 169*cdf0e10cSrcweir for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() ) 170*cdf0e10cSrcweir delete pLabel; 171*cdf0e10cSrcweir } 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir // ------------------------------------------------------------------------ 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir sal_uLong ImpLabelList::ImplGetLabelPos( const String& rLabelName ) 176*cdf0e10cSrcweir { 177*cdf0e10cSrcweir sal_uLong nLabelPos = METAFILE_LABEL_NOTFOUND; 178*cdf0e10cSrcweir 179*cdf0e10cSrcweir for( ImpLabel* pLabel = ImplFirst(); pLabel; pLabel = ImplNext() ) 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir if ( rLabelName == pLabel->aLabelName ) 182*cdf0e10cSrcweir { 183*cdf0e10cSrcweir nLabelPos = GetCurPos(); 184*cdf0e10cSrcweir break; 185*cdf0e10cSrcweir } 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir return nLabelPos; 189*cdf0e10cSrcweir } 190*cdf0e10cSrcweir 191*cdf0e10cSrcweir // --------------- 192*cdf0e10cSrcweir // - GDIMetaFile - 193*cdf0e10cSrcweir // --------------- 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir GDIMetaFile::GDIMetaFile() : 196*cdf0e10cSrcweir List ( 0x3EFF, 64, 64 ), 197*cdf0e10cSrcweir aPrefSize ( 1, 1 ), 198*cdf0e10cSrcweir pPrev ( NULL ), 199*cdf0e10cSrcweir pNext ( NULL ), 200*cdf0e10cSrcweir pOutDev ( NULL ), 201*cdf0e10cSrcweir pLabelList ( NULL ), 202*cdf0e10cSrcweir bPause ( sal_False ), 203*cdf0e10cSrcweir bRecord ( sal_False ) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir // ------------------------------------------------------------------------ 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir GDIMetaFile::GDIMetaFile( const GDIMetaFile& rMtf ) : 210*cdf0e10cSrcweir List ( rMtf ), 211*cdf0e10cSrcweir aPrefMapMode ( rMtf.aPrefMapMode ), 212*cdf0e10cSrcweir aPrefSize ( rMtf.aPrefSize ), 213*cdf0e10cSrcweir aHookHdlLink ( rMtf.aHookHdlLink ), 214*cdf0e10cSrcweir pPrev ( rMtf.pPrev ), 215*cdf0e10cSrcweir pNext ( rMtf.pNext ), 216*cdf0e10cSrcweir pOutDev ( NULL ), 217*cdf0e10cSrcweir bPause ( sal_False ), 218*cdf0e10cSrcweir bRecord ( sal_False ) 219*cdf0e10cSrcweir { 220*cdf0e10cSrcweir // RefCount der MetaActions erhoehen 221*cdf0e10cSrcweir for( void* pAct = First(); pAct; pAct = Next() ) 222*cdf0e10cSrcweir ( (MetaAction*) pAct )->Duplicate(); 223*cdf0e10cSrcweir 224*cdf0e10cSrcweir if( rMtf.pLabelList ) 225*cdf0e10cSrcweir pLabelList = new ImpLabelList( *rMtf.pLabelList ); 226*cdf0e10cSrcweir else 227*cdf0e10cSrcweir pLabelList = NULL; 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir if( rMtf.bRecord ) 230*cdf0e10cSrcweir { 231*cdf0e10cSrcweir Record( rMtf.pOutDev ); 232*cdf0e10cSrcweir 233*cdf0e10cSrcweir if ( rMtf.bPause ) 234*cdf0e10cSrcweir Pause( sal_True ); 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir } 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir // ------------------------------------------------------------------------ 239*cdf0e10cSrcweir 240*cdf0e10cSrcweir GDIMetaFile::~GDIMetaFile() 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir Clear(); 243*cdf0e10cSrcweir } 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir // ------------------------------------------------------------------------ 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir GDIMetaFile& GDIMetaFile::operator=( const GDIMetaFile& rMtf ) 248*cdf0e10cSrcweir { 249*cdf0e10cSrcweir if( this != &rMtf ) 250*cdf0e10cSrcweir { 251*cdf0e10cSrcweir Clear(); 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir List::operator=( rMtf ); 254*cdf0e10cSrcweir 255*cdf0e10cSrcweir // RefCount der MetaActions erhoehen 256*cdf0e10cSrcweir for( void* pAct = First(); pAct; pAct = Next() ) 257*cdf0e10cSrcweir ( (MetaAction*) pAct )->Duplicate(); 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir if( rMtf.pLabelList ) 260*cdf0e10cSrcweir pLabelList = new ImpLabelList( *rMtf.pLabelList ); 261*cdf0e10cSrcweir else 262*cdf0e10cSrcweir pLabelList = NULL; 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir aPrefMapMode = rMtf.aPrefMapMode; 265*cdf0e10cSrcweir aPrefSize = rMtf.aPrefSize; 266*cdf0e10cSrcweir aHookHdlLink = rMtf.aHookHdlLink; 267*cdf0e10cSrcweir pPrev = rMtf.pPrev; 268*cdf0e10cSrcweir pNext = rMtf.pNext; 269*cdf0e10cSrcweir pOutDev = NULL; 270*cdf0e10cSrcweir bPause = sal_False; 271*cdf0e10cSrcweir bRecord = sal_False; 272*cdf0e10cSrcweir 273*cdf0e10cSrcweir if( rMtf.bRecord ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir Record( rMtf.pOutDev ); 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir if( rMtf.bPause ) 278*cdf0e10cSrcweir Pause( sal_True ); 279*cdf0e10cSrcweir } 280*cdf0e10cSrcweir } 281*cdf0e10cSrcweir 282*cdf0e10cSrcweir return *this; 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir // ------------------------------------------------------------------------ 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir sal_Bool GDIMetaFile::operator==( const GDIMetaFile& rMtf ) const 288*cdf0e10cSrcweir { 289*cdf0e10cSrcweir const sal_uLong nObjCount = Count(); 290*cdf0e10cSrcweir sal_Bool bRet = sal_False; 291*cdf0e10cSrcweir 292*cdf0e10cSrcweir if( this == &rMtf ) 293*cdf0e10cSrcweir bRet = sal_True; 294*cdf0e10cSrcweir else if( rMtf.GetActionCount() == nObjCount && 295*cdf0e10cSrcweir rMtf.GetPrefSize() == aPrefSize && 296*cdf0e10cSrcweir rMtf.GetPrefMapMode() == aPrefMapMode ) 297*cdf0e10cSrcweir { 298*cdf0e10cSrcweir bRet = sal_True; 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir for( sal_uLong n = 0UL; n < nObjCount; n++ ) 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir if( GetObject( n ) != rMtf.GetObject( n ) ) 303*cdf0e10cSrcweir { 304*cdf0e10cSrcweir bRet = sal_False; 305*cdf0e10cSrcweir break; 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir return bRet; 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir // ------------------------------------------------------------------------ 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir sal_Bool GDIMetaFile::IsEqual( const GDIMetaFile& rMtf ) const 316*cdf0e10cSrcweir { 317*cdf0e10cSrcweir const sal_uLong nObjCount = Count(); 318*cdf0e10cSrcweir sal_Bool bRet = sal_False; 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir if( this == &rMtf ) 321*cdf0e10cSrcweir bRet = sal_True; 322*cdf0e10cSrcweir else if( rMtf.GetActionCount() == nObjCount && 323*cdf0e10cSrcweir rMtf.GetPrefSize() == aPrefSize && 324*cdf0e10cSrcweir rMtf.GetPrefMapMode() == aPrefMapMode ) 325*cdf0e10cSrcweir { 326*cdf0e10cSrcweir bRet = sal_True; 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir for( sal_uLong n = 0UL; n < nObjCount; n++ ) 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir if(!((MetaAction*)GetObject( n ))->IsEqual(*((MetaAction*)rMtf.GetObject( n )))) 331*cdf0e10cSrcweir { 332*cdf0e10cSrcweir bRet = sal_False; 333*cdf0e10cSrcweir break; 334*cdf0e10cSrcweir } 335*cdf0e10cSrcweir } 336*cdf0e10cSrcweir } 337*cdf0e10cSrcweir 338*cdf0e10cSrcweir return bRet; 339*cdf0e10cSrcweir } 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir // ------------------------------------------------------------------------ 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir void GDIMetaFile::Clear() 344*cdf0e10cSrcweir { 345*cdf0e10cSrcweir if( bRecord ) 346*cdf0e10cSrcweir Stop(); 347*cdf0e10cSrcweir 348*cdf0e10cSrcweir for( void* pAct = First(); pAct; pAct = Next() ) 349*cdf0e10cSrcweir ( (MetaAction*) pAct )->Delete(); 350*cdf0e10cSrcweir 351*cdf0e10cSrcweir List::Clear(); 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir delete pLabelList; 354*cdf0e10cSrcweir pLabelList = NULL; 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir 357*cdf0e10cSrcweir // ------------------------------------------------------------------------ 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir void GDIMetaFile::Linker( OutputDevice* pOut, sal_Bool bLink ) 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir if( bLink ) 362*cdf0e10cSrcweir { 363*cdf0e10cSrcweir pNext = NULL; 364*cdf0e10cSrcweir pPrev = pOut->GetConnectMetaFile(); 365*cdf0e10cSrcweir pOut->SetConnectMetaFile( this ); 366*cdf0e10cSrcweir 367*cdf0e10cSrcweir if( pPrev ) 368*cdf0e10cSrcweir pPrev->pNext = this; 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir else 371*cdf0e10cSrcweir { 372*cdf0e10cSrcweir if( pNext ) 373*cdf0e10cSrcweir { 374*cdf0e10cSrcweir pNext->pPrev = pPrev; 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir if( pPrev ) 377*cdf0e10cSrcweir pPrev->pNext = pNext; 378*cdf0e10cSrcweir } 379*cdf0e10cSrcweir else 380*cdf0e10cSrcweir { 381*cdf0e10cSrcweir if( pPrev ) 382*cdf0e10cSrcweir pPrev->pNext = NULL; 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir pOut->SetConnectMetaFile( pPrev ); 385*cdf0e10cSrcweir } 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir pPrev = NULL; 388*cdf0e10cSrcweir pNext = NULL; 389*cdf0e10cSrcweir } 390*cdf0e10cSrcweir } 391*cdf0e10cSrcweir 392*cdf0e10cSrcweir // ------------------------------------------------------------------------ 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir long GDIMetaFile::Hook() 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir return aHookHdlLink.Call( this ); 397*cdf0e10cSrcweir } 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir // ------------------------------------------------------------------------ 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir void GDIMetaFile::Record( OutputDevice* pOut ) 402*cdf0e10cSrcweir { 403*cdf0e10cSrcweir if( bRecord ) 404*cdf0e10cSrcweir Stop(); 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir Last(); 407*cdf0e10cSrcweir pOutDev = pOut; 408*cdf0e10cSrcweir bRecord = sal_True; 409*cdf0e10cSrcweir Linker( pOut, sal_True ); 410*cdf0e10cSrcweir } 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir // ------------------------------------------------------------------------ 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir void GDIMetaFile::Play( GDIMetaFile& rMtf, sal_uLong nPos ) 415*cdf0e10cSrcweir { 416*cdf0e10cSrcweir if ( !bRecord && !rMtf.bRecord ) 417*cdf0e10cSrcweir { 418*cdf0e10cSrcweir MetaAction* pAction = GetCurAction(); 419*cdf0e10cSrcweir const sal_uLong nObjCount = Count(); 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir if( nPos > nObjCount ) 422*cdf0e10cSrcweir nPos = nObjCount; 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir for( sal_uLong nCurPos = GetCurPos(); nCurPos < nPos; nCurPos++ ) 425*cdf0e10cSrcweir { 426*cdf0e10cSrcweir if( !Hook() ) 427*cdf0e10cSrcweir { 428*cdf0e10cSrcweir pAction->Duplicate(); 429*cdf0e10cSrcweir rMtf.AddAction( pAction ); 430*cdf0e10cSrcweir } 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir pAction = (MetaAction*) Next(); 433*cdf0e10cSrcweir } 434*cdf0e10cSrcweir } 435*cdf0e10cSrcweir } 436*cdf0e10cSrcweir 437*cdf0e10cSrcweir // ------------------------------------------------------------------------ 438*cdf0e10cSrcweir 439*cdf0e10cSrcweir void GDIMetaFile::Play( OutputDevice* pOut, sal_uLong nPos ) 440*cdf0e10cSrcweir { 441*cdf0e10cSrcweir if( !bRecord ) 442*cdf0e10cSrcweir { 443*cdf0e10cSrcweir MetaAction* pAction = GetCurAction(); 444*cdf0e10cSrcweir const sal_uLong nObjCount = Count(); 445*cdf0e10cSrcweir sal_uLong i = 0, nSyncCount = ( pOut->GetOutDevType() == OUTDEV_WINDOW ) ? 0x000000ff : 0xffffffff; 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir if( nPos > nObjCount ) 448*cdf0e10cSrcweir nPos = nObjCount; 449*cdf0e10cSrcweir 450*cdf0e10cSrcweir // #i23407# Set backwards-compatible text language and layout mode 451*cdf0e10cSrcweir // This is necessary, since old metafiles don't even know of these 452*cdf0e10cSrcweir // recent add-ons. Newer metafiles must of course explicitely set 453*cdf0e10cSrcweir // those states. 454*cdf0e10cSrcweir pOut->Push( PUSH_TEXTLAYOUTMODE|PUSH_TEXTLANGUAGE ); 455*cdf0e10cSrcweir pOut->SetLayoutMode( 0 ); 456*cdf0e10cSrcweir pOut->SetDigitLanguage( 0 ); 457*cdf0e10cSrcweir 458*cdf0e10cSrcweir for( sal_uLong nCurPos = GetCurPos(); nCurPos < nPos; nCurPos++ ) 459*cdf0e10cSrcweir { 460*cdf0e10cSrcweir if( !Hook() ) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir pAction->Execute( pOut ); 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir // flush output from time to time 465*cdf0e10cSrcweir if( i++ > nSyncCount ) 466*cdf0e10cSrcweir ( (Window*) pOut )->Flush(), i = 0; 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir 469*cdf0e10cSrcweir pAction = (MetaAction*) Next(); 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir 472*cdf0e10cSrcweir pOut->Pop(); 473*cdf0e10cSrcweir } 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir // ------------------------------------------------------------------------ 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir void GDIMetaFile::Play( OutputDevice* pOut, const Point& rPos, 479*cdf0e10cSrcweir const Size& rSize, sal_uLong nPos ) 480*cdf0e10cSrcweir { 481*cdf0e10cSrcweir Region aDrawClipRegion; 482*cdf0e10cSrcweir MapMode aDrawMap( GetPrefMapMode() ); 483*cdf0e10cSrcweir Size aDestSize( pOut->LogicToPixel( rSize ) ); 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir if( aDestSize.Width() && aDestSize.Height() ) 486*cdf0e10cSrcweir { 487*cdf0e10cSrcweir Size aTmpPrefSize( pOut->LogicToPixel( GetPrefSize(), aDrawMap ) ); 488*cdf0e10cSrcweir GDIMetaFile* pMtf = pOut->GetConnectMetaFile(); 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir if( !aTmpPrefSize.Width() ) 491*cdf0e10cSrcweir aTmpPrefSize.Width() = aDestSize.Width(); 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir if( !aTmpPrefSize.Height() ) 494*cdf0e10cSrcweir aTmpPrefSize.Height() = aDestSize.Height(); 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir Fraction aScaleX( aDestSize.Width(), aTmpPrefSize.Width() ); 497*cdf0e10cSrcweir Fraction aScaleY( aDestSize.Height(), aTmpPrefSize.Height() ); 498*cdf0e10cSrcweir 499*cdf0e10cSrcweir aScaleX *= aDrawMap.GetScaleX(); aDrawMap.SetScaleX( aScaleX ); 500*cdf0e10cSrcweir aScaleY *= aDrawMap.GetScaleY(); aDrawMap.SetScaleY( aScaleY ); 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir // #i47260# Convert logical output position to offset within 503*cdf0e10cSrcweir // the metafile's mapmode. Therefore, disable pixel offset on 504*cdf0e10cSrcweir // outdev, it's inverse mnOutOffLogicX/Y is calculated for a 505*cdf0e10cSrcweir // different mapmode (the one currently set on pOut, that is) 506*cdf0e10cSrcweir // - thus, aDrawMap's origin would generally be wrong. And 507*cdf0e10cSrcweir // even _if_ aDrawMap is similar to pOutDev's current mapmode, 508*cdf0e10cSrcweir // it's _still_ undesirable to have pixel offset unequal zero, 509*cdf0e10cSrcweir // because one would still get round-off errors (the 510*cdf0e10cSrcweir // round-trip error for LogicToPixel( PixelToLogic() ) was the 511*cdf0e10cSrcweir // reason for having pixel offset in the first place). 512*cdf0e10cSrcweir const Size& rOldOffset( pOut->GetPixelOffset() ); 513*cdf0e10cSrcweir const Size aEmptySize; 514*cdf0e10cSrcweir pOut->SetPixelOffset( aEmptySize ); 515*cdf0e10cSrcweir aDrawMap.SetOrigin( pOut->PixelToLogic( pOut->LogicToPixel( rPos ), aDrawMap ) ); 516*cdf0e10cSrcweir pOut->SetPixelOffset( rOldOffset ); 517*cdf0e10cSrcweir 518*cdf0e10cSrcweir pOut->Push(); 519*cdf0e10cSrcweir 520*cdf0e10cSrcweir if ( pMtf && pMtf->IsRecord() && ( pOut->GetOutDevType() != OUTDEV_PRINTER ) ) 521*cdf0e10cSrcweir pOut->SetRelativeMapMode( aDrawMap ); 522*cdf0e10cSrcweir else 523*cdf0e10cSrcweir pOut->SetMapMode( aDrawMap ); 524*cdf0e10cSrcweir 525*cdf0e10cSrcweir // #i23407# Set backwards-compatible text language and layout mode 526*cdf0e10cSrcweir // This is necessary, since old metafiles don't even know of these 527*cdf0e10cSrcweir // recent add-ons. Newer metafiles must of course explicitely set 528*cdf0e10cSrcweir // those states. 529*cdf0e10cSrcweir pOut->SetLayoutMode( 0 ); 530*cdf0e10cSrcweir pOut->SetDigitLanguage( 0 ); 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir Play( pOut, nPos ); 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir pOut->Pop(); 535*cdf0e10cSrcweir } 536*cdf0e10cSrcweir } 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir // ------------------------------------------------------------------------ 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir void GDIMetaFile::Pause( sal_Bool _bPause ) 541*cdf0e10cSrcweir { 542*cdf0e10cSrcweir if( bRecord ) 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir if( _bPause ) 545*cdf0e10cSrcweir { 546*cdf0e10cSrcweir if( !bPause ) 547*cdf0e10cSrcweir Linker( pOutDev, sal_False ); 548*cdf0e10cSrcweir } 549*cdf0e10cSrcweir else 550*cdf0e10cSrcweir { 551*cdf0e10cSrcweir if( bPause ) 552*cdf0e10cSrcweir Linker( pOutDev, sal_True ); 553*cdf0e10cSrcweir } 554*cdf0e10cSrcweir 555*cdf0e10cSrcweir bPause = _bPause; 556*cdf0e10cSrcweir } 557*cdf0e10cSrcweir } 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir // ------------------------------------------------------------------------ 560*cdf0e10cSrcweir 561*cdf0e10cSrcweir void GDIMetaFile::Stop() 562*cdf0e10cSrcweir { 563*cdf0e10cSrcweir if( bRecord ) 564*cdf0e10cSrcweir { 565*cdf0e10cSrcweir bRecord = sal_False; 566*cdf0e10cSrcweir 567*cdf0e10cSrcweir if( !bPause ) 568*cdf0e10cSrcweir Linker( pOutDev, sal_False ); 569*cdf0e10cSrcweir else 570*cdf0e10cSrcweir bPause = sal_False; 571*cdf0e10cSrcweir } 572*cdf0e10cSrcweir } 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir // ------------------------------------------------------------------------ 575*cdf0e10cSrcweir 576*cdf0e10cSrcweir void GDIMetaFile::WindStart() 577*cdf0e10cSrcweir { 578*cdf0e10cSrcweir if( !bRecord ) 579*cdf0e10cSrcweir First(); 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir // ------------------------------------------------------------------------ 583*cdf0e10cSrcweir 584*cdf0e10cSrcweir void GDIMetaFile::WindEnd() 585*cdf0e10cSrcweir { 586*cdf0e10cSrcweir if( !bRecord ) 587*cdf0e10cSrcweir Last(); 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir // ------------------------------------------------------------------------ 591*cdf0e10cSrcweir 592*cdf0e10cSrcweir void GDIMetaFile::Wind( sal_uLong nActionPos ) 593*cdf0e10cSrcweir { 594*cdf0e10cSrcweir if( !bRecord ) 595*cdf0e10cSrcweir Seek( nActionPos ); 596*cdf0e10cSrcweir } 597*cdf0e10cSrcweir 598*cdf0e10cSrcweir // ------------------------------------------------------------------------ 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir void GDIMetaFile::WindPrev() 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir if( !bRecord ) 603*cdf0e10cSrcweir Prev(); 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir // ------------------------------------------------------------------------ 607*cdf0e10cSrcweir 608*cdf0e10cSrcweir void GDIMetaFile::WindNext() 609*cdf0e10cSrcweir { 610*cdf0e10cSrcweir if( !bRecord ) 611*cdf0e10cSrcweir Next(); 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir // ------------------------------------------------------------------------ 615*cdf0e10cSrcweir 616*cdf0e10cSrcweir void GDIMetaFile::AddAction( MetaAction* pAction ) 617*cdf0e10cSrcweir { 618*cdf0e10cSrcweir Insert( pAction, LIST_APPEND ); 619*cdf0e10cSrcweir 620*cdf0e10cSrcweir if( pPrev ) 621*cdf0e10cSrcweir { 622*cdf0e10cSrcweir pAction->Duplicate(); 623*cdf0e10cSrcweir pPrev->AddAction( pAction ); 624*cdf0e10cSrcweir } 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir // ------------------------------------------------------------------------ 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir void GDIMetaFile::AddAction( MetaAction* pAction, sal_uLong nPos ) 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir Insert( pAction, nPos ); 632*cdf0e10cSrcweir 633*cdf0e10cSrcweir if( pPrev ) 634*cdf0e10cSrcweir { 635*cdf0e10cSrcweir pAction->Duplicate(); 636*cdf0e10cSrcweir pPrev->AddAction( pAction, nPos ); 637*cdf0e10cSrcweir } 638*cdf0e10cSrcweir } 639*cdf0e10cSrcweir 640*cdf0e10cSrcweir // ------------------------------------------------------------------------ 641*cdf0e10cSrcweir 642*cdf0e10cSrcweir // @since #110496# 643*cdf0e10cSrcweir void GDIMetaFile::RemoveAction( sal_uLong nPos ) 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir Remove( nPos ); 646*cdf0e10cSrcweir 647*cdf0e10cSrcweir if( pPrev ) 648*cdf0e10cSrcweir pPrev->RemoveAction( nPos ); 649*cdf0e10cSrcweir } 650*cdf0e10cSrcweir 651*cdf0e10cSrcweir // ------------------------------------------------------------------------ 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir MetaAction* GDIMetaFile::CopyAction( sal_uLong nPos ) const 654*cdf0e10cSrcweir { 655*cdf0e10cSrcweir return ( (MetaAction*) GetObject( nPos ) )->Clone(); 656*cdf0e10cSrcweir } 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir // ------------------------------------------------------------------------ 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetActionPos( const String& rLabel ) 661*cdf0e10cSrcweir { 662*cdf0e10cSrcweir ImpLabel* pLabel = NULL; 663*cdf0e10cSrcweir 664*cdf0e10cSrcweir if( pLabelList ) 665*cdf0e10cSrcweir pLabel = pLabelList->ImplGetLabel( pLabelList->ImplGetLabelPos( rLabel ) ); 666*cdf0e10cSrcweir else 667*cdf0e10cSrcweir pLabel = NULL; 668*cdf0e10cSrcweir 669*cdf0e10cSrcweir return( pLabel ? pLabel->nActionPos : METAFILE_LABEL_NOTFOUND ); 670*cdf0e10cSrcweir } 671*cdf0e10cSrcweir 672*cdf0e10cSrcweir // ------------------------------------------------------------------------ 673*cdf0e10cSrcweir 674*cdf0e10cSrcweir sal_Bool GDIMetaFile::InsertLabel( const String& rLabel, sal_uLong nActionPos ) 675*cdf0e10cSrcweir { 676*cdf0e10cSrcweir sal_Bool bRet = sal_False; 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir if( !pLabelList ) 679*cdf0e10cSrcweir pLabelList = new ImpLabelList; 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir if( pLabelList->ImplGetLabelPos( rLabel ) == METAFILE_LABEL_NOTFOUND ) 682*cdf0e10cSrcweir { 683*cdf0e10cSrcweir pLabelList->ImplInsert( new ImpLabel( rLabel, nActionPos ) ); 684*cdf0e10cSrcweir bRet = sal_True; 685*cdf0e10cSrcweir } 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir return bRet; 688*cdf0e10cSrcweir } 689*cdf0e10cSrcweir 690*cdf0e10cSrcweir // ------------------------------------------------------------------------ 691*cdf0e10cSrcweir 692*cdf0e10cSrcweir void GDIMetaFile::RemoveLabel( const String& rLabel ) 693*cdf0e10cSrcweir { 694*cdf0e10cSrcweir if( pLabelList ) 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir const sal_uLong nLabelPos = pLabelList->ImplGetLabelPos( rLabel ); 697*cdf0e10cSrcweir 698*cdf0e10cSrcweir if( nLabelPos != METAFILE_LABEL_NOTFOUND ) 699*cdf0e10cSrcweir delete pLabelList->ImplRemove( nLabelPos ); 700*cdf0e10cSrcweir } 701*cdf0e10cSrcweir } 702*cdf0e10cSrcweir 703*cdf0e10cSrcweir // ------------------------------------------------------------------------ 704*cdf0e10cSrcweir 705*cdf0e10cSrcweir void GDIMetaFile::RenameLabel( const String& rLabel, const String& rNewLabel ) 706*cdf0e10cSrcweir { 707*cdf0e10cSrcweir if( pLabelList ) 708*cdf0e10cSrcweir { 709*cdf0e10cSrcweir const sal_uLong nLabelPos = pLabelList->ImplGetLabelPos( rLabel ); 710*cdf0e10cSrcweir 711*cdf0e10cSrcweir if ( nLabelPos != METAFILE_LABEL_NOTFOUND ) 712*cdf0e10cSrcweir pLabelList->ImplGetLabel( nLabelPos )->aLabelName = rNewLabel; 713*cdf0e10cSrcweir } 714*cdf0e10cSrcweir } 715*cdf0e10cSrcweir 716*cdf0e10cSrcweir // ------------------------------------------------------------------------ 717*cdf0e10cSrcweir 718*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetLabelCount() const 719*cdf0e10cSrcweir { 720*cdf0e10cSrcweir return( pLabelList ? pLabelList->ImplCount() : 0UL ); 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir 723*cdf0e10cSrcweir // ------------------------------------------------------------------------ 724*cdf0e10cSrcweir 725*cdf0e10cSrcweir String GDIMetaFile::GetLabel( sal_uLong nLabel ) 726*cdf0e10cSrcweir { 727*cdf0e10cSrcweir String aString; 728*cdf0e10cSrcweir 729*cdf0e10cSrcweir if( pLabelList ) 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir const ImpLabel* pLabel = pLabelList->ImplGetLabel( nLabel ); 732*cdf0e10cSrcweir 733*cdf0e10cSrcweir if( pLabel ) 734*cdf0e10cSrcweir aString = pLabel->aLabelName; 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir 737*cdf0e10cSrcweir return aString; 738*cdf0e10cSrcweir } 739*cdf0e10cSrcweir 740*cdf0e10cSrcweir // ------------------------------------------------------------------------ 741*cdf0e10cSrcweir 742*cdf0e10cSrcweir sal_Bool GDIMetaFile::SaveStatus() 743*cdf0e10cSrcweir { 744*cdf0e10cSrcweir if ( bRecord ) 745*cdf0e10cSrcweir { 746*cdf0e10cSrcweir if ( bPause ) 747*cdf0e10cSrcweir Linker( pOutDev, sal_True ); 748*cdf0e10cSrcweir 749*cdf0e10cSrcweir AddAction( new MetaLineColorAction( pOutDev->GetLineColor(), 750*cdf0e10cSrcweir pOutDev->IsLineColor() ) ); 751*cdf0e10cSrcweir AddAction( new MetaFillColorAction( pOutDev->GetFillColor(), 752*cdf0e10cSrcweir pOutDev->IsFillColor() ) ); 753*cdf0e10cSrcweir AddAction( new MetaFontAction( pOutDev->GetFont() ) ); 754*cdf0e10cSrcweir AddAction( new MetaTextColorAction( pOutDev->GetTextColor() ) ); 755*cdf0e10cSrcweir AddAction( new MetaTextFillColorAction( pOutDev->GetTextFillColor(), 756*cdf0e10cSrcweir pOutDev->IsTextFillColor() ) ); 757*cdf0e10cSrcweir AddAction( new MetaTextLineColorAction( pOutDev->GetTextLineColor(), 758*cdf0e10cSrcweir pOutDev->IsTextLineColor() ) ); 759*cdf0e10cSrcweir AddAction( new MetaOverlineColorAction( pOutDev->GetOverlineColor(), 760*cdf0e10cSrcweir pOutDev->IsOverlineColor() ) ); 761*cdf0e10cSrcweir AddAction( new MetaTextAlignAction( pOutDev->GetTextAlign() ) ); 762*cdf0e10cSrcweir AddAction( new MetaRasterOpAction( pOutDev->GetRasterOp() ) ); 763*cdf0e10cSrcweir AddAction( new MetaMapModeAction( pOutDev->GetMapMode() ) ); 764*cdf0e10cSrcweir AddAction( new MetaClipRegionAction( pOutDev->GetClipRegion(), 765*cdf0e10cSrcweir pOutDev->IsClipRegion() ) ); 766*cdf0e10cSrcweir 767*cdf0e10cSrcweir if ( bPause ) 768*cdf0e10cSrcweir Linker( pOutDev, sal_False ); 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir return sal_True; 771*cdf0e10cSrcweir } 772*cdf0e10cSrcweir else 773*cdf0e10cSrcweir return sal_False; 774*cdf0e10cSrcweir } 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir // ------------------------------------------------------------------------ 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir sal_Bool GDIMetaFile::Mirror( sal_uLong nMirrorFlags ) 779*cdf0e10cSrcweir { 780*cdf0e10cSrcweir const Size aOldPrefSize( GetPrefSize() ); 781*cdf0e10cSrcweir long nMoveX, nMoveY; 782*cdf0e10cSrcweir double fScaleX, fScaleY; 783*cdf0e10cSrcweir sal_Bool bRet; 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir if( nMirrorFlags & MTF_MIRROR_HORZ ) 786*cdf0e10cSrcweir nMoveX = VOS_ABS( aOldPrefSize.Width() ) - 1, fScaleX = -1.0; 787*cdf0e10cSrcweir else 788*cdf0e10cSrcweir nMoveX = 0, fScaleX = 1.0; 789*cdf0e10cSrcweir 790*cdf0e10cSrcweir if( nMirrorFlags & MTF_MIRROR_VERT ) 791*cdf0e10cSrcweir nMoveY = VOS_ABS( aOldPrefSize.Height() ) - 1, fScaleY = -1.0; 792*cdf0e10cSrcweir else 793*cdf0e10cSrcweir nMoveY = 0, fScaleY = 1.0; 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir if( ( fScaleX != 1.0 ) || ( fScaleY != 1.0 ) ) 796*cdf0e10cSrcweir { 797*cdf0e10cSrcweir Scale( fScaleX, fScaleY ); 798*cdf0e10cSrcweir Move( nMoveX, nMoveY ); 799*cdf0e10cSrcweir SetPrefSize( aOldPrefSize ); 800*cdf0e10cSrcweir bRet = sal_True; 801*cdf0e10cSrcweir } 802*cdf0e10cSrcweir else 803*cdf0e10cSrcweir bRet = sal_False; 804*cdf0e10cSrcweir 805*cdf0e10cSrcweir return bRet; 806*cdf0e10cSrcweir } 807*cdf0e10cSrcweir 808*cdf0e10cSrcweir // ------------------------------------------------------------------------ 809*cdf0e10cSrcweir 810*cdf0e10cSrcweir void GDIMetaFile::Move( long nX, long nY ) 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir const Size aBaseOffset( nX, nY ); 813*cdf0e10cSrcweir Size aOffset( aBaseOffset ); 814*cdf0e10cSrcweir VirtualDevice aMapVDev; 815*cdf0e10cSrcweir 816*cdf0e10cSrcweir aMapVDev.EnableOutput( sal_False ); 817*cdf0e10cSrcweir aMapVDev.SetMapMode( GetPrefMapMode() ); 818*cdf0e10cSrcweir 819*cdf0e10cSrcweir for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() ) 820*cdf0e10cSrcweir { 821*cdf0e10cSrcweir const long nType = pAct->GetType(); 822*cdf0e10cSrcweir MetaAction* pModAct; 823*cdf0e10cSrcweir 824*cdf0e10cSrcweir if( pAct->GetRefCount() > 1 ) 825*cdf0e10cSrcweir { 826*cdf0e10cSrcweir Replace( pModAct = pAct->Clone(), GetCurPos() ); 827*cdf0e10cSrcweir pAct->Delete(); 828*cdf0e10cSrcweir } 829*cdf0e10cSrcweir else 830*cdf0e10cSrcweir pModAct = pAct; 831*cdf0e10cSrcweir 832*cdf0e10cSrcweir if( ( META_MAPMODE_ACTION == nType ) || 833*cdf0e10cSrcweir ( META_PUSH_ACTION == nType ) || 834*cdf0e10cSrcweir ( META_POP_ACTION == nType ) ) 835*cdf0e10cSrcweir { 836*cdf0e10cSrcweir pModAct->Execute( &aMapVDev ); 837*cdf0e10cSrcweir aOffset = aMapVDev.LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev.GetMapMode() ); 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir pModAct->Move( aOffset.Width(), aOffset.Height() ); 841*cdf0e10cSrcweir } 842*cdf0e10cSrcweir } 843*cdf0e10cSrcweir 844*cdf0e10cSrcweir void GDIMetaFile::Move( long nX, long nY, long nDPIX, long nDPIY ) 845*cdf0e10cSrcweir { 846*cdf0e10cSrcweir const Size aBaseOffset( nX, nY ); 847*cdf0e10cSrcweir Size aOffset( aBaseOffset ); 848*cdf0e10cSrcweir VirtualDevice aMapVDev; 849*cdf0e10cSrcweir 850*cdf0e10cSrcweir aMapVDev.EnableOutput( sal_False ); 851*cdf0e10cSrcweir aMapVDev.SetReferenceDevice( nDPIX, nDPIY ); 852*cdf0e10cSrcweir aMapVDev.SetMapMode( GetPrefMapMode() ); 853*cdf0e10cSrcweir 854*cdf0e10cSrcweir for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() ) 855*cdf0e10cSrcweir { 856*cdf0e10cSrcweir const long nType = pAct->GetType(); 857*cdf0e10cSrcweir MetaAction* pModAct; 858*cdf0e10cSrcweir 859*cdf0e10cSrcweir if( pAct->GetRefCount() > 1 ) 860*cdf0e10cSrcweir { 861*cdf0e10cSrcweir Replace( pModAct = pAct->Clone(), GetCurPos() ); 862*cdf0e10cSrcweir pAct->Delete(); 863*cdf0e10cSrcweir } 864*cdf0e10cSrcweir else 865*cdf0e10cSrcweir pModAct = pAct; 866*cdf0e10cSrcweir 867*cdf0e10cSrcweir if( ( META_MAPMODE_ACTION == nType ) || 868*cdf0e10cSrcweir ( META_PUSH_ACTION == nType ) || 869*cdf0e10cSrcweir ( META_POP_ACTION == nType ) ) 870*cdf0e10cSrcweir { 871*cdf0e10cSrcweir pModAct->Execute( &aMapVDev ); 872*cdf0e10cSrcweir if( aMapVDev.GetMapMode().GetMapUnit() == MAP_PIXEL ) 873*cdf0e10cSrcweir { 874*cdf0e10cSrcweir aOffset = aMapVDev.LogicToPixel( aBaseOffset, GetPrefMapMode() ); 875*cdf0e10cSrcweir MapMode aMap( aMapVDev.GetMapMode() ); 876*cdf0e10cSrcweir aOffset.Width() = static_cast<long>(aOffset.Width() * (double)aMap.GetScaleX()); 877*cdf0e10cSrcweir aOffset.Height() = static_cast<long>(aOffset.Height() * (double)aMap.GetScaleY()); 878*cdf0e10cSrcweir } 879*cdf0e10cSrcweir else 880*cdf0e10cSrcweir aOffset = aMapVDev.LogicToLogic( aBaseOffset, GetPrefMapMode(), aMapVDev.GetMapMode() ); 881*cdf0e10cSrcweir } 882*cdf0e10cSrcweir 883*cdf0e10cSrcweir pModAct->Move( aOffset.Width(), aOffset.Height() ); 884*cdf0e10cSrcweir } 885*cdf0e10cSrcweir } 886*cdf0e10cSrcweir 887*cdf0e10cSrcweir // ------------------------------------------------------------------------ 888*cdf0e10cSrcweir 889*cdf0e10cSrcweir void GDIMetaFile::Scale( double fScaleX, double fScaleY ) 890*cdf0e10cSrcweir { 891*cdf0e10cSrcweir for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() ) 892*cdf0e10cSrcweir { 893*cdf0e10cSrcweir MetaAction* pModAct; 894*cdf0e10cSrcweir 895*cdf0e10cSrcweir if( pAct->GetRefCount() > 1 ) 896*cdf0e10cSrcweir { 897*cdf0e10cSrcweir Replace( pModAct = pAct->Clone(), GetCurPos() ); 898*cdf0e10cSrcweir pAct->Delete(); 899*cdf0e10cSrcweir } 900*cdf0e10cSrcweir else 901*cdf0e10cSrcweir pModAct = pAct; 902*cdf0e10cSrcweir 903*cdf0e10cSrcweir pModAct->Scale( fScaleX, fScaleY ); 904*cdf0e10cSrcweir } 905*cdf0e10cSrcweir 906*cdf0e10cSrcweir aPrefSize.Width() = FRound( aPrefSize.Width() * fScaleX ); 907*cdf0e10cSrcweir aPrefSize.Height() = FRound( aPrefSize.Height() * fScaleY ); 908*cdf0e10cSrcweir } 909*cdf0e10cSrcweir 910*cdf0e10cSrcweir // ------------------------------------------------------------------------ 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir void GDIMetaFile::Scale( const Fraction& rScaleX, const Fraction& rScaleY ) 913*cdf0e10cSrcweir { 914*cdf0e10cSrcweir Scale( (double) rScaleX, (double) rScaleY ); 915*cdf0e10cSrcweir } 916*cdf0e10cSrcweir 917*cdf0e10cSrcweir // ------------------------------------------------------------------------ 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir void GDIMetaFile::Clip( const Rectangle& i_rClipRect ) 920*cdf0e10cSrcweir { 921*cdf0e10cSrcweir Rectangle aCurRect( i_rClipRect ); 922*cdf0e10cSrcweir VirtualDevice aMapVDev; 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir aMapVDev.EnableOutput( sal_False ); 925*cdf0e10cSrcweir aMapVDev.SetMapMode( GetPrefMapMode() ); 926*cdf0e10cSrcweir 927*cdf0e10cSrcweir for( MetaAction* pAct = (MetaAction*) First(); pAct; pAct = (MetaAction*) Next() ) 928*cdf0e10cSrcweir { 929*cdf0e10cSrcweir const long nType = pAct->GetType(); 930*cdf0e10cSrcweir 931*cdf0e10cSrcweir if( ( META_MAPMODE_ACTION == nType ) || 932*cdf0e10cSrcweir ( META_PUSH_ACTION == nType ) || 933*cdf0e10cSrcweir ( META_POP_ACTION == nType ) ) 934*cdf0e10cSrcweir { 935*cdf0e10cSrcweir pAct->Execute( &aMapVDev ); 936*cdf0e10cSrcweir aCurRect = aMapVDev.LogicToLogic( i_rClipRect, GetPrefMapMode(), aMapVDev.GetMapMode() ); 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir else if( nType == META_CLIPREGION_ACTION ) 939*cdf0e10cSrcweir { 940*cdf0e10cSrcweir MetaClipRegionAction* pOldAct = (MetaClipRegionAction*)pAct; 941*cdf0e10cSrcweir Region aNewReg( aCurRect ); 942*cdf0e10cSrcweir if( pOldAct->IsClipping() ) 943*cdf0e10cSrcweir aNewReg.Intersect( pOldAct->GetRegion() ); 944*cdf0e10cSrcweir MetaClipRegionAction* pNewAct = new MetaClipRegionAction( aNewReg, sal_True ); 945*cdf0e10cSrcweir Replace( pNewAct, GetCurPos() ); 946*cdf0e10cSrcweir pOldAct->Delete(); 947*cdf0e10cSrcweir } 948*cdf0e10cSrcweir } 949*cdf0e10cSrcweir } 950*cdf0e10cSrcweir 951*cdf0e10cSrcweir // ------------------------------------------------------------------------ 952*cdf0e10cSrcweir 953*cdf0e10cSrcweir Point GDIMetaFile::ImplGetRotatedPoint( const Point& rPt, const Point& rRotatePt, 954*cdf0e10cSrcweir const Size& rOffset, double fSin, double fCos ) 955*cdf0e10cSrcweir { 956*cdf0e10cSrcweir const long nX = rPt.X() - rRotatePt.X(); 957*cdf0e10cSrcweir const long nY = rPt.Y() - rRotatePt.Y(); 958*cdf0e10cSrcweir 959*cdf0e10cSrcweir return Point( FRound( fCos * nX + fSin * nY ) + rRotatePt.X() + rOffset.Width(), 960*cdf0e10cSrcweir -FRound( fSin * nX - fCos * nY ) + rRotatePt.Y() + rOffset.Height() ); 961*cdf0e10cSrcweir } 962*cdf0e10cSrcweir 963*cdf0e10cSrcweir // ------------------------------------------------------------------------ 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir Polygon GDIMetaFile::ImplGetRotatedPolygon( const Polygon& rPoly, const Point& rRotatePt, 966*cdf0e10cSrcweir const Size& rOffset, double fSin, double fCos ) 967*cdf0e10cSrcweir { 968*cdf0e10cSrcweir Polygon aRet( rPoly ); 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir aRet.Rotate( rRotatePt, fSin, fCos ); 971*cdf0e10cSrcweir aRet.Move( rOffset.Width(), rOffset.Height() ); 972*cdf0e10cSrcweir 973*cdf0e10cSrcweir return aRet; 974*cdf0e10cSrcweir } 975*cdf0e10cSrcweir 976*cdf0e10cSrcweir // ------------------------------------------------------------------------ 977*cdf0e10cSrcweir 978*cdf0e10cSrcweir PolyPolygon GDIMetaFile::ImplGetRotatedPolyPolygon( const PolyPolygon& rPolyPoly, const Point& rRotatePt, 979*cdf0e10cSrcweir const Size& rOffset, double fSin, double fCos ) 980*cdf0e10cSrcweir { 981*cdf0e10cSrcweir PolyPolygon aRet( rPolyPoly ); 982*cdf0e10cSrcweir 983*cdf0e10cSrcweir aRet.Rotate( rRotatePt, fSin, fCos ); 984*cdf0e10cSrcweir aRet.Move( rOffset.Width(), rOffset.Height() ); 985*cdf0e10cSrcweir 986*cdf0e10cSrcweir return aRet; 987*cdf0e10cSrcweir } 988*cdf0e10cSrcweir 989*cdf0e10cSrcweir // ------------------------------------------------------------------------ 990*cdf0e10cSrcweir 991*cdf0e10cSrcweir void GDIMetaFile::ImplAddGradientEx( GDIMetaFile& rMtf, 992*cdf0e10cSrcweir const OutputDevice& rMapDev, 993*cdf0e10cSrcweir const PolyPolygon& rPolyPoly, 994*cdf0e10cSrcweir const Gradient& rGrad ) 995*cdf0e10cSrcweir { 996*cdf0e10cSrcweir // #105055# Generate comment, GradientEx and Gradient actions 997*cdf0e10cSrcweir // (within DrawGradient) 998*cdf0e10cSrcweir VirtualDevice aVDev( rMapDev, 0 ); 999*cdf0e10cSrcweir aVDev.EnableOutput( sal_False ); 1000*cdf0e10cSrcweir GDIMetaFile aGradMtf; 1001*cdf0e10cSrcweir 1002*cdf0e10cSrcweir aGradMtf.Record( &aVDev ); 1003*cdf0e10cSrcweir aVDev.DrawGradient( rPolyPoly, rGrad ); 1004*cdf0e10cSrcweir aGradMtf.Stop(); 1005*cdf0e10cSrcweir 1006*cdf0e10cSrcweir int i, nAct( aGradMtf.GetActionCount() ); 1007*cdf0e10cSrcweir for( i=0; i<nAct; ++i ) 1008*cdf0e10cSrcweir { 1009*cdf0e10cSrcweir MetaAction* pMetaAct = aGradMtf.GetAction(i); 1010*cdf0e10cSrcweir pMetaAct->Duplicate(); 1011*cdf0e10cSrcweir rMtf.AddAction( pMetaAct ); 1012*cdf0e10cSrcweir } 1013*cdf0e10cSrcweir } 1014*cdf0e10cSrcweir 1015*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1016*cdf0e10cSrcweir 1017*cdf0e10cSrcweir void GDIMetaFile::Rotate( long nAngle10 ) 1018*cdf0e10cSrcweir { 1019*cdf0e10cSrcweir nAngle10 %= 3600L; 1020*cdf0e10cSrcweir nAngle10 = ( nAngle10 < 0L ) ? ( 3599L + nAngle10 ) : nAngle10; 1021*cdf0e10cSrcweir 1022*cdf0e10cSrcweir if( nAngle10 ) 1023*cdf0e10cSrcweir { 1024*cdf0e10cSrcweir GDIMetaFile aMtf; 1025*cdf0e10cSrcweir VirtualDevice aMapVDev; 1026*cdf0e10cSrcweir const double fAngle = F_PI1800 * nAngle10; 1027*cdf0e10cSrcweir const double fSin = sin( fAngle ); 1028*cdf0e10cSrcweir const double fCos = cos( fAngle ); 1029*cdf0e10cSrcweir Rectangle aRect=Rectangle( Point(), GetPrefSize() ); 1030*cdf0e10cSrcweir Polygon aPoly( aRect ); 1031*cdf0e10cSrcweir 1032*cdf0e10cSrcweir aPoly.Rotate( Point(), fSin, fCos ); 1033*cdf0e10cSrcweir 1034*cdf0e10cSrcweir aMapVDev.EnableOutput( sal_False ); 1035*cdf0e10cSrcweir aMapVDev.SetMapMode( GetPrefMapMode() ); 1036*cdf0e10cSrcweir 1037*cdf0e10cSrcweir const Rectangle aNewBound( aPoly.GetBoundRect() ); 1038*cdf0e10cSrcweir 1039*cdf0e10cSrcweir const Point aOrigin( GetPrefMapMode().GetOrigin().X(), GetPrefMapMode().GetOrigin().Y() ); 1040*cdf0e10cSrcweir const Size aOffset( -aNewBound.Left(), -aNewBound.Top() ); 1041*cdf0e10cSrcweir 1042*cdf0e10cSrcweir Point aRotAnchor( aOrigin ); 1043*cdf0e10cSrcweir Size aRotOffset( aOffset ); 1044*cdf0e10cSrcweir 1045*cdf0e10cSrcweir for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() ) 1046*cdf0e10cSrcweir { 1047*cdf0e10cSrcweir const sal_uInt16 nActionType = pAction->GetType(); 1048*cdf0e10cSrcweir 1049*cdf0e10cSrcweir switch( nActionType ) 1050*cdf0e10cSrcweir { 1051*cdf0e10cSrcweir case( META_PIXEL_ACTION ): 1052*cdf0e10cSrcweir { 1053*cdf0e10cSrcweir MetaPixelAction* pAct = (MetaPixelAction*) pAction; 1054*cdf0e10cSrcweir aMtf.AddAction( new MetaPixelAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ), 1055*cdf0e10cSrcweir pAct->GetColor() ) ); 1056*cdf0e10cSrcweir } 1057*cdf0e10cSrcweir break; 1058*cdf0e10cSrcweir 1059*cdf0e10cSrcweir case( META_POINT_ACTION ): 1060*cdf0e10cSrcweir { 1061*cdf0e10cSrcweir MetaPointAction* pAct = (MetaPointAction*) pAction; 1062*cdf0e10cSrcweir aMtf.AddAction( new MetaPointAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1063*cdf0e10cSrcweir } 1064*cdf0e10cSrcweir break; 1065*cdf0e10cSrcweir 1066*cdf0e10cSrcweir case( META_LINE_ACTION ): 1067*cdf0e10cSrcweir { 1068*cdf0e10cSrcweir MetaLineAction* pAct = (MetaLineAction*) pAction; 1069*cdf0e10cSrcweir aMtf.AddAction( new MetaLineAction( ImplGetRotatedPoint( pAct->GetStartPoint(), aRotAnchor, aRotOffset, fSin, fCos ), 1070*cdf0e10cSrcweir ImplGetRotatedPoint( pAct->GetEndPoint(), aRotAnchor, aRotOffset, fSin, fCos ), 1071*cdf0e10cSrcweir pAct->GetLineInfo() ) ); 1072*cdf0e10cSrcweir } 1073*cdf0e10cSrcweir break; 1074*cdf0e10cSrcweir 1075*cdf0e10cSrcweir case( META_RECT_ACTION ): 1076*cdf0e10cSrcweir { 1077*cdf0e10cSrcweir MetaRectAction* pAct = (MetaRectAction*) pAction; 1078*cdf0e10cSrcweir aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1079*cdf0e10cSrcweir } 1080*cdf0e10cSrcweir break; 1081*cdf0e10cSrcweir 1082*cdf0e10cSrcweir case( META_ROUNDRECT_ACTION ): 1083*cdf0e10cSrcweir { 1084*cdf0e10cSrcweir MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction; 1085*cdf0e10cSrcweir const Polygon aRoundRectPoly( pAct->GetRect(), pAct->GetHorzRound(), pAct->GetVertRound() ); 1086*cdf0e10cSrcweir 1087*cdf0e10cSrcweir aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aRoundRectPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1088*cdf0e10cSrcweir } 1089*cdf0e10cSrcweir break; 1090*cdf0e10cSrcweir 1091*cdf0e10cSrcweir case( META_ELLIPSE_ACTION ): 1092*cdf0e10cSrcweir { 1093*cdf0e10cSrcweir MetaEllipseAction* pAct = (MetaEllipseAction*) pAction; 1094*cdf0e10cSrcweir const Polygon aEllipsePoly( pAct->GetRect().Center(), pAct->GetRect().GetWidth() >> 1, pAct->GetRect().GetHeight() >> 1 ); 1095*cdf0e10cSrcweir 1096*cdf0e10cSrcweir aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aEllipsePoly, aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1097*cdf0e10cSrcweir } 1098*cdf0e10cSrcweir break; 1099*cdf0e10cSrcweir 1100*cdf0e10cSrcweir case( META_ARC_ACTION ): 1101*cdf0e10cSrcweir { 1102*cdf0e10cSrcweir MetaArcAction* pAct = (MetaArcAction*) pAction; 1103*cdf0e10cSrcweir const Polygon aArcPoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), POLY_ARC ); 1104*cdf0e10cSrcweir 1105*cdf0e10cSrcweir aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aArcPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1106*cdf0e10cSrcweir } 1107*cdf0e10cSrcweir break; 1108*cdf0e10cSrcweir 1109*cdf0e10cSrcweir case( META_PIE_ACTION ): 1110*cdf0e10cSrcweir { 1111*cdf0e10cSrcweir MetaPieAction* pAct = (MetaPieAction*) pAction; 1112*cdf0e10cSrcweir const Polygon aPiePoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), POLY_PIE ); 1113*cdf0e10cSrcweir 1114*cdf0e10cSrcweir aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aPiePoly, aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1115*cdf0e10cSrcweir } 1116*cdf0e10cSrcweir break; 1117*cdf0e10cSrcweir 1118*cdf0e10cSrcweir case( META_CHORD_ACTION ): 1119*cdf0e10cSrcweir { 1120*cdf0e10cSrcweir MetaChordAction* pAct = (MetaChordAction*) pAction; 1121*cdf0e10cSrcweir const Polygon aChordPoly( pAct->GetRect(), pAct->GetStartPoint(), pAct->GetEndPoint(), POLY_CHORD ); 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aChordPoly, aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1124*cdf0e10cSrcweir } 1125*cdf0e10cSrcweir break; 1126*cdf0e10cSrcweir 1127*cdf0e10cSrcweir case( META_POLYLINE_ACTION ): 1128*cdf0e10cSrcweir { 1129*cdf0e10cSrcweir MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction; 1130*cdf0e10cSrcweir aMtf.AddAction( new MetaPolyLineAction( ImplGetRotatedPolygon( pAct->GetPolygon(), aRotAnchor, aRotOffset, fSin, fCos ), pAct->GetLineInfo() ) ); 1131*cdf0e10cSrcweir } 1132*cdf0e10cSrcweir break; 1133*cdf0e10cSrcweir 1134*cdf0e10cSrcweir case( META_POLYGON_ACTION ): 1135*cdf0e10cSrcweir { 1136*cdf0e10cSrcweir MetaPolygonAction* pAct = (MetaPolygonAction*) pAction; 1137*cdf0e10cSrcweir aMtf.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct->GetPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1138*cdf0e10cSrcweir } 1139*cdf0e10cSrcweir break; 1140*cdf0e10cSrcweir 1141*cdf0e10cSrcweir case( META_POLYPOLYGON_ACTION ): 1142*cdf0e10cSrcweir { 1143*cdf0e10cSrcweir MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction; 1144*cdf0e10cSrcweir aMtf.AddAction( new MetaPolyPolygonAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1145*cdf0e10cSrcweir } 1146*cdf0e10cSrcweir break; 1147*cdf0e10cSrcweir 1148*cdf0e10cSrcweir case( META_TEXT_ACTION ): 1149*cdf0e10cSrcweir { 1150*cdf0e10cSrcweir MetaTextAction* pAct = (MetaTextAction*) pAction; 1151*cdf0e10cSrcweir aMtf.AddAction( new MetaTextAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ), 1152*cdf0e10cSrcweir pAct->GetText(), pAct->GetIndex(), pAct->GetLen() ) ); 1153*cdf0e10cSrcweir } 1154*cdf0e10cSrcweir break; 1155*cdf0e10cSrcweir 1156*cdf0e10cSrcweir case( META_TEXTARRAY_ACTION ): 1157*cdf0e10cSrcweir { 1158*cdf0e10cSrcweir MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction; 1159*cdf0e10cSrcweir aMtf.AddAction( new MetaTextArrayAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ), 1160*cdf0e10cSrcweir pAct->GetText(), pAct->GetDXArray(), pAct->GetIndex(), pAct->GetLen() ) ); 1161*cdf0e10cSrcweir } 1162*cdf0e10cSrcweir break; 1163*cdf0e10cSrcweir 1164*cdf0e10cSrcweir case( META_STRETCHTEXT_ACTION ): 1165*cdf0e10cSrcweir { 1166*cdf0e10cSrcweir MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction; 1167*cdf0e10cSrcweir aMtf.AddAction( new MetaStretchTextAction( ImplGetRotatedPoint( pAct->GetPoint(), aRotAnchor, aRotOffset, fSin, fCos ), 1168*cdf0e10cSrcweir pAct->GetWidth(), pAct->GetText(), pAct->GetIndex(), pAct->GetLen() ) ); 1169*cdf0e10cSrcweir } 1170*cdf0e10cSrcweir break; 1171*cdf0e10cSrcweir 1172*cdf0e10cSrcweir case( META_TEXTLINE_ACTION ): 1173*cdf0e10cSrcweir { 1174*cdf0e10cSrcweir MetaTextLineAction* pAct = (MetaTextLineAction*) pAction; 1175*cdf0e10cSrcweir aMtf.AddAction( new MetaTextLineAction( ImplGetRotatedPoint( pAct->GetStartPoint(), aRotAnchor, aRotOffset, fSin, fCos ), 1176*cdf0e10cSrcweir pAct->GetWidth(), pAct->GetStrikeout(), pAct->GetUnderline(), pAct->GetOverline() ) ); 1177*cdf0e10cSrcweir } 1178*cdf0e10cSrcweir break; 1179*cdf0e10cSrcweir 1180*cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): 1181*cdf0e10cSrcweir { 1182*cdf0e10cSrcweir MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; 1183*cdf0e10cSrcweir Polygon aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) ); 1184*cdf0e10cSrcweir Rectangle aBmpRect( aBmpPoly.GetBoundRect() ); 1185*cdf0e10cSrcweir BitmapEx aBmpEx( pAct->GetBitmap() ); 1186*cdf0e10cSrcweir 1187*cdf0e10cSrcweir aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) ); 1188*cdf0e10cSrcweir aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), 1189*cdf0e10cSrcweir aBmpEx ) ); 1190*cdf0e10cSrcweir } 1191*cdf0e10cSrcweir break; 1192*cdf0e10cSrcweir 1193*cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): 1194*cdf0e10cSrcweir { 1195*cdf0e10cSrcweir MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; 1196*cdf0e10cSrcweir Polygon aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetDestPoint(), pAct->GetDestSize() ), aRotAnchor, aRotOffset, fSin, fCos ) ); 1197*cdf0e10cSrcweir Rectangle aBmpRect( aBmpPoly.GetBoundRect() ); 1198*cdf0e10cSrcweir BitmapEx aBmpEx( pAct->GetBitmap() ); 1199*cdf0e10cSrcweir 1200*cdf0e10cSrcweir aBmpEx.Crop( Rectangle( pAct->GetSrcPoint(), pAct->GetSrcSize() ) ); 1201*cdf0e10cSrcweir aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) ); 1202*cdf0e10cSrcweir 1203*cdf0e10cSrcweir aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) ); 1204*cdf0e10cSrcweir } 1205*cdf0e10cSrcweir break; 1206*cdf0e10cSrcweir 1207*cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): 1208*cdf0e10cSrcweir { 1209*cdf0e10cSrcweir MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; 1210*cdf0e10cSrcweir Polygon aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) ); 1211*cdf0e10cSrcweir Rectangle aBmpRect( aBmpPoly.GetBoundRect() ); 1212*cdf0e10cSrcweir BitmapEx aBmpEx( pAct->GetBitmapEx() ); 1213*cdf0e10cSrcweir 1214*cdf0e10cSrcweir aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) ); 1215*cdf0e10cSrcweir 1216*cdf0e10cSrcweir aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) ); 1217*cdf0e10cSrcweir } 1218*cdf0e10cSrcweir break; 1219*cdf0e10cSrcweir 1220*cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): 1221*cdf0e10cSrcweir { 1222*cdf0e10cSrcweir MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; 1223*cdf0e10cSrcweir Polygon aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetDestPoint(), pAct->GetDestSize() ), aRotAnchor, aRotOffset, fSin, fCos ) ); 1224*cdf0e10cSrcweir Rectangle aBmpRect( aBmpPoly.GetBoundRect() ); 1225*cdf0e10cSrcweir BitmapEx aBmpEx( pAct->GetBitmapEx() ); 1226*cdf0e10cSrcweir 1227*cdf0e10cSrcweir aBmpEx.Crop( Rectangle( pAct->GetSrcPoint(), pAct->GetSrcSize() ) ); 1228*cdf0e10cSrcweir aBmpEx.Rotate( nAngle10, Color( COL_TRANSPARENT ) ); 1229*cdf0e10cSrcweir 1230*cdf0e10cSrcweir aMtf.AddAction( new MetaBmpExScaleAction( aBmpRect.TopLeft(), aBmpRect.GetSize(), aBmpEx ) ); 1231*cdf0e10cSrcweir } 1232*cdf0e10cSrcweir break; 1233*cdf0e10cSrcweir 1234*cdf0e10cSrcweir case( META_GRADIENT_ACTION ): 1235*cdf0e10cSrcweir { 1236*cdf0e10cSrcweir MetaGradientAction* pAct = (MetaGradientAction*) pAction; 1237*cdf0e10cSrcweir 1238*cdf0e10cSrcweir ImplAddGradientEx( aMtf, aMapVDev, 1239*cdf0e10cSrcweir ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ), 1240*cdf0e10cSrcweir pAct->GetGradient() ); 1241*cdf0e10cSrcweir } 1242*cdf0e10cSrcweir break; 1243*cdf0e10cSrcweir 1244*cdf0e10cSrcweir case( META_GRADIENTEX_ACTION ): 1245*cdf0e10cSrcweir { 1246*cdf0e10cSrcweir MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; 1247*cdf0e10cSrcweir aMtf.AddAction( new MetaGradientExAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ), 1248*cdf0e10cSrcweir pAct->GetGradient() ) ); 1249*cdf0e10cSrcweir } 1250*cdf0e10cSrcweir break; 1251*cdf0e10cSrcweir 1252*cdf0e10cSrcweir // #105055# Handle gradientex comment block correctly 1253*cdf0e10cSrcweir case( META_COMMENT_ACTION ): 1254*cdf0e10cSrcweir { 1255*cdf0e10cSrcweir MetaCommentAction* pCommentAct = (MetaCommentAction*) pAction; 1256*cdf0e10cSrcweir if( pCommentAct->GetComment().Equals( "XGRAD_SEQ_BEGIN" ) ) 1257*cdf0e10cSrcweir { 1258*cdf0e10cSrcweir int nBeginComments( 1 ); 1259*cdf0e10cSrcweir pAction = (MetaAction*) Next(); 1260*cdf0e10cSrcweir 1261*cdf0e10cSrcweir // skip everything, except gradientex action 1262*cdf0e10cSrcweir while( pAction ) 1263*cdf0e10cSrcweir { 1264*cdf0e10cSrcweir const sal_uInt16 nType = pAction->GetType(); 1265*cdf0e10cSrcweir 1266*cdf0e10cSrcweir if( META_GRADIENTEX_ACTION == nType ) 1267*cdf0e10cSrcweir { 1268*cdf0e10cSrcweir // Add rotated gradientex 1269*cdf0e10cSrcweir MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; 1270*cdf0e10cSrcweir ImplAddGradientEx( aMtf, aMapVDev, 1271*cdf0e10cSrcweir ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ), 1272*cdf0e10cSrcweir pAct->GetGradient() ); 1273*cdf0e10cSrcweir } 1274*cdf0e10cSrcweir else if( META_COMMENT_ACTION == nType) 1275*cdf0e10cSrcweir { 1276*cdf0e10cSrcweir MetaCommentAction* pAct = (MetaCommentAction*) pAction; 1277*cdf0e10cSrcweir if( pAct->GetComment().Equals( "XGRAD_SEQ_END" ) ) 1278*cdf0e10cSrcweir { 1279*cdf0e10cSrcweir // handle nested blocks 1280*cdf0e10cSrcweir --nBeginComments; 1281*cdf0e10cSrcweir 1282*cdf0e10cSrcweir // gradientex comment block: end reached, done. 1283*cdf0e10cSrcweir if( !nBeginComments ) 1284*cdf0e10cSrcweir break; 1285*cdf0e10cSrcweir } 1286*cdf0e10cSrcweir else if( pAct->GetComment().Equals( "XGRAD_SEQ_BEGIN" ) ) 1287*cdf0e10cSrcweir { 1288*cdf0e10cSrcweir // handle nested blocks 1289*cdf0e10cSrcweir ++nBeginComments; 1290*cdf0e10cSrcweir } 1291*cdf0e10cSrcweir 1292*cdf0e10cSrcweir } 1293*cdf0e10cSrcweir 1294*cdf0e10cSrcweir pAction = (MetaAction*) Next(); 1295*cdf0e10cSrcweir } 1296*cdf0e10cSrcweir } 1297*cdf0e10cSrcweir else 1298*cdf0e10cSrcweir { 1299*cdf0e10cSrcweir sal_Bool bPathStroke = pCommentAct->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" ); 1300*cdf0e10cSrcweir if ( bPathStroke || pCommentAct->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) ) 1301*cdf0e10cSrcweir { 1302*cdf0e10cSrcweir if ( pCommentAct->GetDataSize() ) 1303*cdf0e10cSrcweir { 1304*cdf0e10cSrcweir SvMemoryStream aMemStm( (void*)pCommentAct->GetData(), pCommentAct->GetDataSize(), STREAM_READ ); 1305*cdf0e10cSrcweir SvMemoryStream aDest; 1306*cdf0e10cSrcweir if ( bPathStroke ) 1307*cdf0e10cSrcweir { 1308*cdf0e10cSrcweir SvtGraphicStroke aStroke; 1309*cdf0e10cSrcweir aMemStm >> aStroke; 1310*cdf0e10cSrcweir Polygon aPath; 1311*cdf0e10cSrcweir aStroke.getPath( aPath ); 1312*cdf0e10cSrcweir aStroke.setPath( ImplGetRotatedPolygon( aPath, aRotAnchor, aRotOffset, fSin, fCos ) ); 1313*cdf0e10cSrcweir aDest << aStroke; 1314*cdf0e10cSrcweir aMtf.AddAction( new MetaCommentAction( "XPATHSTROKE_SEQ_BEGIN", 0, 1315*cdf0e10cSrcweir static_cast<const sal_uInt8*>( aDest.GetData()), aDest.Tell() ) ); 1316*cdf0e10cSrcweir } 1317*cdf0e10cSrcweir else 1318*cdf0e10cSrcweir { 1319*cdf0e10cSrcweir SvtGraphicFill aFill; 1320*cdf0e10cSrcweir aMemStm >> aFill; 1321*cdf0e10cSrcweir PolyPolygon aPath; 1322*cdf0e10cSrcweir aFill.getPath( aPath ); 1323*cdf0e10cSrcweir aFill.setPath( ImplGetRotatedPolyPolygon( aPath, aRotAnchor, aRotOffset, fSin, fCos ) ); 1324*cdf0e10cSrcweir aDest << aFill; 1325*cdf0e10cSrcweir aMtf.AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0, 1326*cdf0e10cSrcweir static_cast<const sal_uInt8*>( aDest.GetData()), aDest.Tell() ) ); 1327*cdf0e10cSrcweir } 1328*cdf0e10cSrcweir } 1329*cdf0e10cSrcweir } 1330*cdf0e10cSrcweir else if ( pCommentAct->GetComment().Equals( "XPATHSTROKE_SEQ_END" ) 1331*cdf0e10cSrcweir || pCommentAct->GetComment().Equals( "XPATHFILL_SEQ_END" ) ) 1332*cdf0e10cSrcweir { 1333*cdf0e10cSrcweir pAction->Execute( &aMapVDev ); 1334*cdf0e10cSrcweir pAction->Duplicate(); 1335*cdf0e10cSrcweir aMtf.AddAction( pAction ); 1336*cdf0e10cSrcweir } 1337*cdf0e10cSrcweir } 1338*cdf0e10cSrcweir } 1339*cdf0e10cSrcweir break; 1340*cdf0e10cSrcweir 1341*cdf0e10cSrcweir case( META_HATCH_ACTION ): 1342*cdf0e10cSrcweir { 1343*cdf0e10cSrcweir MetaHatchAction* pAct = (MetaHatchAction*) pAction; 1344*cdf0e10cSrcweir Hatch aHatch( pAct->GetHatch() ); 1345*cdf0e10cSrcweir 1346*cdf0e10cSrcweir aHatch.SetAngle( aHatch.GetAngle() + (sal_uInt16) nAngle10 ); 1347*cdf0e10cSrcweir aMtf.AddAction( new MetaHatchAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ), 1348*cdf0e10cSrcweir aHatch ) ); 1349*cdf0e10cSrcweir } 1350*cdf0e10cSrcweir break; 1351*cdf0e10cSrcweir 1352*cdf0e10cSrcweir case( META_TRANSPARENT_ACTION ): 1353*cdf0e10cSrcweir { 1354*cdf0e10cSrcweir MetaTransparentAction* pAct = (MetaTransparentAction*) pAction; 1355*cdf0e10cSrcweir aMtf.AddAction( new MetaTransparentAction( ImplGetRotatedPolyPolygon( pAct->GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ), 1356*cdf0e10cSrcweir pAct->GetTransparence() ) ); 1357*cdf0e10cSrcweir } 1358*cdf0e10cSrcweir break; 1359*cdf0e10cSrcweir 1360*cdf0e10cSrcweir case( META_FLOATTRANSPARENT_ACTION ): 1361*cdf0e10cSrcweir { 1362*cdf0e10cSrcweir MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction; 1363*cdf0e10cSrcweir GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() ); 1364*cdf0e10cSrcweir Polygon aMtfPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) ); 1365*cdf0e10cSrcweir Rectangle aMtfRect( aMtfPoly.GetBoundRect() ); 1366*cdf0e10cSrcweir 1367*cdf0e10cSrcweir aTransMtf.Rotate( nAngle10 ); 1368*cdf0e10cSrcweir aMtf.AddAction( new MetaFloatTransparentAction( aTransMtf, aMtfRect.TopLeft(), aMtfRect.GetSize(), 1369*cdf0e10cSrcweir pAct->GetGradient() ) ); 1370*cdf0e10cSrcweir } 1371*cdf0e10cSrcweir break; 1372*cdf0e10cSrcweir 1373*cdf0e10cSrcweir case( META_EPS_ACTION ): 1374*cdf0e10cSrcweir { 1375*cdf0e10cSrcweir MetaEPSAction* pAct = (MetaEPSAction*) pAction; 1376*cdf0e10cSrcweir GDIMetaFile aEPSMtf( pAct->GetSubstitute() ); 1377*cdf0e10cSrcweir Polygon aEPSPoly( ImplGetRotatedPolygon( Rectangle( pAct->GetPoint(), pAct->GetSize() ), aRotAnchor, aRotOffset, fSin, fCos ) ); 1378*cdf0e10cSrcweir Rectangle aEPSRect( aEPSPoly.GetBoundRect() ); 1379*cdf0e10cSrcweir 1380*cdf0e10cSrcweir aEPSMtf.Rotate( nAngle10 ); 1381*cdf0e10cSrcweir aMtf.AddAction( new MetaEPSAction( aEPSRect.TopLeft(), aEPSRect.GetSize(), 1382*cdf0e10cSrcweir pAct->GetLink(), aEPSMtf ) ); 1383*cdf0e10cSrcweir } 1384*cdf0e10cSrcweir break; 1385*cdf0e10cSrcweir 1386*cdf0e10cSrcweir case( META_CLIPREGION_ACTION ): 1387*cdf0e10cSrcweir { 1388*cdf0e10cSrcweir MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction; 1389*cdf0e10cSrcweir 1390*cdf0e10cSrcweir if( pAct->IsClipping() && pAct->GetRegion().HasPolyPolygon() ) 1391*cdf0e10cSrcweir aMtf.AddAction( new MetaClipRegionAction( Region( ImplGetRotatedPolyPolygon( pAct->GetRegion().GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ), sal_True ) ); 1392*cdf0e10cSrcweir else 1393*cdf0e10cSrcweir { 1394*cdf0e10cSrcweir pAction->Duplicate(); 1395*cdf0e10cSrcweir aMtf.AddAction( pAction ); 1396*cdf0e10cSrcweir } 1397*cdf0e10cSrcweir } 1398*cdf0e10cSrcweir break; 1399*cdf0e10cSrcweir 1400*cdf0e10cSrcweir case( META_ISECTRECTCLIPREGION_ACTION ): 1401*cdf0e10cSrcweir { 1402*cdf0e10cSrcweir MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction; 1403*cdf0e10cSrcweir aMtf.AddAction( new MetaISectRegionClipRegionAction( ImplGetRotatedPolygon( pAct->GetRect(), aRotAnchor, aRotOffset, fSin, fCos ) ) ); 1404*cdf0e10cSrcweir } 1405*cdf0e10cSrcweir break; 1406*cdf0e10cSrcweir 1407*cdf0e10cSrcweir case( META_ISECTREGIONCLIPREGION_ACTION ): 1408*cdf0e10cSrcweir { 1409*cdf0e10cSrcweir MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction; 1410*cdf0e10cSrcweir const Region& rRegion = pAct->GetRegion(); 1411*cdf0e10cSrcweir 1412*cdf0e10cSrcweir if( rRegion.HasPolyPolygon() ) 1413*cdf0e10cSrcweir aMtf.AddAction( new MetaISectRegionClipRegionAction( Region( ImplGetRotatedPolyPolygon( rRegion.GetPolyPolygon(), aRotAnchor, aRotOffset, fSin, fCos ) ) ) ); 1414*cdf0e10cSrcweir else 1415*cdf0e10cSrcweir { 1416*cdf0e10cSrcweir pAction->Duplicate(); 1417*cdf0e10cSrcweir aMtf.AddAction( pAction ); 1418*cdf0e10cSrcweir } 1419*cdf0e10cSrcweir } 1420*cdf0e10cSrcweir break; 1421*cdf0e10cSrcweir 1422*cdf0e10cSrcweir case( META_REFPOINT_ACTION ): 1423*cdf0e10cSrcweir { 1424*cdf0e10cSrcweir MetaRefPointAction* pAct = (MetaRefPointAction*) pAction; 1425*cdf0e10cSrcweir aMtf.AddAction( new MetaRefPointAction( ImplGetRotatedPoint( pAct->GetRefPoint(), aRotAnchor, aRotOffset, fSin, fCos ), pAct->IsSetting() ) ); 1426*cdf0e10cSrcweir } 1427*cdf0e10cSrcweir break; 1428*cdf0e10cSrcweir 1429*cdf0e10cSrcweir case( META_FONT_ACTION ): 1430*cdf0e10cSrcweir { 1431*cdf0e10cSrcweir MetaFontAction* pAct = (MetaFontAction*) pAction; 1432*cdf0e10cSrcweir Font aFont( pAct->GetFont() ); 1433*cdf0e10cSrcweir 1434*cdf0e10cSrcweir aFont.SetOrientation( aFont.GetOrientation() + (sal_uInt16) nAngle10 ); 1435*cdf0e10cSrcweir aMtf.AddAction( new MetaFontAction( aFont ) ); 1436*cdf0e10cSrcweir } 1437*cdf0e10cSrcweir break; 1438*cdf0e10cSrcweir 1439*cdf0e10cSrcweir case( META_BMP_ACTION ): 1440*cdf0e10cSrcweir case( META_BMPEX_ACTION ): 1441*cdf0e10cSrcweir case( META_MASK_ACTION ): 1442*cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): 1443*cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): 1444*cdf0e10cSrcweir case( META_WALLPAPER_ACTION ): 1445*cdf0e10cSrcweir case( META_TEXTRECT_ACTION ): 1446*cdf0e10cSrcweir case( META_MOVECLIPREGION_ACTION ): 1447*cdf0e10cSrcweir { 1448*cdf0e10cSrcweir DBG_ERROR( "GDIMetaFile::Rotate(): unsupported action" ); 1449*cdf0e10cSrcweir } 1450*cdf0e10cSrcweir break; 1451*cdf0e10cSrcweir 1452*cdf0e10cSrcweir case( META_RENDERGRAPHIC_ACTION ): 1453*cdf0e10cSrcweir { 1454*cdf0e10cSrcweir OSL_TRACE( "Rotate not supported for RenderGraphic MetaActions yet" ); 1455*cdf0e10cSrcweir 1456*cdf0e10cSrcweir pAction->Duplicate(); 1457*cdf0e10cSrcweir aMtf.AddAction( pAction ); 1458*cdf0e10cSrcweir } 1459*cdf0e10cSrcweir break; 1460*cdf0e10cSrcweir 1461*cdf0e10cSrcweir default: 1462*cdf0e10cSrcweir { 1463*cdf0e10cSrcweir pAction->Execute( &aMapVDev ); 1464*cdf0e10cSrcweir pAction->Duplicate(); 1465*cdf0e10cSrcweir aMtf.AddAction( pAction ); 1466*cdf0e10cSrcweir 1467*cdf0e10cSrcweir // update rotation point and offset, if necessary 1468*cdf0e10cSrcweir if( ( META_MAPMODE_ACTION == nActionType ) || 1469*cdf0e10cSrcweir ( META_PUSH_ACTION == nActionType ) || 1470*cdf0e10cSrcweir ( META_POP_ACTION == nActionType ) ) 1471*cdf0e10cSrcweir { 1472*cdf0e10cSrcweir aRotAnchor = aMapVDev.LogicToLogic( aOrigin, aPrefMapMode, aMapVDev.GetMapMode() ); 1473*cdf0e10cSrcweir aRotOffset = aMapVDev.LogicToLogic( aOffset, aPrefMapMode, aMapVDev.GetMapMode() ); 1474*cdf0e10cSrcweir } 1475*cdf0e10cSrcweir } 1476*cdf0e10cSrcweir break; 1477*cdf0e10cSrcweir } 1478*cdf0e10cSrcweir } 1479*cdf0e10cSrcweir 1480*cdf0e10cSrcweir aMtf.aPrefMapMode = aPrefMapMode; 1481*cdf0e10cSrcweir aMtf.aPrefSize = aNewBound.GetSize(); 1482*cdf0e10cSrcweir 1483*cdf0e10cSrcweir *this = aMtf; 1484*cdf0e10cSrcweir } 1485*cdf0e10cSrcweir } 1486*cdf0e10cSrcweir 1487*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1488*cdf0e10cSrcweir 1489*cdf0e10cSrcweir static void ImplActionBounds( Rectangle& o_rOutBounds, 1490*cdf0e10cSrcweir const Rectangle& i_rInBounds, 1491*cdf0e10cSrcweir const std::vector<Rectangle>& i_rClipStack ) 1492*cdf0e10cSrcweir { 1493*cdf0e10cSrcweir Rectangle aBounds( i_rInBounds ); 1494*cdf0e10cSrcweir if( ! i_rInBounds.IsEmpty() && ! i_rClipStack.empty() && ! i_rClipStack.back().IsEmpty() ) 1495*cdf0e10cSrcweir aBounds.Intersection( i_rClipStack.back() ); 1496*cdf0e10cSrcweir if( ! aBounds.IsEmpty() ) 1497*cdf0e10cSrcweir { 1498*cdf0e10cSrcweir if( ! o_rOutBounds.IsEmpty() ) 1499*cdf0e10cSrcweir o_rOutBounds.Union( aBounds ); 1500*cdf0e10cSrcweir else 1501*cdf0e10cSrcweir o_rOutBounds = aBounds; 1502*cdf0e10cSrcweir } 1503*cdf0e10cSrcweir } 1504*cdf0e10cSrcweir 1505*cdf0e10cSrcweir Rectangle GDIMetaFile::GetBoundRect( OutputDevice& i_rReference ) 1506*cdf0e10cSrcweir { 1507*cdf0e10cSrcweir GDIMetaFile aMtf; 1508*cdf0e10cSrcweir VirtualDevice aMapVDev( i_rReference ); 1509*cdf0e10cSrcweir 1510*cdf0e10cSrcweir aMapVDev.EnableOutput( sal_False ); 1511*cdf0e10cSrcweir aMapVDev.SetMapMode( GetPrefMapMode() ); 1512*cdf0e10cSrcweir 1513*cdf0e10cSrcweir std::vector<Rectangle> aClipStack( 1, Rectangle() ); 1514*cdf0e10cSrcweir std::vector<sal_uInt16> aPushFlagStack; 1515*cdf0e10cSrcweir 1516*cdf0e10cSrcweir Rectangle aBound; 1517*cdf0e10cSrcweir 1518*cdf0e10cSrcweir for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() ) 1519*cdf0e10cSrcweir { 1520*cdf0e10cSrcweir const sal_uInt16 nActionType = pAction->GetType(); 1521*cdf0e10cSrcweir 1522*cdf0e10cSrcweir switch( nActionType ) 1523*cdf0e10cSrcweir { 1524*cdf0e10cSrcweir case( META_PIXEL_ACTION ): 1525*cdf0e10cSrcweir { 1526*cdf0e10cSrcweir MetaPixelAction* pAct = (MetaPixelAction*) pAction; 1527*cdf0e10cSrcweir ImplActionBounds( aBound, 1528*cdf0e10cSrcweir Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), 1529*cdf0e10cSrcweir aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), 1530*cdf0e10cSrcweir aClipStack ); 1531*cdf0e10cSrcweir } 1532*cdf0e10cSrcweir break; 1533*cdf0e10cSrcweir 1534*cdf0e10cSrcweir case( META_POINT_ACTION ): 1535*cdf0e10cSrcweir { 1536*cdf0e10cSrcweir MetaPointAction* pAct = (MetaPointAction*) pAction; 1537*cdf0e10cSrcweir ImplActionBounds( aBound, 1538*cdf0e10cSrcweir Rectangle( aMapVDev.LogicToLogic( pAct->GetPoint(), aMapVDev.GetMapMode(), GetPrefMapMode() ), 1539*cdf0e10cSrcweir aMapVDev.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ), 1540*cdf0e10cSrcweir aClipStack ); 1541*cdf0e10cSrcweir } 1542*cdf0e10cSrcweir break; 1543*cdf0e10cSrcweir 1544*cdf0e10cSrcweir case( META_LINE_ACTION ): 1545*cdf0e10cSrcweir { 1546*cdf0e10cSrcweir MetaLineAction* pAct = (MetaLineAction*) pAction; 1547*cdf0e10cSrcweir Point aP1( pAct->GetStartPoint() ), aP2( pAct->GetEndPoint() ); 1548*cdf0e10cSrcweir Rectangle aRect( aP1, aP2 ); 1549*cdf0e10cSrcweir aRect.Justify(); 1550*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1551*cdf0e10cSrcweir } 1552*cdf0e10cSrcweir break; 1553*cdf0e10cSrcweir 1554*cdf0e10cSrcweir case( META_RECT_ACTION ): 1555*cdf0e10cSrcweir { 1556*cdf0e10cSrcweir MetaRectAction* pAct = (MetaRectAction*) pAction; 1557*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1558*cdf0e10cSrcweir } 1559*cdf0e10cSrcweir break; 1560*cdf0e10cSrcweir 1561*cdf0e10cSrcweir case( META_ROUNDRECT_ACTION ): 1562*cdf0e10cSrcweir { 1563*cdf0e10cSrcweir MetaRoundRectAction* pAct = (MetaRoundRectAction*) pAction; 1564*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1565*cdf0e10cSrcweir } 1566*cdf0e10cSrcweir break; 1567*cdf0e10cSrcweir 1568*cdf0e10cSrcweir case( META_ELLIPSE_ACTION ): 1569*cdf0e10cSrcweir { 1570*cdf0e10cSrcweir MetaEllipseAction* pAct = (MetaEllipseAction*) pAction; 1571*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1572*cdf0e10cSrcweir } 1573*cdf0e10cSrcweir break; 1574*cdf0e10cSrcweir 1575*cdf0e10cSrcweir case( META_ARC_ACTION ): 1576*cdf0e10cSrcweir { 1577*cdf0e10cSrcweir MetaArcAction* pAct = (MetaArcAction*) pAction; 1578*cdf0e10cSrcweir // FIXME: this is imprecise 1579*cdf0e10cSrcweir // e.g. for small arcs the whole rectangle is WAY too large 1580*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1581*cdf0e10cSrcweir } 1582*cdf0e10cSrcweir break; 1583*cdf0e10cSrcweir 1584*cdf0e10cSrcweir case( META_PIE_ACTION ): 1585*cdf0e10cSrcweir { 1586*cdf0e10cSrcweir MetaPieAction* pAct = (MetaPieAction*) pAction; 1587*cdf0e10cSrcweir // FIXME: this is imprecise 1588*cdf0e10cSrcweir // e.g. for small arcs the whole rectangle is WAY too large 1589*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1590*cdf0e10cSrcweir } 1591*cdf0e10cSrcweir break; 1592*cdf0e10cSrcweir 1593*cdf0e10cSrcweir case( META_CHORD_ACTION ): 1594*cdf0e10cSrcweir { 1595*cdf0e10cSrcweir MetaChordAction* pAct = (MetaChordAction*) pAction; 1596*cdf0e10cSrcweir // FIXME: this is imprecise 1597*cdf0e10cSrcweir // e.g. for small arcs the whole rectangle is WAY too large 1598*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1599*cdf0e10cSrcweir } 1600*cdf0e10cSrcweir break; 1601*cdf0e10cSrcweir 1602*cdf0e10cSrcweir case( META_POLYLINE_ACTION ): 1603*cdf0e10cSrcweir { 1604*cdf0e10cSrcweir MetaPolyLineAction* pAct = (MetaPolyLineAction*) pAction; 1605*cdf0e10cSrcweir Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); 1606*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1607*cdf0e10cSrcweir } 1608*cdf0e10cSrcweir break; 1609*cdf0e10cSrcweir 1610*cdf0e10cSrcweir case( META_POLYGON_ACTION ): 1611*cdf0e10cSrcweir { 1612*cdf0e10cSrcweir MetaPolygonAction* pAct = (MetaPolygonAction*) pAction; 1613*cdf0e10cSrcweir Rectangle aRect( pAct->GetPolygon().GetBoundRect() ); 1614*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1615*cdf0e10cSrcweir } 1616*cdf0e10cSrcweir break; 1617*cdf0e10cSrcweir 1618*cdf0e10cSrcweir case( META_POLYPOLYGON_ACTION ): 1619*cdf0e10cSrcweir { 1620*cdf0e10cSrcweir MetaPolyPolygonAction* pAct = (MetaPolyPolygonAction*) pAction; 1621*cdf0e10cSrcweir Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); 1622*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1623*cdf0e10cSrcweir } 1624*cdf0e10cSrcweir break; 1625*cdf0e10cSrcweir 1626*cdf0e10cSrcweir case( META_TEXT_ACTION ): 1627*cdf0e10cSrcweir { 1628*cdf0e10cSrcweir MetaTextAction* pAct = (MetaTextAction*) pAction; 1629*cdf0e10cSrcweir Rectangle aRect; 1630*cdf0e10cSrcweir // hdu said base = index 1631*cdf0e10cSrcweir aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen() ); 1632*cdf0e10cSrcweir Point aPt( pAct->GetPoint() ); 1633*cdf0e10cSrcweir aRect.Move( aPt.X(), aPt.Y() ); 1634*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1635*cdf0e10cSrcweir } 1636*cdf0e10cSrcweir break; 1637*cdf0e10cSrcweir 1638*cdf0e10cSrcweir case( META_TEXTARRAY_ACTION ): 1639*cdf0e10cSrcweir { 1640*cdf0e10cSrcweir MetaTextArrayAction* pAct = (MetaTextArrayAction*) pAction; 1641*cdf0e10cSrcweir Rectangle aRect; 1642*cdf0e10cSrcweir // hdu said base = index 1643*cdf0e10cSrcweir aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), 1644*cdf0e10cSrcweir 0, pAct->GetDXArray() ); 1645*cdf0e10cSrcweir Point aPt( pAct->GetPoint() ); 1646*cdf0e10cSrcweir aRect.Move( aPt.X(), aPt.Y() ); 1647*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1648*cdf0e10cSrcweir } 1649*cdf0e10cSrcweir break; 1650*cdf0e10cSrcweir 1651*cdf0e10cSrcweir case( META_STRETCHTEXT_ACTION ): 1652*cdf0e10cSrcweir { 1653*cdf0e10cSrcweir MetaStretchTextAction* pAct = (MetaStretchTextAction*) pAction; 1654*cdf0e10cSrcweir Rectangle aRect; 1655*cdf0e10cSrcweir // hdu said base = index 1656*cdf0e10cSrcweir aMapVDev.GetTextBoundRect( aRect, pAct->GetText(), pAct->GetIndex(), pAct->GetIndex(), pAct->GetLen(), 1657*cdf0e10cSrcweir pAct->GetWidth(), NULL ); 1658*cdf0e10cSrcweir Point aPt( pAct->GetPoint() ); 1659*cdf0e10cSrcweir aRect.Move( aPt.X(), aPt.Y() ); 1660*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1661*cdf0e10cSrcweir } 1662*cdf0e10cSrcweir break; 1663*cdf0e10cSrcweir 1664*cdf0e10cSrcweir case( META_TEXTLINE_ACTION ): 1665*cdf0e10cSrcweir { 1666*cdf0e10cSrcweir MetaTextLineAction* pAct = (MetaTextLineAction*) pAction; 1667*cdf0e10cSrcweir // measure a test string to get ascend and descent right 1668*cdf0e10cSrcweir static const sal_Unicode pStr[] = { 0xc4, 0x67, 0 }; 1669*cdf0e10cSrcweir String aStr( pStr ); 1670*cdf0e10cSrcweir 1671*cdf0e10cSrcweir Rectangle aRect; 1672*cdf0e10cSrcweir aMapVDev.GetTextBoundRect( aRect, aStr, 0, 0, aStr.Len(), 0, NULL ); 1673*cdf0e10cSrcweir Point aPt( pAct->GetStartPoint() ); 1674*cdf0e10cSrcweir aRect.Move( aPt.X(), aPt.Y() ); 1675*cdf0e10cSrcweir aRect.Right() = aRect.Left() + pAct->GetWidth(); 1676*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1677*cdf0e10cSrcweir } 1678*cdf0e10cSrcweir break; 1679*cdf0e10cSrcweir 1680*cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): 1681*cdf0e10cSrcweir { 1682*cdf0e10cSrcweir MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; 1683*cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); 1684*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1685*cdf0e10cSrcweir } 1686*cdf0e10cSrcweir break; 1687*cdf0e10cSrcweir 1688*cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): 1689*cdf0e10cSrcweir { 1690*cdf0e10cSrcweir MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; 1691*cdf0e10cSrcweir Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); 1692*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1693*cdf0e10cSrcweir } 1694*cdf0e10cSrcweir break; 1695*cdf0e10cSrcweir 1696*cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): 1697*cdf0e10cSrcweir { 1698*cdf0e10cSrcweir MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; 1699*cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); 1700*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1701*cdf0e10cSrcweir } 1702*cdf0e10cSrcweir break; 1703*cdf0e10cSrcweir 1704*cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): 1705*cdf0e10cSrcweir { 1706*cdf0e10cSrcweir MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; 1707*cdf0e10cSrcweir Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); 1708*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1709*cdf0e10cSrcweir } 1710*cdf0e10cSrcweir break; 1711*cdf0e10cSrcweir 1712*cdf0e10cSrcweir case( META_GRADIENT_ACTION ): 1713*cdf0e10cSrcweir { 1714*cdf0e10cSrcweir MetaGradientAction* pAct = (MetaGradientAction*) pAction; 1715*cdf0e10cSrcweir Rectangle aRect( pAct->GetRect() ); 1716*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1717*cdf0e10cSrcweir } 1718*cdf0e10cSrcweir break; 1719*cdf0e10cSrcweir 1720*cdf0e10cSrcweir case( META_GRADIENTEX_ACTION ): 1721*cdf0e10cSrcweir { 1722*cdf0e10cSrcweir MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; 1723*cdf0e10cSrcweir Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); 1724*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1725*cdf0e10cSrcweir } 1726*cdf0e10cSrcweir break; 1727*cdf0e10cSrcweir 1728*cdf0e10cSrcweir case( META_COMMENT_ACTION ): 1729*cdf0e10cSrcweir { 1730*cdf0e10cSrcweir // nothing to do 1731*cdf0e10cSrcweir }; 1732*cdf0e10cSrcweir break; 1733*cdf0e10cSrcweir 1734*cdf0e10cSrcweir case( META_HATCH_ACTION ): 1735*cdf0e10cSrcweir { 1736*cdf0e10cSrcweir MetaHatchAction* pAct = (MetaHatchAction*) pAction; 1737*cdf0e10cSrcweir Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); 1738*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1739*cdf0e10cSrcweir } 1740*cdf0e10cSrcweir break; 1741*cdf0e10cSrcweir 1742*cdf0e10cSrcweir case( META_TRANSPARENT_ACTION ): 1743*cdf0e10cSrcweir { 1744*cdf0e10cSrcweir MetaTransparentAction* pAct = (MetaTransparentAction*) pAction; 1745*cdf0e10cSrcweir Rectangle aRect( pAct->GetPolyPolygon().GetBoundRect() ); 1746*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1747*cdf0e10cSrcweir } 1748*cdf0e10cSrcweir break; 1749*cdf0e10cSrcweir 1750*cdf0e10cSrcweir case( META_FLOATTRANSPARENT_ACTION ): 1751*cdf0e10cSrcweir { 1752*cdf0e10cSrcweir MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction; 1753*cdf0e10cSrcweir GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() ); 1754*cdf0e10cSrcweir // get the bound rect of the contained metafile 1755*cdf0e10cSrcweir Rectangle aRect( aTransMtf.GetBoundRect( i_rReference ) ); 1756*cdf0e10cSrcweir // scale the rect now on the assumption that the correct top left of the metafile 1757*cdf0e10cSrcweir // (not its bounds !) is (0,0) 1758*cdf0e10cSrcweir Size aPSize( aTransMtf.GetPrefSize() ); 1759*cdf0e10cSrcweir aPSize = aMapVDev.LogicToLogic( aPSize, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); 1760*cdf0e10cSrcweir Size aActSize( pAct->GetSize() ); 1761*cdf0e10cSrcweir double fX = double(aActSize.Width())/double(aPSize.Width()); 1762*cdf0e10cSrcweir double fY = double(aActSize.Height())/double(aPSize.Height()); 1763*cdf0e10cSrcweir aRect.Left() = long(double(aRect.Left())*fX); 1764*cdf0e10cSrcweir aRect.Right() = long(double(aRect.Right())*fX); 1765*cdf0e10cSrcweir aRect.Top() = long(double(aRect.Top())*fY); 1766*cdf0e10cSrcweir aRect.Bottom() = long(double(aRect.Bottom())*fY); 1767*cdf0e10cSrcweir 1768*cdf0e10cSrcweir // transform the rect to current VDev state 1769*cdf0e10cSrcweir aRect = aMapVDev.LogicToLogic( aRect, aTransMtf.GetPrefMapMode(), aMapVDev.GetMapMode() ); 1770*cdf0e10cSrcweir 1771*cdf0e10cSrcweir ImplActionBounds( aBound, aRect, aClipStack ); 1772*cdf0e10cSrcweir } 1773*cdf0e10cSrcweir break; 1774*cdf0e10cSrcweir 1775*cdf0e10cSrcweir case( META_EPS_ACTION ): 1776*cdf0e10cSrcweir { 1777*cdf0e10cSrcweir MetaEPSAction* pAct = (MetaEPSAction*) pAction; 1778*cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); 1779*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1780*cdf0e10cSrcweir } 1781*cdf0e10cSrcweir break; 1782*cdf0e10cSrcweir 1783*cdf0e10cSrcweir case( META_CLIPREGION_ACTION ): 1784*cdf0e10cSrcweir { 1785*cdf0e10cSrcweir MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction; 1786*cdf0e10cSrcweir if( pAct->IsClipping() ) 1787*cdf0e10cSrcweir aClipStack.back() = aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ); 1788*cdf0e10cSrcweir else 1789*cdf0e10cSrcweir aClipStack.back() = Rectangle(); 1790*cdf0e10cSrcweir } 1791*cdf0e10cSrcweir break; 1792*cdf0e10cSrcweir 1793*cdf0e10cSrcweir case( META_ISECTRECTCLIPREGION_ACTION ): 1794*cdf0e10cSrcweir { 1795*cdf0e10cSrcweir MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction; 1796*cdf0e10cSrcweir Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); 1797*cdf0e10cSrcweir if( aClipStack.back().IsEmpty() ) 1798*cdf0e10cSrcweir aClipStack.back() = aRect; 1799*cdf0e10cSrcweir else 1800*cdf0e10cSrcweir aClipStack.back().Intersection( aRect ); 1801*cdf0e10cSrcweir } 1802*cdf0e10cSrcweir break; 1803*cdf0e10cSrcweir 1804*cdf0e10cSrcweir case( META_ISECTREGIONCLIPREGION_ACTION ): 1805*cdf0e10cSrcweir { 1806*cdf0e10cSrcweir MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction; 1807*cdf0e10cSrcweir Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); 1808*cdf0e10cSrcweir if( aClipStack.back().IsEmpty() ) 1809*cdf0e10cSrcweir aClipStack.back() = aRect; 1810*cdf0e10cSrcweir else 1811*cdf0e10cSrcweir aClipStack.back().Intersection( aRect ); 1812*cdf0e10cSrcweir } 1813*cdf0e10cSrcweir break; 1814*cdf0e10cSrcweir 1815*cdf0e10cSrcweir case( META_BMP_ACTION ): 1816*cdf0e10cSrcweir { 1817*cdf0e10cSrcweir MetaBmpAction* pAct = (MetaBmpAction*) pAction; 1818*cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); 1819*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1820*cdf0e10cSrcweir } 1821*cdf0e10cSrcweir break; 1822*cdf0e10cSrcweir 1823*cdf0e10cSrcweir case( META_BMPEX_ACTION ): 1824*cdf0e10cSrcweir { 1825*cdf0e10cSrcweir MetaBmpExAction* pAct = (MetaBmpExAction*) pAction; 1826*cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) ); 1827*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1828*cdf0e10cSrcweir } 1829*cdf0e10cSrcweir break; 1830*cdf0e10cSrcweir 1831*cdf0e10cSrcweir case( META_MASK_ACTION ): 1832*cdf0e10cSrcweir { 1833*cdf0e10cSrcweir MetaMaskAction* pAct = (MetaMaskAction*) pAction; 1834*cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); 1835*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1836*cdf0e10cSrcweir } 1837*cdf0e10cSrcweir break; 1838*cdf0e10cSrcweir 1839*cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): 1840*cdf0e10cSrcweir { 1841*cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 1842*cdf0e10cSrcweir Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); 1843*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1844*cdf0e10cSrcweir } 1845*cdf0e10cSrcweir break; 1846*cdf0e10cSrcweir 1847*cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): 1848*cdf0e10cSrcweir { 1849*cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 1850*cdf0e10cSrcweir Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); 1851*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1852*cdf0e10cSrcweir } 1853*cdf0e10cSrcweir break; 1854*cdf0e10cSrcweir 1855*cdf0e10cSrcweir case( META_WALLPAPER_ACTION ): 1856*cdf0e10cSrcweir { 1857*cdf0e10cSrcweir MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction; 1858*cdf0e10cSrcweir Rectangle aRect( pAct->GetRect() ); 1859*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1860*cdf0e10cSrcweir } 1861*cdf0e10cSrcweir break; 1862*cdf0e10cSrcweir 1863*cdf0e10cSrcweir case( META_TEXTRECT_ACTION ): 1864*cdf0e10cSrcweir { 1865*cdf0e10cSrcweir MetaTextRectAction* pAct = (MetaTextRectAction*) pAction; 1866*cdf0e10cSrcweir Rectangle aRect( pAct->GetRect() ); 1867*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1868*cdf0e10cSrcweir } 1869*cdf0e10cSrcweir break; 1870*cdf0e10cSrcweir 1871*cdf0e10cSrcweir case( META_MOVECLIPREGION_ACTION ): 1872*cdf0e10cSrcweir { 1873*cdf0e10cSrcweir MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction; 1874*cdf0e10cSrcweir if( ! aClipStack.back().IsEmpty() ) 1875*cdf0e10cSrcweir { 1876*cdf0e10cSrcweir Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() ); 1877*cdf0e10cSrcweir aDelta = aMapVDev.LogicToLogic( aDelta, aMapVDev.GetMapMode(), GetPrefMapMode() ); 1878*cdf0e10cSrcweir aClipStack.back().Move( aDelta.Width(), aDelta.Width() ); 1879*cdf0e10cSrcweir } 1880*cdf0e10cSrcweir } 1881*cdf0e10cSrcweir break; 1882*cdf0e10cSrcweir 1883*cdf0e10cSrcweir case( META_RENDERGRAPHIC_ACTION ): 1884*cdf0e10cSrcweir { 1885*cdf0e10cSrcweir MetaRenderGraphicAction* pAct = (MetaRenderGraphicAction*) pAction; 1886*cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); 1887*cdf0e10cSrcweir ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack ); 1888*cdf0e10cSrcweir } 1889*cdf0e10cSrcweir break; 1890*cdf0e10cSrcweir 1891*cdf0e10cSrcweir default: 1892*cdf0e10cSrcweir { 1893*cdf0e10cSrcweir pAction->Execute( &aMapVDev ); 1894*cdf0e10cSrcweir 1895*cdf0e10cSrcweir if( nActionType == META_PUSH_ACTION ) 1896*cdf0e10cSrcweir { 1897*cdf0e10cSrcweir MetaPushAction* pAct = (MetaPushAction*) pAction; 1898*cdf0e10cSrcweir aPushFlagStack.push_back( pAct->GetFlags() ); 1899*cdf0e10cSrcweir if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 ) 1900*cdf0e10cSrcweir { 1901*cdf0e10cSrcweir Rectangle aRect( aClipStack.back() ); 1902*cdf0e10cSrcweir aClipStack.push_back( aRect ); 1903*cdf0e10cSrcweir } 1904*cdf0e10cSrcweir } 1905*cdf0e10cSrcweir else if( nActionType == META_POP_ACTION ) 1906*cdf0e10cSrcweir { 1907*cdf0e10cSrcweir // sanity check 1908*cdf0e10cSrcweir if( ! aPushFlagStack.empty() ) 1909*cdf0e10cSrcweir { 1910*cdf0e10cSrcweir if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 ) 1911*cdf0e10cSrcweir { 1912*cdf0e10cSrcweir if( aClipStack.size() > 1 ) 1913*cdf0e10cSrcweir aClipStack.pop_back(); 1914*cdf0e10cSrcweir } 1915*cdf0e10cSrcweir aPushFlagStack.pop_back(); 1916*cdf0e10cSrcweir } 1917*cdf0e10cSrcweir } 1918*cdf0e10cSrcweir } 1919*cdf0e10cSrcweir break; 1920*cdf0e10cSrcweir } 1921*cdf0e10cSrcweir } 1922*cdf0e10cSrcweir return aBound; 1923*cdf0e10cSrcweir } 1924*cdf0e10cSrcweir 1925*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1926*cdf0e10cSrcweir 1927*cdf0e10cSrcweir Color GDIMetaFile::ImplColAdjustFnc( const Color& rColor, const void* pColParam ) 1928*cdf0e10cSrcweir { 1929*cdf0e10cSrcweir return Color( rColor.GetTransparency(), 1930*cdf0e10cSrcweir ( (const ImplColAdjustParam*) pColParam )->pMapR[ rColor.GetRed() ], 1931*cdf0e10cSrcweir ( (const ImplColAdjustParam*) pColParam )->pMapG[ rColor.GetGreen() ], 1932*cdf0e10cSrcweir ( (const ImplColAdjustParam*) pColParam )->pMapB[ rColor.GetBlue() ] ); 1933*cdf0e10cSrcweir 1934*cdf0e10cSrcweir } 1935*cdf0e10cSrcweir 1936*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1937*cdf0e10cSrcweir 1938*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpAdjustFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 1939*cdf0e10cSrcweir { 1940*cdf0e10cSrcweir const ImplBmpAdjustParam* p = (const ImplBmpAdjustParam*) pBmpParam; 1941*cdf0e10cSrcweir BitmapEx aRet( rBmpEx ); 1942*cdf0e10cSrcweir 1943*cdf0e10cSrcweir aRet.Adjust( p->nLuminancePercent, p->nContrastPercent, 1944*cdf0e10cSrcweir p->nChannelRPercent, p->nChannelGPercent, p->nChannelBPercent, 1945*cdf0e10cSrcweir p->fGamma, p->bInvert ); 1946*cdf0e10cSrcweir 1947*cdf0e10cSrcweir return aRet; 1948*cdf0e10cSrcweir } 1949*cdf0e10cSrcweir 1950*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1951*cdf0e10cSrcweir 1952*cdf0e10cSrcweir Color GDIMetaFile::ImplColConvertFnc( const Color& rColor, const void* pColParam ) 1953*cdf0e10cSrcweir { 1954*cdf0e10cSrcweir sal_uInt8 cLum = rColor.GetLuminance(); 1955*cdf0e10cSrcweir 1956*cdf0e10cSrcweir if( MTF_CONVERSION_1BIT_THRESHOLD == ( (const ImplColConvertParam*) pColParam )->eConversion ) 1957*cdf0e10cSrcweir cLum = ( cLum < 128 ) ? 0 : 255; 1958*cdf0e10cSrcweir 1959*cdf0e10cSrcweir return Color( rColor.GetTransparency(), cLum, cLum, cLum ); 1960*cdf0e10cSrcweir } 1961*cdf0e10cSrcweir 1962*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1963*cdf0e10cSrcweir 1964*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpConvertFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 1965*cdf0e10cSrcweir { 1966*cdf0e10cSrcweir BitmapEx aRet( rBmpEx ); 1967*cdf0e10cSrcweir 1968*cdf0e10cSrcweir aRet.Convert( ( (const ImplBmpConvertParam*) pBmpParam )->eConversion ); 1969*cdf0e10cSrcweir 1970*cdf0e10cSrcweir return aRet; 1971*cdf0e10cSrcweir } 1972*cdf0e10cSrcweir 1973*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1974*cdf0e10cSrcweir 1975*cdf0e10cSrcweir Color GDIMetaFile::ImplColMonoFnc( const Color&, const void* pColParam ) 1976*cdf0e10cSrcweir { 1977*cdf0e10cSrcweir return( ( (const ImplColMonoParam*) pColParam )->aColor ); 1978*cdf0e10cSrcweir } 1979*cdf0e10cSrcweir 1980*cdf0e10cSrcweir // ------------------------------------------------------------------------ 1981*cdf0e10cSrcweir 1982*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpMonoFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 1983*cdf0e10cSrcweir { 1984*cdf0e10cSrcweir BitmapPalette aPal( 3 ); 1985*cdf0e10cSrcweir 1986*cdf0e10cSrcweir aPal[ 0 ] = Color( COL_BLACK ); 1987*cdf0e10cSrcweir aPal[ 1 ] = Color( COL_WHITE ); 1988*cdf0e10cSrcweir aPal[ 2 ] = ( (const ImplBmpMonoParam*) pBmpParam )->aColor; 1989*cdf0e10cSrcweir 1990*cdf0e10cSrcweir Bitmap aBmp( rBmpEx.GetSizePixel(), 4, &aPal ); 1991*cdf0e10cSrcweir aBmp.Erase( ( (const ImplBmpMonoParam*) pBmpParam )->aColor ); 1992*cdf0e10cSrcweir 1993*cdf0e10cSrcweir if( rBmpEx.IsAlpha() ) 1994*cdf0e10cSrcweir return BitmapEx( aBmp, rBmpEx.GetAlpha() ); 1995*cdf0e10cSrcweir else if( rBmpEx.IsTransparent() ) 1996*cdf0e10cSrcweir return BitmapEx( aBmp, rBmpEx.GetMask() ); 1997*cdf0e10cSrcweir else 1998*cdf0e10cSrcweir return aBmp; 1999*cdf0e10cSrcweir } 2000*cdf0e10cSrcweir 2001*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2002*cdf0e10cSrcweir 2003*cdf0e10cSrcweir Color GDIMetaFile::ImplColReplaceFnc( const Color& rColor, const void* pColParam ) 2004*cdf0e10cSrcweir { 2005*cdf0e10cSrcweir const sal_uLong nR = rColor.GetRed(), nG = rColor.GetGreen(), nB = rColor.GetBlue(); 2006*cdf0e10cSrcweir 2007*cdf0e10cSrcweir for( sal_uLong i = 0; i < ( (const ImplColReplaceParam*) pColParam )->nCount; i++ ) 2008*cdf0e10cSrcweir { 2009*cdf0e10cSrcweir if( ( ( (const ImplColReplaceParam*) pColParam )->pMinR[ i ] <= nR ) && 2010*cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMaxR[ i ] >= nR ) && 2011*cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMinG[ i ] <= nG ) && 2012*cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMaxG[ i ] >= nG ) && 2013*cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMinB[ i ] <= nB ) && 2014*cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMaxB[ i ] >= nB ) ) 2015*cdf0e10cSrcweir { 2016*cdf0e10cSrcweir return( ( (const ImplColReplaceParam*) pColParam )->pDstCols[ i ] ); 2017*cdf0e10cSrcweir } 2018*cdf0e10cSrcweir } 2019*cdf0e10cSrcweir 2020*cdf0e10cSrcweir return rColor; 2021*cdf0e10cSrcweir } 2022*cdf0e10cSrcweir 2023*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2024*cdf0e10cSrcweir 2025*cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpReplaceFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 2026*cdf0e10cSrcweir { 2027*cdf0e10cSrcweir const ImplBmpReplaceParam* p = (const ImplBmpReplaceParam*) pBmpParam; 2028*cdf0e10cSrcweir BitmapEx aRet( rBmpEx ); 2029*cdf0e10cSrcweir 2030*cdf0e10cSrcweir aRet.Replace( p->pSrcCols, p->pDstCols, p->nCount, p->pTols ); 2031*cdf0e10cSrcweir 2032*cdf0e10cSrcweir return aRet; 2033*cdf0e10cSrcweir } 2034*cdf0e10cSrcweir 2035*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2036*cdf0e10cSrcweir 2037*cdf0e10cSrcweir void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pColParam, 2038*cdf0e10cSrcweir BmpExchangeFnc pFncBmp, const void* pBmpParam ) 2039*cdf0e10cSrcweir { 2040*cdf0e10cSrcweir GDIMetaFile aMtf; 2041*cdf0e10cSrcweir 2042*cdf0e10cSrcweir aMtf.aPrefSize = aPrefSize; 2043*cdf0e10cSrcweir aMtf.aPrefMapMode = aPrefMapMode; 2044*cdf0e10cSrcweir 2045*cdf0e10cSrcweir for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() ) 2046*cdf0e10cSrcweir { 2047*cdf0e10cSrcweir const sal_uInt16 nType = pAction->GetType(); 2048*cdf0e10cSrcweir 2049*cdf0e10cSrcweir switch( nType ) 2050*cdf0e10cSrcweir { 2051*cdf0e10cSrcweir case( META_PIXEL_ACTION ): 2052*cdf0e10cSrcweir { 2053*cdf0e10cSrcweir MetaPixelAction* pAct = (MetaPixelAction*) pAction; 2054*cdf0e10cSrcweir aMtf.Insert( new MetaPixelAction( pAct->GetPoint(), pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND ); 2055*cdf0e10cSrcweir } 2056*cdf0e10cSrcweir break; 2057*cdf0e10cSrcweir 2058*cdf0e10cSrcweir case( META_LINECOLOR_ACTION ): 2059*cdf0e10cSrcweir { 2060*cdf0e10cSrcweir MetaLineColorAction* pAct = (MetaLineColorAction*) pAction; 2061*cdf0e10cSrcweir 2062*cdf0e10cSrcweir if( !pAct->IsSetting() ) 2063*cdf0e10cSrcweir pAct->Duplicate(); 2064*cdf0e10cSrcweir else 2065*cdf0e10cSrcweir pAct = new MetaLineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2066*cdf0e10cSrcweir 2067*cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2068*cdf0e10cSrcweir } 2069*cdf0e10cSrcweir break; 2070*cdf0e10cSrcweir 2071*cdf0e10cSrcweir case( META_FILLCOLOR_ACTION ): 2072*cdf0e10cSrcweir { 2073*cdf0e10cSrcweir MetaFillColorAction* pAct = (MetaFillColorAction*) pAction; 2074*cdf0e10cSrcweir 2075*cdf0e10cSrcweir if( !pAct->IsSetting() ) 2076*cdf0e10cSrcweir pAct->Duplicate(); 2077*cdf0e10cSrcweir else 2078*cdf0e10cSrcweir pAct = new MetaFillColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2079*cdf0e10cSrcweir 2080*cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2081*cdf0e10cSrcweir } 2082*cdf0e10cSrcweir break; 2083*cdf0e10cSrcweir 2084*cdf0e10cSrcweir case( META_TEXTCOLOR_ACTION ): 2085*cdf0e10cSrcweir { 2086*cdf0e10cSrcweir MetaTextColorAction* pAct = (MetaTextColorAction*) pAction; 2087*cdf0e10cSrcweir aMtf.Insert( new MetaTextColorAction( pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND ); 2088*cdf0e10cSrcweir } 2089*cdf0e10cSrcweir break; 2090*cdf0e10cSrcweir 2091*cdf0e10cSrcweir case( META_TEXTFILLCOLOR_ACTION ): 2092*cdf0e10cSrcweir { 2093*cdf0e10cSrcweir MetaTextFillColorAction* pAct = (MetaTextFillColorAction*) pAction; 2094*cdf0e10cSrcweir 2095*cdf0e10cSrcweir if( !pAct->IsSetting() ) 2096*cdf0e10cSrcweir pAct->Duplicate(); 2097*cdf0e10cSrcweir else 2098*cdf0e10cSrcweir pAct = new MetaTextFillColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2099*cdf0e10cSrcweir 2100*cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2101*cdf0e10cSrcweir } 2102*cdf0e10cSrcweir break; 2103*cdf0e10cSrcweir 2104*cdf0e10cSrcweir case( META_TEXTLINECOLOR_ACTION ): 2105*cdf0e10cSrcweir { 2106*cdf0e10cSrcweir MetaTextLineColorAction* pAct = (MetaTextLineColorAction*) pAction; 2107*cdf0e10cSrcweir 2108*cdf0e10cSrcweir if( !pAct->IsSetting() ) 2109*cdf0e10cSrcweir pAct->Duplicate(); 2110*cdf0e10cSrcweir else 2111*cdf0e10cSrcweir pAct = new MetaTextLineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2112*cdf0e10cSrcweir 2113*cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2114*cdf0e10cSrcweir } 2115*cdf0e10cSrcweir break; 2116*cdf0e10cSrcweir 2117*cdf0e10cSrcweir case( META_OVERLINECOLOR_ACTION ): 2118*cdf0e10cSrcweir { 2119*cdf0e10cSrcweir MetaOverlineColorAction* pAct = (MetaOverlineColorAction*) pAction; 2120*cdf0e10cSrcweir 2121*cdf0e10cSrcweir if( !pAct->IsSetting() ) 2122*cdf0e10cSrcweir pAct->Duplicate(); 2123*cdf0e10cSrcweir else 2124*cdf0e10cSrcweir pAct = new MetaOverlineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2125*cdf0e10cSrcweir 2126*cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2127*cdf0e10cSrcweir } 2128*cdf0e10cSrcweir break; 2129*cdf0e10cSrcweir 2130*cdf0e10cSrcweir case( META_FONT_ACTION ): 2131*cdf0e10cSrcweir { 2132*cdf0e10cSrcweir MetaFontAction* pAct = (MetaFontAction*) pAction; 2133*cdf0e10cSrcweir Font aFont( pAct->GetFont() ); 2134*cdf0e10cSrcweir 2135*cdf0e10cSrcweir aFont.SetColor( pFncCol( aFont.GetColor(), pColParam ) ); 2136*cdf0e10cSrcweir aFont.SetFillColor( pFncCol( aFont.GetFillColor(), pColParam ) ); 2137*cdf0e10cSrcweir aMtf.Insert( new MetaFontAction( aFont ), LIST_APPEND ); 2138*cdf0e10cSrcweir } 2139*cdf0e10cSrcweir break; 2140*cdf0e10cSrcweir 2141*cdf0e10cSrcweir case( META_WALLPAPER_ACTION ): 2142*cdf0e10cSrcweir { 2143*cdf0e10cSrcweir MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction; 2144*cdf0e10cSrcweir Wallpaper aWall( pAct->GetWallpaper() ); 2145*cdf0e10cSrcweir const Rectangle& rRect = pAct->GetRect(); 2146*cdf0e10cSrcweir 2147*cdf0e10cSrcweir aWall.SetColor( pFncCol( aWall.GetColor(), pColParam ) ); 2148*cdf0e10cSrcweir 2149*cdf0e10cSrcweir if( aWall.IsBitmap() ) 2150*cdf0e10cSrcweir aWall.SetBitmap( pFncBmp( aWall.GetBitmap(), pBmpParam ) ); 2151*cdf0e10cSrcweir 2152*cdf0e10cSrcweir if( aWall.IsGradient() ) 2153*cdf0e10cSrcweir { 2154*cdf0e10cSrcweir Gradient aGradient( aWall.GetGradient() ); 2155*cdf0e10cSrcweir 2156*cdf0e10cSrcweir aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) ); 2157*cdf0e10cSrcweir aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) ); 2158*cdf0e10cSrcweir aWall.SetGradient( aGradient ); 2159*cdf0e10cSrcweir } 2160*cdf0e10cSrcweir 2161*cdf0e10cSrcweir aMtf.Insert( new MetaWallpaperAction( rRect, aWall ), LIST_APPEND ); 2162*cdf0e10cSrcweir } 2163*cdf0e10cSrcweir break; 2164*cdf0e10cSrcweir 2165*cdf0e10cSrcweir case( META_BMP_ACTION ): 2166*cdf0e10cSrcweir case( META_BMPEX_ACTION ): 2167*cdf0e10cSrcweir case( META_MASK_ACTION ): 2168*cdf0e10cSrcweir { 2169*cdf0e10cSrcweir DBG_ERROR( "Don't use bitmap actions of this type in metafiles!" ); 2170*cdf0e10cSrcweir } 2171*cdf0e10cSrcweir break; 2172*cdf0e10cSrcweir 2173*cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): 2174*cdf0e10cSrcweir { 2175*cdf0e10cSrcweir MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; 2176*cdf0e10cSrcweir aMtf.Insert( new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(), 2177*cdf0e10cSrcweir pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ), 2178*cdf0e10cSrcweir LIST_APPEND ); 2179*cdf0e10cSrcweir } 2180*cdf0e10cSrcweir break; 2181*cdf0e10cSrcweir 2182*cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): 2183*cdf0e10cSrcweir { 2184*cdf0e10cSrcweir MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; 2185*cdf0e10cSrcweir aMtf.Insert( new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), 2186*cdf0e10cSrcweir pAct->GetSrcPoint(), pAct->GetSrcSize(), 2187*cdf0e10cSrcweir pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ), 2188*cdf0e10cSrcweir LIST_APPEND ); 2189*cdf0e10cSrcweir } 2190*cdf0e10cSrcweir break; 2191*cdf0e10cSrcweir 2192*cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): 2193*cdf0e10cSrcweir { 2194*cdf0e10cSrcweir MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; 2195*cdf0e10cSrcweir aMtf.Insert( new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(), 2196*cdf0e10cSrcweir pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ), 2197*cdf0e10cSrcweir LIST_APPEND ); 2198*cdf0e10cSrcweir } 2199*cdf0e10cSrcweir break; 2200*cdf0e10cSrcweir 2201*cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): 2202*cdf0e10cSrcweir { 2203*cdf0e10cSrcweir MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; 2204*cdf0e10cSrcweir aMtf.Insert( new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), 2205*cdf0e10cSrcweir pAct->GetSrcPoint(), pAct->GetSrcSize(), 2206*cdf0e10cSrcweir pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ), 2207*cdf0e10cSrcweir LIST_APPEND ); 2208*cdf0e10cSrcweir } 2209*cdf0e10cSrcweir break; 2210*cdf0e10cSrcweir 2211*cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): 2212*cdf0e10cSrcweir { 2213*cdf0e10cSrcweir MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction; 2214*cdf0e10cSrcweir aMtf.Insert( new MetaMaskScaleAction( pAct->GetPoint(), pAct->GetSize(), 2215*cdf0e10cSrcweir pAct->GetBitmap(), 2216*cdf0e10cSrcweir pFncCol( pAct->GetColor(), pColParam ) ), 2217*cdf0e10cSrcweir LIST_APPEND ); 2218*cdf0e10cSrcweir } 2219*cdf0e10cSrcweir break; 2220*cdf0e10cSrcweir 2221*cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): 2222*cdf0e10cSrcweir { 2223*cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 2224*cdf0e10cSrcweir aMtf.Insert( new MetaMaskScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), 2225*cdf0e10cSrcweir pAct->GetSrcPoint(), pAct->GetSrcSize(), 2226*cdf0e10cSrcweir pAct->GetBitmap(), 2227*cdf0e10cSrcweir pFncCol( pAct->GetColor(), pColParam ) ), 2228*cdf0e10cSrcweir LIST_APPEND ); 2229*cdf0e10cSrcweir } 2230*cdf0e10cSrcweir break; 2231*cdf0e10cSrcweir 2232*cdf0e10cSrcweir case( META_GRADIENT_ACTION ): 2233*cdf0e10cSrcweir { 2234*cdf0e10cSrcweir MetaGradientAction* pAct = (MetaGradientAction*) pAction; 2235*cdf0e10cSrcweir Gradient aGradient( pAct->GetGradient() ); 2236*cdf0e10cSrcweir 2237*cdf0e10cSrcweir aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) ); 2238*cdf0e10cSrcweir aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) ); 2239*cdf0e10cSrcweir aMtf.Insert( new MetaGradientAction( pAct->GetRect(), aGradient ), LIST_APPEND ); 2240*cdf0e10cSrcweir } 2241*cdf0e10cSrcweir break; 2242*cdf0e10cSrcweir 2243*cdf0e10cSrcweir case( META_GRADIENTEX_ACTION ): 2244*cdf0e10cSrcweir { 2245*cdf0e10cSrcweir MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; 2246*cdf0e10cSrcweir Gradient aGradient( pAct->GetGradient() ); 2247*cdf0e10cSrcweir 2248*cdf0e10cSrcweir aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) ); 2249*cdf0e10cSrcweir aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) ); 2250*cdf0e10cSrcweir aMtf.Insert( new MetaGradientExAction( pAct->GetPolyPolygon(), aGradient ), LIST_APPEND ); 2251*cdf0e10cSrcweir } 2252*cdf0e10cSrcweir break; 2253*cdf0e10cSrcweir 2254*cdf0e10cSrcweir case( META_HATCH_ACTION ): 2255*cdf0e10cSrcweir { 2256*cdf0e10cSrcweir MetaHatchAction* pAct = (MetaHatchAction*) pAction; 2257*cdf0e10cSrcweir Hatch aHatch( pAct->GetHatch() ); 2258*cdf0e10cSrcweir 2259*cdf0e10cSrcweir aHatch.SetColor( pFncCol( aHatch.GetColor(), pColParam ) ); 2260*cdf0e10cSrcweir aMtf.Insert( new MetaHatchAction( pAct->GetPolyPolygon(), aHatch ), LIST_APPEND ); 2261*cdf0e10cSrcweir } 2262*cdf0e10cSrcweir break; 2263*cdf0e10cSrcweir 2264*cdf0e10cSrcweir case( META_FLOATTRANSPARENT_ACTION ): 2265*cdf0e10cSrcweir { 2266*cdf0e10cSrcweir MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction; 2267*cdf0e10cSrcweir GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() ); 2268*cdf0e10cSrcweir 2269*cdf0e10cSrcweir aTransMtf.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam ); 2270*cdf0e10cSrcweir aMtf.Insert( new MetaFloatTransparentAction( aTransMtf, 2271*cdf0e10cSrcweir pAct->GetPoint(), pAct->GetSize(), 2272*cdf0e10cSrcweir pAct->GetGradient() ), 2273*cdf0e10cSrcweir LIST_APPEND ); 2274*cdf0e10cSrcweir } 2275*cdf0e10cSrcweir break; 2276*cdf0e10cSrcweir 2277*cdf0e10cSrcweir case( META_EPS_ACTION ): 2278*cdf0e10cSrcweir { 2279*cdf0e10cSrcweir MetaEPSAction* pAct = (MetaEPSAction*) pAction; 2280*cdf0e10cSrcweir GDIMetaFile aSubst( pAct->GetSubstitute() ); 2281*cdf0e10cSrcweir 2282*cdf0e10cSrcweir aSubst.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam ); 2283*cdf0e10cSrcweir aMtf.Insert( new MetaEPSAction( pAct->GetPoint(), pAct->GetSize(), 2284*cdf0e10cSrcweir pAct->GetLink(), aSubst ), 2285*cdf0e10cSrcweir LIST_APPEND ); 2286*cdf0e10cSrcweir } 2287*cdf0e10cSrcweir break; 2288*cdf0e10cSrcweir 2289*cdf0e10cSrcweir case( META_RENDERGRAPHIC_ACTION ): 2290*cdf0e10cSrcweir { 2291*cdf0e10cSrcweir OSL_TRACE( "ExchangeColors not supported for RenderGraphic MetaActions yet" ); 2292*cdf0e10cSrcweir 2293*cdf0e10cSrcweir pAction->Duplicate(); 2294*cdf0e10cSrcweir aMtf.Insert( pAction, LIST_APPEND ); 2295*cdf0e10cSrcweir } 2296*cdf0e10cSrcweir break; 2297*cdf0e10cSrcweir 2298*cdf0e10cSrcweir default: 2299*cdf0e10cSrcweir { 2300*cdf0e10cSrcweir pAction->Duplicate(); 2301*cdf0e10cSrcweir aMtf.Insert( pAction, LIST_APPEND ); 2302*cdf0e10cSrcweir } 2303*cdf0e10cSrcweir break; 2304*cdf0e10cSrcweir } 2305*cdf0e10cSrcweir } 2306*cdf0e10cSrcweir 2307*cdf0e10cSrcweir *this = aMtf; 2308*cdf0e10cSrcweir } 2309*cdf0e10cSrcweir 2310*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2311*cdf0e10cSrcweir 2312*cdf0e10cSrcweir void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent, 2313*cdf0e10cSrcweir short nChannelRPercent, short nChannelGPercent, 2314*cdf0e10cSrcweir short nChannelBPercent, double fGamma, sal_Bool bInvert ) 2315*cdf0e10cSrcweir { 2316*cdf0e10cSrcweir // nothing to do? => return quickly 2317*cdf0e10cSrcweir if( nLuminancePercent || nContrastPercent || 2318*cdf0e10cSrcweir nChannelRPercent || nChannelGPercent || nChannelBPercent || 2319*cdf0e10cSrcweir ( fGamma != 1.0 ) || bInvert ) 2320*cdf0e10cSrcweir { 2321*cdf0e10cSrcweir double fM, fROff, fGOff, fBOff, fOff; 2322*cdf0e10cSrcweir ImplColAdjustParam aColParam; 2323*cdf0e10cSrcweir ImplBmpAdjustParam aBmpParam; 2324*cdf0e10cSrcweir 2325*cdf0e10cSrcweir aColParam.pMapR = new sal_uInt8[ 256 ]; 2326*cdf0e10cSrcweir aColParam.pMapG = new sal_uInt8[ 256 ]; 2327*cdf0e10cSrcweir aColParam.pMapB = new sal_uInt8[ 256 ]; 2328*cdf0e10cSrcweir 2329*cdf0e10cSrcweir // calculate slope 2330*cdf0e10cSrcweir if( nContrastPercent >= 0 ) 2331*cdf0e10cSrcweir fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) ); 2332*cdf0e10cSrcweir else 2333*cdf0e10cSrcweir fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0; 2334*cdf0e10cSrcweir 2335*cdf0e10cSrcweir // total offset = luminance offset + contrast offset 2336*cdf0e10cSrcweir fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0; 2337*cdf0e10cSrcweir 2338*cdf0e10cSrcweir // channel offset = channel offset + total offset 2339*cdf0e10cSrcweir fROff = nChannelRPercent * 2.55 + fOff; 2340*cdf0e10cSrcweir fGOff = nChannelGPercent * 2.55 + fOff; 2341*cdf0e10cSrcweir fBOff = nChannelBPercent * 2.55 + fOff; 2342*cdf0e10cSrcweir 2343*cdf0e10cSrcweir // calculate gamma value 2344*cdf0e10cSrcweir fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma ); 2345*cdf0e10cSrcweir const sal_Bool bGamma = ( fGamma != 1.0 ); 2346*cdf0e10cSrcweir 2347*cdf0e10cSrcweir // create mapping table 2348*cdf0e10cSrcweir for( long nX = 0L; nX < 256L; nX++ ) 2349*cdf0e10cSrcweir { 2350*cdf0e10cSrcweir aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L ); 2351*cdf0e10cSrcweir aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L ); 2352*cdf0e10cSrcweir aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L ); 2353*cdf0e10cSrcweir 2354*cdf0e10cSrcweir if( bGamma ) 2355*cdf0e10cSrcweir { 2356*cdf0e10cSrcweir aColParam.pMapR[ nX ] = GAMMA( aColParam.pMapR[ nX ], fGamma ); 2357*cdf0e10cSrcweir aColParam.pMapG[ nX ] = GAMMA( aColParam.pMapG[ nX ], fGamma ); 2358*cdf0e10cSrcweir aColParam.pMapB[ nX ] = GAMMA( aColParam.pMapB[ nX ], fGamma ); 2359*cdf0e10cSrcweir } 2360*cdf0e10cSrcweir 2361*cdf0e10cSrcweir if( bInvert ) 2362*cdf0e10cSrcweir { 2363*cdf0e10cSrcweir aColParam.pMapR[ nX ] = ~aColParam.pMapR[ nX ]; 2364*cdf0e10cSrcweir aColParam.pMapG[ nX ] = ~aColParam.pMapG[ nX ]; 2365*cdf0e10cSrcweir aColParam.pMapB[ nX ] = ~aColParam.pMapB[ nX ]; 2366*cdf0e10cSrcweir } 2367*cdf0e10cSrcweir } 2368*cdf0e10cSrcweir 2369*cdf0e10cSrcweir aBmpParam.nLuminancePercent = nLuminancePercent; 2370*cdf0e10cSrcweir aBmpParam.nContrastPercent = nContrastPercent; 2371*cdf0e10cSrcweir aBmpParam.nChannelRPercent = nChannelRPercent; 2372*cdf0e10cSrcweir aBmpParam.nChannelGPercent = nChannelGPercent; 2373*cdf0e10cSrcweir aBmpParam.nChannelBPercent = nChannelBPercent; 2374*cdf0e10cSrcweir aBmpParam.fGamma = fGamma; 2375*cdf0e10cSrcweir aBmpParam.bInvert = bInvert; 2376*cdf0e10cSrcweir 2377*cdf0e10cSrcweir // do color adjustment 2378*cdf0e10cSrcweir ImplExchangeColors( ImplColAdjustFnc, &aColParam, ImplBmpAdjustFnc, &aBmpParam ); 2379*cdf0e10cSrcweir 2380*cdf0e10cSrcweir delete[] aColParam.pMapR; 2381*cdf0e10cSrcweir delete[] aColParam.pMapG; 2382*cdf0e10cSrcweir delete[] aColParam.pMapB; 2383*cdf0e10cSrcweir } 2384*cdf0e10cSrcweir } 2385*cdf0e10cSrcweir 2386*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2387*cdf0e10cSrcweir 2388*cdf0e10cSrcweir void GDIMetaFile::Convert( MtfConversion eConversion ) 2389*cdf0e10cSrcweir { 2390*cdf0e10cSrcweir // nothing to do? => return quickly 2391*cdf0e10cSrcweir if( eConversion != MTF_CONVERSION_NONE ) 2392*cdf0e10cSrcweir { 2393*cdf0e10cSrcweir ImplColConvertParam aColParam; 2394*cdf0e10cSrcweir ImplBmpConvertParam aBmpParam; 2395*cdf0e10cSrcweir 2396*cdf0e10cSrcweir aColParam.eConversion = eConversion; 2397*cdf0e10cSrcweir aBmpParam.eConversion = ( MTF_CONVERSION_1BIT_THRESHOLD == eConversion ) ? BMP_CONVERSION_1BIT_THRESHOLD : BMP_CONVERSION_8BIT_GREYS; 2398*cdf0e10cSrcweir 2399*cdf0e10cSrcweir ImplExchangeColors( ImplColConvertFnc, &aColParam, ImplBmpConvertFnc, &aBmpParam ); 2400*cdf0e10cSrcweir } 2401*cdf0e10cSrcweir } 2402*cdf0e10cSrcweir 2403*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2404*cdf0e10cSrcweir 2405*cdf0e10cSrcweir void GDIMetaFile::ReplaceColors( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol ) 2406*cdf0e10cSrcweir { 2407*cdf0e10cSrcweir ReplaceColors( &rSearchColor, &rReplaceColor, 1, &nTol ); 2408*cdf0e10cSrcweir } 2409*cdf0e10cSrcweir 2410*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2411*cdf0e10cSrcweir 2412*cdf0e10cSrcweir void GDIMetaFile::ReplaceColors( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, sal_uLong* pTols ) 2413*cdf0e10cSrcweir { 2414*cdf0e10cSrcweir ImplColReplaceParam aColParam; 2415*cdf0e10cSrcweir ImplBmpReplaceParam aBmpParam; 2416*cdf0e10cSrcweir 2417*cdf0e10cSrcweir aColParam.pMinR = new sal_uLong[ nColorCount ]; 2418*cdf0e10cSrcweir aColParam.pMaxR = new sal_uLong[ nColorCount ]; 2419*cdf0e10cSrcweir aColParam.pMinG = new sal_uLong[ nColorCount ]; 2420*cdf0e10cSrcweir aColParam.pMaxG = new sal_uLong[ nColorCount ]; 2421*cdf0e10cSrcweir aColParam.pMinB = new sal_uLong[ nColorCount ]; 2422*cdf0e10cSrcweir aColParam.pMaxB = new sal_uLong[ nColorCount ]; 2423*cdf0e10cSrcweir 2424*cdf0e10cSrcweir for( sal_uLong i = 0; i < nColorCount; i++ ) 2425*cdf0e10cSrcweir { 2426*cdf0e10cSrcweir const long nTol = pTols ? ( pTols[ i ] * 255 ) / 100 : 0; 2427*cdf0e10cSrcweir long nVal; 2428*cdf0e10cSrcweir 2429*cdf0e10cSrcweir nVal = pSearchColors[ i ].GetRed(); 2430*cdf0e10cSrcweir aColParam.pMinR[ i ] = (sal_uLong) Max( nVal - nTol, 0L ); 2431*cdf0e10cSrcweir aColParam.pMaxR[ i ] = (sal_uLong) Min( nVal + nTol, 255L ); 2432*cdf0e10cSrcweir 2433*cdf0e10cSrcweir nVal = pSearchColors[ i ].GetGreen(); 2434*cdf0e10cSrcweir aColParam.pMinG[ i ] = (sal_uLong) Max( nVal - nTol, 0L ); 2435*cdf0e10cSrcweir aColParam.pMaxG[ i ] = (sal_uLong) Min( nVal + nTol, 255L ); 2436*cdf0e10cSrcweir 2437*cdf0e10cSrcweir nVal = pSearchColors[ i ].GetBlue(); 2438*cdf0e10cSrcweir aColParam.pMinB[ i ] = (sal_uLong) Max( nVal - nTol, 0L ); 2439*cdf0e10cSrcweir aColParam.pMaxB[ i ] = (sal_uLong) Min( nVal + nTol, 255L ); 2440*cdf0e10cSrcweir } 2441*cdf0e10cSrcweir 2442*cdf0e10cSrcweir aColParam.pDstCols = pReplaceColors; 2443*cdf0e10cSrcweir aColParam.nCount = nColorCount; 2444*cdf0e10cSrcweir 2445*cdf0e10cSrcweir aBmpParam.pSrcCols = pSearchColors; 2446*cdf0e10cSrcweir aBmpParam.pDstCols = pReplaceColors; 2447*cdf0e10cSrcweir aBmpParam.nCount = nColorCount; 2448*cdf0e10cSrcweir aBmpParam.pTols = pTols; 2449*cdf0e10cSrcweir 2450*cdf0e10cSrcweir ImplExchangeColors( ImplColReplaceFnc, &aColParam, ImplBmpReplaceFnc, &aBmpParam ); 2451*cdf0e10cSrcweir 2452*cdf0e10cSrcweir delete[] aColParam.pMinR; 2453*cdf0e10cSrcweir delete[] aColParam.pMaxR; 2454*cdf0e10cSrcweir delete[] aColParam.pMinG; 2455*cdf0e10cSrcweir delete[] aColParam.pMaxG; 2456*cdf0e10cSrcweir delete[] aColParam.pMinB; 2457*cdf0e10cSrcweir delete[] aColParam.pMaxB; 2458*cdf0e10cSrcweir }; 2459*cdf0e10cSrcweir 2460*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2461*cdf0e10cSrcweir 2462*cdf0e10cSrcweir GDIMetaFile GDIMetaFile::GetMonochromeMtf( const Color& rColor ) const 2463*cdf0e10cSrcweir { 2464*cdf0e10cSrcweir GDIMetaFile aRet( *this ); 2465*cdf0e10cSrcweir 2466*cdf0e10cSrcweir ImplColMonoParam aColParam; 2467*cdf0e10cSrcweir ImplBmpMonoParam aBmpParam; 2468*cdf0e10cSrcweir 2469*cdf0e10cSrcweir aColParam.aColor = rColor; 2470*cdf0e10cSrcweir aBmpParam.aColor = rColor; 2471*cdf0e10cSrcweir 2472*cdf0e10cSrcweir aRet.ImplExchangeColors( ImplColMonoFnc, &aColParam, ImplBmpMonoFnc, &aBmpParam ); 2473*cdf0e10cSrcweir 2474*cdf0e10cSrcweir return aRet; 2475*cdf0e10cSrcweir } 2476*cdf0e10cSrcweir 2477*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2478*cdf0e10cSrcweir 2479*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetChecksum() const 2480*cdf0e10cSrcweir { 2481*cdf0e10cSrcweir GDIMetaFile aMtf; 2482*cdf0e10cSrcweir SvMemoryStream aMemStm( 65535, 65535 ); 2483*cdf0e10cSrcweir ImplMetaWriteData aWriteData; 2484*cdf0e10cSrcweir SVBT16 aBT16; 2485*cdf0e10cSrcweir SVBT32 aBT32; 2486*cdf0e10cSrcweir sal_uLong nCrc = 0; 2487*cdf0e10cSrcweir 2488*cdf0e10cSrcweir aWriteData.meActualCharSet = aMemStm.GetStreamCharSet(); 2489*cdf0e10cSrcweir 2490*cdf0e10cSrcweir for( sal_uLong i = 0, nObjCount = GetActionCount(); i < nObjCount; i++ ) 2491*cdf0e10cSrcweir { 2492*cdf0e10cSrcweir MetaAction* pAction = GetAction( i ); 2493*cdf0e10cSrcweir 2494*cdf0e10cSrcweir switch( pAction->GetType() ) 2495*cdf0e10cSrcweir { 2496*cdf0e10cSrcweir case( META_BMP_ACTION ): 2497*cdf0e10cSrcweir { 2498*cdf0e10cSrcweir MetaBmpAction* pAct = (MetaBmpAction*) pAction; 2499*cdf0e10cSrcweir 2500*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2501*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2502*cdf0e10cSrcweir 2503*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2504*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2505*cdf0e10cSrcweir 2506*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2507*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2508*cdf0e10cSrcweir 2509*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2510*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2511*cdf0e10cSrcweir } 2512*cdf0e10cSrcweir break; 2513*cdf0e10cSrcweir 2514*cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): 2515*cdf0e10cSrcweir { 2516*cdf0e10cSrcweir MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; 2517*cdf0e10cSrcweir 2518*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2519*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2520*cdf0e10cSrcweir 2521*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2522*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2523*cdf0e10cSrcweir 2524*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2525*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2526*cdf0e10cSrcweir 2527*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2528*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2529*cdf0e10cSrcweir 2530*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); 2531*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2532*cdf0e10cSrcweir 2533*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); 2534*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2535*cdf0e10cSrcweir } 2536*cdf0e10cSrcweir break; 2537*cdf0e10cSrcweir 2538*cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): 2539*cdf0e10cSrcweir { 2540*cdf0e10cSrcweir MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; 2541*cdf0e10cSrcweir 2542*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2543*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2544*cdf0e10cSrcweir 2545*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2546*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2547*cdf0e10cSrcweir 2548*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 ); 2549*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2550*cdf0e10cSrcweir 2551*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 ); 2552*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2553*cdf0e10cSrcweir 2554*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 ); 2555*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2556*cdf0e10cSrcweir 2557*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 ); 2558*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2559*cdf0e10cSrcweir 2560*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 ); 2561*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2562*cdf0e10cSrcweir 2563*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 ); 2564*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2565*cdf0e10cSrcweir 2566*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 ); 2567*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2568*cdf0e10cSrcweir 2569*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 ); 2570*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2571*cdf0e10cSrcweir } 2572*cdf0e10cSrcweir break; 2573*cdf0e10cSrcweir 2574*cdf0e10cSrcweir case( META_BMPEX_ACTION ): 2575*cdf0e10cSrcweir { 2576*cdf0e10cSrcweir MetaBmpExAction* pAct = (MetaBmpExAction*) pAction; 2577*cdf0e10cSrcweir 2578*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2579*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2580*cdf0e10cSrcweir 2581*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 ); 2582*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2583*cdf0e10cSrcweir 2584*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2585*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2586*cdf0e10cSrcweir 2587*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2588*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2589*cdf0e10cSrcweir } 2590*cdf0e10cSrcweir break; 2591*cdf0e10cSrcweir 2592*cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): 2593*cdf0e10cSrcweir { 2594*cdf0e10cSrcweir MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; 2595*cdf0e10cSrcweir 2596*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2597*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2598*cdf0e10cSrcweir 2599*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 ); 2600*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2601*cdf0e10cSrcweir 2602*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2603*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2604*cdf0e10cSrcweir 2605*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2606*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2607*cdf0e10cSrcweir 2608*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); 2609*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2610*cdf0e10cSrcweir 2611*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); 2612*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2613*cdf0e10cSrcweir } 2614*cdf0e10cSrcweir break; 2615*cdf0e10cSrcweir 2616*cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): 2617*cdf0e10cSrcweir { 2618*cdf0e10cSrcweir MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; 2619*cdf0e10cSrcweir 2620*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2621*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2622*cdf0e10cSrcweir 2623*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 ); 2624*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2625*cdf0e10cSrcweir 2626*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 ); 2627*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2628*cdf0e10cSrcweir 2629*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 ); 2630*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2631*cdf0e10cSrcweir 2632*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 ); 2633*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2634*cdf0e10cSrcweir 2635*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 ); 2636*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2637*cdf0e10cSrcweir 2638*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 ); 2639*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2640*cdf0e10cSrcweir 2641*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 ); 2642*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2643*cdf0e10cSrcweir 2644*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 ); 2645*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2646*cdf0e10cSrcweir 2647*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 ); 2648*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2649*cdf0e10cSrcweir } 2650*cdf0e10cSrcweir break; 2651*cdf0e10cSrcweir 2652*cdf0e10cSrcweir case( META_MASK_ACTION ): 2653*cdf0e10cSrcweir { 2654*cdf0e10cSrcweir MetaMaskAction* pAct = (MetaMaskAction*) pAction; 2655*cdf0e10cSrcweir 2656*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2657*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2658*cdf0e10cSrcweir 2659*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2660*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2661*cdf0e10cSrcweir 2662*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 ); 2663*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2664*cdf0e10cSrcweir 2665*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2666*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2667*cdf0e10cSrcweir 2668*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2669*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2670*cdf0e10cSrcweir } 2671*cdf0e10cSrcweir break; 2672*cdf0e10cSrcweir 2673*cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): 2674*cdf0e10cSrcweir { 2675*cdf0e10cSrcweir MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction; 2676*cdf0e10cSrcweir 2677*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2678*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2679*cdf0e10cSrcweir 2680*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2681*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2682*cdf0e10cSrcweir 2683*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 ); 2684*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2685*cdf0e10cSrcweir 2686*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2687*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2688*cdf0e10cSrcweir 2689*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2690*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2691*cdf0e10cSrcweir 2692*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); 2693*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2694*cdf0e10cSrcweir 2695*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); 2696*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2697*cdf0e10cSrcweir } 2698*cdf0e10cSrcweir break; 2699*cdf0e10cSrcweir 2700*cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): 2701*cdf0e10cSrcweir { 2702*cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 2703*cdf0e10cSrcweir 2704*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2705*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2706*cdf0e10cSrcweir 2707*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2708*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2709*cdf0e10cSrcweir 2710*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 ); 2711*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2712*cdf0e10cSrcweir 2713*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 ); 2714*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2715*cdf0e10cSrcweir 2716*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 ); 2717*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2718*cdf0e10cSrcweir 2719*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 ); 2720*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2721*cdf0e10cSrcweir 2722*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 ); 2723*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2724*cdf0e10cSrcweir 2725*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 ); 2726*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2727*cdf0e10cSrcweir 2728*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 ); 2729*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2730*cdf0e10cSrcweir 2731*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 ); 2732*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2733*cdf0e10cSrcweir 2734*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 ); 2735*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2736*cdf0e10cSrcweir } 2737*cdf0e10cSrcweir break; 2738*cdf0e10cSrcweir 2739*cdf0e10cSrcweir case META_EPS_ACTION : 2740*cdf0e10cSrcweir { 2741*cdf0e10cSrcweir MetaEPSAction* pAct = (MetaEPSAction*) pAction; 2742*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, pAct->GetLink().GetData(), pAct->GetLink().GetDataSize() ); 2743*cdf0e10cSrcweir } 2744*cdf0e10cSrcweir break; 2745*cdf0e10cSrcweir 2746*cdf0e10cSrcweir case( META_RENDERGRAPHIC_ACTION ): 2747*cdf0e10cSrcweir { 2748*cdf0e10cSrcweir MetaRenderGraphicAction* pAct = (MetaRenderGraphicAction*) pAction; 2749*cdf0e10cSrcweir const ::vcl::RenderGraphic& rRenderGraphic = pAct->GetRenderGraphic(); 2750*cdf0e10cSrcweir 2751*cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2752*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2753*cdf0e10cSrcweir 2754*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, rRenderGraphic.GetGraphicData().get(), rRenderGraphic.GetGraphicDataLength() ); 2755*cdf0e10cSrcweir 2756*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2757*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2758*cdf0e10cSrcweir 2759*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2760*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2761*cdf0e10cSrcweir 2762*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); 2763*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2764*cdf0e10cSrcweir 2765*cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); 2766*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2767*cdf0e10cSrcweir } 2768*cdf0e10cSrcweir break; 2769*cdf0e10cSrcweir 2770*cdf0e10cSrcweir default: 2771*cdf0e10cSrcweir { 2772*cdf0e10cSrcweir pAction->Write( aMemStm, &aWriteData ); 2773*cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aMemStm.GetData(), aMemStm.Tell() ); 2774*cdf0e10cSrcweir aMemStm.Seek( 0 ); 2775*cdf0e10cSrcweir } 2776*cdf0e10cSrcweir break; 2777*cdf0e10cSrcweir } 2778*cdf0e10cSrcweir } 2779*cdf0e10cSrcweir 2780*cdf0e10cSrcweir return nCrc; 2781*cdf0e10cSrcweir } 2782*cdf0e10cSrcweir 2783*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2784*cdf0e10cSrcweir 2785*cdf0e10cSrcweir sal_uLong GDIMetaFile::GetSizeBytes() const 2786*cdf0e10cSrcweir { 2787*cdf0e10cSrcweir sal_uLong nSizeBytes = 0; 2788*cdf0e10cSrcweir 2789*cdf0e10cSrcweir for( sal_uLong i = 0, nObjCount = GetActionCount(); i < nObjCount; ++i ) 2790*cdf0e10cSrcweir { 2791*cdf0e10cSrcweir MetaAction* pAction = GetAction( i ); 2792*cdf0e10cSrcweir 2793*cdf0e10cSrcweir // default action size is set to 32 (=> not the exact value) 2794*cdf0e10cSrcweir nSizeBytes += 32; 2795*cdf0e10cSrcweir 2796*cdf0e10cSrcweir // add sizes for large action content 2797*cdf0e10cSrcweir switch( pAction->GetType() ) 2798*cdf0e10cSrcweir { 2799*cdf0e10cSrcweir case( META_BMP_ACTION ): nSizeBytes += ( (MetaBmpAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2800*cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): nSizeBytes += ( (MetaBmpScaleAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2801*cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): nSizeBytes += ( (MetaBmpScalePartAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2802*cdf0e10cSrcweir 2803*cdf0e10cSrcweir case( META_BMPEX_ACTION ): nSizeBytes += ( (MetaBmpExAction*) pAction )->GetBitmapEx().GetSizeBytes(); break; 2804*cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): nSizeBytes += ( (MetaBmpExScaleAction*) pAction )->GetBitmapEx().GetSizeBytes(); break; 2805*cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): nSizeBytes += ( (MetaBmpExScalePartAction*) pAction )->GetBitmapEx().GetSizeBytes(); break; 2806*cdf0e10cSrcweir 2807*cdf0e10cSrcweir case( META_MASK_ACTION ): nSizeBytes += ( (MetaMaskAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2808*cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): nSizeBytes += ( (MetaMaskScaleAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2809*cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): nSizeBytes += ( (MetaMaskScalePartAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2810*cdf0e10cSrcweir 2811*cdf0e10cSrcweir case( META_POLYLINE_ACTION ): nSizeBytes += ( ( (MetaPolyLineAction*) pAction )->GetPolygon().GetSize() * sizeof( Point ) ); break; 2812*cdf0e10cSrcweir case( META_POLYGON_ACTION ): nSizeBytes += ( ( (MetaPolygonAction*) pAction )->GetPolygon().GetSize() * sizeof( Point ) ); break; 2813*cdf0e10cSrcweir case( META_POLYPOLYGON_ACTION ): 2814*cdf0e10cSrcweir { 2815*cdf0e10cSrcweir const PolyPolygon& rPolyPoly = ( (MetaPolyPolygonAction*) pAction )->GetPolyPolygon(); 2816*cdf0e10cSrcweir 2817*cdf0e10cSrcweir for( sal_uInt16 n = 0; n < rPolyPoly.Count(); ++n ) 2818*cdf0e10cSrcweir nSizeBytes += ( rPolyPoly[ n ].GetSize() * sizeof( Point ) ); 2819*cdf0e10cSrcweir } 2820*cdf0e10cSrcweir break; 2821*cdf0e10cSrcweir 2822*cdf0e10cSrcweir case( META_TEXT_ACTION ): nSizeBytes += ( ( (MetaTextAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break; 2823*cdf0e10cSrcweir case( META_STRETCHTEXT_ACTION ): nSizeBytes += ( ( (MetaStretchTextAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break; 2824*cdf0e10cSrcweir case( META_TEXTRECT_ACTION ): nSizeBytes += ( ( (MetaTextRectAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break; 2825*cdf0e10cSrcweir case( META_TEXTARRAY_ACTION ): 2826*cdf0e10cSrcweir { 2827*cdf0e10cSrcweir MetaTextArrayAction* pTextArrayAction = (MetaTextArrayAction*) pAction; 2828*cdf0e10cSrcweir 2829*cdf0e10cSrcweir nSizeBytes += ( pTextArrayAction->GetText().Len() * sizeof( sal_Unicode ) ); 2830*cdf0e10cSrcweir 2831*cdf0e10cSrcweir if( pTextArrayAction->GetDXArray() ) 2832*cdf0e10cSrcweir nSizeBytes += ( pTextArrayAction->GetLen() << 2 ); 2833*cdf0e10cSrcweir } 2834*cdf0e10cSrcweir break; 2835*cdf0e10cSrcweir 2836*cdf0e10cSrcweir case( META_RENDERGRAPHIC_ACTION ): nSizeBytes += ( ( (MetaRenderGraphicAction*) pAction )->GetRenderGraphic() ).GetGraphicDataLength(); break; 2837*cdf0e10cSrcweir } 2838*cdf0e10cSrcweir } 2839*cdf0e10cSrcweir 2840*cdf0e10cSrcweir return( nSizeBytes ); 2841*cdf0e10cSrcweir } 2842*cdf0e10cSrcweir 2843*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2844*cdf0e10cSrcweir 2845*cdf0e10cSrcweir SvStream& operator>>( SvStream& rIStm, GDIMetaFile& rGDIMetaFile ) 2846*cdf0e10cSrcweir { 2847*cdf0e10cSrcweir if( !rIStm.GetError() ) 2848*cdf0e10cSrcweir { 2849*cdf0e10cSrcweir char aId[ 7 ]; 2850*cdf0e10cSrcweir sal_uLong nStmPos = rIStm.Tell(); 2851*cdf0e10cSrcweir sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); 2852*cdf0e10cSrcweir 2853*cdf0e10cSrcweir rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 2854*cdf0e10cSrcweir 2855*cdf0e10cSrcweir aId[ 0 ] = 0; 2856*cdf0e10cSrcweir aId[ 6 ] = 0; 2857*cdf0e10cSrcweir rIStm.Read( aId, 6 ); 2858*cdf0e10cSrcweir 2859*cdf0e10cSrcweir if ( !strcmp( aId, "VCLMTF" ) ) 2860*cdf0e10cSrcweir { 2861*cdf0e10cSrcweir // new format 2862*cdf0e10cSrcweir VersionCompat* pCompat; 2863*cdf0e10cSrcweir MetaAction* pAction; 2864*cdf0e10cSrcweir sal_uInt32 nStmCompressMode = 0; 2865*cdf0e10cSrcweir sal_uInt32 nCount = 0; 2866*cdf0e10cSrcweir sal_uInt8 bRenderGraphicReplacements = 0; 2867*cdf0e10cSrcweir 2868*cdf0e10cSrcweir pCompat = new VersionCompat( rIStm, STREAM_READ ); 2869*cdf0e10cSrcweir { 2870*cdf0e10cSrcweir // version 1 2871*cdf0e10cSrcweir rIStm >> nStmCompressMode; 2872*cdf0e10cSrcweir rIStm >> rGDIMetaFile.aPrefMapMode; 2873*cdf0e10cSrcweir rIStm >> rGDIMetaFile.aPrefSize; 2874*cdf0e10cSrcweir rIStm >> nCount; 2875*cdf0e10cSrcweir 2876*cdf0e10cSrcweir if( pCompat->GetVersion() >= 2 ) 2877*cdf0e10cSrcweir { 2878*cdf0e10cSrcweir // version 2 2879*cdf0e10cSrcweir // ========= 2880*cdf0e10cSrcweir // contains an additional flag to indicate that RenderGraphic 2881*cdf0e10cSrcweir // actions are immediately followed by a replacement image, that 2882*cdf0e10cSrcweir // needs to be skipped in case the flag is set (KA 01/2011) 2883*cdf0e10cSrcweir 2884*cdf0e10cSrcweir rIStm >> bRenderGraphicReplacements; 2885*cdf0e10cSrcweir } 2886*cdf0e10cSrcweir } 2887*cdf0e10cSrcweir delete pCompat; 2888*cdf0e10cSrcweir 2889*cdf0e10cSrcweir ImplMetaReadData aReadData; 2890*cdf0e10cSrcweir aReadData.meActualCharSet = rIStm.GetStreamCharSet(); 2891*cdf0e10cSrcweir 2892*cdf0e10cSrcweir for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); ++nAction ) 2893*cdf0e10cSrcweir { 2894*cdf0e10cSrcweir pAction = MetaAction::ReadMetaAction( rIStm, &aReadData ); 2895*cdf0e10cSrcweir 2896*cdf0e10cSrcweir if( pAction ) 2897*cdf0e10cSrcweir { 2898*cdf0e10cSrcweir rGDIMetaFile.AddAction( pAction ); 2899*cdf0e10cSrcweir 2900*cdf0e10cSrcweir // if the MetaFile was written in RenderGraphics replacement mode 2901*cdf0e10cSrcweir // and we just read a RenderGraphic action, skip the following 2902*cdf0e10cSrcweir // META_BMPEXSCALE_ACTION, since this is the replacement image, 2903*cdf0e10cSrcweir // just needed for old implementations; don't forget to increment 2904*cdf0e10cSrcweir // the action read counter! (KA 01/2011) 2905*cdf0e10cSrcweir if( bRenderGraphicReplacements && 2906*cdf0e10cSrcweir ( META_RENDERGRAPHIC_ACTION == pAction->GetType() ) && 2907*cdf0e10cSrcweir ( ++nAction < nCount ) && !rIStm.IsEof() ) 2908*cdf0e10cSrcweir { 2909*cdf0e10cSrcweir sal_uInt16 nFollowingType; 2910*cdf0e10cSrcweir 2911*cdf0e10cSrcweir // dummy read of the next following META_BMPEXSCALE_ACTION 2912*cdf0e10cSrcweir // RenderGraphic replacement action (KA 01/2011) 2913*cdf0e10cSrcweir rIStm >> nFollowingType; 2914*cdf0e10cSrcweir delete ( new VersionCompat( rIStm, STREAM_READ ) ); 2915*cdf0e10cSrcweir 2916*cdf0e10cSrcweir OSL_ENSURE( META_BMPEXSCALE_ACTION == nFollowingType, \ 2917*cdf0e10cSrcweir "META_RENDERGRAPHIC_ACTION read in RenderGraphic replacement mode \ 2918*cdf0e10cSrcweir without following META_BMPEXSCALE_ACTION replacement" ); 2919*cdf0e10cSrcweir } 2920*cdf0e10cSrcweir } 2921*cdf0e10cSrcweir } 2922*cdf0e10cSrcweir } 2923*cdf0e10cSrcweir else 2924*cdf0e10cSrcweir { 2925*cdf0e10cSrcweir // to avoid possible compiler optimizations => new/delete 2926*cdf0e10cSrcweir rIStm.Seek( nStmPos ); 2927*cdf0e10cSrcweir delete( new SVMConverter( rIStm, rGDIMetaFile, CONVERT_FROM_SVM1 ) ); 2928*cdf0e10cSrcweir } 2929*cdf0e10cSrcweir 2930*cdf0e10cSrcweir // check for errors 2931*cdf0e10cSrcweir if( rIStm.GetError() ) 2932*cdf0e10cSrcweir { 2933*cdf0e10cSrcweir rGDIMetaFile.Clear(); 2934*cdf0e10cSrcweir rIStm.Seek( nStmPos ); 2935*cdf0e10cSrcweir } 2936*cdf0e10cSrcweir 2937*cdf0e10cSrcweir rIStm.SetNumberFormatInt( nOldFormat ); 2938*cdf0e10cSrcweir } 2939*cdf0e10cSrcweir 2940*cdf0e10cSrcweir return rIStm; 2941*cdf0e10cSrcweir } 2942*cdf0e10cSrcweir 2943*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2944*cdf0e10cSrcweir 2945*cdf0e10cSrcweir SvStream& operator<<( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile ) 2946*cdf0e10cSrcweir { 2947*cdf0e10cSrcweir if( !rOStm.GetError() ) 2948*cdf0e10cSrcweir { 2949*cdf0e10cSrcweir static const char* pEnableSVM1 = getenv( "SAL_ENABLE_SVM1" ); 2950*cdf0e10cSrcweir static const bool bNoSVM1 = (NULL == pEnableSVM1 ) || ( '0' == *pEnableSVM1 ); 2951*cdf0e10cSrcweir 2952*cdf0e10cSrcweir if( bNoSVM1 || rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) 2953*cdf0e10cSrcweir { 2954*cdf0e10cSrcweir const_cast< GDIMetaFile& >( rGDIMetaFile ).Write( rOStm ); 2955*cdf0e10cSrcweir } 2956*cdf0e10cSrcweir else 2957*cdf0e10cSrcweir { 2958*cdf0e10cSrcweir delete( new SVMConverter( rOStm, const_cast< GDIMetaFile& >( rGDIMetaFile ), CONVERT_TO_SVM1 ) ); 2959*cdf0e10cSrcweir } 2960*cdf0e10cSrcweir 2961*cdf0e10cSrcweir #ifdef DEBUG 2962*cdf0e10cSrcweir if( !bNoSVM1 && rOStm.GetVersion() < SOFFICE_FILEFORMAT_50 ) 2963*cdf0e10cSrcweir { 2964*cdf0e10cSrcweir OSL_TRACE( \ 2965*cdf0e10cSrcweir "GDIMetaFile would normally be written in old SVM1 format by this call. \ 2966*cdf0e10cSrcweir The current implementation always writes in VCLMTF format. \ 2967*cdf0e10cSrcweir Please set environment variable SAL_ENABLE_SVM1 to '1' to reenable old behavior" ); 2968*cdf0e10cSrcweir } 2969*cdf0e10cSrcweir #endif // DEBUG 2970*cdf0e10cSrcweir } 2971*cdf0e10cSrcweir 2972*cdf0e10cSrcweir return rOStm; 2973*cdf0e10cSrcweir } 2974*cdf0e10cSrcweir 2975*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2976*cdf0e10cSrcweir 2977*cdf0e10cSrcweir SvStream& GDIMetaFile::Read( SvStream& rIStm ) 2978*cdf0e10cSrcweir { 2979*cdf0e10cSrcweir Clear(); 2980*cdf0e10cSrcweir rIStm >> *this; 2981*cdf0e10cSrcweir 2982*cdf0e10cSrcweir return rIStm; 2983*cdf0e10cSrcweir } 2984*cdf0e10cSrcweir 2985*cdf0e10cSrcweir // ------------------------------------------------------------------------ 2986*cdf0e10cSrcweir 2987*cdf0e10cSrcweir SvStream& GDIMetaFile::Write( SvStream& rOStm, GDIMetaFileWriteFlags nWriteFlags ) 2988*cdf0e10cSrcweir { 2989*cdf0e10cSrcweir VersionCompat* pCompat; 2990*cdf0e10cSrcweir const sal_uInt32 nStmCompressMode = rOStm.GetCompressMode(); 2991*cdf0e10cSrcweir sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt(); 2992*cdf0e10cSrcweir const sal_uInt8 bRenderGraphicReplacements = 2993*cdf0e10cSrcweir ( ( ( GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC & nWriteFlags ) != 0 ) ? 1 : 0 ); 2994*cdf0e10cSrcweir 2995*cdf0e10cSrcweir // With the introduction of the META_RENDERGRAPHIC_ACTION, it is neccessary 2996*cdf0e10cSrcweir // to provide some kind of document backward compatibility: 2997*cdf0e10cSrcweir // 2998*cdf0e10cSrcweir // If the flag GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set in 2999*cdf0e10cSrcweir // parameter nWriteFlags, each META_RENDERGRAPHIC_ACTION is followed by 3000*cdf0e10cSrcweir // an additional META_BMPEXSCALE_ACTION, that contains a replacement 3001*cdf0e10cSrcweir // image for the new RenderGraphic action. 3002*cdf0e10cSrcweir // 3003*cdf0e10cSrcweir // Old implementations, not knowing anything about META_RENDERGRAPHIC_ACTION, 3004*cdf0e10cSrcweir // will skip this new action and read the META_BMPEXSCALE_ACTION instead 3005*cdf0e10cSrcweir // 3006*cdf0e10cSrcweir // Since the current implementation is able to handle the new action, the 3007*cdf0e10cSrcweir // then following image replacement action needs to be skipped by this 3008*cdf0e10cSrcweir // implementation, if the metafile was written in the RenderGraphic 3009*cdf0e10cSrcweir // replacement mode. 3010*cdf0e10cSrcweir // 3011*cdf0e10cSrcweir // To be able to detect this compatibility mode, the header needs to 3012*cdf0e10cSrcweir // be extended by a corresponding flag, resulting in version 2 of 3013*cdf0e10cSrcweir // the header. The surrounding VersionCompat of the header 3014*cdf0e10cSrcweir // allows to add such new data without any problems (KA 01/2011) 3015*cdf0e10cSrcweir 3016*cdf0e10cSrcweir rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 3017*cdf0e10cSrcweir rOStm.Write( "VCLMTF", 6 ); 3018*cdf0e10cSrcweir 3019*cdf0e10cSrcweir pCompat = new VersionCompat( rOStm, STREAM_WRITE, 2 ); 3020*cdf0e10cSrcweir 3021*cdf0e10cSrcweir { 3022*cdf0e10cSrcweir // version 1 3023*cdf0e10cSrcweir sal_uInt32 nActionCount = 0; 3024*cdf0e10cSrcweir 3025*cdf0e10cSrcweir // calculate correct action count and watch for 3026*cdf0e10cSrcweir // additional RenderGraphic replacement actions, if the 3027*cdf0e10cSrcweir // GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC is set 3028*cdf0e10cSrcweir // and META_RENDERGRAPHIC_ACTION are encountered (KA 01/2011) 3029*cdf0e10cSrcweir for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) ) 3030*cdf0e10cSrcweir { 3031*cdf0e10cSrcweir nActionCount += ( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) ? 2 : 1 ); 3032*cdf0e10cSrcweir } 3033*cdf0e10cSrcweir 3034*cdf0e10cSrcweir rOStm << nStmCompressMode << aPrefMapMode << aPrefSize << nActionCount; 3035*cdf0e10cSrcweir 3036*cdf0e10cSrcweir { 3037*cdf0e10cSrcweir // version 2 3038*cdf0e10cSrcweir // ========= 3039*cdf0e10cSrcweir // since version 2, a GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag 3040*cdf0e10cSrcweir // is written, to indicate that each META_BMPEXSCALE_ACTION following 3041*cdf0e10cSrcweir // a META_RENDERGRAPHIC_ACTION needs to be skipped, in case the flag is 3042*cdf0e10cSrcweir // set (KA 01/2011) 3043*cdf0e10cSrcweir rOStm << bRenderGraphicReplacements; 3044*cdf0e10cSrcweir } 3045*cdf0e10cSrcweir } 3046*cdf0e10cSrcweir 3047*cdf0e10cSrcweir delete pCompat; 3048*cdf0e10cSrcweir 3049*cdf0e10cSrcweir ImplMetaWriteData aWriteData; 3050*cdf0e10cSrcweir 3051*cdf0e10cSrcweir aWriteData.meActualCharSet = rOStm.GetStreamCharSet(); 3052*cdf0e10cSrcweir aWriteData.mnWriteFlags = nWriteFlags; 3053*cdf0e10cSrcweir 3054*cdf0e10cSrcweir for( MetaAction* pAct = static_cast< MetaAction* >( First() ); pAct; pAct = static_cast< MetaAction* >( Next() ) ) 3055*cdf0e10cSrcweir { 3056*cdf0e10cSrcweir pAct->Write( rOStm, &aWriteData ); 3057*cdf0e10cSrcweir 3058*cdf0e10cSrcweir // write the RenderGraphic replacement image, if the 3059*cdf0e10cSrcweir // GDIMETAFILE_WRITE_REPLACEMENT_RENDERGRAPHIC flag is set 3060*cdf0e10cSrcweir // and if a META_RENDERGRAPHIC_ACTION is encountered (KA 01/2011) 3061*cdf0e10cSrcweir if( bRenderGraphicReplacements && ( META_RENDERGRAPHIC_ACTION == pAct->GetType() ) ) 3062*cdf0e10cSrcweir { 3063*cdf0e10cSrcweir MetaRenderGraphicAction* pRenderAction = static_cast< MetaRenderGraphicAction* >( pAct ); 3064*cdf0e10cSrcweir MetaBmpExScaleAction* pBmpExScaleAction = new MetaBmpExScaleAction( 3065*cdf0e10cSrcweir pRenderAction->GetPoint(), pRenderAction->GetSize(), 3066*cdf0e10cSrcweir pRenderAction->GetRenderGraphic().GetReplacement() ); 3067*cdf0e10cSrcweir 3068*cdf0e10cSrcweir pBmpExScaleAction->Write( rOStm, &aWriteData ); 3069*cdf0e10cSrcweir pBmpExScaleAction->Delete(); 3070*cdf0e10cSrcweir } 3071*cdf0e10cSrcweir } 3072*cdf0e10cSrcweir 3073*cdf0e10cSrcweir rOStm.SetNumberFormatInt( nOldFormat ); 3074*cdf0e10cSrcweir 3075*cdf0e10cSrcweir return rOStm; 3076*cdf0e10cSrcweir } 3077*cdf0e10cSrcweir 3078*cdf0e10cSrcweir // ------------------------------------------------------------------------ 3079*cdf0e10cSrcweir 3080*cdf0e10cSrcweir sal_Bool GDIMetaFile::CreateThumbnail( sal_uInt32 nMaximumExtent, 3081*cdf0e10cSrcweir BitmapEx& rBmpEx, 3082*cdf0e10cSrcweir const BitmapEx* pOverlay, 3083*cdf0e10cSrcweir const Rectangle* pOverlayRect ) const 3084*cdf0e10cSrcweir { 3085*cdf0e10cSrcweir // the implementation is provided by KA 3086*cdf0e10cSrcweir 3087*cdf0e10cSrcweir // initialization seems to be complicated but is used to avoid rounding errors 3088*cdf0e10cSrcweir VirtualDevice aVDev; 3089*cdf0e10cSrcweir const Point aNullPt; 3090*cdf0e10cSrcweir const Point aTLPix( aVDev.LogicToPixel( aNullPt, GetPrefMapMode() ) ); 3091*cdf0e10cSrcweir const Point aBRPix( aVDev.LogicToPixel( Point( GetPrefSize().Width() - 1, GetPrefSize().Height() - 1 ), GetPrefMapMode() ) ); 3092*cdf0e10cSrcweir Size aDrawSize( aVDev.LogicToPixel( GetPrefSize(), GetPrefMapMode() ) ); 3093*cdf0e10cSrcweir Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 ); 3094*cdf0e10cSrcweir Point aPosPix; 3095*cdf0e10cSrcweir 3096*cdf0e10cSrcweir if ( !rBmpEx.IsEmpty() ) 3097*cdf0e10cSrcweir rBmpEx.SetEmpty(); 3098*cdf0e10cSrcweir 3099*cdf0e10cSrcweir // determine size that has the same aspect ratio as image size and 3100*cdf0e10cSrcweir // fits into the rectangle determined by nMaximumExtent 3101*cdf0e10cSrcweir if ( aSizePix.Width() && aSizePix.Height() 3102*cdf0e10cSrcweir && ( sal::static_int_cast< unsigned long >(aSizePix.Width()) > 3103*cdf0e10cSrcweir nMaximumExtent || 3104*cdf0e10cSrcweir sal::static_int_cast< unsigned long >(aSizePix.Height()) > 3105*cdf0e10cSrcweir nMaximumExtent ) ) 3106*cdf0e10cSrcweir { 3107*cdf0e10cSrcweir const Size aOldSizePix( aSizePix ); 3108*cdf0e10cSrcweir double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height(); 3109*cdf0e10cSrcweir 3110*cdf0e10cSrcweir if ( fWH <= 1.0 ) 3111*cdf0e10cSrcweir { 3112*cdf0e10cSrcweir aSizePix.Width() = FRound( nMaximumExtent * fWH ); 3113*cdf0e10cSrcweir aSizePix.Height() = nMaximumExtent; 3114*cdf0e10cSrcweir } 3115*cdf0e10cSrcweir else 3116*cdf0e10cSrcweir { 3117*cdf0e10cSrcweir aSizePix.Width() = nMaximumExtent; 3118*cdf0e10cSrcweir aSizePix.Height() = FRound( nMaximumExtent / fWH ); 3119*cdf0e10cSrcweir } 3120*cdf0e10cSrcweir 3121*cdf0e10cSrcweir aDrawSize.Width() = FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() ); 3122*cdf0e10cSrcweir aDrawSize.Height() = FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() ); 3123*cdf0e10cSrcweir } 3124*cdf0e10cSrcweir 3125*cdf0e10cSrcweir Size aFullSize; 3126*cdf0e10cSrcweir Point aBackPosPix; 3127*cdf0e10cSrcweir Rectangle aOverlayRect; 3128*cdf0e10cSrcweir 3129*cdf0e10cSrcweir // calculate addigtional positions and sizes if an overlay image is used 3130*cdf0e10cSrcweir if ( pOverlay ) 3131*cdf0e10cSrcweir { 3132*cdf0e10cSrcweir aFullSize = Size( nMaximumExtent, nMaximumExtent ); 3133*cdf0e10cSrcweir aOverlayRect = Rectangle( aNullPt, aFullSize ); 3134*cdf0e10cSrcweir 3135*cdf0e10cSrcweir aOverlayRect.Intersection( pOverlayRect ? *pOverlayRect : Rectangle( aNullPt, pOverlay->GetSizePixel() ) ); 3136*cdf0e10cSrcweir 3137*cdf0e10cSrcweir if ( !aOverlayRect.IsEmpty() ) 3138*cdf0e10cSrcweir aBackPosPix = Point( ( nMaximumExtent - aSizePix.Width() ) >> 1, ( nMaximumExtent - aSizePix.Height() ) >> 1 ); 3139*cdf0e10cSrcweir else 3140*cdf0e10cSrcweir pOverlay = NULL; 3141*cdf0e10cSrcweir } 3142*cdf0e10cSrcweir else 3143*cdf0e10cSrcweir { 3144*cdf0e10cSrcweir aFullSize = aSizePix; 3145*cdf0e10cSrcweir pOverlay = NULL; 3146*cdf0e10cSrcweir } 3147*cdf0e10cSrcweir 3148*cdf0e10cSrcweir // draw image(s) into VDev and get resulting image 3149*cdf0e10cSrcweir if ( aVDev.SetOutputSizePixel( aFullSize ) ) 3150*cdf0e10cSrcweir { 3151*cdf0e10cSrcweir // draw metafile into VDev 3152*cdf0e10cSrcweir const_cast<GDIMetaFile *>(this)->WindStart(); 3153*cdf0e10cSrcweir const_cast<GDIMetaFile *>(this)->Play( &aVDev, aBackPosPix, aDrawSize ); 3154*cdf0e10cSrcweir 3155*cdf0e10cSrcweir // draw overlay if neccessary 3156*cdf0e10cSrcweir if ( pOverlay ) 3157*cdf0e10cSrcweir aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), *pOverlay ); 3158*cdf0e10cSrcweir 3159*cdf0e10cSrcweir // get paint bitmap 3160*cdf0e10cSrcweir Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) ); 3161*cdf0e10cSrcweir 3162*cdf0e10cSrcweir // assure that we have a true color image 3163*cdf0e10cSrcweir if ( aBmp.GetBitCount() != 24 ) 3164*cdf0e10cSrcweir aBmp.Convert( BMP_CONVERSION_24BIT ); 3165*cdf0e10cSrcweir 3166*cdf0e10cSrcweir // create resulting mask bitmap with metafile output set to black 3167*cdf0e10cSrcweir GDIMetaFile aMonchromeMtf( GetMonochromeMtf( COL_BLACK ) ); 3168*cdf0e10cSrcweir aVDev.DrawWallpaper( Rectangle( aNullPt, aSizePix ), Wallpaper( Color( COL_WHITE ) ) ); 3169*cdf0e10cSrcweir aMonchromeMtf.WindStart(); 3170*cdf0e10cSrcweir aMonchromeMtf.Play( &aVDev, aBackPosPix, aDrawSize ); 3171*cdf0e10cSrcweir 3172*cdf0e10cSrcweir // watch for overlay mask 3173*cdf0e10cSrcweir if ( pOverlay ) 3174*cdf0e10cSrcweir { 3175*cdf0e10cSrcweir Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) ); 3176*cdf0e10cSrcweir 3177*cdf0e10cSrcweir // create ANDed resulting mask at overlay area 3178*cdf0e10cSrcweir if ( pOverlay->IsTransparent() ) 3179*cdf0e10cSrcweir aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), pOverlay->GetMask() ); 3180*cdf0e10cSrcweir else 3181*cdf0e10cSrcweir { 3182*cdf0e10cSrcweir aVDev.SetLineColor( COL_BLACK ); 3183*cdf0e10cSrcweir aVDev.SetFillColor( COL_BLACK ); 3184*cdf0e10cSrcweir aVDev.DrawRect( aOverlayRect); 3185*cdf0e10cSrcweir } 3186*cdf0e10cSrcweir 3187*cdf0e10cSrcweir aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND ); 3188*cdf0e10cSrcweir aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp ); 3189*cdf0e10cSrcweir } 3190*cdf0e10cSrcweir 3191*cdf0e10cSrcweir rBmpEx = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) ); 3192*cdf0e10cSrcweir } 3193*cdf0e10cSrcweir 3194*cdf0e10cSrcweir return !rBmpEx.IsEmpty(); 3195*cdf0e10cSrcweir } 3196