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, 1479bb18ee55SArmin Le Grand const std::vector<Rectangle>& i_rClipStack, 1480bb18ee55SArmin 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; 1491bb18ee55SArmin Le Grand 1492bb18ee55SArmin Le Grand if(o_pHairline) 1493bb18ee55SArmin Le Grand { 1494bb18ee55SArmin Le Grand if( ! o_pHairline->IsEmpty() ) 1495bb18ee55SArmin Le Grand o_pHairline->Union( aBounds ); 1496bb18ee55SArmin Le Grand else 1497bb18ee55SArmin Le Grand *o_pHairline = aBounds; 1498bb18ee55SArmin Le Grand } 1499cdf0e10cSrcweir } 1500cdf0e10cSrcweir } 1501cdf0e10cSrcweir 1502bb18ee55SArmin 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 1515bb18ee55SArmin Le Grand if(pHairline) 1516cdf0e10cSrcweir { 1517bb18ee55SArmin Le Grand *pHairline = Rectangle(); 1518bb18ee55SArmin Le Grand } 1519bb18ee55SArmin Le Grand 1520*fdbfc3c2SPavel Janík const sal_uLong nActionCount(GetActionCount()); 1521bb18ee55SArmin Le Grand 1522*fdbfc3c2SPavel Janík for(sal_uLong a(0); a < nActionCount; a++) 1523bb18ee55SArmin Le Grand { 1524bb18ee55SArmin Le Grand MetaAction* pAction = GetAction(a); 1525cdf0e10cSrcweir const sal_uInt16 nActionType = pAction->GetType(); 1526bb18ee55SArmin 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() ) ), 1536bb18ee55SArmin 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() ) ), 1546bb18ee55SArmin 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(); 1556bb18ee55SArmin Le Grand 1557bb18ee55SArmin Le Grand if(pUseHairline) 1558bb18ee55SArmin Le Grand { 1559bb18ee55SArmin Le Grand const LineInfo& rLineInfo = pAct->GetLineInfo(); 1560bb18ee55SArmin Le Grand 1561bb18ee55SArmin Le Grand if(0 != rLineInfo.GetWidth()) 1562bb18ee55SArmin Le Grand { 1563bb18ee55SArmin Le Grand pUseHairline = 0; 1564bb18ee55SArmin Le Grand } 1565bb18ee55SArmin Le Grand } 1566bb18ee55SArmin Le Grand 1567bb18ee55SArmin 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; 1574bb18ee55SArmin 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; 1581bb18ee55SArmin 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; 1588bb18ee55SArmin 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 1597bb18ee55SArmin 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 1606bb18ee55SArmin 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 1615bb18ee55SArmin 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() ); 1623bb18ee55SArmin Le Grand 1624bb18ee55SArmin Le Grand if(pUseHairline) 1625bb18ee55SArmin Le Grand { 1626bb18ee55SArmin Le Grand const LineInfo& rLineInfo = pAct->GetLineInfo(); 1627bb18ee55SArmin Le Grand 1628bb18ee55SArmin Le Grand if(0 != rLineInfo.GetWidth()) 1629bb18ee55SArmin Le Grand { 1630bb18ee55SArmin Le Grand pUseHairline = 0; 1631bb18ee55SArmin Le Grand } 1632bb18ee55SArmin Le Grand } 1633bb18ee55SArmin Le Grand 1634bb18ee55SArmin 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() ); 1642bb18ee55SArmin 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() ); 1650bb18ee55SArmin 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() ); 1662bb18ee55SArmin 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() ); 1675bb18ee55SArmin 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() ); 1688bb18ee55SArmin 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(); 1704bb18ee55SArmin 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() ); 1712bb18ee55SArmin 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() ); 1720bb18ee55SArmin 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() ); 1728bb18ee55SArmin 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() ); 1736bb18ee55SArmin 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() ); 1744bb18ee55SArmin 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() ); 1752bb18ee55SArmin 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() ); 1766bb18ee55SArmin 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() ); 1774bb18ee55SArmin 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; 17816904e6c1SArmin Le Grand // MetaFloatTransparentAction is defined limiting it's content Metafile 17826904e6c1SArmin Le Grand // to it's geometry definition(Point, Size), so use these directly 17836904e6c1SArmin Le Grand const Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); 17846904e6c1SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1785cdf0e10cSrcweir } 1786cdf0e10cSrcweir break; 1787cdf0e10cSrcweir 1788cdf0e10cSrcweir case( META_EPS_ACTION ): 1789cdf0e10cSrcweir { 1790cdf0e10cSrcweir MetaEPSAction* pAct = (MetaEPSAction*) pAction; 1791cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), pAct->GetSize() ); 1792bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1793cdf0e10cSrcweir } 1794cdf0e10cSrcweir break; 1795cdf0e10cSrcweir 1796cdf0e10cSrcweir case( META_CLIPREGION_ACTION ): 1797cdf0e10cSrcweir { 1798cdf0e10cSrcweir MetaClipRegionAction* pAct = (MetaClipRegionAction*) pAction; 1799cdf0e10cSrcweir if( pAct->IsClipping() ) 1800cdf0e10cSrcweir aClipStack.back() = aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ); 1801cdf0e10cSrcweir else 1802cdf0e10cSrcweir aClipStack.back() = Rectangle(); 1803cdf0e10cSrcweir } 1804cdf0e10cSrcweir break; 1805cdf0e10cSrcweir 1806cdf0e10cSrcweir case( META_ISECTRECTCLIPREGION_ACTION ): 1807cdf0e10cSrcweir { 1808cdf0e10cSrcweir MetaISectRectClipRegionAction* pAct = (MetaISectRectClipRegionAction*) pAction; 1809cdf0e10cSrcweir Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); 1810cdf0e10cSrcweir if( aClipStack.back().IsEmpty() ) 1811cdf0e10cSrcweir aClipStack.back() = aRect; 1812cdf0e10cSrcweir else 1813cdf0e10cSrcweir aClipStack.back().Intersection( aRect ); 1814cdf0e10cSrcweir } 1815cdf0e10cSrcweir break; 1816cdf0e10cSrcweir 1817cdf0e10cSrcweir case( META_ISECTREGIONCLIPREGION_ACTION ): 1818cdf0e10cSrcweir { 1819cdf0e10cSrcweir MetaISectRegionClipRegionAction* pAct = (MetaISectRegionClipRegionAction*) pAction; 1820cdf0e10cSrcweir Rectangle aRect( aMapVDev.LogicToLogic( pAct->GetRegion().GetBoundRect(), aMapVDev.GetMapMode(), GetPrefMapMode() ) ); 1821cdf0e10cSrcweir if( aClipStack.back().IsEmpty() ) 1822cdf0e10cSrcweir aClipStack.back() = aRect; 1823cdf0e10cSrcweir else 1824cdf0e10cSrcweir aClipStack.back().Intersection( aRect ); 1825cdf0e10cSrcweir } 1826cdf0e10cSrcweir break; 1827cdf0e10cSrcweir 1828cdf0e10cSrcweir case( META_BMP_ACTION ): 1829cdf0e10cSrcweir { 1830cdf0e10cSrcweir MetaBmpAction* pAct = (MetaBmpAction*) pAction; 1831cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); 1832bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1833cdf0e10cSrcweir } 1834cdf0e10cSrcweir break; 1835cdf0e10cSrcweir 1836cdf0e10cSrcweir case( META_BMPEX_ACTION ): 1837cdf0e10cSrcweir { 1838cdf0e10cSrcweir MetaBmpExAction* pAct = (MetaBmpExAction*) pAction; 1839cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmapEx().GetSizePixel() ) ); 1840bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1841cdf0e10cSrcweir } 1842cdf0e10cSrcweir break; 1843cdf0e10cSrcweir 1844cdf0e10cSrcweir case( META_MASK_ACTION ): 1845cdf0e10cSrcweir { 1846cdf0e10cSrcweir MetaMaskAction* pAct = (MetaMaskAction*) pAction; 1847cdf0e10cSrcweir Rectangle aRect( pAct->GetPoint(), aMapVDev.PixelToLogic( pAct->GetBitmap().GetSizePixel() ) ); 1848bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1849cdf0e10cSrcweir } 1850cdf0e10cSrcweir break; 1851cdf0e10cSrcweir 1852cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): 1853cdf0e10cSrcweir { 1854cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 1855cdf0e10cSrcweir Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); 1856bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1857cdf0e10cSrcweir } 1858cdf0e10cSrcweir break; 1859cdf0e10cSrcweir 1860cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): 1861cdf0e10cSrcweir { 1862cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 1863cdf0e10cSrcweir Rectangle aRect( pAct->GetDestPoint(), pAct->GetDestSize() ); 1864bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1865cdf0e10cSrcweir } 1866cdf0e10cSrcweir break; 1867cdf0e10cSrcweir 1868cdf0e10cSrcweir case( META_WALLPAPER_ACTION ): 1869cdf0e10cSrcweir { 1870cdf0e10cSrcweir MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction; 1871cdf0e10cSrcweir Rectangle aRect( pAct->GetRect() ); 1872bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1873cdf0e10cSrcweir } 1874cdf0e10cSrcweir break; 1875cdf0e10cSrcweir 1876cdf0e10cSrcweir case( META_TEXTRECT_ACTION ): 1877cdf0e10cSrcweir { 1878cdf0e10cSrcweir MetaTextRectAction* pAct = (MetaTextRectAction*) pAction; 1879cdf0e10cSrcweir Rectangle aRect( pAct->GetRect() ); 1880bb18ee55SArmin Le Grand ImplActionBounds( aBound, aMapVDev.LogicToLogic( aRect, aMapVDev.GetMapMode(), GetPrefMapMode() ), aClipStack, 0 ); 1881cdf0e10cSrcweir } 1882cdf0e10cSrcweir break; 1883cdf0e10cSrcweir 1884cdf0e10cSrcweir case( META_MOVECLIPREGION_ACTION ): 1885cdf0e10cSrcweir { 1886cdf0e10cSrcweir MetaMoveClipRegionAction* pAct = (MetaMoveClipRegionAction*) pAction; 1887cdf0e10cSrcweir if( ! aClipStack.back().IsEmpty() ) 1888cdf0e10cSrcweir { 1889cdf0e10cSrcweir Size aDelta( pAct->GetHorzMove(), pAct->GetVertMove() ); 1890cdf0e10cSrcweir aDelta = aMapVDev.LogicToLogic( aDelta, aMapVDev.GetMapMode(), GetPrefMapMode() ); 1891cdf0e10cSrcweir aClipStack.back().Move( aDelta.Width(), aDelta.Width() ); 1892cdf0e10cSrcweir } 1893cdf0e10cSrcweir } 1894cdf0e10cSrcweir break; 1895cdf0e10cSrcweir 1896cdf0e10cSrcweir default: 1897cdf0e10cSrcweir { 1898cdf0e10cSrcweir pAction->Execute( &aMapVDev ); 1899cdf0e10cSrcweir 1900cdf0e10cSrcweir if( nActionType == META_PUSH_ACTION ) 1901cdf0e10cSrcweir { 1902cdf0e10cSrcweir MetaPushAction* pAct = (MetaPushAction*) pAction; 1903cdf0e10cSrcweir aPushFlagStack.push_back( pAct->GetFlags() ); 1904cdf0e10cSrcweir if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 ) 1905cdf0e10cSrcweir { 1906cdf0e10cSrcweir Rectangle aRect( aClipStack.back() ); 1907cdf0e10cSrcweir aClipStack.push_back( aRect ); 1908cdf0e10cSrcweir } 1909cdf0e10cSrcweir } 1910cdf0e10cSrcweir else if( nActionType == META_POP_ACTION ) 1911cdf0e10cSrcweir { 1912cdf0e10cSrcweir // sanity check 1913cdf0e10cSrcweir if( ! aPushFlagStack.empty() ) 1914cdf0e10cSrcweir { 1915cdf0e10cSrcweir if( (aPushFlagStack.back() & PUSH_CLIPREGION) != 0 ) 1916cdf0e10cSrcweir { 1917cdf0e10cSrcweir if( aClipStack.size() > 1 ) 1918cdf0e10cSrcweir aClipStack.pop_back(); 1919cdf0e10cSrcweir } 1920cdf0e10cSrcweir aPushFlagStack.pop_back(); 1921cdf0e10cSrcweir } 1922cdf0e10cSrcweir } 1923cdf0e10cSrcweir } 1924cdf0e10cSrcweir break; 1925cdf0e10cSrcweir } 1926cdf0e10cSrcweir } 1927cdf0e10cSrcweir return aBound; 1928cdf0e10cSrcweir } 1929cdf0e10cSrcweir 1930cdf0e10cSrcweir // ------------------------------------------------------------------------ 1931cdf0e10cSrcweir 1932cdf0e10cSrcweir Color GDIMetaFile::ImplColAdjustFnc( const Color& rColor, const void* pColParam ) 1933cdf0e10cSrcweir { 1934cdf0e10cSrcweir return Color( rColor.GetTransparency(), 1935cdf0e10cSrcweir ( (const ImplColAdjustParam*) pColParam )->pMapR[ rColor.GetRed() ], 1936cdf0e10cSrcweir ( (const ImplColAdjustParam*) pColParam )->pMapG[ rColor.GetGreen() ], 1937cdf0e10cSrcweir ( (const ImplColAdjustParam*) pColParam )->pMapB[ rColor.GetBlue() ] ); 1938cdf0e10cSrcweir 1939cdf0e10cSrcweir } 1940cdf0e10cSrcweir 1941cdf0e10cSrcweir // ------------------------------------------------------------------------ 1942cdf0e10cSrcweir 1943cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpAdjustFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 1944cdf0e10cSrcweir { 1945cdf0e10cSrcweir const ImplBmpAdjustParam* p = (const ImplBmpAdjustParam*) pBmpParam; 1946cdf0e10cSrcweir BitmapEx aRet( rBmpEx ); 1947cdf0e10cSrcweir 1948cdf0e10cSrcweir aRet.Adjust( p->nLuminancePercent, p->nContrastPercent, 1949cdf0e10cSrcweir p->nChannelRPercent, p->nChannelGPercent, p->nChannelBPercent, 1950cdf0e10cSrcweir p->fGamma, p->bInvert ); 1951cdf0e10cSrcweir 1952cdf0e10cSrcweir return aRet; 1953cdf0e10cSrcweir } 1954cdf0e10cSrcweir 1955cdf0e10cSrcweir // ------------------------------------------------------------------------ 1956cdf0e10cSrcweir 1957cdf0e10cSrcweir Color GDIMetaFile::ImplColConvertFnc( const Color& rColor, const void* pColParam ) 1958cdf0e10cSrcweir { 1959cdf0e10cSrcweir sal_uInt8 cLum = rColor.GetLuminance(); 1960cdf0e10cSrcweir 1961cdf0e10cSrcweir if( MTF_CONVERSION_1BIT_THRESHOLD == ( (const ImplColConvertParam*) pColParam )->eConversion ) 1962cdf0e10cSrcweir cLum = ( cLum < 128 ) ? 0 : 255; 1963cdf0e10cSrcweir 1964cdf0e10cSrcweir return Color( rColor.GetTransparency(), cLum, cLum, cLum ); 1965cdf0e10cSrcweir } 1966cdf0e10cSrcweir 1967cdf0e10cSrcweir // ------------------------------------------------------------------------ 1968cdf0e10cSrcweir 1969cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpConvertFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 1970cdf0e10cSrcweir { 1971cdf0e10cSrcweir BitmapEx aRet( rBmpEx ); 1972cdf0e10cSrcweir 1973cdf0e10cSrcweir aRet.Convert( ( (const ImplBmpConvertParam*) pBmpParam )->eConversion ); 1974cdf0e10cSrcweir 1975cdf0e10cSrcweir return aRet; 1976cdf0e10cSrcweir } 1977cdf0e10cSrcweir 1978cdf0e10cSrcweir // ------------------------------------------------------------------------ 1979cdf0e10cSrcweir 1980cdf0e10cSrcweir Color GDIMetaFile::ImplColMonoFnc( const Color&, const void* pColParam ) 1981cdf0e10cSrcweir { 1982cdf0e10cSrcweir return( ( (const ImplColMonoParam*) pColParam )->aColor ); 1983cdf0e10cSrcweir } 1984cdf0e10cSrcweir 1985cdf0e10cSrcweir // ------------------------------------------------------------------------ 1986cdf0e10cSrcweir 1987cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpMonoFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 1988cdf0e10cSrcweir { 1989cdf0e10cSrcweir BitmapPalette aPal( 3 ); 1990cdf0e10cSrcweir 1991cdf0e10cSrcweir aPal[ 0 ] = Color( COL_BLACK ); 1992cdf0e10cSrcweir aPal[ 1 ] = Color( COL_WHITE ); 1993cdf0e10cSrcweir aPal[ 2 ] = ( (const ImplBmpMonoParam*) pBmpParam )->aColor; 1994cdf0e10cSrcweir 1995cdf0e10cSrcweir Bitmap aBmp( rBmpEx.GetSizePixel(), 4, &aPal ); 1996cdf0e10cSrcweir aBmp.Erase( ( (const ImplBmpMonoParam*) pBmpParam )->aColor ); 1997cdf0e10cSrcweir 1998cdf0e10cSrcweir if( rBmpEx.IsAlpha() ) 1999cdf0e10cSrcweir return BitmapEx( aBmp, rBmpEx.GetAlpha() ); 2000cdf0e10cSrcweir else if( rBmpEx.IsTransparent() ) 2001cdf0e10cSrcweir return BitmapEx( aBmp, rBmpEx.GetMask() ); 2002cdf0e10cSrcweir else 2003cdf0e10cSrcweir return aBmp; 2004cdf0e10cSrcweir } 2005cdf0e10cSrcweir 2006cdf0e10cSrcweir // ------------------------------------------------------------------------ 2007cdf0e10cSrcweir 2008cdf0e10cSrcweir Color GDIMetaFile::ImplColReplaceFnc( const Color& rColor, const void* pColParam ) 2009cdf0e10cSrcweir { 2010cdf0e10cSrcweir const sal_uLong nR = rColor.GetRed(), nG = rColor.GetGreen(), nB = rColor.GetBlue(); 2011cdf0e10cSrcweir 2012cdf0e10cSrcweir for( sal_uLong i = 0; i < ( (const ImplColReplaceParam*) pColParam )->nCount; i++ ) 2013cdf0e10cSrcweir { 2014cdf0e10cSrcweir if( ( ( (const ImplColReplaceParam*) pColParam )->pMinR[ i ] <= nR ) && 2015cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMaxR[ i ] >= nR ) && 2016cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMinG[ i ] <= nG ) && 2017cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMaxG[ i ] >= nG ) && 2018cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMinB[ i ] <= nB ) && 2019cdf0e10cSrcweir ( ( (const ImplColReplaceParam*) pColParam )->pMaxB[ i ] >= nB ) ) 2020cdf0e10cSrcweir { 2021cdf0e10cSrcweir return( ( (const ImplColReplaceParam*) pColParam )->pDstCols[ i ] ); 2022cdf0e10cSrcweir } 2023cdf0e10cSrcweir } 2024cdf0e10cSrcweir 2025cdf0e10cSrcweir return rColor; 2026cdf0e10cSrcweir } 2027cdf0e10cSrcweir 2028cdf0e10cSrcweir // ------------------------------------------------------------------------ 2029cdf0e10cSrcweir 2030cdf0e10cSrcweir BitmapEx GDIMetaFile::ImplBmpReplaceFnc( const BitmapEx& rBmpEx, const void* pBmpParam ) 2031cdf0e10cSrcweir { 2032cdf0e10cSrcweir const ImplBmpReplaceParam* p = (const ImplBmpReplaceParam*) pBmpParam; 2033cdf0e10cSrcweir BitmapEx aRet( rBmpEx ); 2034cdf0e10cSrcweir 2035cdf0e10cSrcweir aRet.Replace( p->pSrcCols, p->pDstCols, p->nCount, p->pTols ); 2036cdf0e10cSrcweir 2037cdf0e10cSrcweir return aRet; 2038cdf0e10cSrcweir } 2039cdf0e10cSrcweir 2040cdf0e10cSrcweir // ------------------------------------------------------------------------ 2041cdf0e10cSrcweir 2042cdf0e10cSrcweir void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol, const void* pColParam, 2043cdf0e10cSrcweir BmpExchangeFnc pFncBmp, const void* pBmpParam ) 2044cdf0e10cSrcweir { 2045cdf0e10cSrcweir GDIMetaFile aMtf; 2046cdf0e10cSrcweir 2047cdf0e10cSrcweir aMtf.aPrefSize = aPrefSize; 2048cdf0e10cSrcweir aMtf.aPrefMapMode = aPrefMapMode; 2049cdf0e10cSrcweir 2050cdf0e10cSrcweir for( MetaAction* pAction = (MetaAction*) First(); pAction; pAction = (MetaAction*) Next() ) 2051cdf0e10cSrcweir { 2052cdf0e10cSrcweir const sal_uInt16 nType = pAction->GetType(); 2053cdf0e10cSrcweir 2054cdf0e10cSrcweir switch( nType ) 2055cdf0e10cSrcweir { 2056cdf0e10cSrcweir case( META_PIXEL_ACTION ): 2057cdf0e10cSrcweir { 2058cdf0e10cSrcweir MetaPixelAction* pAct = (MetaPixelAction*) pAction; 2059cdf0e10cSrcweir aMtf.Insert( new MetaPixelAction( pAct->GetPoint(), pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND ); 2060cdf0e10cSrcweir } 2061cdf0e10cSrcweir break; 2062cdf0e10cSrcweir 2063cdf0e10cSrcweir case( META_LINECOLOR_ACTION ): 2064cdf0e10cSrcweir { 2065cdf0e10cSrcweir MetaLineColorAction* pAct = (MetaLineColorAction*) pAction; 2066cdf0e10cSrcweir 2067cdf0e10cSrcweir if( !pAct->IsSetting() ) 2068cdf0e10cSrcweir pAct->Duplicate(); 2069cdf0e10cSrcweir else 2070cdf0e10cSrcweir pAct = new MetaLineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2071cdf0e10cSrcweir 2072cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2073cdf0e10cSrcweir } 2074cdf0e10cSrcweir break; 2075cdf0e10cSrcweir 2076cdf0e10cSrcweir case( META_FILLCOLOR_ACTION ): 2077cdf0e10cSrcweir { 2078cdf0e10cSrcweir MetaFillColorAction* pAct = (MetaFillColorAction*) pAction; 2079cdf0e10cSrcweir 2080cdf0e10cSrcweir if( !pAct->IsSetting() ) 2081cdf0e10cSrcweir pAct->Duplicate(); 2082cdf0e10cSrcweir else 2083cdf0e10cSrcweir pAct = new MetaFillColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2084cdf0e10cSrcweir 2085cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2086cdf0e10cSrcweir } 2087cdf0e10cSrcweir break; 2088cdf0e10cSrcweir 2089cdf0e10cSrcweir case( META_TEXTCOLOR_ACTION ): 2090cdf0e10cSrcweir { 2091cdf0e10cSrcweir MetaTextColorAction* pAct = (MetaTextColorAction*) pAction; 2092cdf0e10cSrcweir aMtf.Insert( new MetaTextColorAction( pFncCol( pAct->GetColor(), pColParam ) ), LIST_APPEND ); 2093cdf0e10cSrcweir } 2094cdf0e10cSrcweir break; 2095cdf0e10cSrcweir 2096cdf0e10cSrcweir case( META_TEXTFILLCOLOR_ACTION ): 2097cdf0e10cSrcweir { 2098cdf0e10cSrcweir MetaTextFillColorAction* pAct = (MetaTextFillColorAction*) pAction; 2099cdf0e10cSrcweir 2100cdf0e10cSrcweir if( !pAct->IsSetting() ) 2101cdf0e10cSrcweir pAct->Duplicate(); 2102cdf0e10cSrcweir else 2103cdf0e10cSrcweir pAct = new MetaTextFillColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2104cdf0e10cSrcweir 2105cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2106cdf0e10cSrcweir } 2107cdf0e10cSrcweir break; 2108cdf0e10cSrcweir 2109cdf0e10cSrcweir case( META_TEXTLINECOLOR_ACTION ): 2110cdf0e10cSrcweir { 2111cdf0e10cSrcweir MetaTextLineColorAction* pAct = (MetaTextLineColorAction*) pAction; 2112cdf0e10cSrcweir 2113cdf0e10cSrcweir if( !pAct->IsSetting() ) 2114cdf0e10cSrcweir pAct->Duplicate(); 2115cdf0e10cSrcweir else 2116cdf0e10cSrcweir pAct = new MetaTextLineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2117cdf0e10cSrcweir 2118cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2119cdf0e10cSrcweir } 2120cdf0e10cSrcweir break; 2121cdf0e10cSrcweir 2122cdf0e10cSrcweir case( META_OVERLINECOLOR_ACTION ): 2123cdf0e10cSrcweir { 2124cdf0e10cSrcweir MetaOverlineColorAction* pAct = (MetaOverlineColorAction*) pAction; 2125cdf0e10cSrcweir 2126cdf0e10cSrcweir if( !pAct->IsSetting() ) 2127cdf0e10cSrcweir pAct->Duplicate(); 2128cdf0e10cSrcweir else 2129cdf0e10cSrcweir pAct = new MetaOverlineColorAction( pFncCol( pAct->GetColor(), pColParam ), sal_True ); 2130cdf0e10cSrcweir 2131cdf0e10cSrcweir aMtf.Insert( pAct, LIST_APPEND ); 2132cdf0e10cSrcweir } 2133cdf0e10cSrcweir break; 2134cdf0e10cSrcweir 2135cdf0e10cSrcweir case( META_FONT_ACTION ): 2136cdf0e10cSrcweir { 2137cdf0e10cSrcweir MetaFontAction* pAct = (MetaFontAction*) pAction; 2138cdf0e10cSrcweir Font aFont( pAct->GetFont() ); 2139cdf0e10cSrcweir 2140cdf0e10cSrcweir aFont.SetColor( pFncCol( aFont.GetColor(), pColParam ) ); 2141cdf0e10cSrcweir aFont.SetFillColor( pFncCol( aFont.GetFillColor(), pColParam ) ); 2142cdf0e10cSrcweir aMtf.Insert( new MetaFontAction( aFont ), LIST_APPEND ); 2143cdf0e10cSrcweir } 2144cdf0e10cSrcweir break; 2145cdf0e10cSrcweir 2146cdf0e10cSrcweir case( META_WALLPAPER_ACTION ): 2147cdf0e10cSrcweir { 2148cdf0e10cSrcweir MetaWallpaperAction* pAct = (MetaWallpaperAction*) pAction; 2149cdf0e10cSrcweir Wallpaper aWall( pAct->GetWallpaper() ); 2150cdf0e10cSrcweir const Rectangle& rRect = pAct->GetRect(); 2151cdf0e10cSrcweir 2152cdf0e10cSrcweir aWall.SetColor( pFncCol( aWall.GetColor(), pColParam ) ); 2153cdf0e10cSrcweir 2154cdf0e10cSrcweir if( aWall.IsBitmap() ) 2155cdf0e10cSrcweir aWall.SetBitmap( pFncBmp( aWall.GetBitmap(), pBmpParam ) ); 2156cdf0e10cSrcweir 2157cdf0e10cSrcweir if( aWall.IsGradient() ) 2158cdf0e10cSrcweir { 2159cdf0e10cSrcweir Gradient aGradient( aWall.GetGradient() ); 2160cdf0e10cSrcweir 2161cdf0e10cSrcweir aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) ); 2162cdf0e10cSrcweir aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) ); 2163cdf0e10cSrcweir aWall.SetGradient( aGradient ); 2164cdf0e10cSrcweir } 2165cdf0e10cSrcweir 2166cdf0e10cSrcweir aMtf.Insert( new MetaWallpaperAction( rRect, aWall ), LIST_APPEND ); 2167cdf0e10cSrcweir } 2168cdf0e10cSrcweir break; 2169cdf0e10cSrcweir 2170cdf0e10cSrcweir case( META_BMP_ACTION ): 2171cdf0e10cSrcweir case( META_BMPEX_ACTION ): 2172cdf0e10cSrcweir case( META_MASK_ACTION ): 2173cdf0e10cSrcweir { 2174cdf0e10cSrcweir DBG_ERROR( "Don't use bitmap actions of this type in metafiles!" ); 2175cdf0e10cSrcweir } 2176cdf0e10cSrcweir break; 2177cdf0e10cSrcweir 2178cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): 2179cdf0e10cSrcweir { 2180cdf0e10cSrcweir MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; 2181cdf0e10cSrcweir aMtf.Insert( new MetaBmpScaleAction( pAct->GetPoint(), pAct->GetSize(), 2182cdf0e10cSrcweir pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ), 2183cdf0e10cSrcweir LIST_APPEND ); 2184cdf0e10cSrcweir } 2185cdf0e10cSrcweir break; 2186cdf0e10cSrcweir 2187cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): 2188cdf0e10cSrcweir { 2189cdf0e10cSrcweir MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; 2190cdf0e10cSrcweir aMtf.Insert( new MetaBmpScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), 2191cdf0e10cSrcweir pAct->GetSrcPoint(), pAct->GetSrcSize(), 2192cdf0e10cSrcweir pFncBmp( pAct->GetBitmap(), pBmpParam ).GetBitmap() ), 2193cdf0e10cSrcweir LIST_APPEND ); 2194cdf0e10cSrcweir } 2195cdf0e10cSrcweir break; 2196cdf0e10cSrcweir 2197cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): 2198cdf0e10cSrcweir { 2199cdf0e10cSrcweir MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; 2200cdf0e10cSrcweir aMtf.Insert( new MetaBmpExScaleAction( pAct->GetPoint(), pAct->GetSize(), 2201cdf0e10cSrcweir pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ), 2202cdf0e10cSrcweir LIST_APPEND ); 2203cdf0e10cSrcweir } 2204cdf0e10cSrcweir break; 2205cdf0e10cSrcweir 2206cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): 2207cdf0e10cSrcweir { 2208cdf0e10cSrcweir MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; 2209cdf0e10cSrcweir aMtf.Insert( new MetaBmpExScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), 2210cdf0e10cSrcweir pAct->GetSrcPoint(), pAct->GetSrcSize(), 2211cdf0e10cSrcweir pFncBmp( pAct->GetBitmapEx(), pBmpParam ) ), 2212cdf0e10cSrcweir LIST_APPEND ); 2213cdf0e10cSrcweir } 2214cdf0e10cSrcweir break; 2215cdf0e10cSrcweir 2216cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): 2217cdf0e10cSrcweir { 2218cdf0e10cSrcweir MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction; 2219cdf0e10cSrcweir aMtf.Insert( new MetaMaskScaleAction( pAct->GetPoint(), pAct->GetSize(), 2220cdf0e10cSrcweir pAct->GetBitmap(), 2221cdf0e10cSrcweir pFncCol( pAct->GetColor(), pColParam ) ), 2222cdf0e10cSrcweir LIST_APPEND ); 2223cdf0e10cSrcweir } 2224cdf0e10cSrcweir break; 2225cdf0e10cSrcweir 2226cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): 2227cdf0e10cSrcweir { 2228cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 2229cdf0e10cSrcweir aMtf.Insert( new MetaMaskScalePartAction( pAct->GetDestPoint(), pAct->GetDestSize(), 2230cdf0e10cSrcweir pAct->GetSrcPoint(), pAct->GetSrcSize(), 2231cdf0e10cSrcweir pAct->GetBitmap(), 2232cdf0e10cSrcweir pFncCol( pAct->GetColor(), pColParam ) ), 2233cdf0e10cSrcweir LIST_APPEND ); 2234cdf0e10cSrcweir } 2235cdf0e10cSrcweir break; 2236cdf0e10cSrcweir 2237cdf0e10cSrcweir case( META_GRADIENT_ACTION ): 2238cdf0e10cSrcweir { 2239cdf0e10cSrcweir MetaGradientAction* pAct = (MetaGradientAction*) pAction; 2240cdf0e10cSrcweir Gradient aGradient( pAct->GetGradient() ); 2241cdf0e10cSrcweir 2242cdf0e10cSrcweir aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) ); 2243cdf0e10cSrcweir aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) ); 2244cdf0e10cSrcweir aMtf.Insert( new MetaGradientAction( pAct->GetRect(), aGradient ), LIST_APPEND ); 2245cdf0e10cSrcweir } 2246cdf0e10cSrcweir break; 2247cdf0e10cSrcweir 2248cdf0e10cSrcweir case( META_GRADIENTEX_ACTION ): 2249cdf0e10cSrcweir { 2250cdf0e10cSrcweir MetaGradientExAction* pAct = (MetaGradientExAction*) pAction; 2251cdf0e10cSrcweir Gradient aGradient( pAct->GetGradient() ); 2252cdf0e10cSrcweir 2253cdf0e10cSrcweir aGradient.SetStartColor( pFncCol( aGradient.GetStartColor(), pColParam ) ); 2254cdf0e10cSrcweir aGradient.SetEndColor( pFncCol( aGradient.GetEndColor(), pColParam ) ); 2255cdf0e10cSrcweir aMtf.Insert( new MetaGradientExAction( pAct->GetPolyPolygon(), aGradient ), LIST_APPEND ); 2256cdf0e10cSrcweir } 2257cdf0e10cSrcweir break; 2258cdf0e10cSrcweir 2259cdf0e10cSrcweir case( META_HATCH_ACTION ): 2260cdf0e10cSrcweir { 2261cdf0e10cSrcweir MetaHatchAction* pAct = (MetaHatchAction*) pAction; 2262cdf0e10cSrcweir Hatch aHatch( pAct->GetHatch() ); 2263cdf0e10cSrcweir 2264cdf0e10cSrcweir aHatch.SetColor( pFncCol( aHatch.GetColor(), pColParam ) ); 2265cdf0e10cSrcweir aMtf.Insert( new MetaHatchAction( pAct->GetPolyPolygon(), aHatch ), LIST_APPEND ); 2266cdf0e10cSrcweir } 2267cdf0e10cSrcweir break; 2268cdf0e10cSrcweir 2269cdf0e10cSrcweir case( META_FLOATTRANSPARENT_ACTION ): 2270cdf0e10cSrcweir { 2271cdf0e10cSrcweir MetaFloatTransparentAction* pAct = (MetaFloatTransparentAction*) pAction; 2272cdf0e10cSrcweir GDIMetaFile aTransMtf( pAct->GetGDIMetaFile() ); 2273cdf0e10cSrcweir 2274cdf0e10cSrcweir aTransMtf.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam ); 2275cdf0e10cSrcweir aMtf.Insert( new MetaFloatTransparentAction( aTransMtf, 2276cdf0e10cSrcweir pAct->GetPoint(), pAct->GetSize(), 2277cdf0e10cSrcweir pAct->GetGradient() ), 2278cdf0e10cSrcweir LIST_APPEND ); 2279cdf0e10cSrcweir } 2280cdf0e10cSrcweir break; 2281cdf0e10cSrcweir 2282cdf0e10cSrcweir case( META_EPS_ACTION ): 2283cdf0e10cSrcweir { 2284cdf0e10cSrcweir MetaEPSAction* pAct = (MetaEPSAction*) pAction; 2285cdf0e10cSrcweir GDIMetaFile aSubst( pAct->GetSubstitute() ); 2286cdf0e10cSrcweir 2287cdf0e10cSrcweir aSubst.ImplExchangeColors( pFncCol, pColParam, pFncBmp, pBmpParam ); 2288cdf0e10cSrcweir aMtf.Insert( new MetaEPSAction( pAct->GetPoint(), pAct->GetSize(), 2289cdf0e10cSrcweir pAct->GetLink(), aSubst ), 2290cdf0e10cSrcweir LIST_APPEND ); 2291cdf0e10cSrcweir } 2292cdf0e10cSrcweir break; 2293cdf0e10cSrcweir 2294cdf0e10cSrcweir default: 2295cdf0e10cSrcweir { 2296cdf0e10cSrcweir pAction->Duplicate(); 2297cdf0e10cSrcweir aMtf.Insert( pAction, LIST_APPEND ); 2298cdf0e10cSrcweir } 2299cdf0e10cSrcweir break; 2300cdf0e10cSrcweir } 2301cdf0e10cSrcweir } 2302cdf0e10cSrcweir 2303cdf0e10cSrcweir *this = aMtf; 2304cdf0e10cSrcweir } 2305cdf0e10cSrcweir 2306cdf0e10cSrcweir // ------------------------------------------------------------------------ 2307cdf0e10cSrcweir 2308cdf0e10cSrcweir void GDIMetaFile::Adjust( short nLuminancePercent, short nContrastPercent, 2309cdf0e10cSrcweir short nChannelRPercent, short nChannelGPercent, 2310cdf0e10cSrcweir short nChannelBPercent, double fGamma, sal_Bool bInvert ) 2311cdf0e10cSrcweir { 2312cdf0e10cSrcweir // nothing to do? => return quickly 2313cdf0e10cSrcweir if( nLuminancePercent || nContrastPercent || 2314cdf0e10cSrcweir nChannelRPercent || nChannelGPercent || nChannelBPercent || 2315cdf0e10cSrcweir ( fGamma != 1.0 ) || bInvert ) 2316cdf0e10cSrcweir { 2317cdf0e10cSrcweir double fM, fROff, fGOff, fBOff, fOff; 2318cdf0e10cSrcweir ImplColAdjustParam aColParam; 2319cdf0e10cSrcweir ImplBmpAdjustParam aBmpParam; 2320cdf0e10cSrcweir 2321cdf0e10cSrcweir aColParam.pMapR = new sal_uInt8[ 256 ]; 2322cdf0e10cSrcweir aColParam.pMapG = new sal_uInt8[ 256 ]; 2323cdf0e10cSrcweir aColParam.pMapB = new sal_uInt8[ 256 ]; 2324cdf0e10cSrcweir 2325cdf0e10cSrcweir // calculate slope 2326cdf0e10cSrcweir if( nContrastPercent >= 0 ) 2327cdf0e10cSrcweir fM = 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent, 0L, 100L ) ); 2328cdf0e10cSrcweir else 2329cdf0e10cSrcweir fM = ( 128.0 + 1.27 * MinMax( nContrastPercent, -100L, 0L ) ) / 128.0; 2330cdf0e10cSrcweir 2331cdf0e10cSrcweir // total offset = luminance offset + contrast offset 2332cdf0e10cSrcweir fOff = MinMax( nLuminancePercent, -100L, 100L ) * 2.55 + 128.0 - fM * 128.0; 2333cdf0e10cSrcweir 2334cdf0e10cSrcweir // channel offset = channel offset + total offset 2335cdf0e10cSrcweir fROff = nChannelRPercent * 2.55 + fOff; 2336cdf0e10cSrcweir fGOff = nChannelGPercent * 2.55 + fOff; 2337cdf0e10cSrcweir fBOff = nChannelBPercent * 2.55 + fOff; 2338cdf0e10cSrcweir 2339cdf0e10cSrcweir // calculate gamma value 2340cdf0e10cSrcweir fGamma = ( fGamma <= 0.0 || fGamma > 10.0 ) ? 1.0 : ( 1.0 / fGamma ); 2341cdf0e10cSrcweir const sal_Bool bGamma = ( fGamma != 1.0 ); 2342cdf0e10cSrcweir 2343cdf0e10cSrcweir // create mapping table 2344cdf0e10cSrcweir for( long nX = 0L; nX < 256L; nX++ ) 2345cdf0e10cSrcweir { 2346cdf0e10cSrcweir aColParam.pMapR[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fROff ), 0L, 255L ); 2347cdf0e10cSrcweir aColParam.pMapG[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fGOff ), 0L, 255L ); 2348cdf0e10cSrcweir aColParam.pMapB[ nX ] = (sal_uInt8) MinMax( FRound( nX * fM + fBOff ), 0L, 255L ); 2349cdf0e10cSrcweir 2350cdf0e10cSrcweir if( bGamma ) 2351cdf0e10cSrcweir { 2352cdf0e10cSrcweir aColParam.pMapR[ nX ] = GAMMA( aColParam.pMapR[ nX ], fGamma ); 2353cdf0e10cSrcweir aColParam.pMapG[ nX ] = GAMMA( aColParam.pMapG[ nX ], fGamma ); 2354cdf0e10cSrcweir aColParam.pMapB[ nX ] = GAMMA( aColParam.pMapB[ nX ], fGamma ); 2355cdf0e10cSrcweir } 2356cdf0e10cSrcweir 2357cdf0e10cSrcweir if( bInvert ) 2358cdf0e10cSrcweir { 2359cdf0e10cSrcweir aColParam.pMapR[ nX ] = ~aColParam.pMapR[ nX ]; 2360cdf0e10cSrcweir aColParam.pMapG[ nX ] = ~aColParam.pMapG[ nX ]; 2361cdf0e10cSrcweir aColParam.pMapB[ nX ] = ~aColParam.pMapB[ nX ]; 2362cdf0e10cSrcweir } 2363cdf0e10cSrcweir } 2364cdf0e10cSrcweir 2365cdf0e10cSrcweir aBmpParam.nLuminancePercent = nLuminancePercent; 2366cdf0e10cSrcweir aBmpParam.nContrastPercent = nContrastPercent; 2367cdf0e10cSrcweir aBmpParam.nChannelRPercent = nChannelRPercent; 2368cdf0e10cSrcweir aBmpParam.nChannelGPercent = nChannelGPercent; 2369cdf0e10cSrcweir aBmpParam.nChannelBPercent = nChannelBPercent; 2370cdf0e10cSrcweir aBmpParam.fGamma = fGamma; 2371cdf0e10cSrcweir aBmpParam.bInvert = bInvert; 2372cdf0e10cSrcweir 2373cdf0e10cSrcweir // do color adjustment 2374cdf0e10cSrcweir ImplExchangeColors( ImplColAdjustFnc, &aColParam, ImplBmpAdjustFnc, &aBmpParam ); 2375cdf0e10cSrcweir 2376cdf0e10cSrcweir delete[] aColParam.pMapR; 2377cdf0e10cSrcweir delete[] aColParam.pMapG; 2378cdf0e10cSrcweir delete[] aColParam.pMapB; 2379cdf0e10cSrcweir } 2380cdf0e10cSrcweir } 2381cdf0e10cSrcweir 2382cdf0e10cSrcweir // ------------------------------------------------------------------------ 2383cdf0e10cSrcweir 2384cdf0e10cSrcweir void GDIMetaFile::Convert( MtfConversion eConversion ) 2385cdf0e10cSrcweir { 2386cdf0e10cSrcweir // nothing to do? => return quickly 2387cdf0e10cSrcweir if( eConversion != MTF_CONVERSION_NONE ) 2388cdf0e10cSrcweir { 2389cdf0e10cSrcweir ImplColConvertParam aColParam; 2390cdf0e10cSrcweir ImplBmpConvertParam aBmpParam; 2391cdf0e10cSrcweir 2392cdf0e10cSrcweir aColParam.eConversion = eConversion; 2393cdf0e10cSrcweir aBmpParam.eConversion = ( MTF_CONVERSION_1BIT_THRESHOLD == eConversion ) ? BMP_CONVERSION_1BIT_THRESHOLD : BMP_CONVERSION_8BIT_GREYS; 2394cdf0e10cSrcweir 2395cdf0e10cSrcweir ImplExchangeColors( ImplColConvertFnc, &aColParam, ImplBmpConvertFnc, &aBmpParam ); 2396cdf0e10cSrcweir } 2397cdf0e10cSrcweir } 2398cdf0e10cSrcweir 2399cdf0e10cSrcweir // ------------------------------------------------------------------------ 2400cdf0e10cSrcweir 2401cdf0e10cSrcweir void GDIMetaFile::ReplaceColors( const Color& rSearchColor, const Color& rReplaceColor, sal_uLong nTol ) 2402cdf0e10cSrcweir { 2403cdf0e10cSrcweir ReplaceColors( &rSearchColor, &rReplaceColor, 1, &nTol ); 2404cdf0e10cSrcweir } 2405cdf0e10cSrcweir 2406cdf0e10cSrcweir // ------------------------------------------------------------------------ 2407cdf0e10cSrcweir 2408cdf0e10cSrcweir void GDIMetaFile::ReplaceColors( const Color* pSearchColors, const Color* pReplaceColors, sal_uLong nColorCount, sal_uLong* pTols ) 2409cdf0e10cSrcweir { 2410cdf0e10cSrcweir ImplColReplaceParam aColParam; 2411cdf0e10cSrcweir ImplBmpReplaceParam aBmpParam; 2412cdf0e10cSrcweir 2413cdf0e10cSrcweir aColParam.pMinR = new sal_uLong[ nColorCount ]; 2414cdf0e10cSrcweir aColParam.pMaxR = new sal_uLong[ nColorCount ]; 2415cdf0e10cSrcweir aColParam.pMinG = new sal_uLong[ nColorCount ]; 2416cdf0e10cSrcweir aColParam.pMaxG = new sal_uLong[ nColorCount ]; 2417cdf0e10cSrcweir aColParam.pMinB = new sal_uLong[ nColorCount ]; 2418cdf0e10cSrcweir aColParam.pMaxB = new sal_uLong[ nColorCount ]; 2419cdf0e10cSrcweir 2420cdf0e10cSrcweir for( sal_uLong i = 0; i < nColorCount; i++ ) 2421cdf0e10cSrcweir { 2422cdf0e10cSrcweir const long nTol = pTols ? ( pTols[ i ] * 255 ) / 100 : 0; 2423cdf0e10cSrcweir long nVal; 2424cdf0e10cSrcweir 2425cdf0e10cSrcweir nVal = pSearchColors[ i ].GetRed(); 2426cdf0e10cSrcweir aColParam.pMinR[ i ] = (sal_uLong) Max( nVal - nTol, 0L ); 2427cdf0e10cSrcweir aColParam.pMaxR[ i ] = (sal_uLong) Min( nVal + nTol, 255L ); 2428cdf0e10cSrcweir 2429cdf0e10cSrcweir nVal = pSearchColors[ i ].GetGreen(); 2430cdf0e10cSrcweir aColParam.pMinG[ i ] = (sal_uLong) Max( nVal - nTol, 0L ); 2431cdf0e10cSrcweir aColParam.pMaxG[ i ] = (sal_uLong) Min( nVal + nTol, 255L ); 2432cdf0e10cSrcweir 2433cdf0e10cSrcweir nVal = pSearchColors[ i ].GetBlue(); 2434cdf0e10cSrcweir aColParam.pMinB[ i ] = (sal_uLong) Max( nVal - nTol, 0L ); 2435cdf0e10cSrcweir aColParam.pMaxB[ i ] = (sal_uLong) Min( nVal + nTol, 255L ); 2436cdf0e10cSrcweir } 2437cdf0e10cSrcweir 2438cdf0e10cSrcweir aColParam.pDstCols = pReplaceColors; 2439cdf0e10cSrcweir aColParam.nCount = nColorCount; 2440cdf0e10cSrcweir 2441cdf0e10cSrcweir aBmpParam.pSrcCols = pSearchColors; 2442cdf0e10cSrcweir aBmpParam.pDstCols = pReplaceColors; 2443cdf0e10cSrcweir aBmpParam.nCount = nColorCount; 2444cdf0e10cSrcweir aBmpParam.pTols = pTols; 2445cdf0e10cSrcweir 2446cdf0e10cSrcweir ImplExchangeColors( ImplColReplaceFnc, &aColParam, ImplBmpReplaceFnc, &aBmpParam ); 2447cdf0e10cSrcweir 2448cdf0e10cSrcweir delete[] aColParam.pMinR; 2449cdf0e10cSrcweir delete[] aColParam.pMaxR; 2450cdf0e10cSrcweir delete[] aColParam.pMinG; 2451cdf0e10cSrcweir delete[] aColParam.pMaxG; 2452cdf0e10cSrcweir delete[] aColParam.pMinB; 2453cdf0e10cSrcweir delete[] aColParam.pMaxB; 2454cdf0e10cSrcweir }; 2455cdf0e10cSrcweir 2456cdf0e10cSrcweir // ------------------------------------------------------------------------ 2457cdf0e10cSrcweir 2458cdf0e10cSrcweir GDIMetaFile GDIMetaFile::GetMonochromeMtf( const Color& rColor ) const 2459cdf0e10cSrcweir { 2460cdf0e10cSrcweir GDIMetaFile aRet( *this ); 2461cdf0e10cSrcweir 2462cdf0e10cSrcweir ImplColMonoParam aColParam; 2463cdf0e10cSrcweir ImplBmpMonoParam aBmpParam; 2464cdf0e10cSrcweir 2465cdf0e10cSrcweir aColParam.aColor = rColor; 2466cdf0e10cSrcweir aBmpParam.aColor = rColor; 2467cdf0e10cSrcweir 2468cdf0e10cSrcweir aRet.ImplExchangeColors( ImplColMonoFnc, &aColParam, ImplBmpMonoFnc, &aBmpParam ); 2469cdf0e10cSrcweir 2470cdf0e10cSrcweir return aRet; 2471cdf0e10cSrcweir } 2472cdf0e10cSrcweir 2473cdf0e10cSrcweir // ------------------------------------------------------------------------ 2474cdf0e10cSrcweir 2475cdf0e10cSrcweir sal_uLong GDIMetaFile::GetChecksum() const 2476cdf0e10cSrcweir { 2477cdf0e10cSrcweir GDIMetaFile aMtf; 2478cdf0e10cSrcweir SvMemoryStream aMemStm( 65535, 65535 ); 2479cdf0e10cSrcweir ImplMetaWriteData aWriteData; 2480cdf0e10cSrcweir SVBT16 aBT16; 2481cdf0e10cSrcweir SVBT32 aBT32; 2482cdf0e10cSrcweir sal_uLong nCrc = 0; 2483cdf0e10cSrcweir 2484cdf0e10cSrcweir aWriteData.meActualCharSet = aMemStm.GetStreamCharSet(); 2485cdf0e10cSrcweir 2486cdf0e10cSrcweir for( sal_uLong i = 0, nObjCount = GetActionCount(); i < nObjCount; i++ ) 2487cdf0e10cSrcweir { 2488cdf0e10cSrcweir MetaAction* pAction = GetAction( i ); 2489cdf0e10cSrcweir 2490cdf0e10cSrcweir switch( pAction->GetType() ) 2491cdf0e10cSrcweir { 2492cdf0e10cSrcweir case( META_BMP_ACTION ): 2493cdf0e10cSrcweir { 2494cdf0e10cSrcweir MetaBmpAction* pAct = (MetaBmpAction*) pAction; 2495cdf0e10cSrcweir 2496cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2497cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2498cdf0e10cSrcweir 2499cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2500cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2501cdf0e10cSrcweir 2502cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2503cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2504cdf0e10cSrcweir 2505cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2506cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2507cdf0e10cSrcweir } 2508cdf0e10cSrcweir break; 2509cdf0e10cSrcweir 2510cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): 2511cdf0e10cSrcweir { 2512cdf0e10cSrcweir MetaBmpScaleAction* pAct = (MetaBmpScaleAction*) pAction; 2513cdf0e10cSrcweir 2514cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2515cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2516cdf0e10cSrcweir 2517cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2518cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2519cdf0e10cSrcweir 2520cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2521cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2522cdf0e10cSrcweir 2523cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2524cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2525cdf0e10cSrcweir 2526cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); 2527cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2528cdf0e10cSrcweir 2529cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); 2530cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2531cdf0e10cSrcweir } 2532cdf0e10cSrcweir break; 2533cdf0e10cSrcweir 2534cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): 2535cdf0e10cSrcweir { 2536cdf0e10cSrcweir MetaBmpScalePartAction* pAct = (MetaBmpScalePartAction*) pAction; 2537cdf0e10cSrcweir 2538cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2539cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2540cdf0e10cSrcweir 2541cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2542cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2543cdf0e10cSrcweir 2544cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 ); 2545cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2546cdf0e10cSrcweir 2547cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 ); 2548cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2549cdf0e10cSrcweir 2550cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 ); 2551cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2552cdf0e10cSrcweir 2553cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 ); 2554cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2555cdf0e10cSrcweir 2556cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 ); 2557cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2558cdf0e10cSrcweir 2559cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 ); 2560cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2561cdf0e10cSrcweir 2562cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 ); 2563cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2564cdf0e10cSrcweir 2565cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 ); 2566cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2567cdf0e10cSrcweir } 2568cdf0e10cSrcweir break; 2569cdf0e10cSrcweir 2570cdf0e10cSrcweir case( META_BMPEX_ACTION ): 2571cdf0e10cSrcweir { 2572cdf0e10cSrcweir MetaBmpExAction* pAct = (MetaBmpExAction*) pAction; 2573cdf0e10cSrcweir 2574cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2575cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2576cdf0e10cSrcweir 2577cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 ); 2578cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2579cdf0e10cSrcweir 2580cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2581cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2582cdf0e10cSrcweir 2583cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2584cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2585cdf0e10cSrcweir } 2586cdf0e10cSrcweir break; 2587cdf0e10cSrcweir 2588cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): 2589cdf0e10cSrcweir { 2590cdf0e10cSrcweir MetaBmpExScaleAction* pAct = (MetaBmpExScaleAction*) pAction; 2591cdf0e10cSrcweir 2592cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2593cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2594cdf0e10cSrcweir 2595cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 ); 2596cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2597cdf0e10cSrcweir 2598cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2599cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2600cdf0e10cSrcweir 2601cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2602cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2603cdf0e10cSrcweir 2604cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); 2605cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2606cdf0e10cSrcweir 2607cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); 2608cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2609cdf0e10cSrcweir } 2610cdf0e10cSrcweir break; 2611cdf0e10cSrcweir 2612cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): 2613cdf0e10cSrcweir { 2614cdf0e10cSrcweir MetaBmpExScalePartAction* pAct = (MetaBmpExScalePartAction*) pAction; 2615cdf0e10cSrcweir 2616cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2617cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2618cdf0e10cSrcweir 2619cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmapEx().GetChecksum(), aBT32 ); 2620cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2621cdf0e10cSrcweir 2622cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 ); 2623cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2624cdf0e10cSrcweir 2625cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 ); 2626cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2627cdf0e10cSrcweir 2628cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 ); 2629cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2630cdf0e10cSrcweir 2631cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 ); 2632cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2633cdf0e10cSrcweir 2634cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 ); 2635cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2636cdf0e10cSrcweir 2637cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 ); 2638cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2639cdf0e10cSrcweir 2640cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 ); 2641cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2642cdf0e10cSrcweir 2643cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 ); 2644cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2645cdf0e10cSrcweir } 2646cdf0e10cSrcweir break; 2647cdf0e10cSrcweir 2648cdf0e10cSrcweir case( META_MASK_ACTION ): 2649cdf0e10cSrcweir { 2650cdf0e10cSrcweir MetaMaskAction* pAct = (MetaMaskAction*) pAction; 2651cdf0e10cSrcweir 2652cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2653cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2654cdf0e10cSrcweir 2655cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2656cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2657cdf0e10cSrcweir 2658cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 ); 2659cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2660cdf0e10cSrcweir 2661cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2662cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2663cdf0e10cSrcweir 2664cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2665cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2666cdf0e10cSrcweir } 2667cdf0e10cSrcweir break; 2668cdf0e10cSrcweir 2669cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): 2670cdf0e10cSrcweir { 2671cdf0e10cSrcweir MetaMaskScaleAction* pAct = (MetaMaskScaleAction*) pAction; 2672cdf0e10cSrcweir 2673cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2674cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2675cdf0e10cSrcweir 2676cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2677cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2678cdf0e10cSrcweir 2679cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 ); 2680cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2681cdf0e10cSrcweir 2682cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().X(), aBT32 ); 2683cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2684cdf0e10cSrcweir 2685cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetPoint().Y(), aBT32 ); 2686cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2687cdf0e10cSrcweir 2688cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Width(), aBT32 ); 2689cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2690cdf0e10cSrcweir 2691cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSize().Height(), aBT32 ); 2692cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2693cdf0e10cSrcweir } 2694cdf0e10cSrcweir break; 2695cdf0e10cSrcweir 2696cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): 2697cdf0e10cSrcweir { 2698cdf0e10cSrcweir MetaMaskScalePartAction* pAct = (MetaMaskScalePartAction*) pAction; 2699cdf0e10cSrcweir 2700cdf0e10cSrcweir ShortToSVBT16( pAct->GetType(), aBT16 ); 2701cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT16, 2 ); 2702cdf0e10cSrcweir 2703cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetBitmap().GetChecksum(), aBT32 ); 2704cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2705cdf0e10cSrcweir 2706cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetColor().GetColor(), aBT32 ); 2707cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2708cdf0e10cSrcweir 2709cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().X(), aBT32 ); 2710cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2711cdf0e10cSrcweir 2712cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestPoint().Y(), aBT32 ); 2713cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2714cdf0e10cSrcweir 2715cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Width(), aBT32 ); 2716cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2717cdf0e10cSrcweir 2718cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetDestSize().Height(), aBT32 ); 2719cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2720cdf0e10cSrcweir 2721cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().X(), aBT32 ); 2722cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2723cdf0e10cSrcweir 2724cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcPoint().Y(), aBT32 ); 2725cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2726cdf0e10cSrcweir 2727cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Width(), aBT32 ); 2728cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2729cdf0e10cSrcweir 2730cdf0e10cSrcweir UInt32ToSVBT32( pAct->GetSrcSize().Height(), aBT32 ); 2731cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aBT32, 4 ); 2732cdf0e10cSrcweir } 2733cdf0e10cSrcweir break; 2734cdf0e10cSrcweir 2735cdf0e10cSrcweir case META_EPS_ACTION : 2736cdf0e10cSrcweir { 2737cdf0e10cSrcweir MetaEPSAction* pAct = (MetaEPSAction*) pAction; 2738cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, pAct->GetLink().GetData(), pAct->GetLink().GetDataSize() ); 2739cdf0e10cSrcweir } 2740cdf0e10cSrcweir break; 2741cdf0e10cSrcweir 2742ddde725dSArmin Le Grand case META_CLIPREGION_ACTION : 2743cdf0e10cSrcweir { 2744ddde725dSArmin Le Grand MetaClipRegionAction* pAct = dynamic_cast< MetaClipRegionAction* >(pAction); 2745ddde725dSArmin Le Grand const Region& rRegion = pAct->GetRegion(); 2746cdf0e10cSrcweir 2747ddde725dSArmin Le Grand if(rRegion.HasPolyPolygon()) 2748ddde725dSArmin Le Grand { 2749ddde725dSArmin Le Grand // It has shown that this is a possible bottleneck for checksum calculation. 2750ddde725dSArmin Le Grand // In worst case a very expensive RegionHandle representation gets created. 2751ddde725dSArmin Le Grand // In this case it's cheaper to use the PolyPolygon 2752ddde725dSArmin Le Grand const basegfx::B2DPolyPolygon aPolyPolygon(rRegion.GetB2DPolyPolygon()); 2753ddde725dSArmin Le Grand const sal_uInt32 nPolyCount(aPolyPolygon.count()); 2754ddde725dSArmin Le Grand SVBT64 aSVBT64; 2755cdf0e10cSrcweir 2756ddde725dSArmin Le Grand for(sal_uInt32 a(0); a < nPolyCount; a++) 2757ddde725dSArmin Le Grand { 2758ddde725dSArmin Le Grand const basegfx::B2DPolygon aPolygon(aPolyPolygon.getB2DPolygon(a)); 2759ddde725dSArmin Le Grand const sal_uInt32 nPointCount(aPolygon.count()); 2760ddde725dSArmin Le Grand const bool bControl(aPolygon.areControlPointsUsed()); 2761cdf0e10cSrcweir 2762ddde725dSArmin Le Grand for(sal_uInt32 b(0); b < nPointCount; b++) 2763ddde725dSArmin Le Grand { 2764ddde725dSArmin Le Grand const basegfx::B2DPoint aPoint(aPolygon.getB2DPoint(b)); 2765cdf0e10cSrcweir 2766ddde725dSArmin Le Grand DoubleToSVBT64(aPoint.getX(), aSVBT64); 2767ddde725dSArmin Le Grand nCrc = rtl_crc32(nCrc, aSVBT64, 8); 2768ddde725dSArmin Le Grand DoubleToSVBT64(aPoint.getY(), aSVBT64); 2769ddde725dSArmin Le Grand nCrc = rtl_crc32(nCrc, aSVBT64, 8); 2770cdf0e10cSrcweir 2771ddde725dSArmin Le Grand if(bControl) 2772ddde725dSArmin Le Grand { 2773ddde725dSArmin Le Grand if(aPolygon.isPrevControlPointUsed(b)) 2774ddde725dSArmin Le Grand { 2775ddde725dSArmin Le Grand const basegfx::B2DPoint aCtrl(aPolygon.getPrevControlPoint(b)); 2776cdf0e10cSrcweir 2777ddde725dSArmin Le Grand DoubleToSVBT64(aCtrl.getX(), aSVBT64); 2778ddde725dSArmin Le Grand nCrc = rtl_crc32(nCrc, aSVBT64, 8); 2779ddde725dSArmin Le Grand DoubleToSVBT64(aCtrl.getY(), aSVBT64); 2780ddde725dSArmin Le Grand nCrc = rtl_crc32(nCrc, aSVBT64, 8); 2781ddde725dSArmin Le Grand } 2782ddde725dSArmin Le Grand 2783ddde725dSArmin Le Grand if(aPolygon.isNextControlPointUsed(b)) 2784ddde725dSArmin Le Grand { 2785ddde725dSArmin Le Grand const basegfx::B2DPoint aCtrl(aPolygon.getNextControlPoint(b)); 2786ddde725dSArmin Le Grand 2787ddde725dSArmin Le Grand DoubleToSVBT64(aCtrl.getX(), aSVBT64); 2788ddde725dSArmin Le Grand nCrc = rtl_crc32(nCrc, aSVBT64, 8); 2789ddde725dSArmin Le Grand DoubleToSVBT64(aCtrl.getY(), aSVBT64); 2790ddde725dSArmin Le Grand nCrc = rtl_crc32(nCrc, aSVBT64, 8); 2791ddde725dSArmin Le Grand } 2792ddde725dSArmin Le Grand } 2793ddde725dSArmin Le Grand } 2794ddde725dSArmin Le Grand } 2795ddde725dSArmin Le Grand 2796ddde725dSArmin Le Grand SVBT8 aSVBT8; 2797ddde725dSArmin Le Grand ByteToSVBT8((sal_uInt8)pAct->IsClipping(), aSVBT8); 2798ddde725dSArmin Le Grand nCrc = rtl_crc32(nCrc, aSVBT8, 1); 2799ddde725dSArmin Le Grand } 2800ddde725dSArmin Le Grand else 2801ddde725dSArmin Le Grand { 2802ddde725dSArmin Le Grand pAction->Write( aMemStm, &aWriteData ); 2803ddde725dSArmin Le Grand nCrc = rtl_crc32( nCrc, aMemStm.GetData(), aMemStm.Tell() ); 2804ddde725dSArmin Le Grand aMemStm.Seek( 0 ); 2805ddde725dSArmin Le Grand } 2806cdf0e10cSrcweir } 2807cdf0e10cSrcweir break; 2808cdf0e10cSrcweir 2809cdf0e10cSrcweir default: 2810cdf0e10cSrcweir { 2811cdf0e10cSrcweir pAction->Write( aMemStm, &aWriteData ); 2812cdf0e10cSrcweir nCrc = rtl_crc32( nCrc, aMemStm.GetData(), aMemStm.Tell() ); 2813cdf0e10cSrcweir aMemStm.Seek( 0 ); 2814cdf0e10cSrcweir } 2815cdf0e10cSrcweir break; 2816cdf0e10cSrcweir } 2817cdf0e10cSrcweir } 2818cdf0e10cSrcweir 2819cdf0e10cSrcweir return nCrc; 2820cdf0e10cSrcweir } 2821cdf0e10cSrcweir 2822cdf0e10cSrcweir // ------------------------------------------------------------------------ 2823cdf0e10cSrcweir 2824cdf0e10cSrcweir sal_uLong GDIMetaFile::GetSizeBytes() const 2825cdf0e10cSrcweir { 2826cdf0e10cSrcweir sal_uLong nSizeBytes = 0; 2827cdf0e10cSrcweir 2828cdf0e10cSrcweir for( sal_uLong i = 0, nObjCount = GetActionCount(); i < nObjCount; ++i ) 2829cdf0e10cSrcweir { 2830cdf0e10cSrcweir MetaAction* pAction = GetAction( i ); 2831cdf0e10cSrcweir 2832cdf0e10cSrcweir // default action size is set to 32 (=> not the exact value) 2833cdf0e10cSrcweir nSizeBytes += 32; 2834cdf0e10cSrcweir 2835cdf0e10cSrcweir // add sizes for large action content 2836cdf0e10cSrcweir switch( pAction->GetType() ) 2837cdf0e10cSrcweir { 2838cdf0e10cSrcweir case( META_BMP_ACTION ): nSizeBytes += ( (MetaBmpAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2839cdf0e10cSrcweir case( META_BMPSCALE_ACTION ): nSizeBytes += ( (MetaBmpScaleAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2840cdf0e10cSrcweir case( META_BMPSCALEPART_ACTION ): nSizeBytes += ( (MetaBmpScalePartAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2841cdf0e10cSrcweir 2842cdf0e10cSrcweir case( META_BMPEX_ACTION ): nSizeBytes += ( (MetaBmpExAction*) pAction )->GetBitmapEx().GetSizeBytes(); break; 2843cdf0e10cSrcweir case( META_BMPEXSCALE_ACTION ): nSizeBytes += ( (MetaBmpExScaleAction*) pAction )->GetBitmapEx().GetSizeBytes(); break; 2844cdf0e10cSrcweir case( META_BMPEXSCALEPART_ACTION ): nSizeBytes += ( (MetaBmpExScalePartAction*) pAction )->GetBitmapEx().GetSizeBytes(); break; 2845cdf0e10cSrcweir 2846cdf0e10cSrcweir case( META_MASK_ACTION ): nSizeBytes += ( (MetaMaskAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2847cdf0e10cSrcweir case( META_MASKSCALE_ACTION ): nSizeBytes += ( (MetaMaskScaleAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2848cdf0e10cSrcweir case( META_MASKSCALEPART_ACTION ): nSizeBytes += ( (MetaMaskScalePartAction*) pAction )->GetBitmap().GetSizeBytes(); break; 2849cdf0e10cSrcweir 2850cdf0e10cSrcweir case( META_POLYLINE_ACTION ): nSizeBytes += ( ( (MetaPolyLineAction*) pAction )->GetPolygon().GetSize() * sizeof( Point ) ); break; 2851cdf0e10cSrcweir case( META_POLYGON_ACTION ): nSizeBytes += ( ( (MetaPolygonAction*) pAction )->GetPolygon().GetSize() * sizeof( Point ) ); break; 2852cdf0e10cSrcweir case( META_POLYPOLYGON_ACTION ): 2853cdf0e10cSrcweir { 2854cdf0e10cSrcweir const PolyPolygon& rPolyPoly = ( (MetaPolyPolygonAction*) pAction )->GetPolyPolygon(); 2855cdf0e10cSrcweir 2856cdf0e10cSrcweir for( sal_uInt16 n = 0; n < rPolyPoly.Count(); ++n ) 2857cdf0e10cSrcweir nSizeBytes += ( rPolyPoly[ n ].GetSize() * sizeof( Point ) ); 2858cdf0e10cSrcweir } 2859cdf0e10cSrcweir break; 2860cdf0e10cSrcweir 2861cdf0e10cSrcweir case( META_TEXT_ACTION ): nSizeBytes += ( ( (MetaTextAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break; 2862cdf0e10cSrcweir case( META_STRETCHTEXT_ACTION ): nSizeBytes += ( ( (MetaStretchTextAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break; 2863cdf0e10cSrcweir case( META_TEXTRECT_ACTION ): nSizeBytes += ( ( (MetaTextRectAction*) pAction )->GetText().Len() * sizeof( sal_Unicode ) ); break; 2864cdf0e10cSrcweir case( META_TEXTARRAY_ACTION ): 2865cdf0e10cSrcweir { 2866cdf0e10cSrcweir MetaTextArrayAction* pTextArrayAction = (MetaTextArrayAction*) pAction; 2867cdf0e10cSrcweir 2868cdf0e10cSrcweir nSizeBytes += ( pTextArrayAction->GetText().Len() * sizeof( sal_Unicode ) ); 2869cdf0e10cSrcweir 2870cdf0e10cSrcweir if( pTextArrayAction->GetDXArray() ) 2871cdf0e10cSrcweir nSizeBytes += ( pTextArrayAction->GetLen() << 2 ); 2872cdf0e10cSrcweir } 2873cdf0e10cSrcweir break; 2874cdf0e10cSrcweir } 2875cdf0e10cSrcweir } 2876cdf0e10cSrcweir 2877cdf0e10cSrcweir return( nSizeBytes ); 2878cdf0e10cSrcweir } 2879cdf0e10cSrcweir 2880cdf0e10cSrcweir // ------------------------------------------------------------------------ 2881cdf0e10cSrcweir 2882cdf0e10cSrcweir SvStream& operator>>( SvStream& rIStm, GDIMetaFile& rGDIMetaFile ) 2883cdf0e10cSrcweir { 2884cdf0e10cSrcweir if( !rIStm.GetError() ) 2885cdf0e10cSrcweir { 2886cdf0e10cSrcweir char aId[ 7 ]; 2887cdf0e10cSrcweir sal_uLong nStmPos = rIStm.Tell(); 2888cdf0e10cSrcweir sal_uInt16 nOldFormat = rIStm.GetNumberFormatInt(); 2889cdf0e10cSrcweir 2890cdf0e10cSrcweir rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 2891cdf0e10cSrcweir 2892cdf0e10cSrcweir aId[ 0 ] = 0; 2893cdf0e10cSrcweir aId[ 6 ] = 0; 2894cdf0e10cSrcweir rIStm.Read( aId, 6 ); 2895cdf0e10cSrcweir 2896cdf0e10cSrcweir if ( !strcmp( aId, "VCLMTF" ) ) 2897cdf0e10cSrcweir { 2898cdf0e10cSrcweir // new format 2899cdf0e10cSrcweir VersionCompat* pCompat; 2900cdf0e10cSrcweir MetaAction* pAction; 2901cdf0e10cSrcweir sal_uInt32 nStmCompressMode = 0; 2902cdf0e10cSrcweir sal_uInt32 nCount = 0; 2903cdf0e10cSrcweir 2904cdf0e10cSrcweir pCompat = new VersionCompat( rIStm, STREAM_READ ); 2905ddde725dSArmin Le Grand 2906cdf0e10cSrcweir rIStm >> nStmCompressMode; 2907cdf0e10cSrcweir rIStm >> rGDIMetaFile.aPrefMapMode; 2908cdf0e10cSrcweir rIStm >> rGDIMetaFile.aPrefSize; 2909cdf0e10cSrcweir rIStm >> nCount; 2910cdf0e10cSrcweir 2911cdf0e10cSrcweir delete pCompat; 2912cdf0e10cSrcweir 2913cdf0e10cSrcweir ImplMetaReadData aReadData; 2914cdf0e10cSrcweir aReadData.meActualCharSet = rIStm.GetStreamCharSet(); 2915cdf0e10cSrcweir 2916ddde725dSArmin Le Grand for( sal_uInt32 nAction = 0UL; ( nAction < nCount ) && !rIStm.IsEof(); nAction++ ) 2917cdf0e10cSrcweir { 2918cdf0e10cSrcweir pAction = MetaAction::ReadMetaAction( rIStm, &aReadData ); 2919cdf0e10cSrcweir 2920cdf0e10cSrcweir if( pAction ) 2921cdf0e10cSrcweir rGDIMetaFile.AddAction( pAction ); 2922cdf0e10cSrcweir } 2923cdf0e10cSrcweir } 2924cdf0e10cSrcweir else 2925cdf0e10cSrcweir { 2926cdf0e10cSrcweir // to avoid possible compiler optimizations => new/delete 2927cdf0e10cSrcweir rIStm.Seek( nStmPos ); 2928cdf0e10cSrcweir delete( new SVMConverter( rIStm, rGDIMetaFile, CONVERT_FROM_SVM1 ) ); 2929cdf0e10cSrcweir } 2930cdf0e10cSrcweir 2931cdf0e10cSrcweir // check for errors 2932cdf0e10cSrcweir if( rIStm.GetError() ) 2933cdf0e10cSrcweir { 2934cdf0e10cSrcweir rGDIMetaFile.Clear(); 2935cdf0e10cSrcweir rIStm.Seek( nStmPos ); 2936cdf0e10cSrcweir } 2937cdf0e10cSrcweir 2938cdf0e10cSrcweir rIStm.SetNumberFormatInt( nOldFormat ); 2939cdf0e10cSrcweir } 2940cdf0e10cSrcweir 2941cdf0e10cSrcweir return rIStm; 2942cdf0e10cSrcweir } 2943cdf0e10cSrcweir 2944cdf0e10cSrcweir // ------------------------------------------------------------------------ 2945cdf0e10cSrcweir 2946cdf0e10cSrcweir SvStream& operator<<( SvStream& rOStm, const GDIMetaFile& rGDIMetaFile ) 2947cdf0e10cSrcweir { 2948cdf0e10cSrcweir if( !rOStm.GetError() ) 2949cdf0e10cSrcweir { 2950cdf0e10cSrcweir static const char* pEnableSVM1 = getenv( "SAL_ENABLE_SVM1" ); 2951cdf0e10cSrcweir static const bool bNoSVM1 = (NULL == pEnableSVM1 ) || ( '0' == *pEnableSVM1 ); 2952cdf0e10cSrcweir 2953cdf0e10cSrcweir if( bNoSVM1 || rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) 2954cdf0e10cSrcweir { 2955cdf0e10cSrcweir const_cast< GDIMetaFile& >( rGDIMetaFile ).Write( rOStm ); 2956cdf0e10cSrcweir } 2957cdf0e10cSrcweir else 2958cdf0e10cSrcweir { 2959cdf0e10cSrcweir delete( new SVMConverter( rOStm, const_cast< GDIMetaFile& >( rGDIMetaFile ), CONVERT_TO_SVM1 ) ); 2960cdf0e10cSrcweir } 2961cdf0e10cSrcweir 2962cdf0e10cSrcweir #ifdef DEBUG 2963cdf0e10cSrcweir if( !bNoSVM1 && rOStm.GetVersion() < SOFFICE_FILEFORMAT_50 ) 2964cdf0e10cSrcweir { 2965cdf0e10cSrcweir OSL_TRACE( \ 2966cdf0e10cSrcweir "GDIMetaFile would normally be written in old SVM1 format by this call. \ 2967cdf0e10cSrcweir The current implementation always writes in VCLMTF format. \ 2968cdf0e10cSrcweir Please set environment variable SAL_ENABLE_SVM1 to '1' to reenable old behavior" ); 2969cdf0e10cSrcweir } 2970cdf0e10cSrcweir #endif // DEBUG 2971cdf0e10cSrcweir } 2972cdf0e10cSrcweir 2973cdf0e10cSrcweir return rOStm; 2974cdf0e10cSrcweir } 2975cdf0e10cSrcweir 2976cdf0e10cSrcweir // ------------------------------------------------------------------------ 2977cdf0e10cSrcweir 2978cdf0e10cSrcweir SvStream& GDIMetaFile::Read( SvStream& rIStm ) 2979cdf0e10cSrcweir { 2980cdf0e10cSrcweir Clear(); 2981cdf0e10cSrcweir rIStm >> *this; 2982cdf0e10cSrcweir 2983cdf0e10cSrcweir return rIStm; 2984cdf0e10cSrcweir } 2985cdf0e10cSrcweir 2986cdf0e10cSrcweir // ------------------------------------------------------------------------ 2987cdf0e10cSrcweir 2988ddde725dSArmin Le Grand SvStream& GDIMetaFile::Write( SvStream& rOStm ) 2989cdf0e10cSrcweir { 2990cdf0e10cSrcweir VersionCompat* pCompat; 2991cdf0e10cSrcweir const sal_uInt32 nStmCompressMode = rOStm.GetCompressMode(); 2992cdf0e10cSrcweir sal_uInt16 nOldFormat = rOStm.GetNumberFormatInt(); 2993cdf0e10cSrcweir 2994cdf0e10cSrcweir rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN ); 2995cdf0e10cSrcweir rOStm.Write( "VCLMTF", 6 ); 2996cdf0e10cSrcweir 2997ddde725dSArmin Le Grand pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 ); 2998cdf0e10cSrcweir 2999ddde725dSArmin Le Grand rOStm << nStmCompressMode; 3000ddde725dSArmin Le Grand rOStm << aPrefMapMode; 3001ddde725dSArmin Le Grand rOStm << aPrefSize; 3002ddde725dSArmin Le Grand rOStm << (sal_uInt32) GetActionCount(); 3003cdf0e10cSrcweir 3004cdf0e10cSrcweir delete pCompat; 3005cdf0e10cSrcweir 3006cdf0e10cSrcweir ImplMetaWriteData aWriteData; 3007cdf0e10cSrcweir aWriteData.meActualCharSet = rOStm.GetStreamCharSet(); 3008cdf0e10cSrcweir 3009ddde725dSArmin Le Grand MetaAction* pAct = (MetaAction*)First(); 3010ddde725dSArmin Le Grand while ( pAct ) 3011cdf0e10cSrcweir { 3012cdf0e10cSrcweir pAct->Write( rOStm, &aWriteData ); 3013ddde725dSArmin Le Grand pAct = (MetaAction*)Next(); 3014cdf0e10cSrcweir } 3015cdf0e10cSrcweir 3016cdf0e10cSrcweir rOStm.SetNumberFormatInt( nOldFormat ); 3017cdf0e10cSrcweir 3018cdf0e10cSrcweir return rOStm; 3019cdf0e10cSrcweir } 3020cdf0e10cSrcweir 3021cdf0e10cSrcweir // ------------------------------------------------------------------------ 3022cdf0e10cSrcweir 3023cdf0e10cSrcweir sal_Bool GDIMetaFile::CreateThumbnail( sal_uInt32 nMaximumExtent, 3024cdf0e10cSrcweir BitmapEx& rBmpEx, 3025cdf0e10cSrcweir const BitmapEx* pOverlay, 3026cdf0e10cSrcweir const Rectangle* pOverlayRect ) const 3027cdf0e10cSrcweir { 3028cdf0e10cSrcweir // the implementation is provided by KA 3029cdf0e10cSrcweir 3030cdf0e10cSrcweir // initialization seems to be complicated but is used to avoid rounding errors 3031cdf0e10cSrcweir VirtualDevice aVDev; 3032cdf0e10cSrcweir const Point aNullPt; 3033cdf0e10cSrcweir const Point aTLPix( aVDev.LogicToPixel( aNullPt, GetPrefMapMode() ) ); 3034cdf0e10cSrcweir const Point aBRPix( aVDev.LogicToPixel( Point( GetPrefSize().Width() - 1, GetPrefSize().Height() - 1 ), GetPrefMapMode() ) ); 3035cdf0e10cSrcweir Size aDrawSize( aVDev.LogicToPixel( GetPrefSize(), GetPrefMapMode() ) ); 3036cdf0e10cSrcweir Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 ); 3037cdf0e10cSrcweir Point aPosPix; 3038cdf0e10cSrcweir 3039cdf0e10cSrcweir if ( !rBmpEx.IsEmpty() ) 3040cdf0e10cSrcweir rBmpEx.SetEmpty(); 3041cdf0e10cSrcweir 3042cdf0e10cSrcweir // determine size that has the same aspect ratio as image size and 3043cdf0e10cSrcweir // fits into the rectangle determined by nMaximumExtent 3044cdf0e10cSrcweir if ( aSizePix.Width() && aSizePix.Height() 3045cdf0e10cSrcweir && ( sal::static_int_cast< unsigned long >(aSizePix.Width()) > 3046cdf0e10cSrcweir nMaximumExtent || 3047cdf0e10cSrcweir sal::static_int_cast< unsigned long >(aSizePix.Height()) > 3048cdf0e10cSrcweir nMaximumExtent ) ) 3049cdf0e10cSrcweir { 3050cdf0e10cSrcweir const Size aOldSizePix( aSizePix ); 3051cdf0e10cSrcweir double fWH = static_cast< double >( aSizePix.Width() ) / aSizePix.Height(); 3052cdf0e10cSrcweir 3053cdf0e10cSrcweir if ( fWH <= 1.0 ) 3054cdf0e10cSrcweir { 3055cdf0e10cSrcweir aSizePix.Width() = FRound( nMaximumExtent * fWH ); 3056cdf0e10cSrcweir aSizePix.Height() = nMaximumExtent; 3057cdf0e10cSrcweir } 3058cdf0e10cSrcweir else 3059cdf0e10cSrcweir { 3060cdf0e10cSrcweir aSizePix.Width() = nMaximumExtent; 3061cdf0e10cSrcweir aSizePix.Height() = FRound( nMaximumExtent / fWH ); 3062cdf0e10cSrcweir } 3063cdf0e10cSrcweir 3064cdf0e10cSrcweir aDrawSize.Width() = FRound( ( static_cast< double >( aDrawSize.Width() ) * aSizePix.Width() ) / aOldSizePix.Width() ); 3065cdf0e10cSrcweir aDrawSize.Height() = FRound( ( static_cast< double >( aDrawSize.Height() ) * aSizePix.Height() ) / aOldSizePix.Height() ); 3066cdf0e10cSrcweir } 3067cdf0e10cSrcweir 3068cdf0e10cSrcweir Size aFullSize; 3069cdf0e10cSrcweir Point aBackPosPix; 3070cdf0e10cSrcweir Rectangle aOverlayRect; 3071cdf0e10cSrcweir 3072cdf0e10cSrcweir // calculate addigtional positions and sizes if an overlay image is used 3073cdf0e10cSrcweir if ( pOverlay ) 3074cdf0e10cSrcweir { 3075cdf0e10cSrcweir aFullSize = Size( nMaximumExtent, nMaximumExtent ); 3076cdf0e10cSrcweir aOverlayRect = Rectangle( aNullPt, aFullSize ); 3077cdf0e10cSrcweir 3078cdf0e10cSrcweir aOverlayRect.Intersection( pOverlayRect ? *pOverlayRect : Rectangle( aNullPt, pOverlay->GetSizePixel() ) ); 3079cdf0e10cSrcweir 3080cdf0e10cSrcweir if ( !aOverlayRect.IsEmpty() ) 3081cdf0e10cSrcweir aBackPosPix = Point( ( nMaximumExtent - aSizePix.Width() ) >> 1, ( nMaximumExtent - aSizePix.Height() ) >> 1 ); 3082cdf0e10cSrcweir else 3083cdf0e10cSrcweir pOverlay = NULL; 3084cdf0e10cSrcweir } 3085cdf0e10cSrcweir else 3086cdf0e10cSrcweir { 3087cdf0e10cSrcweir aFullSize = aSizePix; 3088cdf0e10cSrcweir pOverlay = NULL; 3089cdf0e10cSrcweir } 3090cdf0e10cSrcweir 3091cdf0e10cSrcweir // draw image(s) into VDev and get resulting image 3092cdf0e10cSrcweir if ( aVDev.SetOutputSizePixel( aFullSize ) ) 3093cdf0e10cSrcweir { 3094cdf0e10cSrcweir // draw metafile into VDev 3095cdf0e10cSrcweir const_cast<GDIMetaFile *>(this)->WindStart(); 3096cdf0e10cSrcweir const_cast<GDIMetaFile *>(this)->Play( &aVDev, aBackPosPix, aDrawSize ); 3097cdf0e10cSrcweir 3098cdf0e10cSrcweir // draw overlay if neccessary 3099cdf0e10cSrcweir if ( pOverlay ) 3100cdf0e10cSrcweir aVDev.DrawBitmapEx( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), *pOverlay ); 3101cdf0e10cSrcweir 3102cdf0e10cSrcweir // get paint bitmap 3103cdf0e10cSrcweir Bitmap aBmp( aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) ); 3104cdf0e10cSrcweir 3105cdf0e10cSrcweir // assure that we have a true color image 3106cdf0e10cSrcweir if ( aBmp.GetBitCount() != 24 ) 3107cdf0e10cSrcweir aBmp.Convert( BMP_CONVERSION_24BIT ); 3108cdf0e10cSrcweir 3109cdf0e10cSrcweir // create resulting mask bitmap with metafile output set to black 3110cdf0e10cSrcweir GDIMetaFile aMonchromeMtf( GetMonochromeMtf( COL_BLACK ) ); 3111cdf0e10cSrcweir aVDev.DrawWallpaper( Rectangle( aNullPt, aSizePix ), Wallpaper( Color( COL_WHITE ) ) ); 3112cdf0e10cSrcweir aMonchromeMtf.WindStart(); 3113cdf0e10cSrcweir aMonchromeMtf.Play( &aVDev, aBackPosPix, aDrawSize ); 3114cdf0e10cSrcweir 3115cdf0e10cSrcweir // watch for overlay mask 3116cdf0e10cSrcweir if ( pOverlay ) 3117cdf0e10cSrcweir { 3118cdf0e10cSrcweir Bitmap aOverlayMergeBmp( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ) ); 3119cdf0e10cSrcweir 3120cdf0e10cSrcweir // create ANDed resulting mask at overlay area 3121cdf0e10cSrcweir if ( pOverlay->IsTransparent() ) 3122cdf0e10cSrcweir aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), pOverlay->GetMask() ); 3123cdf0e10cSrcweir else 3124cdf0e10cSrcweir { 3125cdf0e10cSrcweir aVDev.SetLineColor( COL_BLACK ); 3126cdf0e10cSrcweir aVDev.SetFillColor( COL_BLACK ); 3127cdf0e10cSrcweir aVDev.DrawRect( aOverlayRect); 3128cdf0e10cSrcweir } 3129cdf0e10cSrcweir 3130cdf0e10cSrcweir aOverlayMergeBmp.CombineSimple( aVDev.GetBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize() ), BMP_COMBINE_AND ); 3131cdf0e10cSrcweir aVDev.DrawBitmap( aOverlayRect.TopLeft(), aOverlayRect.GetSize(), aOverlayMergeBmp ); 3132cdf0e10cSrcweir } 3133cdf0e10cSrcweir 3134cdf0e10cSrcweir rBmpEx = BitmapEx( aBmp, aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() ) ); 3135cdf0e10cSrcweir } 3136cdf0e10cSrcweir 3137cdf0e10cSrcweir return !rBmpEx.IsEmpty(); 3138cdf0e10cSrcweir } 3139