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