Update ooo320-m1
[ooovba.git] / vcl / source / gdi / impgraph.cxx
blobadd20ce2c979772ffbec1ffc9d3c7e298e0452a8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: impgraph.cxx,v $
10 * $Revision: 1.32 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
33 #include <tools/vcompat.hxx>
34 #include <tools/urlobj.hxx>
35 #include <tools/debug.hxx>
36 #include <ucbhelper/content.hxx>
37 #include <unotools/ucbstreamhelper.hxx>
38 #ifndef _UNTOOLS_TEMPFILE_HXX
39 #include <unotools/tempfile.hxx>
40 #endif
41 #include <vcl/outdev.hxx>
42 #include <vcl/virdev.hxx>
43 #include <tools/debug.hxx>
44 #include <tools/stream.hxx>
45 #include <vcl/impgraph.hxx>
46 #include <vcl/gfxlink.hxx>
47 #include <vcl/cvtgrf.hxx>
48 #include <vcl/salbtype.hxx>
49 #include <vcl/graph.hxx>
50 #include <vcl/metaact.hxx>
51 #include <com/sun/star/ucb/CommandAbortedException.hpp>
53 // -----------
54 // - Defines -
55 // -----------
57 #define GRAPHIC_MAXPARTLEN 256000L
58 #define GRAPHIC_MTFTOBMP_MAXEXT 2048
59 #define GRAPHIC_STREAMBUFSIZE 8192UL
61 #define SYS_WINMETAFILE 0x00000003L
62 #define SYS_WNTMETAFILE 0x00000004L
63 #define SYS_OS2METAFILE 0x00000005L
64 #define SYS_MACMETAFILE 0x00000006L
66 #define GRAPHIC_FORMAT_50 static_cast<sal_uInt32>(COMPAT_FORMAT( 'G', 'R', 'F', '5' ))
67 #define NATIVE_FORMAT_50 static_cast<sal_uInt32>(COMPAT_FORMAT( 'N', 'A', 'T', '5' ))
69 // ---------------
70 // - ImpSwapFile -
71 // ---------------
73 struct ImpSwapFile
75 INetURLObject aSwapURL;
76 ULONG nRefCount;
79 // -----------------
80 // - Graphicreader -
81 // -----------------
83 class ReaderData
85 public:
86 Size maPreviewSize;
89 GraphicReader::~GraphicReader()
91 delete mpReaderData;
94 // ------------------------------------------------------------------------
96 BOOL GraphicReader::IsPreviewModeEnabled() const
98 if( !mpReaderData )
99 return FALSE;
100 if( mpReaderData->maPreviewSize.Width() )
101 return TRUE;
102 if( mpReaderData->maPreviewSize.Height() )
103 return TRUE;
104 return FALSE;
107 // ------------------------------------------------------------------------
109 void GraphicReader::DisablePreviewMode()
111 if( mpReaderData )
112 mpReaderData->maPreviewSize = Size( 0, 0 );
115 // ------------------------------------------------------------------------
117 void GraphicReader::SetPreviewSize( const Size& rSize )
119 if( !mpReaderData )
120 mpReaderData = new ReaderData;
121 mpReaderData->maPreviewSize = rSize;
124 // ------------------------------------------------------------------------
126 Size GraphicReader::GetPreviewSize() const
128 Size aSize( 0, 0 );
129 if( mpReaderData )
130 aSize = mpReaderData->maPreviewSize;
131 return aSize;
134 // --------------
135 // - ImpGraphic -
136 // --------------
138 ImpGraphic::ImpGraphic() :
139 mpAnimation ( NULL ),
140 mpContext ( NULL ),
141 mpSwapFile ( NULL ),
142 mpGfxLink ( NULL ),
143 meType ( GRAPHIC_NONE ),
144 mnDocFilePos ( 0UL ),
145 mnSizeBytes ( 0UL ),
146 mnRefCount ( 1UL ),
147 mbSwapOut ( FALSE ),
148 mbSwapUnderway ( FALSE )
152 // ------------------------------------------------------------------------
154 ImpGraphic::ImpGraphic( const ImpGraphic& rImpGraphic ) :
155 maMetaFile ( rImpGraphic.maMetaFile ),
156 maEx ( rImpGraphic.maEx ),
157 mpContext ( NULL ),
158 mpSwapFile ( rImpGraphic.mpSwapFile ),
159 meType ( rImpGraphic.meType ),
160 maDocFileURLStr ( rImpGraphic.maDocFileURLStr ),
161 mnDocFilePos ( rImpGraphic.mnDocFilePos ),
162 mnSizeBytes ( rImpGraphic.mnSizeBytes ),
163 mnRefCount ( 1UL ),
164 mbSwapOut ( rImpGraphic.mbSwapOut ),
165 mbSwapUnderway ( FALSE )
167 if( mpSwapFile )
168 mpSwapFile->nRefCount++;
170 if( rImpGraphic.mpGfxLink )
171 mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink );
172 else
173 mpGfxLink = NULL;
175 if( rImpGraphic.mpAnimation )
177 mpAnimation = new Animation( *rImpGraphic.mpAnimation );
178 maEx = mpAnimation->GetBitmapEx();
180 else
181 mpAnimation = NULL;
184 // ------------------------------------------------------------------------
186 ImpGraphic::ImpGraphic( const Bitmap& rBitmap ) :
187 maEx ( rBitmap ),
188 mpAnimation ( NULL ),
189 mpContext ( NULL ),
190 mpSwapFile ( NULL ),
191 mpGfxLink ( NULL ),
192 meType ( !rBitmap ? GRAPHIC_NONE : GRAPHIC_BITMAP ),
193 mnDocFilePos ( 0UL ),
194 mnSizeBytes ( 0UL ),
195 mnRefCount ( 1UL ),
196 mbSwapOut ( FALSE ),
197 mbSwapUnderway ( FALSE )
201 // ------------------------------------------------------------------------
203 ImpGraphic::ImpGraphic( const BitmapEx& rBitmapEx ) :
204 maEx ( rBitmapEx ),
205 mpAnimation ( NULL ),
206 mpContext ( NULL ),
207 mpSwapFile ( NULL ),
208 mpGfxLink ( NULL ),
209 meType ( !rBitmapEx ? GRAPHIC_NONE : GRAPHIC_BITMAP ),
210 mnDocFilePos ( 0UL ),
211 mnSizeBytes ( 0UL ),
212 mnRefCount ( 1UL ),
213 mbSwapOut ( FALSE ),
214 mbSwapUnderway ( FALSE )
218 // ------------------------------------------------------------------------
220 ImpGraphic::ImpGraphic( const Animation& rAnimation ) :
221 maEx ( rAnimation.GetBitmapEx() ),
222 mpAnimation ( new Animation( rAnimation ) ),
223 mpContext ( NULL ),
224 mpSwapFile ( NULL ),
225 mpGfxLink ( NULL ),
226 meType ( GRAPHIC_BITMAP ),
227 mnDocFilePos ( 0UL ),
228 mnSizeBytes ( 0UL ),
229 mnRefCount ( 1UL ),
230 mbSwapOut ( FALSE ),
231 mbSwapUnderway ( FALSE )
235 // ------------------------------------------------------------------------
237 ImpGraphic::ImpGraphic( const GDIMetaFile& rMtf ) :
238 maMetaFile ( rMtf ),
239 mpAnimation ( NULL ),
240 mpContext ( NULL ),
241 mpSwapFile ( NULL ),
242 mpGfxLink ( NULL ),
243 meType ( GRAPHIC_GDIMETAFILE ),
244 mnDocFilePos ( 0UL ),
245 mnSizeBytes ( 0UL ),
246 mnRefCount ( 1UL ),
247 mbSwapOut ( FALSE ),
248 mbSwapUnderway ( FALSE )
252 // ------------------------------------------------------------------------
254 ImpGraphic::~ImpGraphic()
256 ImplClear();
258 if( (ULONG) mpContext > 1UL )
259 delete mpContext;
262 // ------------------------------------------------------------------------
264 ImpGraphic& ImpGraphic::operator=( const ImpGraphic& rImpGraphic )
266 if( &rImpGraphic != this )
268 if( !mbSwapUnderway )
269 ImplClear();
271 maMetaFile = rImpGraphic.maMetaFile;
272 meType = rImpGraphic.meType;
273 mnSizeBytes = rImpGraphic.mnSizeBytes;
275 delete mpAnimation;
277 if ( rImpGraphic.mpAnimation )
279 mpAnimation = new Animation( *rImpGraphic.mpAnimation );
280 maEx = mpAnimation->GetBitmapEx();
282 else
284 mpAnimation = NULL;
285 maEx = rImpGraphic.maEx;
288 if( !mbSwapUnderway )
290 maDocFileURLStr = rImpGraphic.maDocFileURLStr;
291 mnDocFilePos = rImpGraphic.mnDocFilePos;
292 mbSwapOut = rImpGraphic.mbSwapOut;
293 mpSwapFile = rImpGraphic.mpSwapFile;
295 if( mpSwapFile )
296 mpSwapFile->nRefCount++;
299 delete mpGfxLink;
301 if( rImpGraphic.mpGfxLink )
302 mpGfxLink = new GfxLink( *rImpGraphic.mpGfxLink );
303 else
304 mpGfxLink = NULL;
307 return *this;
310 // ------------------------------------------------------------------------
312 BOOL ImpGraphic::operator==( const ImpGraphic& rImpGraphic ) const
314 BOOL bRet = FALSE;
316 if( this == &rImpGraphic )
317 bRet = TRUE;
318 else if( !ImplIsSwapOut() && ( rImpGraphic.meType == meType ) )
320 switch( meType )
322 case( GRAPHIC_NONE ):
323 bRet = TRUE;
324 break;
326 case( GRAPHIC_GDIMETAFILE ):
328 if( rImpGraphic.maMetaFile == maMetaFile )
329 bRet = TRUE;
331 break;
333 case( GRAPHIC_BITMAP ):
335 if( mpAnimation )
337 if( rImpGraphic.mpAnimation && ( *rImpGraphic.mpAnimation == *mpAnimation ) )
338 bRet = TRUE;
340 else if( !rImpGraphic.mpAnimation && ( rImpGraphic.maEx == maEx ) )
341 bRet = TRUE;
343 break;
345 default:
346 break;
350 return bRet;
353 // ------------------------------------------------------------------------
355 void ImpGraphic::ImplClearGraphics( BOOL bCreateSwapInfo )
357 if( bCreateSwapInfo && !ImplIsSwapOut() )
359 maSwapInfo.maPrefMapMode = ImplGetPrefMapMode();
360 maSwapInfo.maPrefSize = ImplGetPrefSize();
363 maEx.Clear();
364 maMetaFile.Clear();
366 if( mpAnimation )
368 mpAnimation->Clear();
369 delete mpAnimation;
370 mpAnimation = NULL;
373 if( mpGfxLink )
375 delete mpGfxLink;
376 mpGfxLink = NULL;
380 // ------------------------------------------------------------------------
382 void ImpGraphic::ImplClear()
384 if( mpSwapFile )
386 if( mpSwapFile->nRefCount > 1 )
387 mpSwapFile->nRefCount--;
388 else
392 ::ucbhelper::Content aCnt( mpSwapFile->aSwapURL.GetMainURL( INetURLObject::NO_DECODE ),
393 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
395 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
396 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
398 catch( const ::com::sun::star::ucb::ContentCreationException& )
401 catch( const ::com::sun::star::uno::RuntimeException& )
404 catch( const ::com::sun::star::ucb::CommandAbortedException& )
407 catch( const ::com::sun::star::uno::Exception& )
411 delete mpSwapFile;
414 mpSwapFile = NULL;
417 mbSwapOut = FALSE;
418 mnDocFilePos = 0UL;
419 maDocFileURLStr.Erase();
421 // cleanup
422 ImplClearGraphics( FALSE );
423 meType = GRAPHIC_NONE;
424 mnSizeBytes = 0;
427 // ------------------------------------------------------------------------
429 GraphicType ImpGraphic::ImplGetType() const
431 return meType;
434 // ------------------------------------------------------------------------
436 void ImpGraphic::ImplSetDefaultType()
438 ImplClear();
439 meType = GRAPHIC_DEFAULT;
442 // ------------------------------------------------------------------------
444 BOOL ImpGraphic::ImplIsSupportedGraphic() const
446 return( meType != GRAPHIC_NONE );
449 // ------------------------------------------------------------------------
451 BOOL ImpGraphic::ImplIsTransparent() const
453 BOOL bRet;
455 if( meType == GRAPHIC_BITMAP )
456 bRet = ( mpAnimation ? mpAnimation->IsTransparent() : maEx.IsTransparent() );
457 else
458 bRet = TRUE;
460 return bRet;
463 // ------------------------------------------------------------------------
465 BOOL ImpGraphic::ImplIsAlpha() const
467 BOOL bRet;
469 if( meType == GRAPHIC_BITMAP )
470 bRet = ( NULL == mpAnimation ) && maEx.IsAlpha();
471 else
472 bRet = FALSE;
474 return bRet;
477 // ------------------------------------------------------------------------
479 BOOL ImpGraphic::ImplIsAnimated() const
481 return( mpAnimation != NULL );
484 // ------------------------------------------------------------------------
486 Bitmap ImpGraphic::ImplGetBitmap(const GraphicConversionParameters& rParameters) const
488 Bitmap aRetBmp;
490 if( meType == GRAPHIC_BITMAP )
492 const BitmapEx& rRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
493 const Color aReplaceColor( COL_WHITE );
495 aRetBmp = rRetBmpEx.GetBitmap( &aReplaceColor );
497 if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
498 aRetBmp.Scale(rParameters.getSizePixel());
500 else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
502 // use corner points of graphic to determine the pixel
503 // extent of the graphic (rounding errors are possible else)
504 VirtualDevice aVDev;
505 const Point aNullPt;
506 const Point aTLPix( aVDev.LogicToPixel( aNullPt, maMetaFile.GetPrefMapMode() ) );
507 const Point aBRPix( aVDev.LogicToPixel( Point( maMetaFile.GetPrefSize().Width() - 1, maMetaFile.GetPrefSize().Height() - 1 ), maMetaFile.GetPrefMapMode() ) );
508 Size aDrawSize( aVDev.LogicToPixel( maMetaFile.GetPrefSize(), maMetaFile.GetPrefMapMode() ) );
509 Size aSizePix( labs( aBRPix.X() - aTLPix.X() ) + 1, labs( aBRPix.Y() - aTLPix.Y() ) + 1 );
511 if(rParameters.getSizePixel().Width() && rParameters.getSizePixel().Height())
513 aDrawSize.Width() = FRound((double)rParameters.getSizePixel().Width() *
514 (double)aDrawSize.Width() / (double)aSizePix.Width());
515 aDrawSize.Height() = FRound((double)rParameters.getSizePixel().Height() *
516 (double)aDrawSize.Height() / (double)aSizePix.Height());
518 aSizePix = rParameters.getSizePixel();
521 if( aSizePix.Width() && aSizePix.Height() && !rParameters.getUnlimitedSize()
522 && (aSizePix.Width() > GRAPHIC_MTFTOBMP_MAXEXT || aSizePix.Height() > GRAPHIC_MTFTOBMP_MAXEXT))
524 const Size aOldSizePix( aSizePix );
525 double fWH = (double) aSizePix.Width() / aSizePix.Height();
527 if( fWH <= 1.0 )
528 aSizePix.Width() = FRound( GRAPHIC_MTFTOBMP_MAXEXT * fWH ), aSizePix.Height() = GRAPHIC_MTFTOBMP_MAXEXT;
529 else
530 aSizePix.Width() = GRAPHIC_MTFTOBMP_MAXEXT, aSizePix.Height() = FRound( GRAPHIC_MTFTOBMP_MAXEXT / fWH );
532 aDrawSize.Width() = FRound( ( (double) aDrawSize.Width() * aSizePix.Width() ) / aOldSizePix.Width() );
533 aDrawSize.Height() = FRound( ( (double) aDrawSize.Height() * aSizePix.Height() ) / aOldSizePix.Height() );
536 if( aVDev.SetOutputSizePixel( aSizePix ) )
538 if(rParameters.getAntiAliase())
540 aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_ENABLE_B2DDRAW);
543 if(rParameters.getSnapHorVerLines())
545 aVDev.SetAntialiasing(aVDev.GetAntialiasing() | ANTIALIASING_PIXELSNAPHAIRLINE);
548 ImplDraw( &aVDev, aNullPt, aDrawSize );
549 aRetBmp = aVDev.GetBitmap( aNullPt, aVDev.GetOutputSizePixel() );
553 if( !!aRetBmp )
555 aRetBmp.SetPrefMapMode( ImplGetPrefMapMode() );
556 aRetBmp.SetPrefSize( ImplGetPrefSize() );
559 return aRetBmp;
562 // ------------------------------------------------------------------------
564 BitmapEx ImpGraphic::ImplGetBitmapEx(const GraphicConversionParameters& rParameters) const
566 BitmapEx aRetBmpEx;
568 if( meType == GRAPHIC_BITMAP )
570 aRetBmpEx = ( mpAnimation ? mpAnimation->GetBitmapEx() : maEx );
572 if(rParameters.getSizePixel().Width() || rParameters.getSizePixel().Height())
573 aRetBmpEx.Scale(rParameters.getSizePixel());
575 else if( ( meType != GRAPHIC_DEFAULT ) && ImplIsSupportedGraphic() )
577 const ImpGraphic aMonoMask( maMetaFile.GetMonochromeMtf( COL_BLACK ) );
578 aRetBmpEx = BitmapEx(ImplGetBitmap(rParameters), aMonoMask.ImplGetBitmap(rParameters));
581 return aRetBmpEx;
584 // ------------------------------------------------------------------------
586 Animation ImpGraphic::ImplGetAnimation() const
588 Animation aAnimation;
590 if( mpAnimation )
591 aAnimation = *mpAnimation;
593 return aAnimation;
596 // ------------------------------------------------------------------------
598 const GDIMetaFile& ImpGraphic::ImplGetGDIMetaFile() const
600 return maMetaFile;
603 // ------------------------------------------------------------------------
605 Size ImpGraphic::ImplGetPrefSize() const
607 Size aSize;
609 if( ImplIsSwapOut() )
610 aSize = maSwapInfo.maPrefSize;
611 else
613 switch( meType )
615 case( GRAPHIC_NONE ):
616 case( GRAPHIC_DEFAULT ):
617 break;
619 case( GRAPHIC_BITMAP ):
621 aSize = maEx.GetPrefSize();
623 if( !aSize.Width() || !aSize.Height() )
624 aSize = maEx.GetSizePixel();
626 break;
628 default:
630 if( ImplIsSupportedGraphic() )
631 aSize = maMetaFile.GetPrefSize();
633 break;
637 return aSize;
640 // ------------------------------------------------------------------------
642 void ImpGraphic::ImplSetPrefSize( const Size& rPrefSize )
644 switch( meType )
646 case( GRAPHIC_NONE ):
647 case( GRAPHIC_DEFAULT ):
648 break;
650 case( GRAPHIC_BITMAP ):
651 // #108077# Push through pref size to animation object,
652 // will be lost on copy otherwise
653 if( ImplIsAnimated() )
654 const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefSize( rPrefSize );
656 maEx.SetPrefSize( rPrefSize );
657 break;
659 default:
661 if( ImplIsSupportedGraphic() )
662 maMetaFile.SetPrefSize( rPrefSize );
664 break;
668 // ------------------------------------------------------------------------
670 MapMode ImpGraphic::ImplGetPrefMapMode() const
672 MapMode aMapMode;
674 if( ImplIsSwapOut() )
675 aMapMode = maSwapInfo.maPrefMapMode;
676 else
678 switch( meType )
680 case( GRAPHIC_NONE ):
681 case( GRAPHIC_DEFAULT ):
682 break;
684 case( GRAPHIC_BITMAP ):
686 const Size aSize( maEx.GetPrefSize() );
688 if ( aSize.Width() && aSize.Height() )
689 aMapMode = maEx.GetPrefMapMode();
691 break;
693 default:
695 if( ImplIsSupportedGraphic() )
696 return maMetaFile.GetPrefMapMode();
698 break;
702 return aMapMode;
705 // ------------------------------------------------------------------------
707 void ImpGraphic::ImplSetPrefMapMode( const MapMode& rPrefMapMode )
709 switch( meType )
711 case( GRAPHIC_NONE ):
712 case( GRAPHIC_DEFAULT ):
713 break;
715 case( GRAPHIC_BITMAP ):
716 // #108077# Push through pref mapmode to animation object,
717 // will be lost on copy otherwise
718 if( ImplIsAnimated() )
719 const_cast< BitmapEx& >(mpAnimation->GetBitmapEx()).SetPrefMapMode( rPrefMapMode );
721 maEx.SetPrefMapMode( rPrefMapMode );
722 break;
724 default:
726 if( ImplIsSupportedGraphic() )
727 maMetaFile.SetPrefMapMode( rPrefMapMode );
729 break;
733 // ------------------------------------------------------------------------
735 ULONG ImpGraphic::ImplGetSizeBytes() const
737 if( 0 == mnSizeBytes )
739 if( meType == GRAPHIC_BITMAP )
741 mnSizeBytes = mpAnimation ? mpAnimation->GetSizeBytes() : maEx.GetSizeBytes();
743 else if( meType == GRAPHIC_GDIMETAFILE )
745 mnSizeBytes = maMetaFile.GetSizeBytes();
749 return( mnSizeBytes );
752 // ------------------------------------------------------------------------
754 void ImpGraphic::ImplDraw( OutputDevice* pOutDev, const Point& rDestPt ) const
756 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
758 switch( meType )
760 case( GRAPHIC_DEFAULT ):
761 break;
763 case( GRAPHIC_BITMAP ):
765 if ( mpAnimation )
766 mpAnimation->Draw( pOutDev, rDestPt );
767 else
768 maEx.Draw( pOutDev, rDestPt );
770 break;
772 default:
773 ImplDraw( pOutDev, rDestPt, maMetaFile.GetPrefSize() );
774 break;
779 // ------------------------------------------------------------------------
781 void ImpGraphic::ImplDraw( OutputDevice* pOutDev,
782 const Point& rDestPt, const Size& rDestSize ) const
784 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
786 switch( meType )
788 case( GRAPHIC_DEFAULT ):
789 break;
791 case( GRAPHIC_BITMAP ):
793 if( mpAnimation )
794 mpAnimation->Draw( pOutDev, rDestPt, rDestSize );
795 else
796 maEx.Draw( pOutDev, rDestPt, rDestSize );
798 break;
800 default:
802 ( (ImpGraphic*) this )->maMetaFile.WindStart();
803 ( (ImpGraphic*) this )->maMetaFile.Play( pOutDev, rDestPt, rDestSize );
804 ( (ImpGraphic*) this )->maMetaFile.WindStart();
806 break;
811 // ------------------------------------------------------------------------
813 void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev,
814 const Point& rDestPt,
815 long nExtraData,
816 OutputDevice* pFirstFrameOutDev )
818 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
819 mpAnimation->Start( pOutDev, rDestPt, nExtraData, pFirstFrameOutDev );
822 // ------------------------------------------------------------------------
824 void ImpGraphic::ImplStartAnimation( OutputDevice* pOutDev, const Point& rDestPt,
825 const Size& rDestSize, long nExtraData,
826 OutputDevice* pFirstFrameOutDev )
828 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
829 mpAnimation->Start( pOutDev, rDestPt, rDestSize, nExtraData, pFirstFrameOutDev );
832 // ------------------------------------------------------------------------
834 void ImpGraphic::ImplStopAnimation( OutputDevice* pOutDev, long nExtraData )
836 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() && mpAnimation )
837 mpAnimation->Stop( pOutDev, nExtraData );
840 // ------------------------------------------------------------------------
842 void ImpGraphic::ImplSetAnimationNotifyHdl( const Link& rLink )
844 if( mpAnimation )
845 mpAnimation->SetNotifyHdl( rLink );
848 // ------------------------------------------------------------------------
850 Link ImpGraphic::ImplGetAnimationNotifyHdl() const
852 Link aLink;
854 if( mpAnimation )
855 aLink = mpAnimation->GetNotifyHdl();
857 return aLink;
860 // ------------------------------------------------------------------------
862 ULONG ImpGraphic::ImplGetAnimationLoopCount() const
864 return( mpAnimation ? mpAnimation->GetLoopCount() : 0UL );
867 // ------------------------------------------------------------------------
869 void ImpGraphic::ImplResetAnimationLoopCount()
871 if( mpAnimation )
872 mpAnimation->ResetLoopCount();
875 // ------------------------------------------------------------------------
877 List* ImpGraphic::ImplGetAnimationInfoList() const
879 return( mpAnimation ? mpAnimation->GetAInfoList() : NULL );
882 // ------------------------------------------------------------------------
884 GraphicReader* ImpGraphic::ImplGetContext()
886 return mpContext;
889 // ------------------------------------------------------------------------
891 void ImpGraphic::ImplSetContext( GraphicReader* pReader )
893 mpContext = pReader;
896 // ------------------------------------------------------------------------
898 void ImpGraphic::ImplSetDocFileName( const String& rName, ULONG nFilePos )
900 const INetURLObject aURL( rName );
902 DBG_ASSERT( !rName.Len() || ( aURL.GetProtocol() != INET_PROT_NOT_VALID ), "Graphic::SetDocFileName(...): invalid URL" );
904 maDocFileURLStr = aURL.GetMainURL( INetURLObject::NO_DECODE );
905 mnDocFilePos = nFilePos;
908 // ------------------------------------------------------------------------
910 const String& ImpGraphic::ImplGetDocFileName() const
912 return maDocFileURLStr;
915 // ------------------------------------------------------------------------
917 ULONG ImpGraphic::ImplGetDocFilePos() const
919 return mnDocFilePos;
922 // ------------------------------------------------------------------------
924 BOOL ImpGraphic::ImplReadEmbedded( SvStream& rIStm, BOOL bSwap )
926 MapMode aMapMode;
927 Size aSize;
928 const ULONG nStartPos = rIStm.Tell();
929 sal_uInt32 nId;
930 ULONG nHeaderLen;
931 long nType;
932 long nLen;
933 const USHORT nOldFormat = rIStm.GetNumberFormatInt();
934 BOOL bRet = FALSE;
936 if( !mbSwapUnderway )
938 const String aTempURLStr( maDocFileURLStr );
939 const ULONG nTempPos = mnDocFilePos;
941 ImplClear();
943 maDocFileURLStr = aTempURLStr;
944 mnDocFilePos = nTempPos;
947 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
948 rIStm >> nId;
950 // check version
951 if( GRAPHIC_FORMAT_50 == nId )
953 // read new style header
954 VersionCompat* pCompat = new VersionCompat( rIStm, STREAM_READ );
956 rIStm >> nType;
957 rIStm >> nLen;
958 rIStm >> aSize;
959 rIStm >> aMapMode;
961 delete pCompat;
963 else
965 // read old style header
966 long nWidth, nHeight;
967 long nMapMode, nScaleNumX, nScaleDenomX;
968 long nScaleNumY, nScaleDenomY, nOffsX, nOffsY;
970 rIStm.SeekRel( -4L );
972 rIStm >> nType >> nLen >> nWidth >> nHeight;
973 rIStm >> nMapMode >> nScaleNumX >> nScaleDenomX >> nScaleNumY;
974 rIStm >> nScaleDenomY >> nOffsX >> nOffsY;
976 // swapped
977 if( nType > 100L )
979 nType = SWAPLONG( nType );
980 nLen = SWAPLONG( nLen );
981 nWidth = SWAPLONG( nWidth );
982 nHeight = SWAPLONG( nHeight );
983 nMapMode = SWAPLONG( nMapMode );
984 nScaleNumX = SWAPLONG( nScaleNumX );
985 nScaleDenomX = SWAPLONG( nScaleDenomX );
986 nScaleNumY = SWAPLONG( nScaleNumY );
987 nScaleDenomY = SWAPLONG( nScaleDenomY );
988 nOffsX = SWAPLONG( nOffsX );
989 nOffsY = SWAPLONG( nOffsY );
992 aSize = Size( nWidth, nHeight );
993 aMapMode = MapMode( (MapUnit) nMapMode, Point( nOffsX, nOffsY ),
994 Fraction( nScaleNumX, nScaleDenomX ),
995 Fraction( nScaleNumY, nScaleDenomY ) );
998 nHeaderLen = rIStm.Tell() - nStartPos;
999 meType = (GraphicType) nType;
1001 if( meType )
1003 if( meType == GRAPHIC_BITMAP )
1005 maEx.aBitmapSize = aSize;
1007 if( aMapMode != MapMode() )
1009 maEx.SetPrefMapMode( aMapMode );
1010 maEx.SetPrefSize( aSize );
1013 else
1015 maMetaFile.SetPrefMapMode( aMapMode );
1016 maMetaFile.SetPrefSize( aSize );
1019 if( bSwap )
1021 if( maDocFileURLStr.Len() )
1023 rIStm.Seek( nStartPos + nHeaderLen + nLen );
1024 bRet = mbSwapOut = TRUE;
1026 else
1028 ::utl::TempFile aTempFile;
1029 const INetURLObject aTmpURL( aTempFile.GetURL() );
1031 if( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() )
1033 SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
1035 if( pOStm )
1037 ULONG nFullLen = nHeaderLen + nLen;
1038 ULONG nPartLen = Min( nFullLen, (ULONG) GRAPHIC_MAXPARTLEN );
1039 BYTE* pBuffer = (BYTE*) rtl_allocateMemory( nPartLen );
1041 pOStm->SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1043 if( pBuffer )
1045 rIStm.Seek( nStartPos );
1047 while( nFullLen )
1049 rIStm.Read( (char*) pBuffer, nPartLen );
1050 pOStm->Write( (char*) pBuffer, nPartLen );
1052 nFullLen -= nPartLen;
1054 if( nFullLen < GRAPHIC_MAXPARTLEN )
1055 nPartLen = nFullLen;
1058 rtl_freeMemory( pBuffer );
1059 ULONG nReadErr = rIStm.GetError(), nWriteErr = pOStm->GetError();
1060 delete pOStm, pOStm = NULL;
1062 if( !nReadErr && !nWriteErr )
1064 bRet = mbSwapOut = TRUE;
1065 mpSwapFile = new ImpSwapFile;
1066 mpSwapFile->nRefCount = 1;
1067 mpSwapFile->aSwapURL = aTmpURL;
1069 else
1073 ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ),
1074 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
1076 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
1077 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
1079 catch( const ::com::sun::star::ucb::ContentCreationException& )
1082 catch( const ::com::sun::star::uno::RuntimeException& )
1085 catch( const ::com::sun::star::ucb::CommandAbortedException& )
1088 catch( const ::com::sun::star::uno::Exception& )
1094 delete pOStm;
1099 else if( meType == GRAPHIC_BITMAP || meType == GRAPHIC_GDIMETAFILE )
1101 rIStm >> *this;
1102 bRet = ( rIStm.GetError() == 0UL );
1104 else if( meType >= SYS_WINMETAFILE && meType <= SYS_MACMETAFILE )
1106 Graphic aSysGraphic;
1107 ULONG nCvtType;
1109 switch( sal::static_int_cast<ULONG>(meType) )
1111 case( SYS_WINMETAFILE ):
1112 case( SYS_WNTMETAFILE ): nCvtType = CVT_WMF; break;
1113 case( SYS_OS2METAFILE ): nCvtType = CVT_MET; break;
1114 case( SYS_MACMETAFILE ): nCvtType = CVT_PCT; break;
1116 default:
1117 nCvtType = CVT_UNKNOWN;
1118 break;
1121 if( nType && GraphicConverter::Import( rIStm, aSysGraphic, nCvtType ) == ERRCODE_NONE )
1123 *this = ImpGraphic( aSysGraphic.GetGDIMetaFile() );
1124 bRet = ( rIStm.GetError() == 0UL );
1126 else
1127 meType = GRAPHIC_DEFAULT;
1130 if( bRet )
1132 ImplSetPrefMapMode( aMapMode );
1133 ImplSetPrefSize( aSize );
1136 else
1137 bRet = TRUE;
1139 rIStm.SetNumberFormatInt( nOldFormat );
1141 return bRet;
1144 // ------------------------------------------------------------------------
1146 BOOL ImpGraphic::ImplWriteEmbedded( SvStream& rOStm )
1148 BOOL bRet = FALSE;
1150 if( ( meType != GRAPHIC_NONE ) && ( meType != GRAPHIC_DEFAULT ) && !ImplIsSwapOut() )
1152 const MapMode aMapMode( ImplGetPrefMapMode() );
1153 const Size aSize( ImplGetPrefSize() );
1154 const USHORT nOldFormat = rOStm.GetNumberFormatInt();
1155 ULONG nDataFieldPos;
1157 rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1159 // write correct version ( old style/new style header )
1160 if( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 )
1162 // write ID for new format (5.0)
1163 rOStm << GRAPHIC_FORMAT_50;
1165 // write new style header
1166 VersionCompat* pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
1168 rOStm << (long) meType;
1170 // data size is updated later
1171 nDataFieldPos = rOStm.Tell();
1172 rOStm << (long) 0;
1174 rOStm << aSize;
1175 rOStm << aMapMode;
1177 delete pCompat;
1179 else
1181 // write old style (<=4.0) header
1182 rOStm << (long) meType;
1184 // data size is updated later
1185 nDataFieldPos = rOStm.Tell();
1186 rOStm << (long) 0;
1188 rOStm << (long) aSize.Width();
1189 rOStm << (long) aSize.Height();
1190 rOStm << (long) aMapMode.GetMapUnit();
1191 rOStm << (long) aMapMode.GetScaleX().GetNumerator();
1192 rOStm << (long) aMapMode.GetScaleX().GetDenominator();
1193 rOStm << (long) aMapMode.GetScaleY().GetNumerator();
1194 rOStm << (long) aMapMode.GetScaleY().GetDenominator();
1195 rOStm << (long) aMapMode.GetOrigin().X();
1196 rOStm << (long) aMapMode.GetOrigin().Y();
1199 // write data block
1200 if( !rOStm.GetError() )
1202 const ULONG nDataStart = rOStm.Tell();
1204 if( ImplIsSupportedGraphic() )
1205 rOStm << *this;
1207 if( !rOStm.GetError() )
1209 const ULONG nStmPos2 = rOStm.Tell();
1210 rOStm.Seek( nDataFieldPos );
1211 rOStm << (long) ( nStmPos2 - nDataStart );
1212 rOStm.Seek( nStmPos2 );
1213 bRet = TRUE;
1217 rOStm.SetNumberFormatInt( nOldFormat );
1220 return bRet;
1223 // ------------------------------------------------------------------------
1225 BOOL ImpGraphic::ImplSwapOut()
1227 BOOL bRet = FALSE;
1229 if( !ImplIsSwapOut() )
1231 if( !maDocFileURLStr.Len() )
1233 ::utl::TempFile aTempFile;
1234 const INetURLObject aTmpURL( aTempFile.GetURL() );
1236 if( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ).getLength() )
1238 SvStream* pOStm = ::utl::UcbStreamHelper::CreateStream( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
1240 if( pOStm )
1242 pOStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1243 pOStm->SetCompressMode( COMPRESSMODE_NATIVE );
1245 if( ( bRet = ImplSwapOut( pOStm ) ) == TRUE )
1247 mpSwapFile = new ImpSwapFile;
1248 mpSwapFile->nRefCount = 1;
1249 mpSwapFile->aSwapURL = aTmpURL;
1251 else
1253 delete pOStm, pOStm = NULL;
1257 ::ucbhelper::Content aCnt( aTmpURL.GetMainURL( INetURLObject::NO_DECODE ),
1258 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
1260 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
1261 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
1263 catch( const ::com::sun::star::ucb::ContentCreationException& )
1266 catch( const ::com::sun::star::uno::RuntimeException& )
1269 catch( const ::com::sun::star::ucb::CommandAbortedException& )
1272 catch( const ::com::sun::star::uno::Exception& )
1277 delete pOStm;
1281 else
1283 ImplClearGraphics( TRUE );
1284 bRet = mbSwapOut = TRUE;
1288 return bRet;
1291 // ------------------------------------------------------------------------
1293 BOOL ImpGraphic::ImplSwapOut( SvStream* pOStm )
1295 BOOL bRet = FALSE;
1297 if( pOStm )
1299 pOStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE );
1301 if( !pOStm->GetError() && ImplWriteEmbedded( *pOStm ) )
1303 pOStm->Flush();
1305 if( !pOStm->GetError() )
1307 ImplClearGraphics( TRUE );
1308 bRet = mbSwapOut = TRUE;
1312 else
1314 ImplClearGraphics( TRUE );
1315 bRet = mbSwapOut = TRUE;
1318 return bRet;
1321 // ------------------------------------------------------------------------
1323 BOOL ImpGraphic::ImplSwapIn()
1325 BOOL bRet = FALSE;
1327 if( ImplIsSwapOut() )
1329 String aSwapURL;
1331 if( mpSwapFile )
1332 aSwapURL = mpSwapFile->aSwapURL.GetMainURL( INetURLObject::NO_DECODE );
1333 else
1334 aSwapURL = maDocFileURLStr;
1336 if( aSwapURL.Len() )
1338 SvStream* pIStm = ::utl::UcbStreamHelper::CreateStream( aSwapURL, STREAM_READWRITE | STREAM_SHARE_DENYWRITE );
1340 if( pIStm )
1342 pIStm->SetVersion( SOFFICE_FILEFORMAT_50 );
1343 pIStm->SetCompressMode( COMPRESSMODE_NATIVE );
1345 if( !mpSwapFile )
1346 pIStm->Seek( mnDocFilePos );
1348 bRet = ImplSwapIn( pIStm );
1349 delete pIStm;
1351 if( mpSwapFile )
1353 if( mpSwapFile->nRefCount > 1 )
1354 mpSwapFile->nRefCount--;
1355 else
1359 ::ucbhelper::Content aCnt( aSwapURL,
1360 ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment >() );
1362 aCnt.executeCommand( ::rtl::OUString::createFromAscii( "delete" ),
1363 ::com::sun::star::uno::makeAny( sal_Bool( sal_True ) ) );
1365 catch( const ::com::sun::star::ucb::ContentCreationException& )
1368 catch( const ::com::sun::star::uno::RuntimeException& )
1371 catch( const ::com::sun::star::ucb::CommandAbortedException& )
1374 catch( const ::com::sun::star::uno::Exception& )
1378 delete mpSwapFile;
1381 mpSwapFile = NULL;
1387 return bRet;
1390 // ------------------------------------------------------------------------
1392 BOOL ImpGraphic::ImplSwapIn( SvStream* pIStm )
1394 BOOL bRet = FALSE;
1396 if( pIStm )
1398 pIStm->SetBufferSize( GRAPHIC_STREAMBUFSIZE );
1400 if( !pIStm->GetError() )
1402 mbSwapUnderway = TRUE;
1403 bRet = ImplReadEmbedded( *pIStm );
1404 mbSwapUnderway = FALSE;
1406 if( !bRet )
1407 ImplClear();
1408 else
1409 mbSwapOut = FALSE;
1413 return bRet;
1416 // ------------------------------------------------------------------------
1418 BOOL ImpGraphic::ImplIsSwapOut() const
1420 return mbSwapOut;
1423 // ------------------------------------------------------------------------
1425 void ImpGraphic::ImplSetLink( const GfxLink& rGfxLink )
1427 delete mpGfxLink;
1428 mpGfxLink = new GfxLink( rGfxLink );
1430 if( mpGfxLink->IsNative() )
1431 mpGfxLink->SwapOut();
1434 // ------------------------------------------------------------------------
1436 GfxLink ImpGraphic::ImplGetLink()
1438 return( mpGfxLink ? *mpGfxLink : GfxLink() );
1441 // ------------------------------------------------------------------------
1443 BOOL ImpGraphic::ImplIsLink() const
1445 return ( mpGfxLink != NULL ) ? TRUE : FALSE;
1448 // ------------------------------------------------------------------------
1450 ULONG ImpGraphic::ImplGetChecksum() const
1452 ULONG nRet = 0;
1454 if( ImplIsSupportedGraphic() && !ImplIsSwapOut() )
1456 switch( meType )
1458 case( GRAPHIC_DEFAULT ):
1459 break;
1461 case( GRAPHIC_BITMAP ):
1463 if( mpAnimation )
1464 nRet = mpAnimation->GetChecksum();
1465 else
1466 nRet = maEx.GetChecksum();
1468 break;
1470 default:
1471 nRet = maMetaFile.GetChecksum();
1472 break;
1476 return nRet;
1479 // ------------------------------------------------------------------------
1481 BOOL ImpGraphic::ImplExportNative( SvStream& rOStm ) const
1483 BOOL bResult = FALSE;
1485 if( !rOStm.GetError() )
1487 if( !ImplIsSwapOut() )
1489 if( mpGfxLink && mpGfxLink->IsNative() )
1490 bResult = mpGfxLink->ExportNative( rOStm );
1491 else
1493 rOStm << *this;
1494 bResult = ( rOStm.GetError() == ERRCODE_NONE );
1497 else
1498 rOStm.SetError( SVSTREAM_GENERALERROR );
1501 return bResult;
1504 // ------------------------------------------------------------------------
1506 SvStream& operator>>( SvStream& rIStm, ImpGraphic& rImpGraphic )
1508 if( !rIStm.GetError() )
1510 const ULONG nStmPos1 = rIStm.Tell();
1511 sal_uInt32 nTmp;
1513 if ( !rImpGraphic.mbSwapUnderway )
1514 rImpGraphic.ImplClear();
1516 // read Id
1517 rIStm >> nTmp;
1519 // if there is no more data, avoid further expensive
1520 // reading which will create VDevs and other stuff, just to
1521 // read nothing. CAUTION: Eof is only true AFTER reading another
1522 // byte, a speciality of SvMemoryStream (!)
1523 if(!rIStm.GetError() && !rIStm.IsEof())
1525 if( NATIVE_FORMAT_50 == nTmp )
1527 Graphic aGraphic;
1528 GfxLink aLink;
1529 VersionCompat* pCompat;
1531 // read compat info
1532 pCompat = new VersionCompat( rIStm, STREAM_READ );
1533 delete pCompat;
1535 rIStm >> aLink;
1537 // set dummy link to avoid creation of additional link after filtering;
1538 // we set a default link to avoid unnecessary swapping of native data
1539 aGraphic.SetLink( GfxLink() );
1541 if( !rIStm.GetError() && aLink.LoadNative( aGraphic ) )
1543 // set link only, if no other link was set
1544 const BOOL bSetLink = ( rImpGraphic.mpGfxLink == NULL );
1546 // assign graphic
1547 rImpGraphic = *aGraphic.ImplGetImpGraphic();
1549 if( aLink.IsPrefMapModeValid() )
1550 rImpGraphic.ImplSetPrefMapMode( aLink.GetPrefMapMode() );
1552 if( aLink.IsPrefSizeValid() )
1553 rImpGraphic.ImplSetPrefSize( aLink.GetPrefSize() );
1555 if( bSetLink )
1556 rImpGraphic.ImplSetLink( aLink );
1558 else
1560 rIStm.Seek( nStmPos1 );
1561 rIStm.SetError( ERRCODE_IO_WRONGFORMAT );
1564 else
1566 BitmapEx aBmpEx;
1567 const USHORT nOldFormat = rIStm.GetNumberFormatInt();
1569 rIStm.SeekRel( -4 );
1570 rIStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1571 rIStm >> aBmpEx;
1573 if( !rIStm.GetError() )
1575 UINT32 nMagic1(0), nMagic2(0);
1576 ULONG nActPos = rIStm.Tell();
1578 rIStm >> nMagic1 >> nMagic2;
1579 rIStm.Seek( nActPos );
1581 rImpGraphic = ImpGraphic( aBmpEx );
1583 if( !rIStm.GetError() && ( 0x5344414e == nMagic1 ) && ( 0x494d4931 == nMagic2 ) )
1585 delete rImpGraphic.mpAnimation;
1586 rImpGraphic.mpAnimation = new Animation;
1587 rIStm >> *rImpGraphic.mpAnimation;
1589 // #108077# manually set loaded BmpEx to Animation
1590 // (which skips loading its BmpEx if already done)
1591 rImpGraphic.mpAnimation->SetBitmapEx(aBmpEx);
1593 else
1594 rIStm.ResetError();
1596 else
1598 GDIMetaFile aMtf;
1600 rIStm.Seek( nStmPos1 );
1601 rIStm.ResetError();
1602 rIStm >> aMtf;
1604 if( !rIStm.GetError() )
1605 rImpGraphic = aMtf;
1606 else
1607 rIStm.Seek( nStmPos1 );
1610 rIStm.SetNumberFormatInt( nOldFormat );
1615 return rIStm;
1618 // ------------------------------------------------------------------------
1620 SvStream& operator<<( SvStream& rOStm, const ImpGraphic& rImpGraphic )
1622 if( !rOStm.GetError() )
1624 if( !rImpGraphic.ImplIsSwapOut() )
1626 if( ( rOStm.GetVersion() >= SOFFICE_FILEFORMAT_50 ) &&
1627 ( rOStm.GetCompressMode() & COMPRESSMODE_NATIVE ) &&
1628 rImpGraphic.mpGfxLink && rImpGraphic.mpGfxLink->IsNative() )
1630 VersionCompat* pCompat;
1632 // native format
1633 rOStm << NATIVE_FORMAT_50;
1635 // write compat info
1636 pCompat = new VersionCompat( rOStm, STREAM_WRITE, 1 );
1637 delete pCompat;
1639 rImpGraphic.mpGfxLink->SetPrefMapMode( rImpGraphic.ImplGetPrefMapMode() );
1640 rImpGraphic.mpGfxLink->SetPrefSize( rImpGraphic.ImplGetPrefSize() );
1641 rOStm << *rImpGraphic.mpGfxLink;
1643 else
1645 // own format
1646 const USHORT nOldFormat = rOStm.GetNumberFormatInt();
1647 rOStm.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN );
1649 switch( rImpGraphic.ImplGetType() )
1651 case( GRAPHIC_NONE ):
1652 case( GRAPHIC_DEFAULT ):
1653 break;
1655 case GRAPHIC_BITMAP:
1657 if ( rImpGraphic.ImplIsAnimated() )
1658 rOStm << *rImpGraphic.mpAnimation;
1659 else
1660 rOStm << rImpGraphic.maEx;
1662 break;
1664 default:
1666 if( rImpGraphic.ImplIsSupportedGraphic() )
1667 rOStm << rImpGraphic.maMetaFile;
1669 break;
1672 rOStm.SetNumberFormatInt( nOldFormat );
1675 else
1676 rOStm.SetError( SVSTREAM_GENERALERROR );
1679 return rOStm;