xref: /trunk/main/svx/source/svdraw/svdograf.cxx (revision 2037b4dea6c6e1d64a540d6f09020763cd429168)
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_svx.hxx"
26 
27 #define _ANIMATION
28 #include <unotools/streamwrap.hxx>
29 
30 #include <sfx2/lnkbase.hxx>
31 #include <math.h>
32 #include <vcl/salbtype.hxx>
33 #include <sot/formats.hxx>
34 #include <sot/storage.hxx>
35 #include <unotools/ucbstreamhelper.hxx>
36 #include <unotools/localfilehelper.hxx>
37 #include <svl/style.hxx>
38 #include <svtools/filter.hxx>
39 #include <svl/urihelper.hxx>
40 #include <svtools/grfmgr.hxx>
41 #include <vcl/svapp.hxx>
42 
43 #include <sfx2/linkmgr.hxx>
44 #include <sfx2/docfile.hxx>
45 #include <svx/svdetc.hxx>
46 #include "svx/svdglob.hxx"
47 #include "svx/svdstr.hrc"
48 #include <svx/svdpool.hxx>
49 #include <svx/svdmodel.hxx>
50 #include <svx/svdpage.hxx>
51 #include <svx/svdmrkv.hxx>
52 #include <svx/svdpagv.hxx>
53 #include "svx/svdviter.hxx"
54 #include <svx/svdview.hxx>
55 #include "svtools/filter.hxx"
56 #include <svx/svdograf.hxx>
57 #include <svx/svdogrp.hxx>
58 #include <svx/xbitmap.hxx>
59 #include <svx/xbtmpit.hxx>
60 #include <svx/xflbmtit.hxx>
61 #include <svx/svdundo.hxx>
62 #include "svdfmtf.hxx"
63 #include <svx/sdgcpitm.hxx>
64 #include <editeng/eeitem.hxx>
65 #include <svx/sdr/properties/graphicproperties.hxx>
66 #include <svx/sdr/contact/viewcontactofgraphic.hxx>
67 #include <basegfx/polygon/b2dpolygon.hxx>
68 #include <basegfx/polygon/b2dpolygontools.hxx>
69 #include <osl/thread.hxx>
70 #include <vos/mutex.hxx>
71 
72 using namespace ::com::sun::star::uno;
73 using namespace ::com::sun::star::io;
74 
75 // -----------
76 // - Defines -
77 // -----------
78 
79 #define GRAFSTREAMPOS_INVALID   0xffffffff
80 #define SWAPGRAPHIC_TIMEOUT     5000
81 
82 
83 // ------------------
84 // - SdrGraphicLink -
85 // ------------------
86 
87 
88 const Graphic ImpLoadLinkedGraphic( const String aFileName, const String aFilterName )
89 {
90     Graphic aGraphic;
91 
92     SfxMedium xMed( aFileName, STREAM_STD_READ, sal_True );
93     xMed.DownLoad();
94 
95     SvStream* pInStrm = xMed.GetInStream();
96     if ( pInStrm )
97     {
98         pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
99         GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
100 
101         const sal_uInt16 nFilter = aFilterName.Len() && pGF->GetImportFormatCount()
102                             ? pGF->GetImportFormatNumber( aFilterName )
103                             : GRFILTER_FORMAT_DONTKNOW;
104 
105         String aEmptyStr;
106         com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aFilterData( 1 );
107 
108         // Room for improvment:
109         // As this is a linked graphic the GfxLink is not needed if saving/loading our own format.
110         // But this link is required by some filters to access the native graphic (pdf export/ms export),
111         // there we should create a new service to provide this data if needed
112         aFilterData[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
113         aFilterData[ 0 ].Value = Any( sal_True );
114         pGF->ImportGraphic( aGraphic, aEmptyStr, *pInStrm, nFilter, NULL, 0, &aFilterData );
115     }
116     return aGraphic;
117 }
118 
119 class SdrGraphicUpdater;
120 class SdrGraphicLink : public sfx2::SvBaseLink
121 {
122     SdrGrafObj*         pGrafObj;
123     SdrGraphicUpdater*  pGraphicUpdater;
124 
125 public:
126                         SdrGraphicLink(SdrGrafObj* pObj);
127     virtual             ~SdrGraphicLink();
128 
129     virtual void        Closed();
130     virtual void        DataChanged( const String& rMimeType,
131                                 const ::com::sun::star::uno::Any & rValue );
132     void                DataChanged( const Graphic& rGraphic );
133 
134     sal_Bool                Connect() { return 0 != GetRealObject(); }
135     void                UpdateAsynchron();
136     void                RemoveGraphicUpdater();
137 };
138 
139 class SdrGraphicUpdater : public ::osl::Thread
140 {
141 public:
142     SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& );
143     virtual ~SdrGraphicUpdater( void );
144 
145     void SAL_CALL Terminate( void );
146 
147     sal_Bool GraphicLinkChanged( const String& rFileName ){ return maFileName != rFileName; };
148 
149 protected:
150 
151     /** is called from the inherited create method and acts as the
152         main function of this thread.
153     */
154     virtual void SAL_CALL run(void);
155 
156     /** Called after the thread is terminated via the terminate
157         method.  Used to kill the thread by calling delete on this.
158     */
159     virtual void SAL_CALL onTerminated(void);
160 
161 private:
162 
163     const String    maFileName;
164     const String    maFilterName;
165     SdrGraphicLink& mrGraphicLink;
166 
167     volatile bool mbIsTerminated;
168 };
169 
170 SdrGraphicUpdater::SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& rGraphicLink )
171 : maFileName( rFileName )
172 , maFilterName( rFilterName )
173 , mrGraphicLink( rGraphicLink )
174 , mbIsTerminated( sal_False )
175 {
176     create();
177 }
178 
179 SdrGraphicUpdater::~SdrGraphicUpdater( void )
180 {
181 }
182 
183 void SdrGraphicUpdater::Terminate()
184 {
185     mbIsTerminated = sal_True;
186 }
187 
188 void SAL_CALL SdrGraphicUpdater::onTerminated(void)
189 {
190     delete this;
191 }
192 
193 void SAL_CALL SdrGraphicUpdater::run(void)
194 {
195     Graphic aGraphic( ImpLoadLinkedGraphic( maFileName, maFilterName ) );
196     vos::OGuard aSolarGuard( Application::GetSolarMutex() );
197     if ( !mbIsTerminated )
198     {
199         mrGraphicLink.DataChanged( aGraphic );
200         mrGraphicLink.RemoveGraphicUpdater();
201     }
202 }
203 
204 // -----------------------------------------------------------------------------
205 
206 SdrGraphicLink::SdrGraphicLink(SdrGrafObj* pObj)
207 : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB )
208 , pGrafObj( pObj )
209 , pGraphicUpdater( NULL )
210 {
211     SetSynchron( sal_False );
212 }
213 
214 // -----------------------------------------------------------------------------
215 
216 SdrGraphicLink::~SdrGraphicLink()
217 {
218     if ( pGraphicUpdater )
219         pGraphicUpdater->Terminate();
220 }
221 
222 // -----------------------------------------------------------------------------
223 
224 void SdrGraphicLink::DataChanged( const Graphic& rGraphic )
225 {
226     pGrafObj->ImpSetLinkedGraphic( rGraphic );
227 }
228 
229 // -----------------------------------------------------------------------------
230 
231 void SdrGraphicLink::RemoveGraphicUpdater()
232 {
233     pGraphicUpdater = NULL;
234 }
235 
236 // -----------------------------------------------------------------------------
237 
238 void SdrGraphicLink::DataChanged( const String& rMimeType,
239                                 const ::com::sun::star::uno::Any & rValue )
240 {
241     SdrModel*       pModel      = pGrafObj ? pGrafObj->GetModel() : 0;
242     sfx2::LinkManager* pLinkManager= pModel  ? pModel->GetLinkManager() : 0;
243 
244     if( pLinkManager && rValue.hasValue() )
245     {
246         pLinkManager->GetDisplayNames( this, 0, &pGrafObj->aFileName, 0, &pGrafObj->aFilterName );
247 
248         Graphic aGraphic;
249         if( sfx2::LinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
250         {
251             pGrafObj->NbcSetGraphic( aGraphic );
252             pGrafObj->ActionChanged();
253         }
254         else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() )
255         {
256             // broadcasting, to update slidesorter
257             pGrafObj->BroadcastObjectChange();
258         }
259     }
260 }
261 
262 // -----------------------------------------------------------------------------
263 
264 void SdrGraphicLink::Closed()
265 {
266     // Die Verbindung wird aufgehoben; pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
267     pGrafObj->ForceSwapIn();
268     pGrafObj->pGraphicLink=NULL;
269     pGrafObj->ReleaseGraphicLink();
270     SvBaseLink::Closed();
271 }
272 
273 // -----------------------------------------------------------------------------
274 
275 void SdrGraphicLink::UpdateAsynchron()
276 {
277     if( GetObj() )
278     {
279         if ( pGraphicUpdater )
280         {
281             if ( pGraphicUpdater->GraphicLinkChanged( pGrafObj->GetFileName() ) )
282             {
283                 pGraphicUpdater->Terminate();
284                 pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this );
285             }
286         }
287         else
288             pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this );
289     }
290 }
291 
292 // --------------
293 // - SdrGrafObj -
294 // --------------
295 
296 //////////////////////////////////////////////////////////////////////////////
297 // BaseProperties section
298 
299 sdr::properties::BaseProperties* SdrGrafObj::CreateObjectSpecificProperties()
300 {
301     return new sdr::properties::GraphicProperties(*this);
302 }
303 
304 //////////////////////////////////////////////////////////////////////////////
305 // DrawContact section
306 
307 sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
308 {
309     return new sdr::contact::ViewContactOfGraphic(*this);
310 }
311 
312 //////////////////////////////////////////////////////////////////////////////
313 
314 TYPEINIT1(SdrGrafObj,SdrRectObj);
315 
316 // -----------------------------------------------------------------------------
317 
318 SdrGrafObj::SdrGrafObj()
319 :   SdrRectObj(),
320     pGraphicLink    ( NULL ),
321     bMirrored       ( sal_False )
322 {
323     pGraphic = new GraphicObject;
324     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
325 
326     // #i118485# Shear allowed and possible now
327     bNoShear = false;
328 
329     // #111096#
330     mbGrafAnimationAllowed = sal_True;
331 
332     // #i25616#
333     mbLineIsOutsideGeometry = sal_True;
334     mbInsidePaint = sal_False;
335     mbIsPreview = sal_False;
336 
337     // #i25616#
338     mbSupportTextIndentingOnLineWidthChange = sal_False;
339 }
340 
341 // -----------------------------------------------------------------------------
342 
343 SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
344 :   SdrRectObj      ( rRect ),
345     pGraphicLink    ( NULL ),
346     bMirrored       ( sal_False )
347 {
348     pGraphic = new GraphicObject( rGrf );
349     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
350 
351     // #i118485# Shear allowed and possible now
352     bNoShear = false;
353 
354     // #111096#
355     mbGrafAnimationAllowed = sal_True;
356 
357     // #i25616#
358     mbLineIsOutsideGeometry = sal_True;
359     mbInsidePaint = sal_False;
360     mbIsPreview = sal_False;
361 
362     // #i25616#
363     mbSupportTextIndentingOnLineWidthChange = sal_False;
364 }
365 
366 // -----------------------------------------------------------------------------
367 
368 SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
369 :   SdrRectObj(),
370     pGraphicLink    ( NULL ),
371     bMirrored       ( sal_False )
372 {
373     pGraphic = new GraphicObject( rGrf );
374     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
375 
376     // #i118485# Shear allowed and possible now
377     bNoShear = false;
378 
379     // #111096#
380     mbGrafAnimationAllowed = sal_True;
381 
382     // #i25616#
383     mbLineIsOutsideGeometry = sal_True;
384     mbInsidePaint = sal_False;
385     mbIsPreview = sal_False;
386 
387     // #i25616#
388     mbSupportTextIndentingOnLineWidthChange = sal_False;
389 }
390 
391 // -----------------------------------------------------------------------------
392 
393 SdrGrafObj::~SdrGrafObj()
394 {
395     delete pGraphic;
396     ImpLinkAbmeldung();
397 }
398 
399 // -----------------------------------------------------------------------------
400 
401 void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
402 {
403     *pGraphic = rGrfObj;
404     pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), SWAPGRAPHIC_TIMEOUT );
405     pGraphic->SetUserData();
406     mbIsPreview = sal_False;
407     SetChanged();
408     BroadcastObjectChange();
409 }
410 
411 // -----------------------------------------------------------------------------
412 
413 const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
414 {
415     if(bForceSwapIn)
416     {
417         ForceSwapIn();
418     }
419 
420     return *pGraphic;
421 }
422 
423 // -----------------------------------------------------------------------------
424 
425 void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
426 {
427     pGraphic->SetGraphic( rGrf );
428     pGraphic->SetUserData();
429     mbIsPreview = sal_False;
430 }
431 
432 void SdrGrafObj::SetGraphic( const Graphic& rGrf )
433 {
434     NbcSetGraphic(rGrf);
435     SetChanged();
436     BroadcastObjectChange();
437 }
438 
439 // -----------------------------------------------------------------------------
440 
441 const Graphic& SdrGrafObj::GetGraphic() const
442 {
443     ForceSwapIn();
444     return pGraphic->GetGraphic();
445 }
446 
447 // -----------------------------------------------------------------------------
448 
449 Graphic SdrGrafObj::GetTransformedGraphic( sal_uIntPtr nTransformFlags ) const
450 {
451     // #107947# Refactored most of the code to GraphicObject, where
452     // everybody can use e.g. the cropping functionality
453 
454     GraphicType     eType = GetGraphicType();
455     MapMode         aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() );
456     const Size      aDestSize( GetLogicRect().GetSize() );
457     const sal_Bool      bMirror = ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR ) != 0;
458     const sal_Bool      bRotate = ( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) != 0 ) &&
459         ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType );
460 
461     // #104115# Need cropping info earlier
462     ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo();
463     GraphicAttr aActAttr;
464 
465     if( SDRGRAFOBJ_TRANSFORMATTR_NONE != nTransformFlags &&
466         GRAPHIC_NONE != eType )
467     {
468         // actually transform the graphic only in this case. On the
469         // other hand, cropping will always happen
470         aActAttr = aGrafInfo;
471 
472         if( bMirror )
473         {
474             sal_uInt16      nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
475             FASTBOOL    bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
476             FASTBOOL    bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
477 
478             aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );
479         }
480 
481         if( bRotate )
482             aActAttr.SetRotation( sal_uInt16(aGeo.nDrehWink / 10) );
483     }
484 
485     // #107947# Delegate to moved code in GraphicObject
486     return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
487 }
488 
489 // -----------------------------------------------------------------------------
490 
491 GraphicType SdrGrafObj::GetGraphicType() const
492 {
493     return pGraphic->GetType();
494 }
495 
496 sal_Bool SdrGrafObj::IsAnimated() const
497 {
498     return pGraphic->IsAnimated();
499 }
500 
501 sal_Bool SdrGrafObj::IsEPS() const
502 {
503     return pGraphic->IsEPS();
504 }
505 
506 sal_Bool SdrGrafObj::IsRenderGraphic() const
507 {
508     return pGraphic->IsRenderGraphic();
509 }
510 
511 sal_Bool SdrGrafObj::HasRenderGraphic() const
512 {
513     return pGraphic->HasRenderGraphic();
514 }
515 
516 sal_Bool SdrGrafObj::IsSwappedOut() const
517 {
518     return mbIsPreview ? sal_True : pGraphic->IsSwappedOut();
519 }
520 
521 const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
522 {
523     return pGraphic->GetPrefMapMode();
524 }
525 
526 const Size& SdrGrafObj::GetGrafPrefSize() const
527 {
528     return pGraphic->GetPrefSize();
529 }
530 
531 // -----------------------------------------------------------------------------
532 
533 void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL )
534 {
535     mbIsPreview = sal_False;
536     if( !rGraphicStreamURL.Len() )
537     {
538         pGraphic->SetUserData();
539     }
540     else if( pModel->IsSwapGraphics() )
541     {
542         pGraphic->SetUserData( rGraphicStreamURL );
543 
544         // set state of graphic object to 'swapped out'
545         if( pGraphic->GetType() == GRAPHIC_NONE )
546             pGraphic->SetSwapState();
547     }
548 }
549 
550 // -----------------------------------------------------------------------------
551 
552 String SdrGrafObj::GetGrafStreamURL() const
553 {
554     return pGraphic->GetUserData();
555 }
556 
557 // -----------------------------------------------------------------------------
558 
559 void SdrGrafObj::SetFileName(const String& rFileName)
560 {
561     aFileName = rFileName;
562     SetChanged();
563 }
564 
565 // -----------------------------------------------------------------------------
566 
567 void SdrGrafObj::SetFilterName(const String& rFilterName)
568 {
569     aFilterName = rFilterName;
570     SetChanged();
571 }
572 
573 // -----------------------------------------------------------------------------
574 
575 void SdrGrafObj::ForceSwapIn() const
576 {
577     if( mbIsPreview )
578     {
579         // removing preview graphic
580         const String aUserData( pGraphic->GetUserData() );
581 
582         Graphic aEmpty;
583         pGraphic->SetGraphic( aEmpty );
584         pGraphic->SetUserData( aUserData );
585         pGraphic->SetSwapState();
586 
587         const_cast< SdrGrafObj* >( this )->mbIsPreview = sal_False;
588     }
589     if ( pGraphicLink && pGraphic->IsSwappedOut() )
590         ImpUpdateGraphicLink( sal_False );
591     else
592         pGraphic->FireSwapInRequest();
593 
594     if( pGraphic->IsSwappedOut() ||
595         ( pGraphic->GetType() == GRAPHIC_NONE ) ||
596         ( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
597     {
598         Graphic aDefaultGraphic;
599         aDefaultGraphic.SetDefaultType();
600         pGraphic->SetGraphic( aDefaultGraphic );
601     }
602 }
603 
604 // -----------------------------------------------------------------------------
605 
606 void SdrGrafObj::ForceSwapOut() const
607 {
608     pGraphic->FireSwapOutRequest();
609 }
610 
611 // -----------------------------------------------------------------------------
612 
613 void SdrGrafObj::ImpLinkAnmeldung()
614 {
615     sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
616 
617     if( pLinkManager != NULL && pGraphicLink == NULL )
618     {
619         if( aFileName.Len() )
620         {
621             pGraphicLink = new SdrGraphicLink( this );
622             pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL );
623             pGraphicLink->Connect();
624         }
625     }
626 }
627 
628 // -----------------------------------------------------------------------------
629 
630 void SdrGrafObj::ImpLinkAbmeldung()
631 {
632     sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
633 
634     if( pLinkManager != NULL && pGraphicLink!=NULL)
635     {
636         // Bei Remove wird *pGraphicLink implizit deleted
637         pLinkManager->Remove( pGraphicLink );
638         pGraphicLink=NULL;
639     }
640 }
641 
642 // -----------------------------------------------------------------------------
643 
644 void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName )
645 {
646     ImpLinkAbmeldung();
647     aFileName = rFileName;
648     aFilterName = rFilterName;
649     ImpLinkAnmeldung();
650     pGraphic->SetUserData();
651 
652     // #92205# A linked graphic is per definition swapped out (has to be loaded)
653     pGraphic->SetSwapState();
654 }
655 
656 // -----------------------------------------------------------------------------
657 
658 void SdrGrafObj::ReleaseGraphicLink()
659 {
660     ImpLinkAbmeldung();
661     aFileName = String();
662     aFilterName = String();
663 }
664 
665 // -----------------------------------------------------------------------------
666 
667 void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
668 {
669     FASTBOOL bAnim = pGraphic->IsAnimated();
670     FASTBOOL bRenderGraphic = pGraphic->HasRenderGraphic();
671     FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
672 
673     rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
674                                aGeo.nDrehWink % 18000 == 0 ||
675                                aGeo.nDrehWink % 27000 == 0;
676 
677     rInfo.bResizePropAllowed = sal_True;
678     rInfo.bRotateFreeAllowed = bNoPresGrf && !bAnim && !bRenderGraphic;
679     rInfo.bRotate90Allowed = bNoPresGrf && !bAnim && !bRenderGraphic;
680     rInfo.bMirrorFreeAllowed = bNoPresGrf && !bAnim && !bRenderGraphic;
681     rInfo.bMirror45Allowed = bNoPresGrf && !bAnim && !bRenderGraphic;
682     rInfo.bMirror90Allowed = !bEmptyPresObj && !bRenderGraphic;
683     rInfo.bTransparenceAllowed = sal_False;
684     rInfo.bGradientAllowed = sal_False;
685 
686     // #i118485# Shear allowed and possible now
687     rInfo.bShearAllowed = true;
688 
689     rInfo.bEdgeRadiusAllowed=sal_False;
690     rInfo.bCanConvToPath = !IsEPS() && !bRenderGraphic;
691     rInfo.bCanConvToPathLineToArea = sal_False;
692     rInfo.bCanConvToPolyLineToArea = sal_False;
693     rInfo.bCanConvToPoly = !IsEPS() && !bRenderGraphic;
694     rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
695 }
696 
697 // -----------------------------------------------------------------------------
698 
699 sal_uInt16 SdrGrafObj::GetObjIdentifier() const
700 {
701     return sal_uInt16( OBJ_GRAF );
702 }
703 
704 // -----------------------------------------------------------------------------
705 
706 /* The graphic of the GraphicLink will be loaded. If it is called with
707    bAsynchron = true then the graphic will be set later via DataChanged
708 */
709 sal_Bool SdrGrafObj::ImpUpdateGraphicLink( sal_Bool bAsynchron ) const
710 {
711     sal_Bool bRet = sal_False;
712     if( pGraphicLink )
713     {
714         if ( bAsynchron )
715             pGraphicLink->UpdateAsynchron();
716         else
717             pGraphicLink->DataChanged( ImpLoadLinkedGraphic( aFileName, aFilterName ) );
718         bRet = sal_True;
719     }
720     return bRet;
721 }
722 
723 // -----------------------------------------------------------------------------
724 
725 void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
726 {
727     const sal_Bool bIsChanged = GetModel()->IsChanged();
728     NbcSetGraphic( rGraphic );
729     ActionChanged();
730     BroadcastObjectChange();
731     GetModel()->SetChanged( bIsChanged );
732 }
733 
734 // -----------------------------------------------------------------------------
735 
736 void SdrGrafObj::TakeObjNameSingul(XubString& rName) const
737 {
738     switch( pGraphic->GetType() )
739     {
740         case GRAPHIC_BITMAP:
741         {
742             const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
743                                  ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
744                                  ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
745 
746             rName=ImpGetResStr( nId );
747         }
748         break;
749 
750         case GRAPHIC_GDIMETAFILE:
751             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF );
752         break;
753 
754         case GRAPHIC_NONE:
755             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE );
756         break;
757 
758         default:
759             rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF );
760         break;
761     }
762 
763     const String aName(GetName());
764 
765     if( aName.Len() )
766     {
767         rName.AppendAscii( " '" );
768         rName += aName;
769         rName += sal_Unicode( '\'' );
770     }
771 }
772 
773 // -----------------------------------------------------------------------------
774 
775 void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const
776 {
777     switch( pGraphic->GetType() )
778     {
779         case GRAPHIC_BITMAP:
780         {
781             const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
782                                  ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
783                                  ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
784 
785             rName=ImpGetResStr( nId );
786         }
787         break;
788 
789         case GRAPHIC_GDIMETAFILE:
790             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF );
791         break;
792 
793         case GRAPHIC_NONE:
794             rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE );
795         break;
796 
797         default:
798             rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF );
799         break;
800     }
801 
802     const String aName(GetName());
803 
804     if( aName.Len() )
805     {
806         rName.AppendAscii( " '" );
807         rName += aName;
808         rName += sal_Unicode( '\'' );
809     }
810 }
811 
812 // -----------------------------------------------------------------------------
813 
814 SdrObject* SdrGrafObj::getFullDragClone() const
815 {
816     // call parent
817     SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
818 
819     // #i103116# the full drag clone leads to problems
820     // with linked graphics, so reset the link in this
821     // temporary interaction object and load graphic
822     if(pRetval && IsLinkedGraphic())
823     {
824         pRetval->ForceSwapIn();
825         pRetval->ReleaseGraphicLink();
826     }
827 
828     return pRetval;
829 }
830 
831 void SdrGrafObj::operator=( const SdrObject& rObj )
832 {
833     SdrRectObj::operator=( rObj );
834 
835     const SdrGrafObj& rGraf = (SdrGrafObj&) rObj;
836 
837     pGraphic->SetGraphic( rGraf.GetGraphic(), &rGraf.GetGraphicObject() );
838     aCropRect = rGraf.aCropRect;
839     aFileName = rGraf.aFileName;
840     aFilterName = rGraf.aFilterName;
841     bMirrored = rGraf.bMirrored;
842 
843     if( rGraf.pGraphicLink != NULL)
844     {
845         SetGraphicLink( aFileName, aFilterName );
846     }
847 
848     ImpSetAttrToGrafInfo();
849 }
850 
851 // -----------------------------------------------------------------------------
852 // #i25616#
853 
854 basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const
855 {
856     if(mbInsidePaint)
857     {
858         basegfx::B2DPolyPolygon aRetval;
859 
860         // take grown rectangle
861         const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2);
862         const Rectangle aGrownRect(
863             aRect.Left() - nHalfLineWidth,
864             aRect.Top() - nHalfLineWidth,
865             aRect.Right() + nHalfLineWidth,
866             aRect.Bottom() + nHalfLineWidth);
867 
868         XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius()));
869         aRetval.append(aXPoly.getB2DPolygon());
870 
871         return aRetval;
872     }
873     else
874     {
875         // call parent
876         return SdrRectObj::TakeXorPoly();
877     }
878 }
879 
880 // -----------------------------------------------------------------------------
881 
882 sal_uInt32 SdrGrafObj::GetHdlCount() const
883 {
884     return 8L;
885 }
886 
887 // -----------------------------------------------------------------------------
888 
889 SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
890 {
891     return SdrRectObj::GetHdl( nHdlNum + 1L );
892 }
893 
894 // -----------------------------------------------------------------------------
895 
896 void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
897 {
898     SdrRectObj::NbcResize( rRef, xFact, yFact );
899 
900     FASTBOOL bMirrX = xFact.GetNumerator() < 0;
901     FASTBOOL bMirrY = yFact.GetNumerator() < 0;
902 
903     if( bMirrX != bMirrY )
904         bMirrored = !bMirrored;
905 }
906 
907 // -----------------------------------------------------------------------------
908 
909 void SdrGrafObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
910 {
911     SdrRectObj::NbcRotate(rRef,nWink,sn,cs);
912 }
913 
914 // -----------------------------------------------------------------------------
915 
916 void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
917 {
918     SdrRectObj::NbcMirror(rRef1,rRef2);
919     bMirrored = !bMirrored;
920 }
921 
922 // -----------------------------------------------------------------------------
923 
924 void SdrGrafObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
925 {
926     // #i118485# Call Shear now, old version redirected to rotate
927     SdrRectObj::NbcShear(rRef, nWink, tn, bVShear);
928 }
929 
930 // -----------------------------------------------------------------------------
931 
932 void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect)
933 {
934     SdrRectObj::NbcSetSnapRect(rRect);
935 }
936 
937 // -----------------------------------------------------------------------------
938 
939 void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect)
940 {
941     //int bChg=rRect.GetSize()!=aRect.GetSize();
942     SdrRectObj::NbcSetLogicRect(rRect);
943 }
944 
945 // -----------------------------------------------------------------------------
946 
947 SdrObjGeoData* SdrGrafObj::NewGeoData() const
948 {
949     return new SdrGrafObjGeoData;
950 }
951 
952 // -----------------------------------------------------------------------------
953 
954 void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
955 {
956     SdrRectObj::SaveGeoData(rGeo);
957     SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
958     rGGeo.bMirrored=bMirrored;
959 }
960 
961 // -----------------------------------------------------------------------------
962 
963 void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo)
964 {
965     //long      nDrehMerk = aGeo.nDrehWink;
966     //long      nShearMerk = aGeo.nShearWink;
967     //int   bMirrMerk = bMirrored;
968     Size        aSizMerk( aRect.GetSize() );
969 
970     SdrRectObj::RestGeoData(rGeo);
971     SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
972     bMirrored=rGGeo.bMirrored;
973 }
974 
975 // -----------------------------------------------------------------------------
976 
977 void SdrGrafObj::SetPage( SdrPage* pNewPage )
978 {
979     FASTBOOL bRemove = pNewPage == NULL && pPage != NULL;
980     FASTBOOL bInsert = pNewPage != NULL && pPage == NULL;
981 
982     if( bRemove )
983     {
984         // hier kein SwapIn noetig, weil wenn nicht geladen, dann auch nicht animiert.
985         if( pGraphic->IsAnimated())
986             pGraphic->StopAnimation();
987 
988         if( pGraphicLink != NULL )
989             ImpLinkAbmeldung();
990     }
991 
992     SdrRectObj::SetPage( pNewPage );
993 
994     if(aFileName.Len() && bInsert)
995         ImpLinkAnmeldung();
996 }
997 
998 // -----------------------------------------------------------------------------
999 
1000 void SdrGrafObj::SetModel( SdrModel* pNewModel )
1001 {
1002     FASTBOOL bChg = pNewModel != pModel;
1003 
1004     if( bChg )
1005     {
1006         if( pGraphic->HasUserData() )
1007         {
1008             ForceSwapIn();
1009             pGraphic->SetUserData();
1010         }
1011 
1012         if( pGraphicLink != NULL )
1013             ImpLinkAbmeldung();
1014     }
1015 
1016     // Model umsetzen
1017     SdrRectObj::SetModel(pNewModel);
1018 
1019     if( bChg && aFileName.Len() )
1020         ImpLinkAnmeldung();
1021 }
1022 
1023 // -----------------------------------------------------------------------------
1024 
1025 void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/)
1026 {
1027     // #111096#
1028     // use new graf animation
1029     SetGrafAnimationAllowed(sal_True);
1030 }
1031 
1032 // -----------------------------------------------------------------------------
1033 
1034 void SdrGrafObj::StopAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1035 {
1036     // #111096#
1037     // use new graf animation
1038     SetGrafAnimationAllowed(sal_False);
1039 }
1040 
1041 // -----------------------------------------------------------------------------
1042 
1043 FASTBOOL SdrGrafObj::HasGDIMetaFile() const
1044 {
1045     return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE );
1046 }
1047 
1048 // -----------------------------------------------------------------------------
1049 
1050 const GDIMetaFile* SdrGrafObj::GetGDIMetaFile() const
1051 {
1052     DBG_ERROR( "Invalid return value! Don't use it! (KA)" );
1053     return &GetGraphic().GetGDIMetaFile();
1054 }
1055 
1056 // -----------------------------------------------------------------------------
1057 
1058 SdrObject* SdrGrafObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
1059 {
1060     SdrObject* pRetval = NULL;
1061 
1062     switch( GetGraphicType() )
1063     {
1064         case GRAPHIC_GDIMETAFILE:
1065         {
1066             // NUR die aus dem MetaFile erzeugbaren Objekte in eine Gruppe packen und zurueckliefern
1067             ImpSdrGDIMetaFileImport aFilter(*GetModel());
1068             aFilter.SetScaleRect(aRect);
1069             aFilter.SetLayer(GetLayer());
1070 
1071             SdrObjGroup* pGrp = new SdrObjGroup();
1072             sal_uInt32 nInsAnz = aFilter.DoImport(GetTransformedGraphic(
1073                 SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile(),
1074                 *pGrp->GetSubList(), 0);
1075 
1076             if(nInsAnz)
1077             {
1078                 {
1079                     // copy transformation
1080                     GeoStat aGeoStat(GetGeoStat());
1081 
1082                     if(aGeoStat.nShearWink)
1083                     {
1084                         aGeoStat.RecalcTan();
1085                         pGrp->NbcShear(aRect.TopLeft(), aGeoStat.nShearWink, aGeoStat.nTan, false);
1086                     }
1087 
1088                     if(aGeoStat.nDrehWink)
1089                     {
1090                         aGeoStat.RecalcSinCos();
1091                         pGrp->NbcRotate(aRect.TopLeft(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1092                     }
1093                 }
1094 
1095                 pRetval = pGrp;
1096                 pGrp->NbcSetLayer(GetLayer());
1097                 pGrp->SetModel(GetModel());
1098 
1099                 if(bAddText)
1100                 {
1101                     pRetval = ImpConvertAddText(pRetval, bBezier);
1102                 }
1103 
1104                 // convert all children
1105                 if( pRetval )
1106                 {
1107                     SdrObject* pHalfDone = pRetval;
1108                     pRetval = pHalfDone->DoConvertToPolyObj(bBezier, bAddText);
1109                     SdrObject::Free( pHalfDone ); // resulting object is newly created
1110 
1111                     if( pRetval )
1112                     {
1113                         // flatten subgroups. As we call
1114                         // DoConvertToPolyObj() on the resulting group
1115                         // objects, subgroups can exist (e.g. text is
1116                         // a group object for every line).
1117                         SdrObjList* pList = pRetval->GetSubList();
1118                         if( pList )
1119                             pList->FlattenGroups();
1120                     }
1121                 }
1122             }
1123             else
1124             {
1125                 delete pGrp;
1126             }
1127 
1128             // #i118485# convert line and fill
1129             SdrObject* pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false);
1130 
1131             if(pLineFill)
1132             {
1133                 if(pRetval)
1134                 {
1135                     pGrp = dynamic_cast< SdrObjGroup* >(pRetval);
1136 
1137                     if(!pGrp)
1138                     {
1139                         pGrp = new SdrObjGroup();
1140 
1141                         pGrp->NbcSetLayer(GetLayer());
1142                         pGrp->SetModel(GetModel());
1143                         pGrp->GetSubList()->NbcInsertObject(pRetval);
1144                     }
1145 
1146                     pGrp->GetSubList()->NbcInsertObject(pLineFill, 0);
1147                 }
1148                 else
1149                 {
1150                     pRetval = pLineFill;
1151                 }
1152             }
1153 
1154             break;
1155         }
1156         case GRAPHIC_BITMAP:
1157         {
1158             // Grundobjekt kreieren und Fuellung ergaenzen
1159             pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1160 
1161             // Bitmap als Attribut retten
1162             if(pRetval)
1163             {
1164                 // Bitmap als Fuellung holen
1165                 SfxItemSet aSet(GetObjectItemSet());
1166 
1167                 aSet.Put(XFillStyleItem(XFILL_BITMAP));
1168                 Bitmap aBitmap( GetTransformedGraphic().GetBitmap() );
1169                 XOBitmap aXBmp(aBitmap, XBITMAP_STRETCH);
1170                 aSet.Put(XFillBitmapItem(String(), aXBmp));
1171                 aSet.Put(XFillBmpTileItem(sal_False));
1172 
1173                 pRetval->SetMergedItemSet(aSet);
1174             }
1175             break;
1176         }
1177         case GRAPHIC_NONE:
1178         case GRAPHIC_DEFAULT:
1179         {
1180             pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1181             break;
1182         }
1183     }
1184 
1185     return pRetval;
1186 }
1187 
1188 // -----------------------------------------------------------------------------
1189 
1190 void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1191 {
1192     SetXPolyDirty();
1193     SdrRectObj::Notify( rBC, rHint );
1194     ImpSetAttrToGrafInfo();
1195 }
1196 
1197 void SdrGrafObj::ImpSetAttrToGrafInfo()
1198 {
1199     const SfxItemSet& rSet = GetObjectItemSet();
1200     const sal_uInt16 nTrans = ( (SdrGrafTransparenceItem&) rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue();
1201     const SdrGrafCropItem&  rCrop = (const SdrGrafCropItem&) rSet.Get( SDRATTR_GRAFCROP );
1202 
1203     aGrafInfo.SetLuminance( ( (SdrGrafLuminanceItem&) rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() );
1204     aGrafInfo.SetContrast( ( (SdrGrafContrastItem&) rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() );
1205     aGrafInfo.SetChannelR( ( (SdrGrafRedItem&) rSet.Get( SDRATTR_GRAFRED ) ).GetValue() );
1206     aGrafInfo.SetChannelG( ( (SdrGrafGreenItem&) rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() );
1207     aGrafInfo.SetChannelB( ( (SdrGrafBlueItem&) rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() );
1208     aGrafInfo.SetGamma( ( (SdrGrafGamma100Item&) rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 );
1209     aGrafInfo.SetTransparency( (sal_uInt8) FRound( Min( nTrans, (sal_uInt16) 100 )  * 2.55 ) );
1210     aGrafInfo.SetInvert( ( (SdrGrafInvertItem&) rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() );
1211     aGrafInfo.SetDrawMode( ( (SdrGrafModeItem&) rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() );
1212     aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
1213 
1214     SetXPolyDirty();
1215     SetRectsDirty();
1216 }
1217 
1218 // -----------------------------------------------------------------------------
1219 
1220 void SdrGrafObj::ImpSetGrafInfoToAttr()
1221 {
1222     SetObjectItem( SdrGrafLuminanceItem( aGrafInfo.GetLuminance() ) );
1223     SetObjectItem( SdrGrafContrastItem( aGrafInfo.GetContrast() ) );
1224     SetObjectItem( SdrGrafRedItem( aGrafInfo.GetChannelR() ) );
1225     SetObjectItem( SdrGrafGreenItem( aGrafInfo.GetChannelG() ) );
1226     SetObjectItem( SdrGrafBlueItem( aGrafInfo.GetChannelB() ) );
1227     SetObjectItem( SdrGrafGamma100Item( FRound( aGrafInfo.GetGamma() * 100.0 ) ) );
1228     SetObjectItem( SdrGrafTransparenceItem( (sal_uInt16) FRound( aGrafInfo.GetTransparency() / 2.55 ) ) );
1229     SetObjectItem( SdrGrafInvertItem( aGrafInfo.IsInvert() ) );
1230     SetObjectItem( SdrGrafModeItem( aGrafInfo.GetDrawMode() ) );
1231     SetObjectItem( SdrGrafCropItem( aGrafInfo.GetLeftCrop(), aGrafInfo.GetTopCrop(), aGrafInfo.GetRightCrop(), aGrafInfo.GetBottomCrop() ) );
1232 }
1233 
1234 // -----------------------------------------------------------------------------
1235 
1236 void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly )
1237 {
1238     Size aSize;
1239     Size aMaxSize( rMaxRect.GetSize() );
1240     if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1241         aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM );
1242     else
1243         aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1244                                             pGraphic->GetPrefMapMode(),
1245                                             MapMode( MAP_100TH_MM ) );
1246 
1247     if( aSize.Height() != 0 && aSize.Width() != 0 )
1248     {
1249         Point aPos( rMaxRect.TopLeft() );
1250 
1251         // Falls Grafik zu gross, wird die Grafik
1252         // in die Seite eingepasst
1253         if ( (!bShrinkOnly                          ||
1254              ( aSize.Height() > aMaxSize.Height() ) ||
1255             ( aSize.Width()  > aMaxSize.Width()  ) )&&
1256             aSize.Height() && aMaxSize.Height() )
1257         {
1258             float fGrfWH =  (float)aSize.Width() /
1259                             (float)aSize.Height();
1260             float fWinWH =  (float)aMaxSize.Width() /
1261                             (float)aMaxSize.Height();
1262 
1263             // Grafik an Pagesize anpassen (skaliert)
1264             if ( fGrfWH < fWinWH )
1265             {
1266                 aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
1267                 aSize.Height()= aMaxSize.Height();
1268             }
1269             else if ( fGrfWH > 0.F )
1270             {
1271                 aSize.Width() = aMaxSize.Width();
1272                 aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
1273             }
1274 
1275             aPos = rMaxRect.Center();
1276         }
1277 
1278         if( bShrinkOnly )
1279             aPos = aRect.TopLeft();
1280 
1281         aPos.X() -= aSize.Width() / 2;
1282         aPos.Y() -= aSize.Height() / 2;
1283         SetLogicRect( Rectangle( aPos, aSize ) );
1284     }
1285 }
1286 
1287 // -----------------------------------------------------------------------------
1288 
1289 IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
1290 {
1291     SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1292 
1293     if( pO->IsInSwapOut() )
1294     {
1295         if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
1296         {
1297             // test if this object is visualized from someone
1298             // ## test only if there are VOCs other than the preview renderer
1299             if(!GetViewContact().HasViewObjectContacts(true))
1300             {
1301                 const sal_uIntPtr   nSwapMode = pModel->GetSwapGraphicsMode();
1302 
1303                 if( ( pGraphic->HasUserData() || pGraphicLink ) &&
1304                     ( nSwapMode & SDR_SWAPGRAPHICSMODE_PURGE ) )
1305                 {
1306                     pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1307                 }
1308                 else if( nSwapMode & SDR_SWAPGRAPHICSMODE_TEMP )
1309                 {
1310                     pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1311                     pGraphic->SetUserData();
1312                 }
1313 
1314                 // #i102380#
1315                 sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
1316 
1317                 if(pVC)
1318                 {
1319                     pVC->flushGraphicObjects();
1320                 }
1321             }
1322         }
1323     }
1324     else if( pO->IsInSwapIn() )
1325     {
1326         // kann aus dem original Doc-Stream nachgeladen werden...
1327         if( pModel != NULL )
1328         {
1329             if( pGraphic->HasUserData() )
1330             {
1331                 SdrDocumentStreamInfo aStreamInfo;
1332 
1333                 aStreamInfo.mbDeleteAfterUse = sal_False;
1334                 aStreamInfo.maUserData = pGraphic->GetUserData();
1335 
1336                 SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1337 
1338                 if( pStream != NULL )
1339                 {
1340                     Graphic aGraphic;
1341 
1342                     com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL;
1343 
1344                     if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
1345                     {
1346 //                          Rectangle aSnapRect(GetSnapRect());
1347 //                          const Rectangle aSnapRectPixel(pOutDev->LogicToPixel(aSnapRect));
1348 
1349                         pFilterData = new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 );
1350 
1351                         com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
1352                         sal_Bool bAllowPartialStreamRead = sal_True;
1353                         sal_Bool bCreateNativeLink = sal_False;
1354                         (*pFilterData)[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "PreviewSizeHint" ) );
1355                         (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint;
1356                         (*pFilterData)[ 1 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "AllowPartialStreamRead" ) );
1357                         (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead;
1358                         (*pFilterData)[ 2 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
1359                         (*pFilterData)[ 2 ].Value <<= bCreateNativeLink;
1360 
1361                         mbIsPreview = sal_True;
1362                     }
1363 
1364                     if( !GraphicFilter::GetGraphicFilter()->ImportGraphic( aGraphic, String(), *pStream,
1365                                                         GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData ) )
1366                     {
1367                         const String aUserData( pGraphic->GetUserData() );
1368 
1369                         pGraphic->SetGraphic( aGraphic );
1370                         pGraphic->SetUserData( aUserData );
1371 
1372                         // #142146# Graphic successfully swapped in.
1373                         pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1374                     }
1375                     delete pFilterData;
1376 
1377                     pStream->ResetError();
1378 
1379                     if( aStreamInfo.mbDeleteAfterUse || aStreamInfo.mxStorageRef.is() )
1380                     {
1381                         if ( aStreamInfo.mxStorageRef.is() )
1382                         {
1383                             aStreamInfo.mxStorageRef->dispose();
1384                             aStreamInfo.mxStorageRef = 0;
1385                         }
1386 
1387                         delete pStream;
1388                     }
1389                 }
1390             }
1391             else if( !ImpUpdateGraphicLink( sal_False ) )
1392             {
1393                 pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1394             }
1395             else
1396             {
1397                 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1398             }
1399         }
1400         else
1401             pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1402     }
1403 
1404     return (long)(void*) pRet;
1405 }
1406 
1407 // -----------------------------------------------------------------------------
1408 
1409 // #111096#
1410 // Access to GrafAnimationAllowed flag
1411 sal_Bool SdrGrafObj::IsGrafAnimationAllowed() const
1412 {
1413     return mbGrafAnimationAllowed;
1414 }
1415 
1416 void SdrGrafObj::SetGrafAnimationAllowed(sal_Bool bNew)
1417 {
1418     if(mbGrafAnimationAllowed != bNew)
1419     {
1420         mbGrafAnimationAllowed = bNew;
1421         ActionChanged();
1422     }
1423 }
1424 
1425 // #i25616#
1426 sal_Bool SdrGrafObj::IsObjectTransparent() const
1427 {
1428     if(((const SdrGrafTransparenceItem&)GetObjectItem(SDRATTR_GRAFTRANSPARENCE)).GetValue()
1429         || pGraphic->IsTransparent())
1430     {
1431         return sal_True;
1432     }
1433 
1434     return sal_False;
1435 }
1436 
1437 Reference< XInputStream > SdrGrafObj::getInputStream()
1438 {
1439     Reference< XInputStream > xStream;
1440 
1441     if( pModel )
1442     {
1443 //      if( !pGraphic->HasUserData() )
1444 //          pGraphic->SwapOut();
1445 
1446         // kann aus dem original Doc-Stream nachgeladen werden...
1447         if( pGraphic->HasUserData() )
1448         {
1449             SdrDocumentStreamInfo aStreamInfo;
1450 
1451             aStreamInfo.mbDeleteAfterUse = sal_False;
1452             aStreamInfo.maUserData = pGraphic->GetUserData();
1453 
1454             SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1455 
1456             if( pStream )
1457                 xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1458         }
1459         else if( pGraphic && GetGraphic().IsLink() )
1460         {
1461             Graphic aGraphic( GetGraphic() );
1462             GfxLink aLink( aGraphic.GetLink() );
1463             sal_uInt32 nSize = aLink.GetDataSize();
1464             const void* pSourceData = (const void*)aLink.GetData();
1465             if( nSize && pSourceData )
1466             {
1467                 sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
1468                 if( pBuffer )
1469                 {
1470                     memcpy( pBuffer, pSourceData, nSize );
1471 
1472                     SvMemoryStream* pStream = new SvMemoryStream( (void*)pBuffer, (sal_Size)nSize, STREAM_READ );
1473                     pStream->ObjectOwnsMemory( sal_True );
1474                     xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1475                 }
1476             }
1477         }
1478 
1479         if( !xStream.is() && aFileName.Len() )
1480         {
1481             SvFileStream* pStream = new SvFileStream( aFileName, STREAM_READ );
1482             if( pStream )
1483                 xStream.set( new utl::OInputStreamWrapper( pStream ) );
1484         }
1485     }
1486 
1487     return xStream;
1488 }
1489 
1490 // eof
1491