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