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