1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svtools.hxx"
26
27 #define ENABLE_BYTESTRING_STREAM_OPERATORS
28
29 #include <algorithm>
30
31 #include <com/sun/star/uno/Reference.hxx>
32 #include <com/sun/star/document/XLinkAuthorizer.hpp>
33 #include <com/sun/star/frame/XDesktop.hpp>
34 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
35 #include <tools/vcompat.hxx>
36 #include <ucbhelper/contentbroker.hxx>
37 #include <unotools/ucbstreamhelper.hxx>
38 #include <unotools/localfilehelper.hxx>
39 #include <unotools/tempfile.hxx>
40 #include <vcl/svapp.hxx>
41 #include <vcl/cvtgrf.hxx>
42 #include <vcl/metaact.hxx>
43 #include <vcl/virdev.hxx>
44 #include <vcl/salbtype.hxx>
45 #include <unotools/cacheoptions.hxx>
46 #include <svtools/grfmgr.hxx>
47 #include <svtools/linkpolicy.hxx>
48
49 // --> OD 2010-01-04 #i105243#
50 #include <vcl/pdfextoutdevdata.hxx>
51 // <--
52
53 using namespace ::com::sun::star;
54
55 // -----------
56 // - Defines -
57 // -----------
58
59 #define WATERMARK_LUM_OFFSET 50
60 #define WATERMARK_CON_OFFSET -70
61
62 // -----------
63 // - statics -
64 // -----------
65
66 GraphicManager* GraphicObject::mpGlobalMgr = NULL;
67
68 // ---------------------
69 // - GrfDirectCacheObj -
70 // ---------------------
71
72 struct GrfSimpleCacheObj
73 {
74 Graphic maGraphic;
75 GraphicAttr maAttr;
76
GrfSimpleCacheObjGrfSimpleCacheObj77 GrfSimpleCacheObj( const Graphic& rGraphic, const GraphicAttr& rAttr ) :
78 maGraphic( rGraphic ), maAttr( rAttr ) {}
79 };
80
81 // -----------------
82 // - GraphicObject -
83 // -----------------
84
85 TYPEINIT1_AUTOFACTORY( GraphicObject, SvDataCopyStream );
86
87 // unique increasing ID for being able to detect the GraphicObject with the
88 // oldest last data changes
89 static sal_uLong aIncrementingTimeOfLastDataChange = 1;
90
ImplAfterDataChange()91 void GraphicObject::ImplAfterDataChange()
92 {
93 // set unique timestamp ID of last data change
94 mnDataChangeTimeStamp = aIncrementingTimeOfLastDataChange++;
95
96 // check memory footprint of all GraphicObjects managed and evtl. take action
97 GetGraphicManager().ImplCheckSizeOfSwappedInGraphics();
98 }
99
100 // -----------------------------------------------------------------------------
101
GraphicObject(const GraphicManager * pMgr)102 GraphicObject::GraphicObject( const GraphicManager* pMgr ) :
103 mpLink ( NULL ),
104 mpUserData ( NULL )
105 {
106 ImplConstruct();
107 ImplAssignGraphicData();
108 ImplSetGraphicManager( pMgr );
109 }
110
111 // -----------------------------------------------------------------------------
112
GraphicObject(const Graphic & rGraphic,const GraphicManager * pMgr)113 GraphicObject::GraphicObject( const Graphic& rGraphic, const GraphicManager* pMgr ) :
114 maGraphic ( rGraphic ),
115 mpLink ( NULL ),
116 mpUserData ( NULL )
117 {
118 ImplConstruct();
119 ImplAssignGraphicData();
120 ImplSetGraphicManager( pMgr );
121 }
122
123 // -----------------------------------------------------------------------------
124
GraphicObject(const Graphic & rGraphic,const String & rLink,const GraphicManager * pMgr)125 GraphicObject::GraphicObject( const Graphic& rGraphic, const String& rLink, const GraphicManager* pMgr ) :
126 maGraphic ( rGraphic ),
127 mpLink ( rLink.Len() ? ( new String( rLink ) ) : NULL ),
128 mpUserData ( NULL )
129 {
130 ImplConstruct();
131 ImplAssignGraphicData();
132 ImplSetGraphicManager( pMgr );
133 }
134
135 // -----------------------------------------------------------------------------
136
GraphicObject(const GraphicObject & rGraphicObj,const GraphicManager * pMgr)137 GraphicObject::GraphicObject( const GraphicObject& rGraphicObj, const GraphicManager* pMgr ) :
138 SvDataCopyStream(),
139 maGraphic ( rGraphicObj.GetGraphic() ),
140 maAttr ( rGraphicObj.maAttr ),
141 mpLink ( rGraphicObj.mpLink ? ( new String( *rGraphicObj.mpLink ) ) : NULL ),
142 mpUserData ( rGraphicObj.mpUserData ? ( new String( *rGraphicObj.mpUserData ) ) : NULL )
143 {
144 ImplConstruct();
145 ImplAssignGraphicData();
146 ImplSetGraphicManager( pMgr, NULL, &rGraphicObj );
147 }
148
149 // -----------------------------------------------------------------------------
150
GraphicObject(const ByteString & rUniqueID,const GraphicManager * pMgr)151 GraphicObject::GraphicObject( const ByteString& rUniqueID, const GraphicManager* pMgr ) :
152 mpLink ( NULL ),
153 mpUserData ( NULL )
154 {
155 ImplConstruct();
156
157 // assign default properties
158 ImplAssignGraphicData();
159
160 ImplSetGraphicManager( pMgr, &rUniqueID );
161
162 // update properties
163 ImplAssignGraphicData();
164 }
165
166 // -----------------------------------------------------------------------------
167
~GraphicObject()168 GraphicObject::~GraphicObject()
169 {
170 if( mpMgr )
171 {
172 mpMgr->ImplUnregisterObj( *this );
173
174 if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
175 delete mpGlobalMgr, mpGlobalMgr = NULL;
176 }
177
178 delete mpSwapOutTimer;
179 delete mpSwapStreamHdl;
180 delete mpLink;
181 delete mpUserData;
182 delete mpSimpleCache;
183 }
184
185 // -----------------------------------------------------------------------------
186
ImplConstruct()187 void GraphicObject::ImplConstruct()
188 {
189 mpMgr = NULL;
190 mpSwapStreamHdl = NULL;
191 mpSwapOutTimer = NULL;
192 mpSimpleCache = NULL;
193 mnAnimationLoopCount = 0;
194 mbAutoSwapped = sal_False;
195 mbIsInSwapIn = sal_False;
196 mbIsInSwapOut = sal_False;
197
198 // Init with a unique, increasing ID
199 mnDataChangeTimeStamp = aIncrementingTimeOfLastDataChange++;
200 }
201
202 // -----------------------------------------------------------------------------
203
ImplAssignGraphicData()204 void GraphicObject::ImplAssignGraphicData()
205 {
206 maPrefSize = maGraphic.GetPrefSize();
207 maPrefMapMode = maGraphic.GetPrefMapMode();
208 mnSizeBytes = maGraphic.GetSizeBytes();
209 meType = maGraphic.GetType();
210 mbTransparent = maGraphic.IsTransparent();
211 mbAlpha = maGraphic.IsAlpha();
212 mbAnimated = maGraphic.IsAnimated();
213 mbEPS = maGraphic.IsEPS();
214 mnAnimationLoopCount = ( mbAnimated ? maGraphic.GetAnimationLoopCount() : 0 );
215 }
216
217 // -----------------------------------------------------------------------------
218
ImplSetGraphicManager(const GraphicManager * pMgr,const ByteString * pID,const GraphicObject * pCopyObj)219 void GraphicObject::ImplSetGraphicManager( const GraphicManager* pMgr, const ByteString* pID, const GraphicObject* pCopyObj )
220 {
221 if( !mpMgr || ( pMgr != mpMgr ) )
222 {
223 if( !pMgr && mpMgr && ( mpMgr == mpGlobalMgr ) )
224 return;
225 else
226 {
227 if( mpMgr )
228 {
229 mpMgr->ImplUnregisterObj( *this );
230
231 if( ( mpMgr == mpGlobalMgr ) && !mpGlobalMgr->ImplHasObjects() )
232 delete mpGlobalMgr, mpGlobalMgr = NULL;
233 }
234
235 if( !pMgr )
236 {
237 if( !mpGlobalMgr )
238 {
239 SvtCacheOptions aCacheOptions;
240
241 mpGlobalMgr = new GraphicManager( aCacheOptions.GetGraphicManagerTotalCacheSize(),
242 aCacheOptions.GetGraphicManagerObjectCacheSize() );
243 mpGlobalMgr->SetCacheTimeout( aCacheOptions.GetGraphicManagerObjectReleaseTime() );
244 }
245
246 mpMgr = mpGlobalMgr;
247 }
248 else
249 mpMgr = (GraphicManager*) pMgr;
250
251 mpMgr->ImplRegisterObj( *this, maGraphic, pID, pCopyObj );
252 }
253 }
254 }
255
256 // -----------------------------------------------------------------------------
257
ImplAutoSwapIn()258 void GraphicObject::ImplAutoSwapIn()
259 {
260 if( IsSwappedOut() )
261 {
262 if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
263 mbAutoSwapped = sal_False;
264 else
265 {
266 mbIsInSwapIn = sal_True;
267
268 if( maGraphic.SwapIn() )
269 mbAutoSwapped = sal_False;
270 else
271 {
272 SvStream* pStream = GetSwapStream();
273
274 if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
275 {
276 if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
277 {
278 if( HasLink() )
279 {
280 String aURLStr;
281
282 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( GetLink(), aURLStr ) )
283 {
284 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_READ );
285
286 if( pIStm )
287 {
288 (*pIStm) >> maGraphic;
289 mbAutoSwapped = ( maGraphic.GetType() != GRAPHIC_NONE );
290 delete pIStm;
291 }
292 }
293 }
294 }
295 else if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
296 mbAutoSwapped = !maGraphic.SwapIn();
297 else if( GRFMGR_AUTOSWAPSTREAM_LOADED == pStream )
298 mbAutoSwapped = maGraphic.IsSwapOut();
299 else
300 {
301 mbAutoSwapped = !maGraphic.SwapIn( pStream );
302 delete pStream;
303 }
304 }
305 else
306 {
307 DBG_ASSERT( ( GRAPHIC_NONE == meType ) || ( GRAPHIC_DEFAULT == meType ),
308 "GraphicObject::ImplAutoSwapIn: could not get stream to swap in graphic! (=>KA)" );
309 }
310 }
311
312 mbIsInSwapIn = sal_False;
313
314 if( !mbAutoSwapped && mpMgr )
315 mpMgr->ImplGraphicObjectWasSwappedIn( *this );
316 }
317
318 // Handle evtl. needed AfterDataChanges
319 ImplAfterDataChange();
320 }
321 }
322
323 // -----------------------------------------------------------------------------
ImplGetCropParams(OutputDevice * pOut,Point & rPt,Size & rSz,const GraphicAttr * pAttr,PolyPolygon & rClipPolyPoly,sal_Bool & bRectClipRegion) const324 sal_Bool GraphicObject::ImplGetCropParams( OutputDevice* pOut, Point& rPt, Size& rSz, const GraphicAttr* pAttr,
325 PolyPolygon& rClipPolyPoly, sal_Bool& bRectClipRegion ) const
326 {
327 sal_Bool bRet = sal_False;
328
329 if( GetType() != GRAPHIC_NONE )
330 {
331 Polygon aClipPoly( Rectangle( rPt, rSz ) );
332 const sal_uInt16 nRot10 = pAttr->GetRotation() % 3600;
333 const Point aOldOrigin( rPt );
334 // --> OD 2005-09-30 #i54875# - It's not needed to get the graphic again.
335 // const Graphic& rGraphic = GetGraphic();
336 // <--
337 const MapMode aMap100( MAP_100TH_MM );
338 Size aSize100;
339 long nTotalWidth, nTotalHeight;
340 long nNewLeft, nNewTop, nNewRight, nNewBottom;
341 double fScale;
342
343 if( nRot10 )
344 {
345 aClipPoly.Rotate( rPt, nRot10 );
346 bRectClipRegion = sal_False;
347 }
348 else
349 bRectClipRegion = sal_True;
350
351 rClipPolyPoly = aClipPoly;
352
353 // --> OD 2005-09-30 #i54875# - directly access member <maGraphic> to
354 // get <PrefSize> and <PrefMapMode>.
355 // if( rGraphic.GetPrefMapMode() == MAP_PIXEL )
356 // aSize100 = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), aMap100 );
357 // else
358 // aSize100 = pOut->LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), aMap100 );
359 if( maGraphic.GetPrefMapMode() == MAP_PIXEL )
360 aSize100 = Application::GetDefaultDevice()->PixelToLogic( maGraphic.GetPrefSize(), aMap100 );
361 else
362 {
363 MapMode m(maGraphic.GetPrefMapMode());
364 aSize100 = pOut->LogicToLogic( maGraphic.GetPrefSize(), &m, &aMap100 );
365 }
366 // <--
367
368 nTotalWidth = aSize100.Width() - pAttr->GetLeftCrop() - pAttr->GetRightCrop();
369 nTotalHeight = aSize100.Height() - pAttr->GetTopCrop() - pAttr->GetBottomCrop();
370
371 if( aSize100.Width() > 0 && aSize100.Height() > 0 && nTotalWidth > 0 && nTotalHeight > 0 )
372 {
373 fScale = (double) aSize100.Width() / nTotalWidth;
374 nNewLeft = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_HORZ ) ? pAttr->GetRightCrop() : pAttr->GetLeftCrop() ) * fScale );
375 nNewRight = nNewLeft + FRound( aSize100.Width() * fScale ) - 1;
376
377 fScale = (double) rSz.Width() / aSize100.Width();
378 rPt.X() += FRound( nNewLeft * fScale );
379 rSz.Width() = FRound( ( nNewRight - nNewLeft + 1 ) * fScale );
380
381 fScale = (double) aSize100.Height() / nTotalHeight;
382 nNewTop = -FRound( ( ( pAttr->GetMirrorFlags() & BMP_MIRROR_VERT ) ? pAttr->GetBottomCrop() : pAttr->GetTopCrop() ) * fScale );
383 nNewBottom = nNewTop + FRound( aSize100.Height() * fScale ) - 1;
384
385 fScale = (double) rSz.Height() / aSize100.Height();
386 rPt.Y() += FRound( nNewTop * fScale );
387 rSz.Height() = FRound( ( nNewBottom - nNewTop + 1 ) * fScale );
388
389 if( nRot10 )
390 {
391 Polygon aOriginPoly( 1 );
392
393 aOriginPoly[ 0 ] = rPt;
394 aOriginPoly.Rotate( aOldOrigin, nRot10 );
395 rPt = aOriginPoly[ 0 ];
396 }
397
398 bRet = sal_True;
399 }
400 }
401
402 return bRet;
403 }
404
405 // -----------------------------------------------------------------------------
406
operator =(const GraphicObject & rGraphicObj)407 GraphicObject& GraphicObject::operator=( const GraphicObject& rGraphicObj )
408 {
409 if( &rGraphicObj != this )
410 {
411 mpMgr->ImplUnregisterObj( *this );
412
413 delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
414 delete mpSimpleCache, mpSimpleCache = NULL;
415 delete mpLink;
416 delete mpUserData;
417
418 maGraphic = rGraphicObj.GetGraphic();
419 maAttr = rGraphicObj.maAttr;
420 mpLink = rGraphicObj.mpLink ? new String( *rGraphicObj.mpLink ) : NULL;
421 mpUserData = rGraphicObj.mpUserData ? new String( *rGraphicObj.mpUserData ) : NULL;
422 ImplAssignGraphicData();
423 mbAutoSwapped = sal_False;
424 mpMgr = rGraphicObj.mpMgr;
425
426 mpMgr->ImplRegisterObj( *this, maGraphic, NULL, &rGraphicObj );
427 }
428
429 return *this;
430 }
431
432 // -----------------------------------------------------------------------------
433
operator ==(const GraphicObject & rGraphicObj) const434 sal_Bool GraphicObject::operator==( const GraphicObject& rGraphicObj ) const
435 {
436 return( ( rGraphicObj.maGraphic == maGraphic ) &&
437 ( rGraphicObj.maAttr == maAttr ) &&
438 ( rGraphicObj.GetLink() == GetLink() ) );
439 }
440
441 // ------------------------------------------------------------------------
442
Load(SvStream & rIStm)443 void GraphicObject::Load( SvStream& rIStm )
444 {
445 rIStm >> *this;
446 }
447
448 // ------------------------------------------------------------------------
449
Save(SvStream & rOStm)450 void GraphicObject::Save( SvStream& rOStm )
451 {
452 rOStm << *this;
453 }
454
455 // ------------------------------------------------------------------------
456
Assign(const SvDataCopyStream & rCopyStream)457 void GraphicObject::Assign( const SvDataCopyStream& rCopyStream )
458 {
459 *this = (const GraphicObject& ) rCopyStream;
460 }
461
462 // -----------------------------------------------------------------------------
463
GetUniqueID() const464 ByteString GraphicObject::GetUniqueID() const
465 {
466 if ( !IsInSwapIn() && IsEPS() )
467 const_cast<GraphicObject*>(this)->FireSwapInRequest();
468
469 ByteString aRet;
470
471 if( mpMgr )
472 aRet = mpMgr->ImplGetUniqueID( *this );
473
474 return aRet;
475 }
476
477 // -----------------------------------------------------------------------------
478
GetChecksum() const479 sal_uLong GraphicObject::GetChecksum() const
480 {
481 return( ( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() ) ? maGraphic.GetChecksum() : 0 );
482 }
483
484 // -----------------------------------------------------------------------------
485
GetSwapStream() const486 SvStream* GraphicObject::GetSwapStream() const
487 {
488 return( HasSwapStreamHdl() ? (SvStream*) mpSwapStreamHdl->Call( (void*) this ) : GRFMGR_AUTOSWAPSTREAM_NONE );
489 }
490
491 // -----------------------------------------------------------------------------
492
493 // !!! to be removed
GetReleaseFromCache() const494 sal_uLong GraphicObject::GetReleaseFromCache() const
495 {
496 return 0;
497 }
498
499 // -----------------------------------------------------------------------------
500
SetAttr(const GraphicAttr & rAttr)501 void GraphicObject::SetAttr( const GraphicAttr& rAttr )
502 {
503 maAttr = rAttr;
504
505 if( mpSimpleCache && ( mpSimpleCache->maAttr != rAttr ) )
506 delete mpSimpleCache, mpSimpleCache = NULL;
507 }
508
509 // -----------------------------------------------------------------------------
510
SetLink()511 void GraphicObject::SetLink()
512 {
513 if( mpLink )
514 delete mpLink, mpLink = NULL;
515 }
516
517 // -----------------------------------------------------------------------------
518
SetLink(const String & rLink)519 void GraphicObject::SetLink( const String& rLink )
520 {
521 delete mpLink, mpLink = new String( rLink );
522 }
523
524 // -----------------------------------------------------------------------------
525
GetLink() const526 String GraphicObject::GetLink() const
527 {
528 if( mpLink )
529 return *mpLink;
530 else
531 return String();
532 }
533
534 // -----------------------------------------------------------------------------
535
SetUserData()536 void GraphicObject::SetUserData()
537 {
538 if( mpUserData )
539 delete mpUserData, mpUserData = NULL;
540 }
541
542 // -----------------------------------------------------------------------------
543
SetUserData(const String & rUserData)544 void GraphicObject::SetUserData( const String& rUserData )
545 {
546 delete mpUserData, mpUserData = new String( rUserData );
547 }
548
549 // -----------------------------------------------------------------------------
550
GetUserData() const551 String GraphicObject::GetUserData() const
552 {
553 if( mpUserData )
554 return *mpUserData;
555 else
556 return String();
557 }
558
559 // -----------------------------------------------------------------------------
560
SetSwapStreamHdl()561 void GraphicObject::SetSwapStreamHdl()
562 {
563 if( mpSwapStreamHdl )
564 {
565 delete mpSwapOutTimer, mpSwapOutTimer = NULL;
566 delete mpSwapStreamHdl, mpSwapStreamHdl = NULL;
567 }
568 }
569
570 // -----------------------------------------------------------------------------
571
SetSwapStreamHdl(const Link & rHdl,const sal_uLong nSwapOutTimeout)572 void GraphicObject::SetSwapStreamHdl( const Link& rHdl, const sal_uLong nSwapOutTimeout )
573 {
574 delete mpSwapStreamHdl, mpSwapStreamHdl = new Link( rHdl );
575
576 if( nSwapOutTimeout )
577 {
578 if( !mpSwapOutTimer )
579 {
580 mpSwapOutTimer = new Timer;
581 mpSwapOutTimer->SetTimeoutHdl( LINK( this, GraphicObject, ImplAutoSwapOutHdl ) );
582 }
583
584 mpSwapOutTimer->SetTimeout( nSwapOutTimeout );
585 mpSwapOutTimer->Start();
586 }
587 else
588 delete mpSwapOutTimer, mpSwapOutTimer = NULL;
589 }
590
591 // -----------------------------------------------------------------------------
592
GetSwapStreamHdl() const593 Link GraphicObject::GetSwapStreamHdl() const
594 {
595 if( mpSwapStreamHdl )
596 return *mpSwapStreamHdl;
597 else
598 return Link();
599 }
600
601 // -----------------------------------------------------------------------------
602
FireSwapInRequest()603 void GraphicObject::FireSwapInRequest()
604 {
605 ImplAutoSwapIn();
606 }
607
608 // -----------------------------------------------------------------------------
609
FireSwapOutRequest()610 void GraphicObject::FireSwapOutRequest()
611 {
612 ImplAutoSwapOutHdl( NULL );
613 }
614
615 // -----------------------------------------------------------------------------
616
GraphicManagerDestroyed()617 void GraphicObject::GraphicManagerDestroyed()
618 {
619 // we're alive, but our manager doesn't live anymore ==> connect to default manager
620 mpMgr = NULL;
621 ImplSetGraphicManager( NULL );
622 }
623
624 // -----------------------------------------------------------------------------
625
SetGraphicManager(const GraphicManager & rMgr)626 void GraphicObject::SetGraphicManager( const GraphicManager& rMgr )
627 {
628 ImplSetGraphicManager( &rMgr );
629 }
630
631 // -----------------------------------------------------------------------------
632
IsCached(OutputDevice * pOut,const Point & rPt,const Size & rSz,const GraphicAttr * pAttr,sal_uLong nFlags) const633 sal_Bool GraphicObject::IsCached( OutputDevice* pOut, const Point& rPt, const Size& rSz,
634 const GraphicAttr* pAttr, sal_uLong nFlags ) const
635 {
636 sal_Bool bRet;
637
638 if( nFlags & GRFMGR_DRAW_CACHED )
639 {
640 // --> OD 2005-10-11 #i54875# - Consider cropped graphics.
641 // Note: The graphic manager caches a cropped graphic with its
642 // uncropped position and size.
643 // bRet = mpMgr->IsInCache( pOut, rPt, rSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
644 Point aPt( rPt );
645 Size aSz( rSz );
646 if ( pAttr->IsCropped() )
647 {
648 PolyPolygon aClipPolyPoly;
649 sal_Bool bRectClip;
650 ImplGetCropParams( pOut, aPt, aSz, pAttr, aClipPolyPoly, bRectClip );
651 }
652 bRet = mpMgr->IsInCache( pOut, aPt, aSz, *this, ( pAttr ? *pAttr : GetAttr() ) );
653 }
654 else
655 bRet = sal_False;
656
657 return bRet;
658 }
659
660 // -----------------------------------------------------------------------------
661
ReleaseFromCache()662 void GraphicObject::ReleaseFromCache()
663 {
664
665 mpMgr->ReleaseFromCache( *this );
666 }
667
668 // -----------------------------------------------------------------------------
669
SetAnimationNotifyHdl(const Link & rLink)670 void GraphicObject::SetAnimationNotifyHdl( const Link& rLink )
671 {
672 maGraphic.SetAnimationNotifyHdl( rLink );
673 }
674
675 // -----------------------------------------------------------------------------
676
GetAnimationInfoList() const677 List* GraphicObject::GetAnimationInfoList() const
678 {
679 return maGraphic.GetAnimationInfoList();
680 }
681
682 // -----------------------------------------------------------------------------
683
Draw(OutputDevice * pOut,const Point & rPt,const Size & rSz,const GraphicAttr * pAttr,sal_uLong nFlags)684 sal_Bool GraphicObject::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz,
685 const GraphicAttr* pAttr, sal_uLong nFlags )
686 {
687 GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
688 Point aPt( rPt );
689 Size aSz( rSz );
690 const sal_uInt32 nOldDrawMode = pOut->GetDrawMode();
691 sal_Bool bCropped = aAttr.IsCropped();
692 sal_Bool bCached = sal_False;
693 sal_Bool bRet;
694
695 // #i29534# Provide output rects for PDF writer
696 Rectangle aCropRect;
697
698 if( !( GRFMGR_DRAW_USE_DRAWMODE_SETTINGS & nFlags ) )
699 pOut->SetDrawMode( nOldDrawMode & ( ~( DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ) ) );
700
701 // mirrored horizontically
702 if( aSz.Width() < 0L )
703 {
704 aPt.X() += aSz.Width() + 1;
705 aSz.Width() = -aSz.Width();
706 aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_HORZ );
707 }
708
709 // mirrored vertically
710 if( aSz.Height() < 0L )
711 {
712 aPt.Y() += aSz.Height() + 1;
713 aSz.Height() = -aSz.Height();
714 aAttr.SetMirrorFlags( aAttr.GetMirrorFlags() ^ BMP_MIRROR_VERT );
715 }
716
717 if( bCropped )
718 {
719 PolyPolygon aClipPolyPoly;
720 sal_Bool bRectClip;
721 const sal_Bool bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );
722
723 pOut->Push( PUSH_CLIPREGION );
724
725 if( bCrop )
726 {
727 if( bRectClip )
728 {
729 // #i29534# Store crop rect for later forwarding to
730 // PDF writer
731 aCropRect = aClipPolyPoly.GetBoundRect();
732 pOut->IntersectClipRegion( aCropRect );
733 }
734 else
735 {
736 pOut->IntersectClipRegion( aClipPolyPoly );
737 }
738 }
739 }
740
741 bRet = mpMgr->DrawObj( pOut, aPt, aSz, *this, aAttr, nFlags, bCached );
742
743 if( bCropped )
744 pOut->Pop();
745
746 pOut->SetDrawMode( nOldDrawMode );
747
748 // #i29534# Moved below OutDev restoration, to avoid multiple swap-ins
749 // (code above needs to call GetGraphic twice)
750 if( bCached )
751 {
752 if( mpSwapOutTimer )
753 mpSwapOutTimer->Start();
754 else
755 FireSwapOutRequest();
756 }
757
758 return bRet;
759 }
760
761 // --> OD 2010-01-04 #i105243#
DrawWithPDFHandling(OutputDevice & rOutDev,const Point & rPt,const Size & rSz,const GraphicAttr * pGrfAttr,const sal_uLong nFlags)762 sal_Bool GraphicObject::DrawWithPDFHandling( OutputDevice& rOutDev,
763 const Point& rPt, const Size& rSz,
764 const GraphicAttr* pGrfAttr,
765 const sal_uLong nFlags )
766 {
767 const GraphicAttr aGrfAttr( pGrfAttr ? *pGrfAttr : GetAttr() );
768
769 // Notify PDF writer about linked graphic (if any)
770 sal_Bool bWritingPdfLinkedGraphic( sal_False );
771 Point aPt( rPt );
772 Size aSz( rSz );
773 Rectangle aCropRect;
774 vcl::PDFExtOutDevData* pPDFExtOutDevData =
775 dynamic_cast<vcl::PDFExtOutDevData*>(rOutDev.GetExtOutDevData());
776 if( pPDFExtOutDevData )
777 {
778 // only delegate image handling to PDF, if no special treatment is necessary
779 if( GetGraphic().IsLink() &&
780 rSz.Width() > 0L &&
781 rSz.Height() > 0L &&
782 !aGrfAttr.IsSpecialDrawMode() &&
783 !aGrfAttr.IsMirrored() &&
784 !aGrfAttr.IsRotated() &&
785 !aGrfAttr.IsAdjusted() )
786 {
787 bWritingPdfLinkedGraphic = true;
788
789 if( aGrfAttr.IsCropped() )
790 {
791 PolyPolygon aClipPolyPoly;
792 sal_Bool bRectClip;
793 const sal_Bool bCrop = ImplGetCropParams( &rOutDev,
794 aPt, aSz,
795 &aGrfAttr,
796 aClipPolyPoly,
797 bRectClip );
798 if ( bCrop && bRectClip )
799 {
800 aCropRect = aClipPolyPoly.GetBoundRect();
801 }
802 }
803
804 pPDFExtOutDevData->BeginGroup();
805 }
806 }
807
808 sal_Bool bRet = Draw( &rOutDev, rPt, rSz, &aGrfAttr, nFlags );
809
810 // Notify PDF writer about linked graphic (if any)
811 if( bWritingPdfLinkedGraphic )
812 {
813 pPDFExtOutDevData->EndGroup( const_cast< Graphic& >(GetGraphic()),
814 aGrfAttr.GetTransparency(),
815 Rectangle( aPt, aSz ),
816 aCropRect );
817 }
818
819 return bRet;
820 }
821 // <--
822
823 // -----------------------------------------------------------------------------
824
DrawTiled(OutputDevice * pOut,const Rectangle & rArea,const Size & rSize,const Size & rOffset,const GraphicAttr * pAttr,sal_uLong nFlags,int nTileCacheSize1D)825 sal_Bool GraphicObject::DrawTiled( OutputDevice* pOut, const Rectangle& rArea, const Size& rSize,
826 const Size& rOffset, const GraphicAttr* pAttr, sal_uLong nFlags, int nTileCacheSize1D )
827 {
828 if( pOut == NULL || rSize.Width() == 0 || rSize.Height() == 0 )
829 return sal_False;
830
831 const MapMode aOutMapMode( pOut->GetMapMode() );
832 const MapMode aMapMode( aOutMapMode.GetMapUnit(), Point(), aOutMapMode.GetScaleX(), aOutMapMode.GetScaleY() );
833 // #106258# Clamp size to 1 for zero values. This is okay, since
834 // logical size of zero is handled above already
835 const Size aOutTileSize( ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Width() ),
836 ::std::max( 1L, pOut->LogicToPixel( rSize, aOutMapMode ).Height() ) );
837
838 //#i69780 clip final tile size to a sane max size
839 while (((sal_Int64)rSize.Width() * nTileCacheSize1D) > SAL_MAX_UINT16)
840 nTileCacheSize1D /= 2;
841 while (((sal_Int64)rSize.Height() * nTileCacheSize1D) > SAL_MAX_UINT16)
842 nTileCacheSize1D /= 2;
843
844 return ImplDrawTiled( pOut, rArea, aOutTileSize, rOffset, pAttr, nFlags, nTileCacheSize1D );
845 }
846
847 // -----------------------------------------------------------------------------
848
StartAnimation(OutputDevice * pOut,const Point & rPt,const Size & rSz,long nExtraData,const GraphicAttr * pAttr,sal_uLong,OutputDevice * pFirstFrameOutDev)849 sal_Bool GraphicObject::StartAnimation( OutputDevice* pOut, const Point& rPt, const Size& rSz,
850 long nExtraData, const GraphicAttr* pAttr, sal_uLong /*nFlags*/,
851 OutputDevice* pFirstFrameOutDev )
852 {
853 sal_Bool bRet = sal_False;
854
855 GetGraphic();
856
857 if( !IsSwappedOut() )
858 {
859 const GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
860
861 if( mbAnimated )
862 {
863 Point aPt( rPt );
864 Size aSz( rSz );
865 sal_Bool bCropped = aAttr.IsCropped();
866
867 if( bCropped )
868 {
869 PolyPolygon aClipPolyPoly;
870 sal_Bool bRectClip;
871 const sal_Bool bCrop = ImplGetCropParams( pOut, aPt, aSz, &aAttr, aClipPolyPoly, bRectClip );
872
873 pOut->Push( PUSH_CLIPREGION );
874
875 if( bCrop )
876 {
877 if( bRectClip )
878 pOut->IntersectClipRegion( aClipPolyPoly.GetBoundRect() );
879 else
880 pOut->IntersectClipRegion( aClipPolyPoly );
881 }
882 }
883
884 if( !mpSimpleCache || ( mpSimpleCache->maAttr != aAttr ) || pFirstFrameOutDev )
885 {
886 if( mpSimpleCache )
887 delete mpSimpleCache;
888
889 mpSimpleCache = new GrfSimpleCacheObj( GetTransformedGraphic( &aAttr ), aAttr );
890 mpSimpleCache->maGraphic.SetAnimationNotifyHdl( GetAnimationNotifyHdl() );
891 }
892
893 mpSimpleCache->maGraphic.StartAnimation( pOut, aPt, aSz, nExtraData, pFirstFrameOutDev );
894
895 if( bCropped )
896 pOut->Pop();
897
898 bRet = sal_True;
899 }
900 else
901 bRet = Draw( pOut, rPt, rSz, &aAttr, GRFMGR_DRAW_STANDARD );
902 }
903
904 return bRet;
905 }
906
907 // -----------------------------------------------------------------------------
908
StopAnimation(OutputDevice * pOut,long nExtraData)909 void GraphicObject::StopAnimation( OutputDevice* pOut, long nExtraData )
910 {
911 if( mpSimpleCache )
912 mpSimpleCache->maGraphic.StopAnimation( pOut, nExtraData );
913 }
914
915 // -----------------------------------------------------------------------------
916
GetGraphic() const917 const Graphic& GraphicObject::GetGraphic() const
918 {
919 if( mbAutoSwapped )
920 ( (GraphicObject*) this )->ImplAutoSwapIn();
921
922 return maGraphic;
923 }
924
925 // -----------------------------------------------------------------------------
926
SetGraphic(const Graphic & rGraphic,const GraphicObject * pCopyObj)927 void GraphicObject::SetGraphic( const Graphic& rGraphic, const GraphicObject* pCopyObj )
928 {
929 mpMgr->ImplUnregisterObj( *this );
930
931 if( mpSwapOutTimer )
932 mpSwapOutTimer->Stop();
933
934 maGraphic = rGraphic;
935 mbAutoSwapped = sal_False;
936 ImplAssignGraphicData();
937 delete mpLink, mpLink = NULL;
938 delete mpSimpleCache, mpSimpleCache = NULL;
939
940 mpMgr->ImplRegisterObj( *this, maGraphic, 0, pCopyObj);
941
942 if( mpSwapOutTimer )
943 mpSwapOutTimer->Start();
944
945 // Handle evtl. needed AfterDataChanges
946 ImplAfterDataChange();
947 }
948
949 // -----------------------------------------------------------------------------
950
SetGraphic(const Graphic & rGraphic,const String & rLink)951 void GraphicObject::SetGraphic( const Graphic& rGraphic, const String& rLink )
952 {
953 SetGraphic( rGraphic );
954 mpLink = new String( rLink );
955 }
956
957 // -----------------------------------------------------------------------------
958
GetTransformedGraphic(const Size & rDestSize,const MapMode & rDestMap,const GraphicAttr & rAttr) const959 Graphic GraphicObject::GetTransformedGraphic( const Size& rDestSize, const MapMode& rDestMap, const GraphicAttr& rAttr ) const
960 {
961 // #104550# Extracted from svx/source/svdraw/svdograf.cxx
962 Graphic aTransGraphic( maGraphic );
963 const GraphicType eType = GetType();
964 const Size aSrcSize( aTransGraphic.GetPrefSize() );
965
966 // #104115# Convert the crop margins to graphic object mapmode
967 const MapMode aMapGraph( aTransGraphic.GetPrefMapMode() );
968 const MapMode aMap100( MAP_100TH_MM );
969
970 Size aCropLeftTop;
971 Size aCropRightBottom;
972
973 if( GRAPHIC_GDIMETAFILE == eType )
974 {
975 GDIMetaFile aMtf( aTransGraphic.GetGDIMetaFile() );
976
977 if( aMapGraph == MAP_PIXEL )
978 {
979 // crops are in 1/100th mm -> to aMapGraph -> to MAP_PIXEL
980 aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
981 Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
982 aMap100);
983 aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
984 Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
985 aMap100);
986 }
987 else
988 {
989 // crops are in GraphicObject units -> to aMapGraph
990 aCropLeftTop = OutputDevice::LogicToLogic(
991 Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
992 aMap100,
993 aMapGraph);
994 aCropRightBottom = OutputDevice::LogicToLogic(
995 Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
996 aMap100,
997 aMapGraph);
998 }
999
1000 // #104115# If the metafile is cropped, give it a special
1001 // treatment: clip against the remaining area, scale up such
1002 // that this area later fills the desired size, and move the
1003 // origin to the upper left edge of that area.
1004 if( rAttr.IsCropped() )
1005 {
1006 const MapMode aMtfMapMode( aMtf.GetPrefMapMode() );
1007
1008 Rectangle aClipRect( aMtfMapMode.GetOrigin().X() + aCropLeftTop.Width(),
1009 aMtfMapMode.GetOrigin().Y() + aCropLeftTop.Height(),
1010 aMtfMapMode.GetOrigin().X() + aSrcSize.Width() - aCropRightBottom.Width(),
1011 aMtfMapMode.GetOrigin().Y() + aSrcSize.Height() - aCropRightBottom.Height() );
1012
1013 // #104115# To correctly crop rotated metafiles, clip by view rectangle
1014 aMtf.AddAction( new MetaISectRectClipRegionAction( aClipRect ), 0 );
1015
1016 // #104115# To crop the metafile, scale larger than the output rectangle
1017 aMtf.Scale( (double)rDestSize.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()),
1018 (double)rDestSize.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) );
1019
1020 // #104115# Adapt the pref size by hand (scale changes it
1021 // proportionally, but we want it to be smaller than the
1022 // former size, to crop the excess out)
1023 aMtf.SetPrefSize( Size( (long)((double)rDestSize.Width() * (1.0 + (aCropLeftTop.Width() + aCropRightBottom.Width()) / aSrcSize.Width()) + .5),
1024 (long)((double)rDestSize.Height() * (1.0 + (aCropLeftTop.Height() + aCropRightBottom.Height()) / aSrcSize.Height()) + .5) ) );
1025
1026 // #104115# Adapt the origin of the new mapmode, such that it
1027 // is shifted to the place where the cropped output starts
1028 Point aNewOrigin( (long)((double)aMtfMapMode.GetOrigin().X() + rDestSize.Width() * aCropLeftTop.Width() / (aSrcSize.Width() - aCropLeftTop.Width() - aCropRightBottom.Width()) + .5),
1029 (long)((double)aMtfMapMode.GetOrigin().Y() + rDestSize.Height() * aCropLeftTop.Height() / (aSrcSize.Height() - aCropLeftTop.Height() - aCropRightBottom.Height()) + .5) );
1030 MapMode aNewMap( rDestMap );
1031 aNewMap.SetOrigin( OutputDevice::LogicToLogic(aNewOrigin, aMtfMapMode, rDestMap) );
1032 aMtf.SetPrefMapMode( aNewMap );
1033 }
1034 else
1035 {
1036 aMtf.Scale( Fraction( rDestSize.Width(), aSrcSize.Width() ), Fraction( rDestSize.Height(), aSrcSize.Height() ) );
1037 aMtf.SetPrefMapMode( rDestMap );
1038 }
1039
1040 aTransGraphic = aMtf;
1041 }
1042 else if( GRAPHIC_BITMAP == eType )
1043 {
1044 BitmapEx aBitmapEx( aTransGraphic.GetBitmapEx() );
1045 Rectangle aCropRect;
1046
1047 // convert crops to pixel
1048 if(rAttr.IsCropped())
1049 {
1050 if( aMapGraph == MAP_PIXEL )
1051 {
1052 // crops are in 1/100th mm -> to MAP_PIXEL
1053 aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
1054 Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
1055 aMap100);
1056 aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
1057 Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
1058 aMap100);
1059 }
1060 else
1061 {
1062 // crops are in GraphicObject units -> to MAP_PIXEL
1063 aCropLeftTop = Application::GetDefaultDevice()->LogicToPixel(
1064 Size(rAttr.GetLeftCrop(), rAttr.GetTopCrop()),
1065 aMapGraph);
1066 aCropRightBottom = Application::GetDefaultDevice()->LogicToPixel(
1067 Size(rAttr.GetRightCrop(), rAttr.GetBottomCrop()),
1068 aMapGraph);
1069 }
1070
1071 // convert from prefmapmode to pixel
1072 Size aSrcSizePixel(
1073 Application::GetDefaultDevice()->LogicToPixel(
1074 aSrcSize,
1075 aMapGraph));
1076
1077 if(rAttr.IsCropped()
1078 && (aSrcSizePixel.Width() != aBitmapEx.GetSizePixel().Width() || aSrcSizePixel.Height() != aBitmapEx.GetSizePixel().Height())
1079 && aSrcSizePixel.Width())
1080 {
1081 // the size in pixels calculated from Graphic's internal MapMode (aTransGraphic.GetPrefMapMode())
1082 // and it's internal size (aTransGraphic.GetPrefSize()) is different from it's real pixel size.
1083 // This can be interpreted as this values to be set wrong, but needs to be corrected since e.g.
1084 // existing cropping is calculated based on this logic values already.
1085 // aBitmapEx.Scale(aSrcSizePixel);
1086
1087 // another possibility is to adapt the values created so far with a factor; this
1088 // will keep the original Bitmap untouched and thus quality will not change
1089 // caution: convert to double first, else pretty big errors may occurr
1090 const double fFactorX((double)aBitmapEx.GetSizePixel().Width() / aSrcSizePixel.Width());
1091 const double fFactorY((double)aBitmapEx.GetSizePixel().Height() / aSrcSizePixel.Height());
1092
1093 aCropLeftTop.Width() = basegfx::fround(aCropLeftTop.Width() * fFactorX);
1094 aCropLeftTop.Height() = basegfx::fround(aCropLeftTop.Height() * fFactorY);
1095 aCropRightBottom.Width() = basegfx::fround(aCropRightBottom.Width() * fFactorX);
1096 aCropRightBottom.Height() = basegfx::fround(aCropRightBottom.Height() * fFactorY);
1097
1098 aSrcSizePixel = aBitmapEx.GetSizePixel();
1099 }
1100
1101 // setup crop rectangle in pixel
1102 aCropRect = Rectangle( aCropLeftTop.Width(), aCropLeftTop.Height(),
1103 aSrcSizePixel.Width() - aCropRightBottom.Width(),
1104 aSrcSizePixel.Height() - aCropRightBottom.Height() );
1105 }
1106
1107 // #105641# Also crop animations
1108 if( aTransGraphic.IsAnimated() )
1109 {
1110 sal_uInt16 nFrame;
1111 Animation aAnim( aTransGraphic.GetAnimation() );
1112
1113 for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
1114 {
1115 AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );
1116
1117 if( !aCropRect.IsInside( Rectangle(aAnimBmp.aPosPix, aAnimBmp.aSizePix) ) )
1118 {
1119 // setup actual cropping (relative to frame position)
1120 Rectangle aCropRectRel( aCropRect );
1121 aCropRectRel.Move( -aAnimBmp.aPosPix.X(),
1122 -aAnimBmp.aPosPix.Y() );
1123
1124 // cropping affects this frame, apply it then
1125 // do _not_ apply enlargement, this is done below
1126 ImplTransformBitmap( aAnimBmp.aBmpEx, rAttr, Size(), Size(),
1127 aCropRectRel, rDestSize, sal_False );
1128
1129 aAnim.Replace( aAnimBmp, nFrame );
1130 }
1131 // else: bitmap completely within crop area,
1132 // i.e. nothing is cropped away
1133 }
1134
1135 // now, apply enlargement (if any) through global animation size
1136 if( aCropLeftTop.Width() < 0 ||
1137 aCropLeftTop.Height() < 0 ||
1138 aCropRightBottom.Width() < 0 ||
1139 aCropRightBottom.Height() < 0 )
1140 {
1141 Size aNewSize( aAnim.GetDisplaySizePixel() );
1142 aNewSize.Width() += aCropRightBottom.Width() < 0 ? -aCropRightBottom.Width() : 0;
1143 aNewSize.Width() += aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0;
1144 aNewSize.Height() += aCropRightBottom.Height() < 0 ? -aCropRightBottom.Height() : 0;
1145 aNewSize.Height() += aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0;
1146 aAnim.SetDisplaySizePixel( aNewSize );
1147 }
1148
1149 // if topleft has changed, we must move all frames to the
1150 // right and bottom, resp.
1151 if( aCropLeftTop.Width() < 0 ||
1152 aCropLeftTop.Height() < 0 )
1153 {
1154 Point aPosOffset( aCropLeftTop.Width() < 0 ? -aCropLeftTop.Width() : 0,
1155 aCropLeftTop.Height() < 0 ? -aCropLeftTop.Height() : 0 );
1156
1157 for( nFrame=0; nFrame<aAnim.Count(); ++nFrame )
1158 {
1159 AnimationBitmap aAnimBmp( aAnim.Get( nFrame ) );
1160
1161 aAnimBmp.aPosPix += aPosOffset;
1162
1163 aAnim.Replace( aAnimBmp, nFrame );
1164 }
1165 }
1166
1167 aTransGraphic = aAnim;
1168 }
1169 else
1170 {
1171 ImplTransformBitmap( aBitmapEx, rAttr, aCropLeftTop, aCropRightBottom,
1172 aCropRect, rDestSize, sal_True );
1173
1174 aTransGraphic = aBitmapEx;
1175 }
1176
1177 aTransGraphic.SetPrefSize( rDestSize );
1178 aTransGraphic.SetPrefMapMode( rDestMap );
1179 }
1180
1181 GraphicObject aGrfObj( aTransGraphic );
1182 aTransGraphic = aGrfObj.GetTransformedGraphic( &rAttr );
1183
1184 return aTransGraphic;
1185 }
1186
1187 // -----------------------------------------------------------------------------
1188
GetTransformedGraphic(const GraphicAttr * pAttr) const1189 Graphic GraphicObject::GetTransformedGraphic( const GraphicAttr* pAttr ) const // TODO: Change to Impl
1190 {
1191 GetGraphic();
1192
1193 Graphic aGraphic;
1194 GraphicAttr aAttr( pAttr ? *pAttr : GetAttr() );
1195
1196 if( maGraphic.IsSupportedGraphic() && !maGraphic.IsSwapOut() )
1197 {
1198 if( aAttr.IsSpecialDrawMode() || aAttr.IsAdjusted() || aAttr.IsMirrored() || aAttr.IsRotated() || aAttr.IsTransparent() )
1199 {
1200 if( GetType() == GRAPHIC_BITMAP )
1201 {
1202 if( IsAnimated() )
1203 {
1204 Animation aAnimation( maGraphic.GetAnimation() );
1205 GraphicManager::ImplAdjust( aAnimation, aAttr, ADJUSTMENT_ALL );
1206 aAnimation.SetLoopCount( mnAnimationLoopCount );
1207 aGraphic = aAnimation;
1208 }
1209 else
1210 {
1211 BitmapEx aBmpEx( maGraphic.GetBitmapEx() );
1212 GraphicManager::ImplAdjust( aBmpEx, aAttr, ADJUSTMENT_ALL );
1213 aGraphic = aBmpEx;
1214 }
1215 }
1216 else
1217 {
1218 GDIMetaFile aMtf( maGraphic.GetGDIMetaFile() );
1219 GraphicManager::ImplAdjust( aMtf, aAttr, ADJUSTMENT_ALL );
1220 aGraphic = aMtf;
1221 }
1222 }
1223 else
1224 {
1225 if( ( GetType() == GRAPHIC_BITMAP ) && IsAnimated() )
1226 {
1227 Animation aAnimation( maGraphic.GetAnimation() );
1228 aAnimation.SetLoopCount( mnAnimationLoopCount );
1229 aGraphic = aAnimation;
1230 }
1231 else
1232 aGraphic = maGraphic;
1233 }
1234 }
1235
1236 return aGraphic;
1237 }
1238
1239 // -----------------------------------------------------------------------------
1240
ResetAnimationLoopCount()1241 void GraphicObject::ResetAnimationLoopCount()
1242 {
1243 if( IsAnimated() && !IsSwappedOut() )
1244 {
1245 maGraphic.ResetAnimationLoopCount();
1246
1247 if( mpSimpleCache )
1248 mpSimpleCache->maGraphic.ResetAnimationLoopCount();
1249 }
1250 }
1251
1252 // -----------------------------------------------------------------------------
1253
SwapOut()1254 sal_Bool GraphicObject::SwapOut()
1255 {
1256 sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut() : sal_False );
1257
1258 if( bRet && mpMgr )
1259 mpMgr->ImplGraphicObjectWasSwappedOut( *this );
1260
1261 return bRet;
1262 }
1263
1264 // -----------------------------------------------------------------------------
1265
SwapOut(SvStream * pOStm)1266 sal_Bool GraphicObject::SwapOut( SvStream* pOStm )
1267 {
1268 sal_Bool bRet = ( !mbAutoSwapped ? maGraphic.SwapOut( pOStm ) : sal_False );
1269
1270 if( bRet && mpMgr )
1271 mpMgr->ImplGraphicObjectWasSwappedOut( *this );
1272
1273 return bRet;
1274 }
1275
1276 // -----------------------------------------------------------------------------
1277
SwapIn()1278 sal_Bool GraphicObject::SwapIn()
1279 {
1280 sal_Bool bRet;
1281
1282 if( mbAutoSwapped )
1283 {
1284 ImplAutoSwapIn();
1285 bRet = sal_True;
1286 }
1287 else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
1288 {
1289 bRet = sal_True;
1290 }
1291 else
1292 {
1293 bRet = maGraphic.SwapIn();
1294
1295 if( bRet && mpMgr )
1296 mpMgr->ImplGraphicObjectWasSwappedIn( *this );
1297 }
1298
1299 if( bRet )
1300 {
1301 ImplAssignGraphicData();
1302
1303 // Handle evtl. needed AfterDataChanges
1304 ImplAfterDataChange();
1305 }
1306
1307 return bRet;
1308 }
1309
1310 // -----------------------------------------------------------------------------
1311
SwapIn(SvStream * pIStm)1312 sal_Bool GraphicObject::SwapIn( SvStream* pIStm )
1313 {
1314 sal_Bool bRet;
1315
1316 if( mbAutoSwapped )
1317 {
1318 ImplAutoSwapIn();
1319 bRet = sal_True;
1320 }
1321 else if( mpMgr && mpMgr->ImplFillSwappedGraphicObject( *this, maGraphic ) )
1322 {
1323 bRet = sal_True;
1324 }
1325 else
1326 {
1327 bRet = maGraphic.SwapIn( pIStm );
1328
1329 if( bRet && mpMgr )
1330 mpMgr->ImplGraphicObjectWasSwappedIn( *this );
1331 }
1332
1333 if( bRet )
1334 {
1335 ImplAssignGraphicData();
1336
1337 //
1338 ImplAfterDataChange();
1339 }
1340
1341 return bRet;
1342 }
1343
1344 // -----------------------------------------------------------------------------
1345
SetSwapState()1346 void GraphicObject::SetSwapState()
1347 {
1348 if( !IsSwappedOut() )
1349 {
1350 mbAutoSwapped = sal_True;
1351
1352 if( mpMgr )
1353 mpMgr->ImplGraphicObjectWasSwappedOut( *this );
1354 }
1355 }
1356
1357 // -----------------------------------------------------------------------------
1358
IMPL_LINK(GraphicObject,ImplAutoSwapOutHdl,void *,EMPTYARG)1359 IMPL_LINK( GraphicObject, ImplAutoSwapOutHdl, void*, EMPTYARG )
1360 {
1361 if( !IsSwappedOut() )
1362 {
1363 mbIsInSwapOut = sal_True;
1364
1365 SvStream* pStream = GetSwapStream();
1366
1367 if( GRFMGR_AUTOSWAPSTREAM_NONE != pStream )
1368 {
1369 if( GRFMGR_AUTOSWAPSTREAM_LINK == pStream )
1370 mbAutoSwapped = SwapOut( NULL );
1371 else
1372 {
1373 if( GRFMGR_AUTOSWAPSTREAM_TEMP == pStream )
1374 mbAutoSwapped = SwapOut();
1375 else
1376 {
1377 mbAutoSwapped = SwapOut( pStream );
1378 delete pStream;
1379 }
1380 }
1381 }
1382
1383 mbIsInSwapOut = sal_False;
1384 }
1385
1386 if( mpSwapOutTimer )
1387 mpSwapOutTimer->Start();
1388
1389 return 0L;
1390 }
1391
1392 // ------------------------------------------------------------------------
1393
operator >>(SvStream & rIStm,GraphicObject & rGraphicObj)1394 SvStream& operator>>( SvStream& rIStm, GraphicObject& rGraphicObj )
1395 {
1396 VersionCompat aCompat( rIStm, STREAM_READ );
1397 Graphic aGraphic;
1398 GraphicAttr aAttr;
1399 ByteString aLink;
1400 sal_Bool bLink;
1401
1402 rIStm >> aGraphic >> aAttr >> bLink;
1403
1404 rGraphicObj.SetGraphic( aGraphic );
1405 rGraphicObj.SetAttr( aAttr );
1406
1407 if( bLink )
1408 {
1409 rIStm >> aLink;
1410 rGraphicObj.SetLink( UniString( aLink, RTL_TEXTENCODING_UTF8 ) );
1411 }
1412 else
1413 rGraphicObj.SetLink();
1414
1415 rGraphicObj.SetSwapStreamHdl();
1416
1417 return rIStm;
1418 }
1419
1420 // ------------------------------------------------------------------------
1421
operator <<(SvStream & rOStm,const GraphicObject & rGraphicObj)1422 SvStream& operator<<( SvStream& rOStm, const GraphicObject& rGraphicObj )
1423 {
1424 VersionCompat aCompat( rOStm, STREAM_WRITE, 1 );
1425 const sal_Bool bLink = rGraphicObj.HasLink();
1426
1427 rOStm << rGraphicObj.GetGraphic() << rGraphicObj.GetAttr() << bLink;
1428
1429 if( bLink )
1430 rOStm << ByteString( rGraphicObj.GetLink(), RTL_TEXTENCODING_UTF8 );
1431
1432 return rOStm;
1433 }
1434
1435 #define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:"
1436
CreateGraphicObjectFromURL(const::rtl::OUString & rURL)1437 GraphicObject GraphicObject::CreateGraphicObjectFromURL( const ::rtl::OUString &rURL )
1438 {
1439 const String aURL( rURL ), aPrefix( RTL_CONSTASCII_STRINGPARAM(UNO_NAME_GRAPHOBJ_URLPREFIX) );
1440 if( aURL.Search( aPrefix ) == 0 )
1441 {
1442 // graphic manager url
1443 ByteString aUniqueID( String(rURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 )), RTL_TEXTENCODING_UTF8 );
1444 return GraphicObject( aUniqueID );
1445 }
1446 else
1447 {
1448 Graphic aGraphic;
1449 if ( aURL.Len() )
1450 {
1451 // The URL comes out of document content, so it is followed only if
1452 // the shared policy permits it (see svtools/linkpolicy.hxx).
1453 if ( !::svt::linkpolicy::mayFollowDocumentLink( rURL ) )
1454 return GraphicObject( aGraphic );
1455
1456 SvStream* pStream = utl::UcbStreamHelper::CreateStream( aURL, STREAM_READ );
1457 if( pStream )
1458 GraphicConverter::Import( *pStream, aGraphic );
1459 }
1460
1461 return GraphicObject( aGraphic );
1462 }
1463 }
1464
1465 // calculate scalings between real image size and logic object size. This
1466 // is necessary since the crop values are relative to original bitmap size
calculateCropScaling(double fWidth,double fHeight,double fLeftCrop,double fTopCrop,double fRightCrop,double fBottomCrop) const1467 basegfx::B2DVector GraphicObject::calculateCropScaling(
1468 double fWidth,
1469 double fHeight,
1470 double fLeftCrop,
1471 double fTopCrop,
1472 double fRightCrop,
1473 double fBottomCrop) const
1474 {
1475 const MapMode aMapMode100thmm(MAP_100TH_MM);
1476 Size aBitmapSize(GetPrefSize());
1477 double fFactorX(1.0);
1478 double fFactorY(1.0);
1479
1480 if(MAP_PIXEL == GetPrefMapMode().GetMapUnit())
1481 {
1482 aBitmapSize = Application::GetDefaultDevice()->PixelToLogic(aBitmapSize, aMapMode100thmm);
1483 }
1484 else
1485 {
1486 aBitmapSize = Application::GetDefaultDevice()->LogicToLogic(aBitmapSize, GetPrefMapMode(), aMapMode100thmm);
1487 }
1488
1489 const double fDivX(aBitmapSize.Width() - fLeftCrop - fRightCrop);
1490 const double fDivY(aBitmapSize.Height() - fTopCrop - fBottomCrop);
1491
1492 if(!basegfx::fTools::equalZero(fDivX))
1493 {
1494 fFactorX = fabs(fWidth) / fDivX;
1495 }
1496
1497 if(!basegfx::fTools::equalZero(fDivY))
1498 {
1499 fFactorY = fabs(fHeight) / fDivY;
1500 }
1501
1502 return basegfx::B2DVector(fFactorX,fFactorY);
1503 }
1504
1505 // ------------------------------------------------------------------------
1506 // restart SwapOut timer
1507
restartSwapOutTimer() const1508 void GraphicObject::restartSwapOutTimer() const
1509 {
1510 if( mpSwapOutTimer && mpSwapOutTimer->IsActive() )
1511 {
1512 mpSwapOutTimer->Start();
1513 }
1514 }
1515
1516 // eof
1517