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