xref: /trunk/main/svx/source/svdraw/svdograf.cxx (revision 1b9d1397)
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/xbtmpit.hxx>
59 #include <svx/xflbmtit.hxx>
60 #include <svx/svdundo.hxx>
61 #include "svdfmtf.hxx"
62 #include <svx/sdgcpitm.hxx>
63 #include <editeng/eeitem.hxx>
64 #include <svx/sdr/properties/graphicproperties.hxx>
65 #include <svx/sdr/contact/viewcontactofgraphic.hxx>
66 #include <basegfx/polygon/b2dpolygon.hxx>
67 #include <basegfx/polygon/b2dpolygontools.hxx>
68 #include <osl/thread.hxx>
69 #include <vos/mutex.hxx>
70 #include <drawinglayer/processor2d/objectinfoextractor2d.hxx>
71 #include <drawinglayer/primitive2d/objectinfoprimitive2d.hxx>
72 #include <unotools/cacheoptions.hxx>
73 #include <basegfx/matrix/b2dhommatrixtools.hxx>
74 
75 using namespace ::com::sun::star::uno;
76 using namespace ::com::sun::star::io;
77 
78 // -----------
79 // - Defines -
80 // -----------
81 
82 #define GRAFSTREAMPOS_INVALID   0xffffffff
83 #define SWAPGRAPHIC_TIMEOUT     5000
84 
85 // #122985# it is not correct to se the swap-timeout to a hard-coded 5000ms as it was before.
86 // Added code and experimented what to do as a good compromize, see description
getCacheTimeInMs()87 sal_uInt32 getCacheTimeInMs()
88 {
89     static bool bSetAtAll(true);
90 
91     if(bSetAtAll)
92     {
93         static bool bSetToPreferenceTime(true);
94 
95         if(bSetToPreferenceTime)
96         {
97             const SvtCacheOptions aCacheOptions;
98             const sal_Int32 nSeconds(aCacheOptions.GetGraphicManagerObjectReleaseTime());
99 
100             // the default is 10 minutes. The minimum is one minute, thus 60 seconds. When the minimum
101             // should match to the former hard-coded 5 seconds, we have a divisor of 12 to use. For the
102             // default of 10 minutes this would mean 50 seconds. Compared to before this is ten times
103             // more (would allow better navigation by switching through pages) and is controllable
104             // by the user by setting the tools/options/memory/Remove_from_memory_after setting. Seems
105             // to be a good compromize to me.
106             return nSeconds * 1000 / 12;
107         }
108         else
109         {
110             return SWAPGRAPHIC_TIMEOUT;
111         }
112     }
113 
114     return 0;
115 }
116 
117 // ------------------
118 // - SdrGraphicLink	-
119 // ------------------
120 
121 
ImpLoadLinkedGraphic(const String aFileName,const String aFilterName)122 const Graphic ImpLoadLinkedGraphic( const String aFileName, const String aFilterName )
123 {
124 	Graphic aGraphic;
125 
126 	SfxMedium xMed( aFileName, STREAM_STD_READ, sal_True );
127 	xMed.DownLoad();
128 
129 	SvStream* pInStrm = xMed.GetInStream();
130 	if ( pInStrm )
131 	{
132 		pInStrm->Seek( STREAM_SEEK_TO_BEGIN );
133 		GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
134 
135 		const sal_uInt16 nFilter = aFilterName.Len() && pGF->GetImportFormatCount()
136 							? pGF->GetImportFormatNumber( aFilterName )
137 							: GRFILTER_FORMAT_DONTKNOW;
138 
139 		com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue > aFilterData( 1 );
140 
141 		// Room for improvment:
142 		// As this is a linked graphic the GfxLink is not needed if saving/loading our own format.
143 		// But this link is required by some filters to access the native graphic (pdf export/ms export),
144 		// there we should create a new service to provide this data if needed
145 		aFilterData[ 0 ].Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
146 		aFilterData[ 0 ].Value = Any( sal_True );
147 
148         // #123042# for e.g SVG the path is needed, so hand it over here. I have no real idea
149         // what consequences this may have; maybe this is not handed over by purpose here. Not
150         // handing it over means that any GraphicFormat that internallv needs a path as base
151         // to interpret included links may fail.
152         // Alternatively the path may be set at the result after this call when it is known
153         // that it is a SVG graphic, but only because no one yet tried to interpret it.
154         pGF->ImportGraphic( aGraphic, aFileName, *pInStrm, nFilter, NULL, 0, &aFilterData );
155 	}
156 	return aGraphic;
157 }
158 
159 class SdrGraphicUpdater;
160 class SdrGraphicLink : public sfx2::SvBaseLink
161 {
162 	SdrGrafObj*			pGrafObj;
163 	SdrGraphicUpdater*	pGraphicUpdater;
164 
165 public:
166 						SdrGraphicLink(SdrGrafObj* pObj);
167 	virtual				~SdrGraphicLink();
168 
169 	virtual void		Closed();
170 	virtual void		DataChanged( const String& rMimeType,
171 								const ::com::sun::star::uno::Any & rValue );
172 	void				DataChanged( const Graphic& rGraphic );
173 
Connect()174 	sal_Bool				Connect() { return 0 != GetRealObject(); }
175 	void				UpdateAsynchron();
176 	void				RemoveGraphicUpdater();
177 };
178 
179 class SdrGraphicUpdater : public ::osl::Thread
180 {
181 public:
182     SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& );
183     virtual ~SdrGraphicUpdater( void );
184 
185 	void SAL_CALL Terminate( void );
186 
GraphicLinkChanged(const String & rFileName)187     sal_Bool GraphicLinkChanged( const String& rFileName ){ return maFileName != rFileName;	};
188 
189 protected:
190 
191 	/**	is called from the inherited create method and acts as the
192 		main function of this thread.
193 	*/
194 	virtual void SAL_CALL run(void);
195 
196     /**	Called after the thread is terminated via the terminate
197     	method.  Used to kill the thread by calling delete on this.
198     */
199     virtual void SAL_CALL onTerminated(void);
200 
201 private:
202 
203     const String	maFileName;
204 	const String	maFilterName;
205 	SdrGraphicLink& mrGraphicLink;
206 
207 	volatile bool mbIsTerminated;
208 };
209 
SdrGraphicUpdater(const String & rFileName,const String & rFilterName,SdrGraphicLink & rGraphicLink)210 SdrGraphicUpdater::SdrGraphicUpdater( const String& rFileName, const String& rFilterName, SdrGraphicLink& rGraphicLink )
211 : maFileName( rFileName )
212 , maFilterName( rFilterName )
213 , mrGraphicLink( rGraphicLink )
214 , mbIsTerminated( sal_False )
215 {
216 	create();
217 }
218 
~SdrGraphicUpdater(void)219 SdrGraphicUpdater::~SdrGraphicUpdater( void )
220 {
221 }
222 
Terminate()223 void SdrGraphicUpdater::Terminate()
224 {
225     mbIsTerminated = sal_True;
226 }
227 
onTerminated(void)228 void SAL_CALL SdrGraphicUpdater::onTerminated(void)
229 {
230 	delete this;
231 }
232 
run(void)233 void SAL_CALL SdrGraphicUpdater::run(void)
234 {
235 	Graphic aGraphic( ImpLoadLinkedGraphic( maFileName, maFilterName ) );
236 	vos::OGuard aSolarGuard( Application::GetSolarMutex() );
237 	if ( !mbIsTerminated )
238 	{
239 		mrGraphicLink.DataChanged( aGraphic );
240 		mrGraphicLink.RemoveGraphicUpdater();
241 	}
242 }
243 
244 // -----------------------------------------------------------------------------
245 
SdrGraphicLink(SdrGrafObj * pObj)246 SdrGraphicLink::SdrGraphicLink(SdrGrafObj* pObj)
247 : ::sfx2::SvBaseLink( ::sfx2::LINKUPDATE_ONCALL, SOT_FORMATSTR_ID_SVXB )
248 , pGrafObj( pObj )
249 , pGraphicUpdater( NULL )
250 {
251 	SetSynchron( sal_False );
252 }
253 
254 // -----------------------------------------------------------------------------
255 
~SdrGraphicLink()256 SdrGraphicLink::~SdrGraphicLink()
257 {
258 	if ( pGraphicUpdater )
259 		pGraphicUpdater->Terminate();
260 }
261 
262 // -----------------------------------------------------------------------------
263 
DataChanged(const Graphic & rGraphic)264 void SdrGraphicLink::DataChanged( const Graphic& rGraphic )
265 {
266 	pGrafObj->ImpSetLinkedGraphic( rGraphic );
267 }
268 
269 // -----------------------------------------------------------------------------
270 
RemoveGraphicUpdater()271 void SdrGraphicLink::RemoveGraphicUpdater()
272 {
273 	pGraphicUpdater = NULL;
274 }
275 
276 // -----------------------------------------------------------------------------
277 
DataChanged(const String & rMimeType,const::com::sun::star::uno::Any & rValue)278 void SdrGraphicLink::DataChanged( const String& rMimeType,
279 								const ::com::sun::star::uno::Any & rValue )
280 {
281 	SdrModel*       pModel      = pGrafObj ? pGrafObj->GetModel() : 0;
282 	sfx2::LinkManager* pLinkManager= pModel  ? pModel->GetLinkManager() : 0;
283 
284 	if( pLinkManager && rValue.hasValue() )
285 	{
286 		pLinkManager->GetDisplayNames( this, 0, &pGrafObj->aFileName, 0, &pGrafObj->aFilterName );
287 
288 		Graphic aGraphic;
289 		if( sfx2::LinkManager::GetGraphicFromAny( rMimeType, rValue, aGraphic ))
290 		{
291    			pGrafObj->NbcSetGraphic( aGraphic );
292 			pGrafObj->ActionChanged();
293 		}
294 		else if( SotExchange::GetFormatIdFromMimeType( rMimeType ) != sfx2::LinkManager::RegisterStatusInfoId() )
295 		{
296 			// broadcasting, to update slidesorter
297 			pGrafObj->BroadcastObjectChange();
298 		}
299 	}
300 }
301 
302 // -----------------------------------------------------------------------------
303 
Closed()304 void SdrGraphicLink::Closed()
305 {
306 	// Die Verbindung wird aufgehoben; pLink des Objekts auf NULL setzen, da die Link-Instanz ja gerade destruiert wird.
307 	pGrafObj->ForceSwapIn();
308 	pGrafObj->pGraphicLink=NULL;
309 	pGrafObj->ReleaseGraphicLink();
310 	SvBaseLink::Closed();
311 }
312 
313 // -----------------------------------------------------------------------------
314 
UpdateAsynchron()315 void SdrGraphicLink::UpdateAsynchron()
316 {
317 	if( GetObj() )
318 	{
319 		if ( pGraphicUpdater )
320 		{
321 			if ( pGraphicUpdater->GraphicLinkChanged( pGrafObj->GetFileName() ) )
322 			{
323 				pGraphicUpdater->Terminate();
324 				pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this );
325 			}
326 		}
327 		else
328 			pGraphicUpdater = new SdrGraphicUpdater( pGrafObj->GetFileName(), pGrafObj->GetFilterName(), *this );
329 	}
330 }
331 
332 // --------------
333 // - SdrGrafObj -
334 // --------------
335 
336 //////////////////////////////////////////////////////////////////////////////
337 // BaseProperties section
338 
CreateObjectSpecificProperties()339 sdr::properties::BaseProperties* SdrGrafObj::CreateObjectSpecificProperties()
340 {
341 	return new sdr::properties::GraphicProperties(*this);
342 }
343 
344 //////////////////////////////////////////////////////////////////////////////
345 // DrawContact section
346 
CreateObjectSpecificViewContact()347 sdr::contact::ViewContact* SdrGrafObj::CreateObjectSpecificViewContact()
348 {
349 	return new sdr::contact::ViewContactOfGraphic(*this);
350 }
351 
352 //////////////////////////////////////////////////////////////////////////////
353 // check if SVG and if try to get ObjectInfoPrimitive2D and extract info
354 
onGraphicChanged()355 void SdrGrafObj::onGraphicChanged()
356 {
357     String aName;
358     String aTitle;
359     String aDesc;
360 
361     if(pGraphic)
362     {
363         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
364 
365         if(rSvgDataPtr.get())
366         {
367             const drawinglayer::primitive2d::Primitive2DSequence aSequence(rSvgDataPtr->getPrimitive2DSequence());
368 
369             if(aSequence.hasElements())
370             {
371                 drawinglayer::geometry::ViewInformation2D aViewInformation2D;
372                 drawinglayer::processor2d::ObjectInfoPrimitiveExtractor2D aProcessor(aViewInformation2D);
373 
374                 aProcessor.process(aSequence);
375 
376                 const drawinglayer::primitive2d::ObjectInfoPrimitive2D* pResult = aProcessor.getResult();
377 
378                 if(pResult)
379                 {
380                     aName = pResult->getName();
381 			        aTitle = pResult->getTitle();
382 			        aDesc = pResult->getDesc();
383                 }
384             }
385         }
386     }
387 
388     if(aName.Len())
389     {
390         SetName(aName);
391     }
392 
393     if(aTitle.Len())
394     {
395     	SetTitle(aTitle);
396     }
397 
398     if(aDesc.Len())
399     {
400     	SetDescription(aDesc);
401     }
402 }
403 
404 //////////////////////////////////////////////////////////////////////////////
405 
406 TYPEINIT1(SdrGrafObj,SdrRectObj);
407 
408 // -----------------------------------------------------------------------------
409 
SdrGrafObj()410 SdrGrafObj::SdrGrafObj()
411 :	SdrRectObj(),
412 	pGraphicLink	( NULL ),
413 	bMirrored		( sal_False )
414 {
415 	pGraphic = new GraphicObject;
416     mpReplacementGraphic = 0;
417 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() );
418     onGraphicChanged();
419 
420     // #i118485# Shear allowed and possible now
421     bNoShear = false;
422 
423 	// #111096#
424 	mbGrafAnimationAllowed = sal_True;
425 
426 	// #i25616#
427 	mbLineIsOutsideGeometry = sal_True;
428 	mbInsidePaint = sal_False;
429 	mbIsPreview = sal_False;
430 
431 	// #i25616#
432 	mbSupportTextIndentingOnLineWidthChange = sal_False;
433 }
434 
435 // -----------------------------------------------------------------------------
436 
SdrGrafObj(const Graphic & rGrf,const Rectangle & rRect)437 SdrGrafObj::SdrGrafObj(const Graphic& rGrf, const Rectangle& rRect)
438 :	SdrRectObj		( rRect ),
439 	pGraphicLink	( NULL ),
440 	bMirrored		( sal_False )
441 {
442 	pGraphic = new GraphicObject( rGrf );
443     mpReplacementGraphic = 0;
444 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() );
445     onGraphicChanged();
446 
447     // #i118485# Shear allowed and possible now
448     bNoShear = false;
449 
450 	// #111096#
451 	mbGrafAnimationAllowed = sal_True;
452 
453 	// #i25616#
454 	mbLineIsOutsideGeometry = sal_True;
455 	mbInsidePaint = sal_False;
456 	mbIsPreview	= sal_False;
457 
458 	// #i25616#
459 	mbSupportTextIndentingOnLineWidthChange = sal_False;
460 }
461 
462 // -----------------------------------------------------------------------------
463 
SdrGrafObj(const Graphic & rGrf)464 SdrGrafObj::SdrGrafObj( const Graphic& rGrf )
465 :	SdrRectObj(),
466 	pGraphicLink	( NULL ),
467 	bMirrored		( sal_False )
468 {
469 	pGraphic = new GraphicObject( rGrf );
470     mpReplacementGraphic = 0;
471 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() );
472     onGraphicChanged();
473 
474     // #i118485# Shear allowed and possible now
475     bNoShear = false;
476 
477 	// #111096#
478 	mbGrafAnimationAllowed = sal_True;
479 
480 	// #i25616#
481 	mbLineIsOutsideGeometry = sal_True;
482 	mbInsidePaint = sal_False;
483 	mbIsPreview	= sal_False;
484 
485 	// #i25616#
486 	mbSupportTextIndentingOnLineWidthChange = sal_False;
487 }
488 
489 // -----------------------------------------------------------------------------
490 
~SdrGrafObj()491 SdrGrafObj::~SdrGrafObj()
492 {
493 	delete pGraphic;
494     delete mpReplacementGraphic;
495 	ImpLinkAbmeldung();
496 }
497 
498 // -----------------------------------------------------------------------------
499 
SetGraphicObject(const GraphicObject & rGrfObj)500 void SdrGrafObj::SetGraphicObject( const GraphicObject& rGrfObj )
501 {
502 	*pGraphic = rGrfObj;
503     delete mpReplacementGraphic;
504     mpReplacementGraphic = 0;
505 	pGraphic->SetSwapStreamHdl( LINK( this, SdrGrafObj, ImpSwapHdl ), getCacheTimeInMs() );
506 	pGraphic->SetUserData();
507 	mbIsPreview = sal_False;
508 	SetChanged();
509 	BroadcastObjectChange();
510     onGraphicChanged();
511 }
512 
513 // -----------------------------------------------------------------------------
514 
GetGraphicObject(bool bForceSwapIn) const515 const GraphicObject& SdrGrafObj::GetGraphicObject(bool bForceSwapIn) const
516 {
517 	if(bForceSwapIn)
518 	{
519 		ForceSwapIn();
520 	}
521 
522 	return *pGraphic;
523 }
524 
GetReplacementGraphicObject() const525 const GraphicObject* SdrGrafObj::GetReplacementGraphicObject() const
526 {
527     if(!mpReplacementGraphic && pGraphic)
528     {
529         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
530 
531         if(rSvgDataPtr.get())
532         {
533             const_cast< SdrGrafObj* >(this)->mpReplacementGraphic = new GraphicObject(rSvgDataPtr->getReplacement());
534         }
535     }
536 
537     return mpReplacementGraphic;
538 }
539 
540 // -----------------------------------------------------------------------------
541 
NbcSetGraphic(const Graphic & rGrf)542 void SdrGrafObj::NbcSetGraphic( const Graphic& rGrf )
543 {
544 	pGraphic->SetGraphic( rGrf );
545     delete mpReplacementGraphic;
546     mpReplacementGraphic = 0;
547 	pGraphic->SetUserData();
548 	mbIsPreview = sal_False;
549     onGraphicChanged();
550 }
551 
SetGraphic(const Graphic & rGrf)552 void SdrGrafObj::SetGraphic( const Graphic& rGrf )
553 {
554     NbcSetGraphic(rGrf);
555 	SetChanged();
556 	BroadcastObjectChange();
557 }
558 
559 // -----------------------------------------------------------------------------
560 
GetGraphic() const561 const Graphic& SdrGrafObj::GetGraphic() const
562 {
563 	ForceSwapIn();
564 	return pGraphic->GetGraphic();
565 }
566 
567 // -----------------------------------------------------------------------------
568 
GetTransformedGraphic(sal_uIntPtr nTransformFlags) const569 Graphic SdrGrafObj::GetTransformedGraphic( sal_uIntPtr nTransformFlags ) const
570 {
571     // #107947# Refactored most of the code to GraphicObject, where
572     // everybody can use e.g. the cropping functionality
573 
574 	GraphicType	    eType = GetGraphicType();
575     MapMode   		aDestMap( pModel->GetScaleUnit(), Point(), pModel->GetScaleFraction(), pModel->GetScaleFraction() );
576     const Size      aDestSize( GetLogicRect().GetSize() );
577     const sal_Bool      bMirror = ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_MIRROR ) != 0;
578     const sal_Bool      bRotate = ( ( nTransformFlags & SDRGRAFOBJ_TRANSFORMATTR_ROTATE ) != 0 ) &&
579         ( aGeo.nDrehWink && aGeo.nDrehWink != 18000 ) && ( GRAPHIC_NONE != eType );
580 
581     // #104115# Need cropping info earlier
582     ( (SdrGrafObj*) this )->ImpSetAttrToGrafInfo();
583     GraphicAttr aActAttr;
584 
585 	if( SDRGRAFOBJ_TRANSFORMATTR_NONE != nTransformFlags &&
586         GRAPHIC_NONE != eType )
587 	{
588         // actually transform the graphic only in this case. On the
589         // other hand, cropping will always happen
590         aActAttr = aGrafInfo;
591 
592         if( bMirror )
593 		{
594 			sal_uInt16		nMirrorCase = ( aGeo.nDrehWink == 18000 ) ? ( bMirrored ? 3 : 4 ) : ( bMirrored ? 2 : 1 );
595 			FASTBOOL	bHMirr = nMirrorCase == 2 || nMirrorCase == 4;
596 			FASTBOOL	bVMirr = nMirrorCase == 3 || nMirrorCase == 4;
597 
598 			aActAttr.SetMirrorFlags( ( bHMirr ? BMP_MIRROR_HORZ : 0 ) | ( bVMirr ? BMP_MIRROR_VERT : 0 ) );
599 		}
600 
601 		if( bRotate )
602 			aActAttr.SetRotation( sal_uInt16(aGeo.nDrehWink / 10) );
603 	}
604 
605     // #107947# Delegate to moved code in GraphicObject
606     return GetGraphicObject().GetTransformedGraphic( aDestSize, aDestMap, aActAttr );
607 }
608 
609 // -----------------------------------------------------------------------------
610 
GetGraphicType() const611 GraphicType SdrGrafObj::GetGraphicType() const
612 {
613 	return pGraphic->GetType();
614 }
615 
IsAnimated() const616 sal_Bool SdrGrafObj::IsAnimated() const
617 {
618 	return pGraphic->IsAnimated();
619 }
620 
IsEPS() const621 sal_Bool SdrGrafObj::IsEPS() const
622 {
623 	return pGraphic->IsEPS();
624 }
625 
IsSwappedOut() const626 sal_Bool SdrGrafObj::IsSwappedOut() const
627 {
628 	return mbIsPreview ? sal_True : pGraphic->IsSwappedOut();
629 }
630 
GetGrafPrefMapMode() const631 const MapMode& SdrGrafObj::GetGrafPrefMapMode() const
632 {
633 	return pGraphic->GetPrefMapMode();
634 }
635 
GetGrafPrefSize() const636 const Size& SdrGrafObj::GetGrafPrefSize() const
637 {
638 	return pGraphic->GetPrefSize();
639 }
640 
641 // -----------------------------------------------------------------------------
642 
SetGrafStreamURL(const String & rGraphicStreamURL)643 void SdrGrafObj::SetGrafStreamURL( const String& rGraphicStreamURL )
644 {
645 	mbIsPreview = sal_False;
646 	if( !rGraphicStreamURL.Len() )
647 	{
648 		pGraphic->SetUserData();
649 	}
650 	else if( pModel->IsSwapGraphics() )
651 	{
652 		pGraphic->SetUserData( rGraphicStreamURL );
653 
654 		// set state of graphic object to 'swapped out'
655 		if( pGraphic->GetType() == GRAPHIC_NONE )
656 			pGraphic->SetSwapState();
657 	}
658 }
659 
660 // -----------------------------------------------------------------------------
661 
GetGrafStreamURL() const662 String SdrGrafObj::GetGrafStreamURL() const
663 {
664 	return pGraphic->GetUserData();
665 }
666 
667 // -----------------------------------------------------------------------------
668 
SetFileName(const String & rFileName)669 void SdrGrafObj::SetFileName(const String& rFileName)
670 {
671 	aFileName = rFileName;
672 	SetChanged();
673 }
674 
675 // -----------------------------------------------------------------------------
676 
SetFilterName(const String & rFilterName)677 void SdrGrafObj::SetFilterName(const String& rFilterName)
678 {
679 	aFilterName = rFilterName;
680 	SetChanged();
681 }
682 
683 // -----------------------------------------------------------------------------
684 
ForceSwapIn() const685 void SdrGrafObj::ForceSwapIn() const
686 {
687 	if( mbIsPreview )
688 	{
689 		// removing preview graphic
690 		const String aUserData( pGraphic->GetUserData() );
691 
692 		Graphic aEmpty;
693 		pGraphic->SetGraphic( aEmpty );
694 		pGraphic->SetUserData( aUserData );
695 		pGraphic->SetSwapState();
696 
697 		const_cast< SdrGrafObj* >( this )->mbIsPreview = sal_False;
698 	}
699 	if ( pGraphicLink && pGraphic->IsSwappedOut() )
700 		ImpUpdateGraphicLink( sal_False );
701 	else
702 		pGraphic->FireSwapInRequest();
703 
704 	if( pGraphic->IsSwappedOut() ||
705 	    ( pGraphic->GetType() == GRAPHIC_NONE ) ||
706 		( pGraphic->GetType() == GRAPHIC_DEFAULT ) )
707 	{
708 		Graphic aDefaultGraphic;
709 		aDefaultGraphic.SetDefaultType();
710 		pGraphic->SetGraphic( aDefaultGraphic );
711 	}
712 }
713 
714 // -----------------------------------------------------------------------------
715 
ForceSwapOut() const716 void SdrGrafObj::ForceSwapOut() const
717 {
718 	pGraphic->FireSwapOutRequest();
719 }
720 
721 // -----------------------------------------------------------------------------
722 
ImpLinkAnmeldung()723 void SdrGrafObj::ImpLinkAnmeldung()
724 {
725 	sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
726 
727 	if( pLinkManager != NULL && pGraphicLink == NULL )
728 	{
729 		if( aFileName.Len() )
730 		{
731 			pGraphicLink = new SdrGraphicLink( this );
732 			pLinkManager->InsertFileLink( *pGraphicLink, OBJECT_CLIENT_GRF, aFileName, ( aFilterName.Len() ? &aFilterName : NULL ), NULL );
733 			pGraphicLink->Connect();
734 		}
735 	}
736 }
737 
738 // -----------------------------------------------------------------------------
739 
ImpLinkAbmeldung()740 void SdrGrafObj::ImpLinkAbmeldung()
741 {
742 	sfx2::LinkManager* pLinkManager = pModel != NULL ? pModel->GetLinkManager() : NULL;
743 
744 	if( pLinkManager != NULL && pGraphicLink!=NULL)
745 	{
746 		// Bei Remove wird *pGraphicLink implizit deleted
747 		pLinkManager->Remove( pGraphicLink );
748 		pGraphicLink=NULL;
749 	}
750 }
751 
752 // -----------------------------------------------------------------------------
753 
SetGraphicLink(const String & rFileName,const String & rFilterName)754 void SdrGrafObj::SetGraphicLink( const String& rFileName, const String& rFilterName )
755 {
756 	ImpLinkAbmeldung();
757 	aFileName = rFileName;
758 	aFilterName = rFilterName;
759 	ImpLinkAnmeldung();
760 	pGraphic->SetUserData();
761 
762     // #92205# A linked graphic is per definition swapped out (has to be loaded)
763     pGraphic->SetSwapState();
764 }
765 
766 // -----------------------------------------------------------------------------
767 
ReleaseGraphicLink()768 void SdrGrafObj::ReleaseGraphicLink()
769 {
770 	ImpLinkAbmeldung();
771 	aFileName = String();
772 	aFilterName = String();
773 }
774 
775 // -----------------------------------------------------------------------------
776 
TakeObjInfo(SdrObjTransformInfoRec & rInfo) const777 void SdrGrafObj::TakeObjInfo(SdrObjTransformInfoRec& rInfo) const
778 {
779 	FASTBOOL bNoPresGrf = ( pGraphic->GetType() != GRAPHIC_NONE ) && !bEmptyPresObj;
780 
781 	rInfo.bResizeFreeAllowed = aGeo.nDrehWink % 9000 == 0 ||
782 							   aGeo.nDrehWink % 18000 == 0 ||
783 							   aGeo.nDrehWink % 27000 == 0;
784 
785 	rInfo.bResizePropAllowed = sal_True;
786 	rInfo.bRotateFreeAllowed = bNoPresGrf;
787 	rInfo.bRotate90Allowed = bNoPresGrf;
788 	rInfo.bMirrorFreeAllowed = bNoPresGrf;
789 	rInfo.bMirror45Allowed = bNoPresGrf;
790 	rInfo.bMirror90Allowed = !bEmptyPresObj;
791 	rInfo.bTransparenceAllowed = sal_False;
792 	rInfo.bGradientAllowed = sal_False;
793 
794     // #i118485# Shear allowed and possible now
795 	rInfo.bShearAllowed = true;
796 
797     rInfo.bEdgeRadiusAllowed=sal_False;
798 	rInfo.bCanConvToPath = !IsEPS();
799 	rInfo.bCanConvToPathLineToArea = sal_False;
800 	rInfo.bCanConvToPolyLineToArea = sal_False;
801 	rInfo.bCanConvToPoly = !IsEPS();
802 	rInfo.bCanConvToContour = (rInfo.bCanConvToPoly || LineGeometryUsageIsNecessary());
803 }
804 
805 // -----------------------------------------------------------------------------
806 
GetObjIdentifier() const807 sal_uInt16 SdrGrafObj::GetObjIdentifier() const
808 {
809 	return sal_uInt16( OBJ_GRAF );
810 }
811 
812 // -----------------------------------------------------------------------------
813 
814 /* The graphic of the GraphicLink will be loaded. If it is called with
815    bAsynchron = true then the graphic will be set later via DataChanged
816 */
ImpUpdateGraphicLink(sal_Bool bAsynchron) const817 sal_Bool SdrGrafObj::ImpUpdateGraphicLink( sal_Bool bAsynchron ) const
818 {
819     sal_Bool bRet = sal_False;
820     if( pGraphicLink )
821 	{
822         sfx2::LinkManager *linkMgr = pGraphicLink->GetLinkManager();
823         if ((linkMgr == NULL) || (linkMgr->GetUserAllowsLinkUpdate(NULL))) {
824             if ( bAsynchron )
825                 pGraphicLink->UpdateAsynchron();
826             else
827                 pGraphicLink->DataChanged( ImpLoadLinkedGraphic( aFileName, aFilterName ) );
828         } // else links shall not be updated
829         bRet = sal_True;
830     }
831 	return bRet;
832 }
833 
834 // -----------------------------------------------------------------------------
835 
ImpSetLinkedGraphic(const Graphic & rGraphic)836 void SdrGrafObj::ImpSetLinkedGraphic( const Graphic& rGraphic )
837 {
838 	const sal_Bool bIsChanged = GetModel()->IsChanged();
839 	NbcSetGraphic( rGraphic );
840 	ActionChanged();
841 	BroadcastObjectChange();
842 	GetModel()->SetChanged( bIsChanged );
843 }
844 
845 // -----------------------------------------------------------------------------
846 
TakeObjNameSingul(XubString & rName) const847 void SdrGrafObj::TakeObjNameSingul(XubString& rName) const
848 {
849     if(pGraphic)
850     {
851         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
852 
853         if(rSvgDataPtr.get())
854         {
855             rName = ImpGetResStr(STR_ObjNameSingulGRAFSVG);
856         }
857         else
858         {
859 	        switch( pGraphic->GetType() )
860 	        {
861 		        case GRAPHIC_BITMAP:
862                 {
863                     const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
864                                          ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPTRANSLNK : STR_ObjNameSingulGRAFBMPTRANS ) :
865                                          ( IsLinkedGraphic() ? STR_ObjNameSingulGRAFBMPLNK : STR_ObjNameSingulGRAFBMP ) );
866 
867                     rName=ImpGetResStr( nId );
868                 }
869                 break;
870 
871 		        case GRAPHIC_GDIMETAFILE:
872                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFMTFLNK : STR_ObjNameSingulGRAFMTF );
873                 break;
874 
875                 case GRAPHIC_NONE:
876                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNameSingulGRAFNONELNK : STR_ObjNameSingulGRAFNONE );
877                 break;
878 
879                 default:
880                     rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNameSingulGRAFLNK : STR_ObjNameSingulGRAF );
881                 break;
882 	        }
883         }
884 
885 	    const String aName(GetName());
886 
887 	    if( aName.Len() )
888 	    {
889 		    rName.AppendAscii( " '" );
890 		    rName += aName;
891 		    rName += sal_Unicode( '\'' );
892 	    }
893     }
894 }
895 
896 // -----------------------------------------------------------------------------
897 
TakeObjNamePlural(XubString & rName) const898 void SdrGrafObj::TakeObjNamePlural( XubString& rName ) const
899 {
900     if(pGraphic)
901     {
902         const SvgDataPtr& rSvgDataPtr = pGraphic->GetGraphic().getSvgData();
903 
904         if(rSvgDataPtr.get())
905         {
906             rName = ImpGetResStr(STR_ObjNamePluralGRAFSVG);
907         }
908         else
909         {
910 	        switch( pGraphic->GetType() )
911 	        {
912 		        case GRAPHIC_BITMAP:
913                 {
914                     const sal_uInt16 nId = ( ( pGraphic->IsTransparent() || ( (const SdrGrafTransparenceItem&) GetObjectItem( SDRATTR_GRAFTRANSPARENCE ) ).GetValue() ) ?
915                                          ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPTRANSLNK : STR_ObjNamePluralGRAFBMPTRANS ) :
916                                          ( IsLinkedGraphic() ? STR_ObjNamePluralGRAFBMPLNK : STR_ObjNamePluralGRAFBMP ) );
917 
918                     rName=ImpGetResStr( nId );
919                 }
920                 break;
921 
922 		        case GRAPHIC_GDIMETAFILE:
923                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFMTFLNK : STR_ObjNamePluralGRAFMTF );
924                 break;
925 
926                 case GRAPHIC_NONE:
927                     rName=ImpGetResStr( IsLinkedGraphic() ? STR_ObjNamePluralGRAFNONELNK : STR_ObjNamePluralGRAFNONE );
928                 break;
929 
930                 default:
931                     rName=ImpGetResStr(  IsLinkedGraphic() ? STR_ObjNamePluralGRAFLNK : STR_ObjNamePluralGRAF );
932                 break;
933 	        }
934         }
935 
936 	    const String aName(GetName());
937 
938 	    if( aName.Len() )
939 	    {
940 		    rName.AppendAscii( " '" );
941 		    rName += aName;
942 		    rName += sal_Unicode( '\'' );
943 	    }
944     }
945 }
946 
947 // -----------------------------------------------------------------------------
948 
getFullDragClone() const949 SdrObject* SdrGrafObj::getFullDragClone() const
950 {
951     // call parent
952     SdrGrafObj* pRetval = static_cast< SdrGrafObj* >(SdrRectObj::getFullDragClone());
953 
954     // #i103116# the full drag clone leads to problems
955     // with linked graphics, so reset the link in this
956     // temporary interaction object and load graphic
957     if(pRetval && IsLinkedGraphic())
958     {
959         pRetval->ForceSwapIn();
960         pRetval->ReleaseGraphicLink();
961     }
962 
963     return pRetval;
964 }
965 
operator =(const SdrObject & rObj)966 void SdrGrafObj::operator=( const SdrObject& rObj )
967 {
968 	SdrRectObj::operator=( rObj );
969 
970 	const SdrGrafObj& rGraf = (SdrGrafObj&) rObj;
971 
972 	pGraphic->SetGraphic( rGraf.GetGraphic(), &rGraf.GetGraphicObject() );
973 	aCropRect = rGraf.aCropRect;
974 	aFileName = rGraf.aFileName;
975 	aFilterName = rGraf.aFilterName;
976 	bMirrored = rGraf.bMirrored;
977 
978 	if( rGraf.pGraphicLink != NULL)
979 	{
980 		SetGraphicLink( aFileName, aFilterName );
981 	}
982 
983 	ImpSetAttrToGrafInfo();
984 }
985 
986 // -----------------------------------------------------------------------------
987 // #i25616#
988 
TakeXorPoly() const989 basegfx::B2DPolyPolygon SdrGrafObj::TakeXorPoly() const
990 {
991 	if(mbInsidePaint)
992 	{
993 		basegfx::B2DPolyPolygon aRetval;
994 
995 		// take grown rectangle
996 		const sal_Int32 nHalfLineWidth(ImpGetLineWdt() / 2);
997 		const Rectangle aGrownRect(
998 			aRect.Left() - nHalfLineWidth,
999 			aRect.Top() - nHalfLineWidth,
1000 			aRect.Right() + nHalfLineWidth,
1001 			aRect.Bottom() + nHalfLineWidth);
1002 
1003 		XPolygon aXPoly(ImpCalcXPoly(aGrownRect, GetEckenradius()));
1004 		aRetval.append(aXPoly.getB2DPolygon());
1005 
1006 		return aRetval;
1007 	}
1008 	else
1009 	{
1010 		// call parent
1011 		return SdrRectObj::TakeXorPoly();
1012 	}
1013 }
1014 
1015 // -----------------------------------------------------------------------------
1016 
GetHdlCount() const1017 sal_uInt32 SdrGrafObj::GetHdlCount() const
1018 {
1019 	return 8L;
1020 }
1021 
1022 // -----------------------------------------------------------------------------
1023 
GetHdl(sal_uInt32 nHdlNum) const1024 SdrHdl* SdrGrafObj::GetHdl(sal_uInt32 nHdlNum) const
1025 {
1026 	return SdrRectObj::GetHdl( nHdlNum + 1L );
1027 }
1028 
1029 // -----------------------------------------------------------------------------
1030 
NbcResize(const Point & rRef,const Fraction & xFact,const Fraction & yFact)1031 void SdrGrafObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
1032 {
1033 	SdrRectObj::NbcResize( rRef, xFact, yFact );
1034 
1035 	FASTBOOL bMirrX = xFact.GetNumerator() < 0;
1036 	FASTBOOL bMirrY = yFact.GetNumerator() < 0;
1037 
1038 	if( bMirrX != bMirrY )
1039 		bMirrored = !bMirrored;
1040 }
1041 
1042 // -----------------------------------------------------------------------------
1043 
NbcRotate(const Point & rRef,long nWink,double sn,double cs)1044 void SdrGrafObj::NbcRotate(const Point& rRef, long nWink, double sn, double cs)
1045 {
1046 	SdrRectObj::NbcRotate(rRef,nWink,sn,cs);
1047 }
1048 
1049 // -----------------------------------------------------------------------------
1050 
NbcMirror(const Point & rRef1,const Point & rRef2)1051 void SdrGrafObj::NbcMirror(const Point& rRef1, const Point& rRef2)
1052 {
1053 	SdrRectObj::NbcMirror(rRef1,rRef2);
1054 	bMirrored = !bMirrored;
1055 }
1056 
1057 // -----------------------------------------------------------------------------
1058 
NbcShear(const Point & rRef,long nWink,double tn,FASTBOOL bVShear)1059 void SdrGrafObj::NbcShear(const Point& rRef, long nWink, double tn, FASTBOOL bVShear)
1060 {
1061     // #i118485# Call Shear now, old version redirected to rotate
1062 	SdrRectObj::NbcShear(rRef, nWink, tn, bVShear);
1063 }
1064 
1065 // -----------------------------------------------------------------------------
1066 
NbcSetSnapRect(const Rectangle & rRect)1067 void SdrGrafObj::NbcSetSnapRect(const Rectangle& rRect)
1068 {
1069 	SdrRectObj::NbcSetSnapRect(rRect);
1070 }
1071 
1072 // -----------------------------------------------------------------------------
1073 
NbcSetLogicRect(const Rectangle & rRect)1074 void SdrGrafObj::NbcSetLogicRect( const Rectangle& rRect)
1075 {
1076 	//int bChg=rRect.GetSize()!=aRect.GetSize();
1077 	SdrRectObj::NbcSetLogicRect(rRect);
1078 }
1079 
1080 // -----------------------------------------------------------------------------
1081 
NewGeoData() const1082 SdrObjGeoData* SdrGrafObj::NewGeoData() const
1083 {
1084 	return new SdrGrafObjGeoData;
1085 }
1086 
1087 // -----------------------------------------------------------------------------
1088 
SaveGeoData(SdrObjGeoData & rGeo) const1089 void SdrGrafObj::SaveGeoData(SdrObjGeoData& rGeo) const
1090 {
1091 	SdrRectObj::SaveGeoData(rGeo);
1092 	SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
1093 	rGGeo.bMirrored=bMirrored;
1094 }
1095 
1096 // -----------------------------------------------------------------------------
1097 
RestGeoData(const SdrObjGeoData & rGeo)1098 void SdrGrafObj::RestGeoData(const SdrObjGeoData& rGeo)
1099 {
1100 	//long		nDrehMerk = aGeo.nDrehWink;
1101 	//long		nShearMerk = aGeo.nShearWink;
1102 	//int	bMirrMerk = bMirrored;
1103 	Size		aSizMerk( aRect.GetSize() );
1104 
1105 	SdrRectObj::RestGeoData(rGeo);
1106 	SdrGrafObjGeoData& rGGeo=(SdrGrafObjGeoData&)rGeo;
1107 	bMirrored=rGGeo.bMirrored;
1108 }
1109 
1110 // -----------------------------------------------------------------------------
1111 
SetPage(SdrPage * pNewPage)1112 void SdrGrafObj::SetPage( SdrPage* pNewPage )
1113 {
1114 	FASTBOOL bRemove = pNewPage == NULL && pPage != NULL;
1115 	FASTBOOL bInsert = pNewPage != NULL && pPage == NULL;
1116 
1117 	if( bRemove )
1118 	{
1119 		// hier kein SwapIn noetig, weil wenn nicht geladen, dann auch nicht animiert.
1120 		if( pGraphic->IsAnimated())
1121 			pGraphic->StopAnimation();
1122 
1123 		if( pGraphicLink != NULL )
1124 			ImpLinkAbmeldung();
1125 	}
1126 
1127     if(!pModel && !GetStyleSheet() && pNewPage->GetModel())
1128     {
1129         // #119287# Set default StyleSheet for SdrGrafObj here, it is different from 'Default'. This
1130         // needs to be done before the style 'Default' is set from the :SetModel() call which is triggered
1131         // from the following :SetPage().
1132         // TTTT: Needs to be moved in branch aw080 due to having a SdrModel from the beginning, is at this
1133         // place for convenience currently (works in both versions, is not in the way)
1134 		SfxStyleSheet* pSheet = pNewPage->GetModel()->GetDefaultStyleSheetForSdrGrafObjAndSdrOle2Obj();
1135 
1136 		if(pSheet)
1137 		{
1138 			SetStyleSheet(pSheet, false);
1139 		}
1140         else
1141         {
1142 		    SetMergedItem(XFillStyleItem(XFILL_NONE));
1143 		    SetMergedItem(XLineStyleItem(XLINE_NONE));
1144         }
1145     }
1146 
1147 	SdrRectObj::SetPage( pNewPage );
1148 
1149 	if(aFileName.Len() && bInsert)
1150 		ImpLinkAnmeldung();
1151 }
1152 
1153 // -----------------------------------------------------------------------------
1154 
SetModel(SdrModel * pNewModel)1155 void SdrGrafObj::SetModel( SdrModel* pNewModel )
1156 {
1157 	FASTBOOL bChg = pNewModel != pModel;
1158 
1159 	if( bChg )
1160 	{
1161 		if( pGraphic->HasUserData() )
1162 		{
1163 			ForceSwapIn();
1164 			pGraphic->SetUserData();
1165 		}
1166 
1167 		if( pGraphicLink != NULL )
1168 			ImpLinkAbmeldung();
1169 	}
1170 
1171 	// Model umsetzen
1172 	SdrRectObj::SetModel(pNewModel);
1173 
1174 	if( bChg && aFileName.Len() )
1175 		ImpLinkAnmeldung();
1176 }
1177 
1178 // -----------------------------------------------------------------------------
1179 
StartAnimation(OutputDevice *,const Point &,const Size &,long)1180 void SdrGrafObj::StartAnimation( OutputDevice* /*pOutDev*/, const Point& /*rPoint*/, const Size& /*rSize*/, long /*nExtraData*/)
1181 {
1182 	// #111096#
1183 	// use new graf animation
1184 	SetGrafAnimationAllowed(sal_True);
1185 }
1186 
1187 // -----------------------------------------------------------------------------
1188 
StopAnimation(OutputDevice *,long)1189 void SdrGrafObj::StopAnimation(OutputDevice* /*pOutDev*/, long /*nExtraData*/)
1190 {
1191 	// #111096#
1192 	// use new graf animation
1193 	SetGrafAnimationAllowed(sal_False);
1194 }
1195 
1196 // -----------------------------------------------------------------------------
1197 
HasGDIMetaFile() const1198 FASTBOOL SdrGrafObj::HasGDIMetaFile() const
1199 {
1200 	return( pGraphic->GetType() == GRAPHIC_GDIMETAFILE );
1201 }
1202 
1203 // -----------------------------------------------------------------------------
1204 
GetGDIMetaFile() const1205 const GDIMetaFile* SdrGrafObj::GetGDIMetaFile() const
1206 {
1207 	DBG_ERROR( "Invalid return value! Don't use it! (KA)" );
1208 	return &GetGraphic().GetGDIMetaFile();
1209 }
1210 
1211 // -----------------------------------------------------------------------------
1212 
isEmbeddedSvg() const1213 bool SdrGrafObj::isEmbeddedSvg() const
1214 {
1215     return GRAPHIC_BITMAP == GetGraphicType() && GetGraphic().getSvgData().get();
1216 }
1217 
getMetafileFromEmbeddedSvg() const1218 GDIMetaFile SdrGrafObj::getMetafileFromEmbeddedSvg() const
1219 {
1220     GDIMetaFile aRetval;
1221 
1222     if(isEmbeddedSvg() && GetModel())
1223     {
1224         VirtualDevice aOut;
1225         const Rectangle aBoundRect(GetCurrentBoundRect());
1226         const MapMode aMap(GetModel()->GetScaleUnit(), Point(), GetModel()->GetScaleFraction(), GetModel()->GetScaleFraction());
1227 
1228         aOut.EnableOutput(false);
1229         aOut.SetMapMode(aMap);
1230         aRetval.Record(&aOut);
1231         SingleObjectPainter(aOut);
1232         aRetval.Stop();
1233         aRetval.WindStart();
1234         aRetval.Move(-aBoundRect.Left(), -aBoundRect.Top());
1235         aRetval.SetPrefMapMode(aMap);
1236         aRetval.SetPrefSize(aBoundRect.GetSize());
1237     }
1238 
1239     return aRetval;
1240 }
1241 
DoConvertToPolyObj(sal_Bool bBezier,bool bAddText) const1242 SdrObject* SdrGrafObj::DoConvertToPolyObj(sal_Bool bBezier, bool bAddText) const
1243 {
1244 	SdrObject* pRetval = NULL;
1245     GraphicType aGraphicType(GetGraphicType());
1246     GDIMetaFile aMtf;
1247 
1248     if(isEmbeddedSvg())
1249     {
1250         // Embedded Svg
1251         // There is currently no helper to create SdrObjects from primitives (even if I'm thinking
1252         // about writing one for some time). To get the roundtrip to SdrObjects it is necessary to
1253         // use the old converter path over the MetaFile mechanism. Create Metafile from Svg
1254         // primitives here pretty directly
1255         aMtf = getMetafileFromEmbeddedSvg();
1256         aGraphicType = GRAPHIC_GDIMETAFILE;
1257     }
1258     else if(GRAPHIC_GDIMETAFILE == aGraphicType)
1259     {
1260         aMtf = GetTransformedGraphic(SDRGRAFOBJ_TRANSFORMATTR_COLOR|SDRGRAFOBJ_TRANSFORMATTR_MIRROR).GetGDIMetaFile();
1261     }
1262 
1263 	switch(aGraphicType)
1264 	{
1265 		case GRAPHIC_GDIMETAFILE:
1266 		{
1267 			// NUR die aus dem MetaFile erzeugbaren Objekte in eine Gruppe packen und zurueckliefern
1268 			ImpSdrGDIMetaFileImport aFilter(*GetModel(), GetLayer(), aRect);
1269 			SdrObjGroup* pGrp = new SdrObjGroup();
1270 			sal_uInt32 nInsAnz = aFilter.DoImport(aMtf, *pGrp->GetSubList(), 0);
1271 
1272             if(nInsAnz)
1273 			{
1274                 {
1275                         // copy transformation
1276                 	GeoStat aGeoStat(GetGeoStat());
1277 
1278 	                if(aGeoStat.nShearWink)
1279                     {
1280                         aGeoStat.RecalcTan();
1281                         pGrp->NbcShear(aRect.TopLeft(), aGeoStat.nShearWink, aGeoStat.nTan, false);
1282                     }
1283 
1284 	                if(aGeoStat.nDrehWink)
1285                     {
1286 	                    aGeoStat.RecalcSinCos();
1287                         pGrp->NbcRotate(aRect.TopLeft(), aGeoStat.nDrehWink, aGeoStat.nSin, aGeoStat.nCos);
1288                     }
1289                 }
1290 
1291                 pRetval = pGrp;
1292 				pGrp->NbcSetLayer(GetLayer());
1293 				pGrp->SetModel(GetModel());
1294 
1295                 if(bAddText)
1296                 {
1297 				    pRetval = ImpConvertAddText(pRetval, bBezier);
1298                 }
1299 
1300                 // convert all children
1301                 if( pRetval )
1302                 {
1303                     SdrObject* pHalfDone = pRetval;
1304                     pRetval = pHalfDone->DoConvertToPolyObj(bBezier, bAddText);
1305                     SdrObject::Free( pHalfDone ); // resulting object is newly created
1306 
1307                     if( pRetval )
1308                     {
1309                         // flatten subgroups. As we call
1310                         // DoConvertToPolyObj() on the resulting group
1311                         // objects, subgroups can exist (e.g. text is
1312                         // a group object for every line).
1313                         SdrObjList* pList = pRetval->GetSubList();
1314                         if( pList )
1315                             pList->FlattenGroups();
1316                     }
1317                 }
1318 			}
1319 			else
1320             {
1321 				delete pGrp;
1322             }
1323 
1324             // #i118485# convert line and fill
1325             SdrObject* pLineFill = SdrRectObj::DoConvertToPolyObj(bBezier, false);
1326 
1327             if(pLineFill)
1328             {
1329                 if(pRetval)
1330                 {
1331                     pGrp = dynamic_cast< SdrObjGroup* >(pRetval);
1332 
1333                     if(!pGrp)
1334                     {
1335             			pGrp = new SdrObjGroup();
1336 
1337                         pGrp->NbcSetLayer(GetLayer());
1338 				        pGrp->SetModel(GetModel());
1339                         pGrp->GetSubList()->NbcInsertObject(pRetval);
1340                     }
1341 
1342                     pGrp->GetSubList()->NbcInsertObject(pLineFill, 0);
1343                 }
1344                 else
1345                 {
1346                     pRetval = pLineFill;
1347                 }
1348             }
1349 
1350 			break;
1351 		}
1352 		case GRAPHIC_BITMAP:
1353 		{
1354 			// Grundobjekt kreieren und Fuellung ergaenzen
1355 			pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1356 
1357 			// Bitmap als Attribut retten
1358 			if(pRetval)
1359 			{
1360 				// Bitmap als Fuellung holen
1361 				SfxItemSet aSet(GetObjectItemSet());
1362 
1363 				aSet.Put(XFillStyleItem(XFILL_BITMAP));
1364 				const BitmapEx aBitmapEx(GetTransformedGraphic().GetBitmapEx());
1365 				aSet.Put(XFillBitmapItem(String(), Graphic(aBitmapEx)));
1366 				aSet.Put(XFillBmpTileItem(false));
1367 
1368 				pRetval->SetMergedItemSet(aSet);
1369 			}
1370 			break;
1371 		}
1372 		case GRAPHIC_NONE:
1373 		case GRAPHIC_DEFAULT:
1374 		{
1375 			pRetval = SdrRectObj::DoConvertToPolyObj(bBezier, bAddText);
1376 			break;
1377 		}
1378 	}
1379 
1380 	return pRetval;
1381 }
1382 
1383 // -----------------------------------------------------------------------------
1384 
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)1385 void SdrGrafObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
1386 {
1387 	SetXPolyDirty();
1388 	SdrRectObj::Notify( rBC, rHint );
1389 	ImpSetAttrToGrafInfo();
1390 }
1391 
ImpSetAttrToGrafInfo()1392 void SdrGrafObj::ImpSetAttrToGrafInfo()
1393 {
1394 	const SfxItemSet& rSet = GetObjectItemSet();
1395 	const sal_uInt16 nTrans = ( (SdrGrafTransparenceItem&) rSet.Get( SDRATTR_GRAFTRANSPARENCE ) ).GetValue();
1396 	const SdrGrafCropItem&	rCrop = (const SdrGrafCropItem&) rSet.Get( SDRATTR_GRAFCROP );
1397 
1398 	aGrafInfo.SetLuminance( ( (SdrGrafLuminanceItem&) rSet.Get( SDRATTR_GRAFLUMINANCE ) ).GetValue() );
1399 	aGrafInfo.SetContrast( ( (SdrGrafContrastItem&) rSet.Get( SDRATTR_GRAFCONTRAST ) ).GetValue() );
1400 	aGrafInfo.SetChannelR( ( (SdrGrafRedItem&) rSet.Get( SDRATTR_GRAFRED ) ).GetValue() );
1401 	aGrafInfo.SetChannelG( ( (SdrGrafGreenItem&) rSet.Get( SDRATTR_GRAFGREEN ) ).GetValue() );
1402 	aGrafInfo.SetChannelB( ( (SdrGrafBlueItem&) rSet.Get( SDRATTR_GRAFBLUE ) ).GetValue() );
1403 	aGrafInfo.SetGamma( ( (SdrGrafGamma100Item&) rSet.Get( SDRATTR_GRAFGAMMA ) ).GetValue() * 0.01 );
1404 	aGrafInfo.SetTransparency( (sal_uInt8) FRound( Min( nTrans, (sal_uInt16) 100 )  * 2.55 ) );
1405 	aGrafInfo.SetInvert( ( (SdrGrafInvertItem&) rSet.Get( SDRATTR_GRAFINVERT ) ).GetValue() );
1406 	aGrafInfo.SetDrawMode( ( (SdrGrafModeItem&) rSet.Get( SDRATTR_GRAFMODE ) ).GetValue() );
1407 	aGrafInfo.SetCrop( rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom() );
1408 
1409 	SetXPolyDirty();
1410 	SetRectsDirty();
1411 }
1412 
1413 // -----------------------------------------------------------------------------
1414 
ImpSetGrafInfoToAttr()1415 void SdrGrafObj::ImpSetGrafInfoToAttr()
1416 {
1417 	SetObjectItem( SdrGrafLuminanceItem( aGrafInfo.GetLuminance() ) );
1418 	SetObjectItem( SdrGrafContrastItem( aGrafInfo.GetContrast() ) );
1419 	SetObjectItem( SdrGrafRedItem( aGrafInfo.GetChannelR() ) );
1420 	SetObjectItem( SdrGrafGreenItem( aGrafInfo.GetChannelG() ) );
1421 	SetObjectItem( SdrGrafBlueItem( aGrafInfo.GetChannelB() ) );
1422 	SetObjectItem( SdrGrafGamma100Item( FRound( aGrafInfo.GetGamma() * 100.0 ) ) );
1423 	SetObjectItem( SdrGrafTransparenceItem( (sal_uInt16) FRound( aGrafInfo.GetTransparency() / 2.55 ) ) );
1424 	SetObjectItem( SdrGrafInvertItem( aGrafInfo.IsInvert() ) );
1425 	SetObjectItem( SdrGrafModeItem( aGrafInfo.GetDrawMode() ) );
1426 	SetObjectItem( SdrGrafCropItem( aGrafInfo.GetLeftCrop(), aGrafInfo.GetTopCrop(), aGrafInfo.GetRightCrop(), aGrafInfo.GetBottomCrop() ) );
1427 }
1428 
1429 // -----------------------------------------------------------------------------
1430 
AdjustToMaxRect(const Rectangle & rMaxRect,bool bShrinkOnly)1431 void SdrGrafObj::AdjustToMaxRect( const Rectangle& rMaxRect, bool bShrinkOnly )
1432 {
1433 	Size aSize;
1434 	Size aMaxSize( rMaxRect.GetSize() );
1435 	if ( pGraphic->GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1436 		aSize = Application::GetDefaultDevice()->PixelToLogic( pGraphic->GetPrefSize(), MAP_100TH_MM );
1437 	else
1438 		aSize = OutputDevice::LogicToLogic( pGraphic->GetPrefSize(),
1439 										    pGraphic->GetPrefMapMode(),
1440 										    MapMode( MAP_100TH_MM ) );
1441 
1442 	if( aSize.Height() != 0 && aSize.Width() != 0 )
1443 	{
1444 		Point aPos( rMaxRect.TopLeft() );
1445 
1446 		// Falls Grafik zu gross, wird die Grafik
1447 		// in die Seite eingepasst
1448 		if ( (!bShrinkOnly                          ||
1449 	    	 ( aSize.Height() > aMaxSize.Height() ) ||
1450 		 	( aSize.Width()  > aMaxSize.Width()  ) )&&
1451 		 	aSize.Height() && aMaxSize.Height() )
1452 		{
1453 			float fGrfWH =	(float)aSize.Width() /
1454 							(float)aSize.Height();
1455 			float fWinWH =	(float)aMaxSize.Width() /
1456 							(float)aMaxSize.Height();
1457 
1458 			// Grafik an Pagesize anpassen (skaliert)
1459 			if ( fGrfWH < fWinWH )
1460 			{
1461 				aSize.Width() = (long)(aMaxSize.Height() * fGrfWH);
1462 				aSize.Height()= aMaxSize.Height();
1463 			}
1464 			else if ( fGrfWH > 0.F )
1465 			{
1466 				aSize.Width() = aMaxSize.Width();
1467 				aSize.Height()= (long)(aMaxSize.Width() / fGrfWH);
1468 			}
1469 
1470 			aPos = rMaxRect.Center();
1471 		}
1472 
1473 		if( bShrinkOnly )
1474 			aPos = aRect.TopLeft();
1475 
1476 		aPos.X() -= aSize.Width() / 2;
1477 		aPos.Y() -= aSize.Height() / 2;
1478 		SetLogicRect( Rectangle( aPos, aSize ) );
1479 	}
1480 }
1481 
1482 // -----------------------------------------------------------------------------
1483 
IMPL_LINK(SdrGrafObj,ImpSwapHdl,GraphicObject *,pO)1484 IMPL_LINK( SdrGrafObj, ImpSwapHdl, GraphicObject*, pO )
1485 {
1486 	SvStream* pRet = GRFMGR_AUTOSWAPSTREAM_NONE;
1487 
1488 	if( pO->IsInSwapOut() )
1489 	{
1490 		if( pModel && !mbIsPreview && pModel->IsSwapGraphics() && pGraphic->GetSizeBytes() > 20480 )
1491 		{
1492 			// test if this object is visualized from someone
1493             // ## test only if there are VOCs other than the preview renderer
1494 			if(!GetViewContact().HasViewObjectContacts(true))
1495 			{
1496 				const sal_uIntPtr	nSwapMode = pModel->GetSwapGraphicsMode();
1497 
1498 				if( ( pGraphic->HasUserData() || pGraphicLink ) &&
1499 					( nSwapMode & SDR_SWAPGRAPHICSMODE_PURGE ) )
1500 				{
1501 					pRet = GRFMGR_AUTOSWAPSTREAM_LINK;
1502 				}
1503 				else if( nSwapMode & SDR_SWAPGRAPHICSMODE_TEMP )
1504 				{
1505 					pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1506 					pGraphic->SetUserData();
1507 				}
1508 
1509 				// #i102380#
1510 				sdr::contact::ViewContactOfGraphic* pVC = dynamic_cast< sdr::contact::ViewContactOfGraphic* >(&GetViewContact());
1511 
1512 				if(pVC)
1513 				{
1514 					pVC->flushGraphicObjects();
1515 				}
1516 			}
1517 		}
1518 	}
1519 	else if( pO->IsInSwapIn() )
1520 	{
1521 		// kann aus dem original Doc-Stream nachgeladen werden...
1522 		if( pModel != NULL )
1523 		{
1524 			if( pGraphic->HasUserData() )
1525 			{
1526 				SdrDocumentStreamInfo aStreamInfo;
1527 
1528 				aStreamInfo.mbDeleteAfterUse = sal_False;
1529 				aStreamInfo.maUserData = pGraphic->GetUserData();
1530 
1531 				SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1532 
1533 				if( pStream != NULL )
1534 				{
1535 					Graphic aGraphic;
1536 
1537                     com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >* pFilterData = NULL;
1538 
1539 					if(mbInsidePaint && !GetViewContact().HasViewObjectContacts(true))
1540                     {
1541                         pFilterData = new com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >( 3 );
1542 
1543                         const com::sun::star::awt::Size aPreviewSizeHint( 64, 64 );
1544                         const sal_Bool bAllowPartialStreamRead = sal_True;
1545                         // create <GfxLink> instance also for previews in order to avoid that its corresponding
1546                         // data is cleared in the graphic cache entry in case that the preview data equals the complete graphic data
1547                         const sal_Bool bCreateNativeLink = sal_True;
1548                         (*pFilterData)[ 0 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "PreviewSizeHint" ) );
1549                         (*pFilterData)[ 0 ].Value <<= aPreviewSizeHint;
1550                         (*pFilterData)[ 1 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "AllowPartialStreamRead" ) );
1551                         (*pFilterData)[ 1 ].Value <<= bAllowPartialStreamRead;
1552                         (*pFilterData)[ 2 ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "CreateNativeLink" ) );
1553                         (*pFilterData)[ 2 ].Value <<= bCreateNativeLink;
1554 
1555                         mbIsPreview = sal_True;
1556                     }
1557 
1558                     if(!GraphicFilter::GetGraphicFilter()->ImportGraphic(
1559                         aGraphic, aStreamInfo.maUserData, *pStream,
1560                         GRFILTER_FORMAT_DONTKNOW, NULL, 0, pFilterData))
1561                     {
1562                         const String aUserData( pGraphic->GetUserData() );
1563 
1564                         pGraphic->SetGraphic( aGraphic );
1565                         pGraphic->SetUserData( aUserData );
1566 
1567                         // #142146# Graphic successfully swapped in.
1568                         pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1569                     }
1570                     delete pFilterData;
1571 
1572                     pStream->ResetError();
1573 
1574                     if( aStreamInfo.mbDeleteAfterUse || aStreamInfo.mxStorageRef.is() )
1575                     {
1576                         if ( aStreamInfo.mxStorageRef.is() )
1577                         {
1578                             aStreamInfo.mxStorageRef->dispose();
1579                             aStreamInfo.mxStorageRef = 0;
1580                         }
1581 
1582                         delete pStream;
1583                     }
1584                 }
1585 			}
1586 			else if( !ImpUpdateGraphicLink( sal_False ) )
1587             {
1588 				pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1589             }
1590 			else
1591             {
1592                 pRet = GRFMGR_AUTOSWAPSTREAM_LOADED;
1593             }
1594 		}
1595 		else
1596 			pRet = GRFMGR_AUTOSWAPSTREAM_TEMP;
1597 	}
1598 
1599 	return (long)(void*) pRet;
1600 }
1601 
1602 // -----------------------------------------------------------------------------
1603 
1604 // #111096#
1605 // Access to GrafAnimationAllowed flag
IsGrafAnimationAllowed() const1606 sal_Bool SdrGrafObj::IsGrafAnimationAllowed() const
1607 {
1608 	return mbGrafAnimationAllowed;
1609 }
1610 
SetGrafAnimationAllowed(sal_Bool bNew)1611 void SdrGrafObj::SetGrafAnimationAllowed(sal_Bool bNew)
1612 {
1613 	if(mbGrafAnimationAllowed != bNew)
1614 	{
1615 		mbGrafAnimationAllowed = bNew;
1616 		ActionChanged();
1617 	}
1618 }
1619 
1620 // #i25616#
IsObjectTransparent() const1621 sal_Bool SdrGrafObj::IsObjectTransparent() const
1622 {
1623 	if(((const SdrGrafTransparenceItem&)GetObjectItem(SDRATTR_GRAFTRANSPARENCE)).GetValue()
1624 		|| pGraphic->IsTransparent())
1625 	{
1626 		return sal_True;
1627 	}
1628 
1629 	return sal_False;
1630 }
1631 
getInputStream()1632 Reference< XInputStream > SdrGrafObj::getInputStream()
1633 {
1634 	Reference< XInputStream > xStream;
1635 
1636 	if( pModel )
1637 	{
1638 //		if( !pGraphic->HasUserData() )
1639 //			pGraphic->SwapOut();
1640 
1641 		// kann aus dem original Doc-Stream nachgeladen werden...
1642 		if( pGraphic->HasUserData() )
1643 		{
1644 			SdrDocumentStreamInfo aStreamInfo;
1645 
1646 			aStreamInfo.mbDeleteAfterUse = sal_False;
1647 			aStreamInfo.maUserData = pGraphic->GetUserData();
1648 
1649 			SvStream* pStream = pModel->GetDocumentStream( aStreamInfo );
1650 
1651 			if( pStream )
1652 				xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1653 		}
1654 		else if( pGraphic && GetGraphic().IsLink() )
1655 		{
1656 			Graphic aGraphic( GetGraphic() );
1657 			GfxLink aLink( aGraphic.GetLink() );
1658 			sal_uInt32 nSize = aLink.GetDataSize();
1659 			const void* pSourceData = (const void*)aLink.GetData();
1660 			if( nSize && pSourceData )
1661 			{
1662 				sal_uInt8 * pBuffer = new sal_uInt8[ nSize ];
1663 				if( pBuffer )
1664 				{
1665 					memcpy( pBuffer, pSourceData, nSize );
1666 
1667 					SvMemoryStream* pStream = new SvMemoryStream( (void*)pBuffer, (sal_Size)nSize, STREAM_READ );
1668 					pStream->ObjectOwnsMemory( sal_True );
1669 					xStream.set( new utl::OInputStreamWrapper( pStream, sal_True ) );
1670 				}
1671 			}
1672 		}
1673 
1674 		if( !xStream.is() && aFileName.Len() )
1675 		{
1676 			SvFileStream* pStream = new SvFileStream( aFileName, STREAM_READ );
1677 			if( pStream )
1678 				xStream.set( new utl::OInputStreamWrapper( pStream ) );
1679 		}
1680 	}
1681 
1682 	return xStream;
1683 }
1684 
1685 // moved crop handle creation here; this is the object type using them
addCropHandles(SdrHdlList & rTarget) const1686 void SdrGrafObj::addCropHandles(SdrHdlList& rTarget) const
1687 {
1688     basegfx::B2DHomMatrix aMatrix;
1689     basegfx::B2DPolyPolygon aPolyPolygon;
1690 
1691     // get object transformation
1692     TRGetBaseGeometry(aMatrix, aPolyPolygon);
1693 
1694     // part of object transformation correction, but used later, so defined outside next scope
1695     double fShearX(0.0), fRotate(0.0);
1696 
1697     {   // TTTT correct shear, it comes currently mirrored from TRGetBaseGeometry, can be removed with aw080
1698         basegfx::B2DTuple aScale;
1699         basegfx::B2DTuple aTranslate;
1700 
1701         aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1702 
1703         if(!basegfx::fTools::equalZero(fShearX))
1704         {
1705             // shearX is used, correct it
1706             fShearX = -fShearX;
1707         }
1708 
1709         aMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
1710             aScale,
1711             fShearX,
1712             fRotate,
1713             aTranslate);
1714     }
1715 
1716     // get crop values
1717     const SdrGrafCropItem& rCrop = static_cast< const SdrGrafCropItem& >(GetMergedItem(SDRATTR_GRAFCROP));
1718 
1719     if(rCrop.GetLeft() || rCrop.GetTop() || rCrop.GetRight() ||rCrop.GetBottom())
1720     {
1721         // decompose object transformation to have current translate and scale
1722         basegfx::B2DVector aScale, aTranslate;
1723         double fRotate, fShearX;
1724 
1725         aMatrix.decompose(aScale, aTranslate, fRotate, fShearX);
1726 
1727         if(!aScale.equalZero())
1728         {
1729             // get crop scale
1730             const basegfx::B2DVector aCropScaleFactor(
1731                 GetGraphicObject().calculateCropScaling(
1732                     aScale.getX(),
1733                     aScale.getY(),
1734                     rCrop.GetLeft(),
1735                     rCrop.GetTop(),
1736                     rCrop.GetRight(),
1737                     rCrop.GetBottom()));
1738 
1739             // apply crop scale
1740             const double fCropLeft(rCrop.GetLeft() * aCropScaleFactor.getX());
1741             const double fCropTop(rCrop.GetTop() * aCropScaleFactor.getY());
1742             const double fCropRight(rCrop.GetRight() * aCropScaleFactor.getX());
1743             const double fCropBottom(rCrop.GetBottom() * aCropScaleFactor.getY());
1744             basegfx::B2DHomMatrix aMatrixForCropViewHdl(aMatrix);
1745 
1746             if(IsMirrored())
1747             {
1748                 // create corrected new matrix, TTTT can be removed with aw080
1749                 // the old mirror only can mirror horizontally; the vertical mirror
1750                 // is faked by using the horizontal and 180 degree rotation. Since
1751                 // the object can be rotated differently from 180 degree, this is
1752                 // not safe to detect. Just correct horizontal mirror (which is
1753                 // in IsMirrored()) and keep the rotation angle
1754                 // caution: Do not modify aMatrix, it is used below to calculate
1755                 // the exact handle positions
1756                 basegfx::B2DHomMatrix aPreMultiply;
1757 
1758                 // mirrored X, apply
1759                 aPreMultiply.translate(-0.5, 0.0);
1760                 aPreMultiply.scale(-1.0, 1.0);
1761                 aPreMultiply.translate(0.5, 0.0);
1762 
1763                 aMatrixForCropViewHdl = aMatrixForCropViewHdl * aPreMultiply;
1764             }
1765 
1766             rTarget.AddHdl(
1767                 new SdrCropViewHdl(
1768                     aMatrixForCropViewHdl,
1769                     GetGraphicObject().GetGraphic(),
1770                     fCropLeft,
1771                     fCropTop,
1772                     fCropRight,
1773                     fCropBottom));
1774         }
1775     }
1776 
1777     basegfx::B2DPoint aPos;
1778 
1779     aPos = aMatrix * basegfx::B2DPoint(0.0, 0.0);
1780     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPLFT, fShearX, fRotate));
1781     aPos = aMatrix * basegfx::B2DPoint(0.5, 0.0);
1782     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPPER, fShearX, fRotate));
1783     aPos = aMatrix * basegfx::B2DPoint(1.0, 0.0);
1784     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_UPRGT, fShearX, fRotate));
1785     aPos = aMatrix * basegfx::B2DPoint(0.0, 0.5);
1786     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LEFT , fShearX, fRotate));
1787     aPos = aMatrix * basegfx::B2DPoint(1.0, 0.5);
1788     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_RIGHT, fShearX, fRotate));
1789     aPos = aMatrix * basegfx::B2DPoint(0.0, 1.0);
1790     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWLFT, fShearX, fRotate));
1791     aPos = aMatrix * basegfx::B2DPoint(0.5, 1.0);
1792     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LOWER, fShearX, fRotate));
1793     aPos = aMatrix * basegfx::B2DPoint(1.0, 1.0);
1794     rTarget.AddHdl(new SdrCropHdl(Point(basegfx::fround(aPos.getX()), basegfx::fround(aPos.getY())), HDL_LWRGT, fShearX, fRotate));
1795 }
1796 
1797 // eof
1798