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