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