1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: gdimtf.cxx,v $
10 * $Revision: 1.24.134.1 $
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 <vos/macros.hxx>
35 #include <tools/stream.hxx>
36 #include <tools/vcompat.hxx>
37 #include <vcl/metaact.hxx>
38 #include <vcl/salbtype.hxx>
39 #include <vcl/outdev.hxx>
40 #include <vcl/window.hxx>
41 #include <vcl/cvtsvm.hxx>
42 #include <vcl/virdev.hxx>
43 #include <vcl/salbmp.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/svdata.hxx>
46 #include <vcl/salinst.hxx>
47 #include <vcl/gdimtf.hxx>
48 #include <vcl/graphictools.hxx>
49 #include <vcl/canvastools.hxx>
50 #include <vcl/unohelp.hxx>
52 #include <com/sun/star/beans/XFastPropertySet.hpp>
53 #include <com/sun/star/rendering/XCanvas.hpp>
54 #include <com/sun/star/rendering/MtfRenderer.hpp>
55 #include <comphelper/processfactory.hxx>
56 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
57 #include <com/sun/star/lang/XInitialization.hpp>
58 #include <com/sun/star/awt/XGraphics.hpp>
59 #include <com/sun/star/graphic/XGraphic.hpp>
60 #include <com/sun/star/graphic/XGraphicRenderer.hpp>
62 using namespace com::sun::star
;
68 #define GAMMA( _def_cVal, _def_InvGamma ) ((BYTE)MinMax(FRound(pow( _def_cVal/255.0,_def_InvGamma)*255.0),0L,255L))
70 // --------------------------
71 // - Color exchange structs -
72 // --------------------------
74 struct ImplColAdjustParam
81 struct ImplBmpAdjustParam
83 short nLuminancePercent
;
84 short nContrastPercent
;
85 short nChannelRPercent
;
86 short nChannelGPercent
;
87 short nChannelBPercent
;
92 // -----------------------------------------------------------------------------
94 struct ImplColConvertParam
96 MtfConversion eConversion
;
99 struct ImplBmpConvertParam
101 BmpConversion eConversion
;
104 // -----------------------------------------------------------------------------
106 struct ImplColMonoParam
111 struct ImplBmpMonoParam
116 // -----------------------------------------------------------------------------
118 struct ImplColReplaceParam
126 const Color
* pDstCols
;
130 struct ImplBmpReplaceParam
132 const Color
* pSrcCols
;
133 const Color
* pDstCols
;
148 ImpLabel( const String
& rLabelName
, ULONG _nActionPos
) :
149 aLabelName( rLabelName
),
150 nActionPos( _nActionPos
) {}
157 class ImpLabelList
: private List
161 ImpLabelList() : List( 8, 4, 4 ) {}
162 ImpLabelList( const ImpLabelList
& rList
);
165 void ImplInsert( ImpLabel
* p
) { Insert( p
, LIST_APPEND
); }
166 ImpLabel
* ImplRemove( ULONG nPos
) { return (ImpLabel
*) Remove( nPos
); }
167 void ImplReplace( ImpLabel
* p
) { Replace( (void*)p
); }
168 ImpLabel
* ImplFirst() { return (ImpLabel
*) First(); }
169 ImpLabel
* ImplNext() { return (ImpLabel
*) Next(); }
170 ImpLabel
* ImplGetLabel( ULONG nPos
) const { return (ImpLabel
*) GetObject( nPos
); }
171 ULONG
ImplGetLabelPos( const String
& rLabelName
);
172 ULONG
ImplCount() const { return Count(); }
175 // ------------------------------------------------------------------------
177 ImpLabelList::ImpLabelList( const ImpLabelList
& rList
) :
180 for( ImpLabel
* pLabel
= ImplFirst(); pLabel
; pLabel
= ImplNext() )
181 ImplReplace( new ImpLabel( *pLabel
) );
184 // ------------------------------------------------------------------------
186 ImpLabelList::~ImpLabelList()
188 for( ImpLabel
* pLabel
= ImplFirst(); pLabel
; pLabel
= ImplNext() )
192 // ------------------------------------------------------------------------
194 ULONG
ImpLabelList::ImplGetLabelPos( const String
& rLabelName
)
196 ULONG nLabelPos
= METAFILE_LABEL_NOTFOUND
;
198 for( ImpLabel
* pLabel
= ImplFirst(); pLabel
; pLabel
= ImplNext() )
200 if ( rLabelName
== pLabel
->aLabelName
)
202 nLabelPos
= GetCurPos();
214 GDIMetaFile::GDIMetaFile() :
215 List ( 0x3EFF, 64, 64 ),
227 // ------------------------------------------------------------------------
229 GDIMetaFile::GDIMetaFile( const GDIMetaFile
& rMtf
) :
231 aPrefMapMode ( rMtf
.aPrefMapMode
),
232 aPrefSize ( rMtf
.aPrefSize
),
233 aHookHdlLink ( rMtf
.aHookHdlLink
),
234 pPrev ( rMtf
.pPrev
),
235 pNext ( rMtf
.pNext
),
239 bUseCanvas ( rMtf
.bUseCanvas
)
241 // RefCount der MetaActions erhoehen
242 for( void* pAct
= First(); pAct
; pAct
= Next() )
243 ( (MetaAction
*) pAct
)->Duplicate();
245 if( rMtf
.pLabelList
)
246 pLabelList
= new ImpLabelList( *rMtf
.pLabelList
);
252 Record( rMtf
.pOutDev
);
259 // ------------------------------------------------------------------------
261 GDIMetaFile::~GDIMetaFile()
266 // ------------------------------------------------------------------------
268 GDIMetaFile
& GDIMetaFile::operator=( const GDIMetaFile
& rMtf
)
274 List::operator=( rMtf
);
276 // RefCount der MetaActions erhoehen
277 for( void* pAct
= First(); pAct
; pAct
= Next() )
278 ( (MetaAction
*) pAct
)->Duplicate();
280 if( rMtf
.pLabelList
)
281 pLabelList
= new ImpLabelList( *rMtf
.pLabelList
);
285 aPrefMapMode
= rMtf
.aPrefMapMode
;
286 aPrefSize
= rMtf
.aPrefSize
;
287 aHookHdlLink
= rMtf
.aHookHdlLink
;
293 bUseCanvas
= rMtf
.bUseCanvas
;
297 Record( rMtf
.pOutDev
);
307 // ------------------------------------------------------------------------
309 BOOL
GDIMetaFile::operator==( const GDIMetaFile
& rMtf
) const
311 const ULONG nObjCount
= Count();
316 else if( rMtf
.GetActionCount() == nObjCount
&&
317 rMtf
.GetPrefSize() == aPrefSize
&&
318 rMtf
.GetPrefMapMode() == aPrefMapMode
)
322 for( ULONG n
= 0UL; n
< nObjCount
; n
++ )
324 if( GetObject( n
) != rMtf
.GetObject( n
) )
335 // ------------------------------------------------------------------------
337 sal_Bool
GDIMetaFile::IsEqual( const GDIMetaFile
& rMtf
) const
339 const ULONG nObjCount
= Count();
344 else if( rMtf
.GetActionCount() == nObjCount
&&
345 rMtf
.GetPrefSize() == aPrefSize
&&
346 rMtf
.GetPrefMapMode() == aPrefMapMode
)
350 for( ULONG n
= 0UL; n
< nObjCount
; n
++ )
352 if(!((MetaAction
*)GetObject( n
))->IsEqual(*((MetaAction
*)rMtf
.GetObject( n
))))
363 // ------------------------------------------------------------------------
365 void GDIMetaFile::Clear()
370 for( void* pAct
= First(); pAct
; pAct
= Next() )
371 ( (MetaAction
*) pAct
)->Delete();
379 // ------------------------------------------------------------------------
381 void GDIMetaFile::Linker( OutputDevice
* pOut
, BOOL bLink
)
386 pPrev
= pOut
->GetConnectMetaFile();
387 pOut
->SetConnectMetaFile( this );
396 pNext
->pPrev
= pPrev
;
399 pPrev
->pNext
= pNext
;
406 pOut
->SetConnectMetaFile( pPrev
);
414 // ------------------------------------------------------------------------
416 long GDIMetaFile::Hook()
418 return aHookHdlLink
.Call( this );
421 // ------------------------------------------------------------------------
423 void GDIMetaFile::Record( OutputDevice
* pOut
)
431 Linker( pOut
, TRUE
);
434 // ------------------------------------------------------------------------
436 void GDIMetaFile::Play( GDIMetaFile
& rMtf
, ULONG nPos
)
438 if ( !bRecord
&& !rMtf
.bRecord
)
440 MetaAction
* pAction
= GetCurAction();
441 const ULONG nObjCount
= Count();
443 if( nPos
> nObjCount
)
446 for( ULONG nCurPos
= GetCurPos(); nCurPos
< nPos
; nCurPos
++ )
450 pAction
->Duplicate();
451 rMtf
.AddAction( pAction
);
454 pAction
= (MetaAction
*) Next();
459 // ------------------------------------------------------------------------
461 void GDIMetaFile::Play( OutputDevice
* pOut
, ULONG nPos
)
465 MetaAction
* pAction
= GetCurAction();
466 const ULONG nObjCount
= Count();
467 ULONG i
= 0, nSyncCount
= ( pOut
->GetOutDevType() == OUTDEV_WINDOW
) ? 0x000000ff : 0xffffffff;
469 if( nPos
> nObjCount
)
472 // #i23407# Set backwards-compatible text language and layout mode
473 // This is necessary, since old metafiles don't even know of these
474 // recent add-ons. Newer metafiles must of course explicitely set
476 pOut
->Push( PUSH_TEXTLAYOUTMODE
|PUSH_TEXTLANGUAGE
);
477 pOut
->SetLayoutMode( 0 );
478 pOut
->SetDigitLanguage( 0 );
480 for( ULONG nCurPos
= GetCurPos(); nCurPos
< nPos
; nCurPos
++ )
484 MetaCommentAction
* pCommentAct
= static_cast<MetaCommentAction
*>(pAction
);
485 if( pAction
->GetType() == META_COMMENT_ACTION
&&
486 pCommentAct
->GetComment().Equals("DELEGATE_PLUGGABLE_RENDERER") )
488 ImplDelegate2PluggableRenderer(pCommentAct
, pOut
);
492 pAction
->Execute( pOut
);
495 // flush output from time to time
496 if( i
++ > nSyncCount
)
497 ( (Window
*) pOut
)->Flush(), i
= 0;
500 pAction
= (MetaAction
*) Next();
507 // ------------------------------------------------------------------------
509 bool GDIMetaFile::ImplPlayWithRenderer( OutputDevice
* pOut
, const Point
& rPos
, Size rDestSize
)
511 const Window
* win
= dynamic_cast <Window
*> ( pOut
);
514 win
= Application::GetActiveTopWindow();
516 win
= Application::GetFirstTopLevelWindow();
519 const uno::Reference
<rendering::XCanvas
>& xCanvas
= win
->GetCanvas ();
520 Size
aSize (rDestSize
.Width () + 1, rDestSize
.Height () + 1);
521 const uno::Reference
<rendering::XBitmap
>& xBitmap
= xCanvas
->getDevice ()->createCompatibleAlphaBitmap (vcl::unotools::integerSize2DFromSize( aSize
));
522 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= vcl::unohelper::GetMultiServiceFactory();
523 if( xFactory
.is() && xBitmap
.is () ) {
524 uno::Reference
< rendering::XMtfRenderer
> xMtfRenderer
;
525 uno::Sequence
< uno::Any
> args (1);
526 uno::Reference
< rendering::XBitmapCanvas
> xBitmapCanvas( xBitmap
, uno::UNO_QUERY
);
527 if( xBitmapCanvas
.is() ) {
528 args
[0] = uno::Any( xBitmapCanvas
);
529 xMtfRenderer
.set( xFactory
->createInstanceWithArguments( ::rtl::OUString::createFromAscii( "com.sun.star.rendering.MtfRenderer" ),
530 args
), uno::UNO_QUERY
);
532 if( xMtfRenderer
.is() ) {
533 xBitmapCanvas
->clear();
534 uno::Reference
< beans::XFastPropertySet
> xMtfFastPropertySet( xMtfRenderer
, uno::UNO_QUERY
);
535 if( xMtfFastPropertySet
.is() )
536 // set this metafile to the renderer to
537 // speedup things (instead of copying data to
538 // sequence of bytes passed to renderer)
539 xMtfFastPropertySet
->setFastPropertyValue( 0, uno::Any( reinterpret_cast<sal_Int64
>( this ) ) );
541 xMtfRenderer
->draw( rDestSize
.Width(), rDestSize
.Height() );
543 uno::Reference
< beans::XFastPropertySet
> xFastPropertySet( xBitmapCanvas
, uno::UNO_QUERY
);
544 if( xFastPropertySet
.get() ) {
545 // 0 means get BitmapEx
546 uno::Any aAny
= xFastPropertySet
->getFastPropertyValue( 0 );
547 BitmapEx
* pBitmapEx
= (BitmapEx
*) *reinterpret_cast<const sal_Int64
*>(aAny
.getValue());
549 pOut
->DrawBitmapEx( rPos
, *pBitmapEx
);
555 SalBitmap
* pSalBmp
= ImplGetSVData()->mpDefInst
->CreateSalBitmap();
556 SalBitmap
* pSalMask
= ImplGetSVData()->mpDefInst
->CreateSalBitmap();
558 if( pSalBmp
->Create( xBitmapCanvas
, aSize
) && pSalMask
->Create( xBitmapCanvas
, aSize
, true ) ) {
559 Bitmap
aBitmap( pSalBmp
);
560 Bitmap
aMask( pSalMask
);
561 AlphaMask
aAlphaMask( aMask
);
562 BitmapEx
aBitmapEx( aBitmap
, aAlphaMask
);
563 pOut
->DrawBitmapEx( rPos
, aBitmapEx
);
577 // ------------------------------------------------------------------------
579 void GDIMetaFile::ImplDelegate2PluggableRenderer( const MetaCommentAction
* pAct
, OutputDevice
* pOut
)
581 OSL_ASSERT( pAct
->GetComment().Equals("DELEGATE_PLUGGABLE_RENDERER") );
583 // read payload - string of service name, followed by raw render input
584 const BYTE
* pData
= pAct
->GetData();
585 const BYTE
* const pEndData
= pData
+ pAct
->GetDataSize();
589 ::rtl::OUStringBuffer aBuffer
;
590 while( pData
<pEndData
&& *pData
)
591 aBuffer
.append(static_cast<sal_Unicode
>(*pData
++));
592 const ::rtl::OUString aRendererServiceName
=aBuffer
.makeStringAndClear();
595 while( pData
<pEndData
&& *pData
)
596 aBuffer
.append(static_cast<sal_Unicode
>(*pData
++));
597 const ::rtl::OUString aGraphicServiceName
=aBuffer
.makeStringAndClear();
600 uno::Reference
< lang::XMultiServiceFactory
> xFactory
= vcl::unohelper::GetMultiServiceFactory();
601 if( pData
<pEndData
&& xFactory
.is() )
605 // instantiate render service
606 uno::Sequence
<uno::Any
> aRendererArgs(1);
607 aRendererArgs
[0] = makeAny(uno::Reference
<awt::XGraphics
>(pOut
->CreateUnoGraphics()));
608 uno::Reference
<graphic::XGraphicRenderer
> xRenderer(
609 xFactory
->createInstanceWithArguments(
610 aRendererServiceName
,
614 // instantiate graphic service
615 uno::Reference
<graphic::XGraphic
> xGraphic(
616 xFactory
->createInstance(
617 aGraphicServiceName
),
620 uno::Reference
<lang::XInitialization
> xInit(
621 xGraphic
, uno::UNO_QUERY
);
623 if(xGraphic
.is() && xRenderer
.is() && xInit
.is())
625 // delay intialization of XGraphic, to only expose
626 // XGraphic-generating services to arbitrary binary data
627 uno::Sequence
< sal_Int8
> aSeq(
628 (sal_Int8
*)&pData
, pEndData
-pData
);
629 uno::Sequence
<uno::Any
> aGraphicsArgs(1);
630 aGraphicsArgs
[0] = makeAny(aSeq
);
631 xInit
->initialize(aGraphicsArgs
);
633 xRenderer
->render(xGraphic
);
636 catch( uno::RuntimeException
& )
638 // runtime errors are fatal
641 catch( uno::Exception
& )
643 // ignore errors, no way of reporting them here
648 // ------------------------------------------------------------------------
650 void GDIMetaFile::Play( OutputDevice
* pOut
, const Point
& rPos
,
651 const Size
& rSize
, ULONG nPos
)
653 Region aDrawClipRegion
;
654 MapMode
aDrawMap( GetPrefMapMode() );
655 Size
aDestSize( pOut
->LogicToPixel( rSize
) );
657 if( aDestSize
.Width() && aDestSize
.Height() )
659 GDIMetaFile
* pMtf
= pOut
->GetConnectMetaFile();
661 if( bUseCanvas
&& !pMtf
&& ImplPlayWithRenderer( pOut
, rPos
, aDestSize
) )
664 Size
aTmpPrefSize( pOut
->LogicToPixel( GetPrefSize(), aDrawMap
) );
666 if( !aTmpPrefSize
.Width() )
667 aTmpPrefSize
.Width() = aDestSize
.Width();
669 if( !aTmpPrefSize
.Height() )
670 aTmpPrefSize
.Height() = aDestSize
.Height();
672 Fraction
aScaleX( aDestSize
.Width(), aTmpPrefSize
.Width() );
673 Fraction
aScaleY( aDestSize
.Height(), aTmpPrefSize
.Height() );
675 aScaleX
*= aDrawMap
.GetScaleX(); aDrawMap
.SetScaleX( aScaleX
);
676 aScaleY
*= aDrawMap
.GetScaleY(); aDrawMap
.SetScaleY( aScaleY
);
678 // #i47260# Convert logical output position to offset within
679 // the metafile's mapmode. Therefore, disable pixel offset on
680 // outdev, it's inverse mnOutOffLogicX/Y is calculated for a
681 // different mapmode (the one currently set on pOut, that is)
682 // - thus, aDrawMap's origin would generally be wrong. And
683 // even _if_ aDrawMap is similar to pOutDev's current mapmode,
684 // it's _still_ undesirable to have pixel offset unequal zero,
685 // because one would still get round-off errors (the
686 // round-trip error for LogicToPixel( PixelToLogic() ) was the
687 // reason for having pixel offset in the first place).
688 const Size
& rOldOffset( pOut
->GetPixelOffset() );
689 const Size aEmptySize
;
690 pOut
->SetPixelOffset( aEmptySize
);
691 aDrawMap
.SetOrigin( pOut
->PixelToLogic( pOut
->LogicToPixel( rPos
), aDrawMap
) );
692 pOut
->SetPixelOffset( rOldOffset
);
696 if ( pMtf
&& pMtf
->IsRecord() && ( pOut
->GetOutDevType() != OUTDEV_PRINTER
) )
697 pOut
->SetRelativeMapMode( aDrawMap
);
699 pOut
->SetMapMode( aDrawMap
);
701 // #i23407# Set backwards-compatible text language and layout mode
702 // This is necessary, since old metafiles don't even know of these
703 // recent add-ons. Newer metafiles must of course explicitely set
705 pOut
->SetLayoutMode( 0 );
706 pOut
->SetDigitLanguage( 0 );
714 // ------------------------------------------------------------------------
716 void GDIMetaFile::Pause( BOOL _bPause
)
723 Linker( pOutDev
, FALSE
);
728 Linker( pOutDev
, TRUE
);
735 // ------------------------------------------------------------------------
737 void GDIMetaFile::Stop()
744 Linker( pOutDev
, FALSE
);
750 // ------------------------------------------------------------------------
752 void GDIMetaFile::WindStart()
758 // ------------------------------------------------------------------------
760 void GDIMetaFile::WindEnd()
766 // ------------------------------------------------------------------------
768 void GDIMetaFile::Wind( ULONG nActionPos
)
774 // ------------------------------------------------------------------------
776 void GDIMetaFile::WindPrev()
782 // ------------------------------------------------------------------------
784 void GDIMetaFile::WindNext()
790 // ------------------------------------------------------------------------
792 void GDIMetaFile::AddAction( MetaAction
* pAction
)
794 Insert( pAction
, LIST_APPEND
);
798 pAction
->Duplicate();
799 pPrev
->AddAction( pAction
);
803 // ------------------------------------------------------------------------
805 void GDIMetaFile::AddAction( MetaAction
* pAction
, ULONG nPos
)
807 Insert( pAction
, nPos
);
811 pAction
->Duplicate();
812 pPrev
->AddAction( pAction
, nPos
);
816 // ------------------------------------------------------------------------
819 void GDIMetaFile::RemoveAction( ULONG nPos
)
824 pPrev
->RemoveAction( nPos
);
827 // ------------------------------------------------------------------------
829 MetaAction
* GDIMetaFile::CopyAction( ULONG nPos
) const
831 return ( (MetaAction
*) GetObject( nPos
) )->Clone();
834 // ------------------------------------------------------------------------
836 ULONG
GDIMetaFile::GetActionPos( const String
& rLabel
)
838 ImpLabel
* pLabel
= NULL
;
841 pLabel
= pLabelList
->ImplGetLabel( pLabelList
->ImplGetLabelPos( rLabel
) );
845 return( pLabel
? pLabel
->nActionPos
: METAFILE_LABEL_NOTFOUND
);
848 // ------------------------------------------------------------------------
850 BOOL
GDIMetaFile::InsertLabel( const String
& rLabel
, ULONG nActionPos
)
855 pLabelList
= new ImpLabelList
;
857 if( pLabelList
->ImplGetLabelPos( rLabel
) == METAFILE_LABEL_NOTFOUND
)
859 pLabelList
->ImplInsert( new ImpLabel( rLabel
, nActionPos
) );
866 // ------------------------------------------------------------------------
868 void GDIMetaFile::RemoveLabel( const String
& rLabel
)
872 const ULONG nLabelPos
= pLabelList
->ImplGetLabelPos( rLabel
);
874 if( nLabelPos
!= METAFILE_LABEL_NOTFOUND
)
875 delete pLabelList
->ImplRemove( nLabelPos
);
879 // ------------------------------------------------------------------------
881 void GDIMetaFile::RenameLabel( const String
& rLabel
, const String
& rNewLabel
)
885 const ULONG nLabelPos
= pLabelList
->ImplGetLabelPos( rLabel
);
887 if ( nLabelPos
!= METAFILE_LABEL_NOTFOUND
)
888 pLabelList
->ImplGetLabel( nLabelPos
)->aLabelName
= rNewLabel
;
892 // ------------------------------------------------------------------------
894 ULONG
GDIMetaFile::GetLabelCount() const
896 return( pLabelList
? pLabelList
->ImplCount() : 0UL );
899 // ------------------------------------------------------------------------
901 String
GDIMetaFile::GetLabel( ULONG nLabel
)
907 const ImpLabel
* pLabel
= pLabelList
->ImplGetLabel( nLabel
);
910 aString
= pLabel
->aLabelName
;
916 // ------------------------------------------------------------------------
918 BOOL
GDIMetaFile::SaveStatus()
923 Linker( pOutDev
, TRUE
);
925 AddAction( new MetaLineColorAction( pOutDev
->GetLineColor(),
926 pOutDev
->IsLineColor() ) );
927 AddAction( new MetaFillColorAction( pOutDev
->GetFillColor(),
928 pOutDev
->IsFillColor() ) );
929 AddAction( new MetaFontAction( pOutDev
->GetFont() ) );
930 AddAction( new MetaTextColorAction( pOutDev
->GetTextColor() ) );
931 AddAction( new MetaTextFillColorAction( pOutDev
->GetTextFillColor(),
932 pOutDev
->IsTextFillColor() ) );
933 AddAction( new MetaTextLineColorAction( pOutDev
->GetTextLineColor(),
934 pOutDev
->IsTextLineColor() ) );
935 AddAction( new MetaOverlineColorAction( pOutDev
->GetOverlineColor(),
936 pOutDev
->IsOverlineColor() ) );
937 AddAction( new MetaTextAlignAction( pOutDev
->GetTextAlign() ) );
938 AddAction( new MetaRasterOpAction( pOutDev
->GetRasterOp() ) );
939 AddAction( new MetaMapModeAction( pOutDev
->GetMapMode() ) );
940 AddAction( new MetaClipRegionAction( pOutDev
->GetClipRegion(),
941 pOutDev
->IsClipRegion() ) );
944 Linker( pOutDev
, FALSE
);
952 // ------------------------------------------------------------------------
954 BOOL
GDIMetaFile::Mirror( ULONG nMirrorFlags
)
956 const Size
aOldPrefSize( GetPrefSize() );
958 double fScaleX
, fScaleY
;
961 if( nMirrorFlags
& MTF_MIRROR_HORZ
)
962 nMoveX
= VOS_ABS( aOldPrefSize
.Width() ) - 1, fScaleX
= -1.0;
964 nMoveX
= 0, fScaleX
= 1.0;
966 if( nMirrorFlags
& MTF_MIRROR_VERT
)
967 nMoveY
= VOS_ABS( aOldPrefSize
.Height() ) - 1, fScaleY
= -1.0;
969 nMoveY
= 0, fScaleY
= 1.0;
971 if( ( fScaleX
!= 1.0 ) || ( fScaleY
!= 1.0 ) )
973 Scale( fScaleX
, fScaleY
);
974 Move( nMoveX
, nMoveY
);
975 SetPrefSize( aOldPrefSize
);
984 // ------------------------------------------------------------------------
986 void GDIMetaFile::Move( long nX
, long nY
)
988 const Size
aBaseOffset( nX
, nY
);
989 Size
aOffset( aBaseOffset
);
990 VirtualDevice aMapVDev
;
992 aMapVDev
.EnableOutput( FALSE
);
993 aMapVDev
.SetMapMode( GetPrefMapMode() );
995 for( MetaAction
* pAct
= (MetaAction
*) First(); pAct
; pAct
= (MetaAction
*) Next() )
997 const long nType
= pAct
->GetType();
1000 if( pAct
->GetRefCount() > 1 )
1002 Replace( pModAct
= pAct
->Clone(), GetCurPos() );
1008 if( ( META_MAPMODE_ACTION
== nType
) ||
1009 ( META_PUSH_ACTION
== nType
) ||
1010 ( META_POP_ACTION
== nType
) )
1012 pModAct
->Execute( &aMapVDev
);
1013 aOffset
= aMapVDev
.LogicToLogic( aBaseOffset
, GetPrefMapMode(), aMapVDev
.GetMapMode() );
1016 pModAct
->Move( aOffset
.Width(), aOffset
.Height() );
1020 // ------------------------------------------------------------------------
1022 void GDIMetaFile::Scale( double fScaleX
, double fScaleY
)
1024 for( MetaAction
* pAct
= (MetaAction
*) First(); pAct
; pAct
= (MetaAction
*) Next() )
1026 MetaAction
* pModAct
;
1028 if( pAct
->GetRefCount() > 1 )
1030 Replace( pModAct
= pAct
->Clone(), GetCurPos() );
1036 pModAct
->Scale( fScaleX
, fScaleY
);
1039 aPrefSize
.Width() = FRound( aPrefSize
.Width() * fScaleX
);
1040 aPrefSize
.Height() = FRound( aPrefSize
.Height() * fScaleY
);
1043 // ------------------------------------------------------------------------
1045 void GDIMetaFile::Scale( const Fraction
& rScaleX
, const Fraction
& rScaleY
)
1047 Scale( (double) rScaleX
, (double) rScaleY
);
1050 // ------------------------------------------------------------------------
1052 Point
GDIMetaFile::ImplGetRotatedPoint( const Point
& rPt
, const Point
& rRotatePt
,
1053 const Size
& rOffset
, double fSin
, double fCos
)
1055 const long nX
= rPt
.X() - rRotatePt
.X();
1056 const long nY
= rPt
.Y() - rRotatePt
.Y();
1058 return Point( FRound( fCos
* nX
+ fSin
* nY
) + rRotatePt
.X() + rOffset
.Width(),
1059 -FRound( fSin
* nX
- fCos
* nY
) + rRotatePt
.Y() + rOffset
.Height() );
1062 // ------------------------------------------------------------------------
1064 Polygon
GDIMetaFile::ImplGetRotatedPolygon( const Polygon
& rPoly
, const Point
& rRotatePt
,
1065 const Size
& rOffset
, double fSin
, double fCos
)
1067 Polygon
aRet( rPoly
);
1069 aRet
.Rotate( rRotatePt
, fSin
, fCos
);
1070 aRet
.Move( rOffset
.Width(), rOffset
.Height() );
1075 // ------------------------------------------------------------------------
1077 PolyPolygon
GDIMetaFile::ImplGetRotatedPolyPolygon( const PolyPolygon
& rPolyPoly
, const Point
& rRotatePt
,
1078 const Size
& rOffset
, double fSin
, double fCos
)
1080 PolyPolygon
aRet( rPolyPoly
);
1082 aRet
.Rotate( rRotatePt
, fSin
, fCos
);
1083 aRet
.Move( rOffset
.Width(), rOffset
.Height() );
1088 // ------------------------------------------------------------------------
1090 void GDIMetaFile::ImplAddGradientEx( GDIMetaFile
& rMtf
,
1091 const OutputDevice
& rMapDev
,
1092 const PolyPolygon
& rPolyPoly
,
1093 const Gradient
& rGrad
)
1095 // #105055# Generate comment, GradientEx and Gradient actions
1096 // (within DrawGradient)
1097 VirtualDevice
aVDev( rMapDev
, 0 );
1098 aVDev
.EnableOutput( FALSE
);
1099 GDIMetaFile aGradMtf
;
1101 aGradMtf
.Record( &aVDev
);
1102 aVDev
.DrawGradient( rPolyPoly
, rGrad
);
1105 int i
, nAct( aGradMtf
.GetActionCount() );
1106 for( i
=0; i
<nAct
; ++i
)
1108 MetaAction
* pMetaAct
= aGradMtf
.GetAction(i
);
1109 pMetaAct
->Duplicate();
1110 rMtf
.AddAction( pMetaAct
);
1114 // ------------------------------------------------------------------------
1116 void GDIMetaFile::Rotate( long nAngle10
)
1119 nAngle10
= ( nAngle10
< 0L ) ? ( 3599L + nAngle10
) : nAngle10
;
1124 VirtualDevice aMapVDev
;
1125 const double fAngle
= F_PI1800
* nAngle10
;
1126 const double fSin
= sin( fAngle
);
1127 const double fCos
= cos( fAngle
);
1128 Rectangle aRect
=Rectangle( Point(), GetPrefSize() );
1129 Polygon
aPoly( aRect
);
1131 aPoly
.Rotate( Point(), fSin
, fCos
);
1133 aMapVDev
.EnableOutput( FALSE
);
1134 aMapVDev
.SetMapMode( GetPrefMapMode() );
1136 const Rectangle
aNewBound( aPoly
.GetBoundRect() );
1138 const Point
aOrigin( GetPrefMapMode().GetOrigin().X(), GetPrefMapMode().GetOrigin().Y() );
1139 const Size
aOffset( -aNewBound
.Left(), -aNewBound
.Top() );
1141 Point
aRotAnchor( aOrigin
);
1142 Size
aRotOffset( aOffset
);
1144 for( MetaAction
* pAction
= (MetaAction
*) First(); pAction
; pAction
= (MetaAction
*) Next() )
1146 const USHORT nActionType
= pAction
->GetType();
1148 switch( nActionType
)
1150 case( META_PIXEL_ACTION
):
1152 MetaPixelAction
* pAct
= (MetaPixelAction
*) pAction
;
1153 aMtf
.AddAction( new MetaPixelAction( ImplGetRotatedPoint( pAct
->GetPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1154 pAct
->GetColor() ) );
1158 case( META_POINT_ACTION
):
1160 MetaPointAction
* pAct
= (MetaPointAction
*) pAction
;
1161 aMtf
.AddAction( new MetaPointAction( ImplGetRotatedPoint( pAct
->GetPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1165 case( META_LINE_ACTION
):
1167 MetaLineAction
* pAct
= (MetaLineAction
*) pAction
;
1168 aMtf
.AddAction( new MetaLineAction( ImplGetRotatedPoint( pAct
->GetStartPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1169 ImplGetRotatedPoint( pAct
->GetEndPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1170 pAct
->GetLineInfo() ) );
1174 case( META_RECT_ACTION
):
1176 MetaRectAction
* pAct
= (MetaRectAction
*) pAction
;
1177 aMtf
.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct
->GetRect(), aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1181 case( META_ROUNDRECT_ACTION
):
1183 MetaRoundRectAction
* pAct
= (MetaRoundRectAction
*) pAction
;
1184 const Polygon
aRoundRectPoly( pAct
->GetRect(), pAct
->GetHorzRound(), pAct
->GetVertRound() );
1186 aMtf
.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aRoundRectPoly
, aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1190 case( META_ELLIPSE_ACTION
):
1192 MetaEllipseAction
* pAct
= (MetaEllipseAction
*) pAction
;
1193 const Polygon
aEllipsePoly( pAct
->GetRect().Center(), pAct
->GetRect().GetWidth() >> 1, pAct
->GetRect().GetHeight() >> 1 );
1195 aMtf
.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aEllipsePoly
, aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1199 case( META_ARC_ACTION
):
1201 MetaArcAction
* pAct
= (MetaArcAction
*) pAction
;
1202 const Polygon
aArcPoly( pAct
->GetRect(), pAct
->GetStartPoint(), pAct
->GetEndPoint(), POLY_ARC
);
1204 aMtf
.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aArcPoly
, aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1208 case( META_PIE_ACTION
):
1210 MetaPieAction
* pAct
= (MetaPieAction
*) pAction
;
1211 const Polygon
aPiePoly( pAct
->GetRect(), pAct
->GetStartPoint(), pAct
->GetEndPoint(), POLY_PIE
);
1213 aMtf
.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aPiePoly
, aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1217 case( META_CHORD_ACTION
):
1219 MetaChordAction
* pAct
= (MetaChordAction
*) pAction
;
1220 const Polygon
aChordPoly( pAct
->GetRect(), pAct
->GetStartPoint(), pAct
->GetEndPoint(), POLY_CHORD
);
1222 aMtf
.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( aChordPoly
, aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1226 case( META_POLYLINE_ACTION
):
1228 MetaPolyLineAction
* pAct
= (MetaPolyLineAction
*) pAction
;
1229 aMtf
.AddAction( new MetaPolyLineAction( ImplGetRotatedPolygon( pAct
->GetPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
), pAct
->GetLineInfo() ) );
1233 case( META_POLYGON_ACTION
):
1235 MetaPolygonAction
* pAct
= (MetaPolygonAction
*) pAction
;
1236 aMtf
.AddAction( new MetaPolygonAction( ImplGetRotatedPolygon( pAct
->GetPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1240 case( META_POLYPOLYGON_ACTION
):
1242 MetaPolyPolygonAction
* pAct
= (MetaPolyPolygonAction
*) pAction
;
1243 aMtf
.AddAction( new MetaPolyPolygonAction( ImplGetRotatedPolyPolygon( pAct
->GetPolyPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1247 case( META_TEXT_ACTION
):
1249 MetaTextAction
* pAct
= (MetaTextAction
*) pAction
;
1250 aMtf
.AddAction( new MetaTextAction( ImplGetRotatedPoint( pAct
->GetPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1251 pAct
->GetText(), pAct
->GetIndex(), pAct
->GetLen() ) );
1255 case( META_TEXTARRAY_ACTION
):
1257 MetaTextArrayAction
* pAct
= (MetaTextArrayAction
*) pAction
;
1258 aMtf
.AddAction( new MetaTextArrayAction( ImplGetRotatedPoint( pAct
->GetPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1259 pAct
->GetText(), pAct
->GetDXArray(), pAct
->GetIndex(), pAct
->GetLen() ) );
1263 case( META_STRETCHTEXT_ACTION
):
1265 MetaStretchTextAction
* pAct
= (MetaStretchTextAction
*) pAction
;
1266 aMtf
.AddAction( new MetaStretchTextAction( ImplGetRotatedPoint( pAct
->GetPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1267 pAct
->GetWidth(), pAct
->GetText(), pAct
->GetIndex(), pAct
->GetLen() ) );
1271 case( META_TEXTLINE_ACTION
):
1273 MetaTextLineAction
* pAct
= (MetaTextLineAction
*) pAction
;
1274 aMtf
.AddAction( new MetaTextLineAction( ImplGetRotatedPoint( pAct
->GetStartPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1275 pAct
->GetWidth(), pAct
->GetStrikeout(), pAct
->GetUnderline(), pAct
->GetOverline() ) );
1279 case( META_BMPSCALE_ACTION
):
1281 MetaBmpScaleAction
* pAct
= (MetaBmpScaleAction
*) pAction
;
1282 Polygon
aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct
->GetPoint(), pAct
->GetSize() ), aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1283 Rectangle
aBmpRect( aBmpPoly
.GetBoundRect() );
1284 BitmapEx
aBmpEx( pAct
->GetBitmap() );
1286 aBmpEx
.Rotate( nAngle10
, Color( COL_TRANSPARENT
) );
1287 aMtf
.AddAction( new MetaBmpExScaleAction( aBmpRect
.TopLeft(), aBmpRect
.GetSize(),
1292 case( META_BMPSCALEPART_ACTION
):
1294 MetaBmpScalePartAction
* pAct
= (MetaBmpScalePartAction
*) pAction
;
1295 Polygon
aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct
->GetDestPoint(), pAct
->GetDestSize() ), aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1296 Rectangle
aBmpRect( aBmpPoly
.GetBoundRect() );
1297 BitmapEx
aBmpEx( pAct
->GetBitmap() );
1299 aBmpEx
.Crop( Rectangle( pAct
->GetSrcPoint(), pAct
->GetSrcSize() ) );
1300 aBmpEx
.Rotate( nAngle10
, Color( COL_TRANSPARENT
) );
1302 aMtf
.AddAction( new MetaBmpExScaleAction( aBmpRect
.TopLeft(), aBmpRect
.GetSize(), aBmpEx
) );
1306 case( META_BMPEXSCALE_ACTION
):
1308 MetaBmpExScaleAction
* pAct
= (MetaBmpExScaleAction
*) pAction
;
1309 Polygon
aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct
->GetPoint(), pAct
->GetSize() ), aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1310 Rectangle
aBmpRect( aBmpPoly
.GetBoundRect() );
1311 BitmapEx
aBmpEx( pAct
->GetBitmapEx() );
1313 aBmpEx
.Rotate( nAngle10
, Color( COL_TRANSPARENT
) );
1315 aMtf
.AddAction( new MetaBmpExScaleAction( aBmpRect
.TopLeft(), aBmpRect
.GetSize(), aBmpEx
) );
1319 case( META_BMPEXSCALEPART_ACTION
):
1321 MetaBmpExScalePartAction
* pAct
= (MetaBmpExScalePartAction
*) pAction
;
1322 Polygon
aBmpPoly( ImplGetRotatedPolygon( Rectangle( pAct
->GetDestPoint(), pAct
->GetDestSize() ), aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1323 Rectangle
aBmpRect( aBmpPoly
.GetBoundRect() );
1324 BitmapEx
aBmpEx( pAct
->GetBitmapEx() );
1326 aBmpEx
.Crop( Rectangle( pAct
->GetSrcPoint(), pAct
->GetSrcSize() ) );
1327 aBmpEx
.Rotate( nAngle10
, Color( COL_TRANSPARENT
) );
1329 aMtf
.AddAction( new MetaBmpExScaleAction( aBmpRect
.TopLeft(), aBmpRect
.GetSize(), aBmpEx
) );
1333 case( META_GRADIENT_ACTION
):
1335 MetaGradientAction
* pAct
= (MetaGradientAction
*) pAction
;
1337 ImplAddGradientEx( aMtf
, aMapVDev
,
1338 ImplGetRotatedPolygon( pAct
->GetRect(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1339 pAct
->GetGradient() );
1343 case( META_GRADIENTEX_ACTION
):
1345 MetaGradientExAction
* pAct
= (MetaGradientExAction
*) pAction
;
1346 aMtf
.AddAction( new MetaGradientExAction( ImplGetRotatedPolyPolygon( pAct
->GetPolyPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1347 pAct
->GetGradient() ) );
1351 // #105055# Handle gradientex comment block correctly
1352 case( META_COMMENT_ACTION
):
1354 MetaCommentAction
* pCommentAct
= (MetaCommentAction
*) pAction
;
1355 if( pCommentAct
->GetComment().Equals( "XGRAD_SEQ_BEGIN" ) )
1357 int nBeginComments( 1 );
1358 pAction
= (MetaAction
*) Next();
1360 // skip everything, except gradientex action
1363 const USHORT nType
= pAction
->GetType();
1365 if( META_GRADIENTEX_ACTION
== nType
)
1367 // Add rotated gradientex
1368 MetaGradientExAction
* pAct
= (MetaGradientExAction
*) pAction
;
1369 ImplAddGradientEx( aMtf
, aMapVDev
,
1370 ImplGetRotatedPolyPolygon( pAct
->GetPolyPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1371 pAct
->GetGradient() );
1373 else if( META_COMMENT_ACTION
== nType
)
1375 MetaCommentAction
* pAct
= (MetaCommentAction
*) pAction
;
1376 if( pAct
->GetComment().Equals( "XGRAD_SEQ_END" ) )
1378 // handle nested blocks
1381 // gradientex comment block: end reached, done.
1382 if( !nBeginComments
)
1385 else if( pAct
->GetComment().Equals( "XGRAD_SEQ_BEGIN" ) )
1387 // handle nested blocks
1393 pAction
= (MetaAction
*) Next();
1398 sal_Bool bPathStroke
= pCommentAct
->GetComment().Equals( "XPATHSTROKE_SEQ_BEGIN" );
1399 if ( bPathStroke
|| pCommentAct
->GetComment().Equals( "XPATHFILL_SEQ_BEGIN" ) )
1401 if ( pCommentAct
->GetDataSize() )
1403 SvMemoryStream
aMemStm( (void*)pCommentAct
->GetData(), pCommentAct
->GetDataSize(), STREAM_READ
);
1404 SvMemoryStream aDest
;
1407 SvtGraphicStroke aStroke
;
1410 aStroke
.getPath( aPath
);
1411 aStroke
.setPath( ImplGetRotatedPolygon( aPath
, aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1413 aMtf
.AddAction( new MetaCommentAction( "XPATHSTROKE_SEQ_BEGIN", 0,
1414 static_cast<const BYTE
*>( aDest
.GetData()), aDest
.Tell() ) );
1418 SvtGraphicFill aFill
;
1421 aFill
.getPath( aPath
);
1422 aFill
.setPath( ImplGetRotatedPolyPolygon( aPath
, aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1424 aMtf
.AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
1425 static_cast<const BYTE
*>( aDest
.GetData()), aDest
.Tell() ) );
1429 else if ( pCommentAct
->GetComment().Equals( "XPATHSTROKE_SEQ_END" )
1430 || pCommentAct
->GetComment().Equals( "XPATHFILL_SEQ_END" ) )
1432 pAction
->Execute( &aMapVDev
);
1433 pAction
->Duplicate();
1434 aMtf
.AddAction( pAction
);
1440 case( META_HATCH_ACTION
):
1442 MetaHatchAction
* pAct
= (MetaHatchAction
*) pAction
;
1443 Hatch
aHatch( pAct
->GetHatch() );
1445 aHatch
.SetAngle( aHatch
.GetAngle() + (USHORT
) nAngle10
);
1446 aMtf
.AddAction( new MetaHatchAction( ImplGetRotatedPolyPolygon( pAct
->GetPolyPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1451 case( META_TRANSPARENT_ACTION
):
1453 MetaTransparentAction
* pAct
= (MetaTransparentAction
*) pAction
;
1454 aMtf
.AddAction( new MetaTransparentAction( ImplGetRotatedPolyPolygon( pAct
->GetPolyPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
),
1455 pAct
->GetTransparence() ) );
1459 case( META_FLOATTRANSPARENT_ACTION
):
1461 MetaFloatTransparentAction
* pAct
= (MetaFloatTransparentAction
*) pAction
;
1462 GDIMetaFile
aTransMtf( pAct
->GetGDIMetaFile() );
1463 Polygon
aMtfPoly( ImplGetRotatedPolygon( Rectangle( pAct
->GetPoint(), pAct
->GetSize() ), aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1464 Rectangle
aMtfRect( aMtfPoly
.GetBoundRect() );
1466 aTransMtf
.Rotate( nAngle10
);
1467 aMtf
.AddAction( new MetaFloatTransparentAction( aTransMtf
, aMtfRect
.TopLeft(), aMtfRect
.GetSize(),
1468 pAct
->GetGradient() ) );
1472 case( META_EPS_ACTION
):
1474 MetaEPSAction
* pAct
= (MetaEPSAction
*) pAction
;
1475 GDIMetaFile
aEPSMtf( pAct
->GetSubstitute() );
1476 Polygon
aEPSPoly( ImplGetRotatedPolygon( Rectangle( pAct
->GetPoint(), pAct
->GetSize() ), aRotAnchor
, aRotOffset
, fSin
, fCos
) );
1477 Rectangle
aEPSRect( aEPSPoly
.GetBoundRect() );
1479 aEPSMtf
.Rotate( nAngle10
);
1480 aMtf
.AddAction( new MetaEPSAction( aEPSRect
.TopLeft(), aEPSRect
.GetSize(),
1481 pAct
->GetLink(), aEPSMtf
) );
1485 case( META_CLIPREGION_ACTION
):
1487 MetaClipRegionAction
* pAct
= (MetaClipRegionAction
*) pAction
;
1489 if( pAct
->IsClipping() && pAct
->GetRegion().HasPolyPolygon() )
1490 aMtf
.AddAction( new MetaClipRegionAction( Region( ImplGetRotatedPolyPolygon( pAct
->GetRegion().GetPolyPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
) ), TRUE
) );
1493 pAction
->Duplicate();
1494 aMtf
.AddAction( pAction
);
1499 case( META_ISECTRECTCLIPREGION_ACTION
):
1501 MetaISectRectClipRegionAction
* pAct
= (MetaISectRectClipRegionAction
*) pAction
;
1502 aMtf
.AddAction( new MetaISectRegionClipRegionAction( ImplGetRotatedPolygon( pAct
->GetRect(), aRotAnchor
, aRotOffset
, fSin
, fCos
) ) );
1506 case( META_ISECTREGIONCLIPREGION_ACTION
):
1508 MetaISectRegionClipRegionAction
* pAct
= (MetaISectRegionClipRegionAction
*) pAction
;
1509 const Region
& rRegion
= pAct
->GetRegion();
1511 if( rRegion
.HasPolyPolygon() )
1512 aMtf
.AddAction( new MetaISectRegionClipRegionAction( Region( ImplGetRotatedPolyPolygon( rRegion
.GetPolyPolygon(), aRotAnchor
, aRotOffset
, fSin
, fCos
) ) ) );
1515 pAction
->Duplicate();
1516 aMtf
.AddAction( pAction
);
1521 case( META_REFPOINT_ACTION
):
1523 MetaRefPointAction
* pAct
= (MetaRefPointAction
*) pAction
;
1524 aMtf
.AddAction( new MetaRefPointAction( ImplGetRotatedPoint( pAct
->GetRefPoint(), aRotAnchor
, aRotOffset
, fSin
, fCos
), pAct
->IsSetting() ) );
1528 case( META_FONT_ACTION
):
1530 MetaFontAction
* pAct
= (MetaFontAction
*) pAction
;
1531 Font
aFont( pAct
->GetFont() );
1533 aFont
.SetOrientation( aFont
.GetOrientation() + (USHORT
) nAngle10
);
1534 aMtf
.AddAction( new MetaFontAction( aFont
) );
1538 case( META_BMP_ACTION
):
1539 case( META_BMPEX_ACTION
):
1540 case( META_MASK_ACTION
):
1541 case( META_MASKSCALE_ACTION
):
1542 case( META_MASKSCALEPART_ACTION
):
1543 case( META_WALLPAPER_ACTION
):
1544 case( META_TEXTRECT_ACTION
):
1545 case( META_MOVECLIPREGION_ACTION
):
1547 DBG_ERROR( "GDIMetaFile::Rotate(): unsupported action" );
1553 pAction
->Execute( &aMapVDev
);
1554 pAction
->Duplicate();
1555 aMtf
.AddAction( pAction
);
1557 // update rotation point and offset, if necessary
1558 if( ( META_MAPMODE_ACTION
== nActionType
) ||
1559 ( META_PUSH_ACTION
== nActionType
) ||
1560 ( META_POP_ACTION
== nActionType
) )
1562 aRotAnchor
= aMapVDev
.LogicToLogic( aOrigin
, aPrefMapMode
, aMapVDev
.GetMapMode() );
1563 aRotOffset
= aMapVDev
.LogicToLogic( aOffset
, aPrefMapMode
, aMapVDev
.GetMapMode() );
1570 aMtf
.aPrefMapMode
= aPrefMapMode
;
1571 aMtf
.aPrefSize
= aNewBound
.GetSize();
1577 // ------------------------------------------------------------------------
1579 static void ImplActionBounds( Rectangle
& o_rOutBounds
,
1580 const Rectangle
& i_rInBounds
,
1581 const std::vector
<Rectangle
>& i_rClipStack
)
1583 Rectangle
aBounds( i_rInBounds
);
1584 if( ! i_rInBounds
.IsEmpty() && ! i_rClipStack
.empty() && ! i_rClipStack
.back().IsEmpty() )
1585 aBounds
.Intersection( i_rClipStack
.back() );
1586 if( ! aBounds
.IsEmpty() )
1588 if( ! o_rOutBounds
.IsEmpty() )
1589 o_rOutBounds
.Union( aBounds
);
1591 o_rOutBounds
= aBounds
;
1595 Rectangle
GDIMetaFile::GetBoundRect( OutputDevice
& i_rReference
)
1598 VirtualDevice
aMapVDev( i_rReference
);
1600 aMapVDev
.EnableOutput( FALSE
);
1601 aMapVDev
.SetMapMode( GetPrefMapMode() );
1603 std::vector
<Rectangle
> aClipStack( 1, Rectangle() );
1604 std::vector
<USHORT
> aPushFlagStack
;
1608 for( MetaAction
* pAction
= (MetaAction
*) First(); pAction
; pAction
= (MetaAction
*) Next() )
1610 const USHORT nActionType
= pAction
->GetType();
1612 switch( nActionType
)
1614 case( META_PIXEL_ACTION
):
1616 MetaPixelAction
* pAct
= (MetaPixelAction
*) pAction
;
1617 ImplActionBounds( aBound
,
1618 Rectangle( aMapVDev
.LogicToLogic( pAct
->GetPoint(), aMapVDev
.GetMapMode(), GetPrefMapMode() ),
1619 aMapVDev
.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
1624 case( META_POINT_ACTION
):
1626 MetaPointAction
* pAct
= (MetaPointAction
*) pAction
;
1627 ImplActionBounds( aBound
,
1628 Rectangle( aMapVDev
.LogicToLogic( pAct
->GetPoint(), aMapVDev
.GetMapMode(), GetPrefMapMode() ),
1629 aMapVDev
.PixelToLogic( Size( 1, 1 ), GetPrefMapMode() ) ),
1634 case( META_LINE_ACTION
):
1636 MetaLineAction
* pAct
= (MetaLineAction
*) pAction
;
1637 Point
aP1( pAct
->GetStartPoint() ), aP2( pAct
->GetEndPoint() );
1638 Rectangle
aRect( aP1
, aP2
);
1640 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1644 case( META_RECT_ACTION
):
1646 MetaRectAction
* pAct
= (MetaRectAction
*) pAction
;
1647 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( pAct
->GetRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1651 case( META_ROUNDRECT_ACTION
):
1653 MetaRoundRectAction
* pAct
= (MetaRoundRectAction
*) pAction
;
1654 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( pAct
->GetRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1658 case( META_ELLIPSE_ACTION
):
1660 MetaEllipseAction
* pAct
= (MetaEllipseAction
*) pAction
;
1661 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( pAct
->GetRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1665 case( META_ARC_ACTION
):
1667 MetaArcAction
* pAct
= (MetaArcAction
*) pAction
;
1668 // FIXME: this is imprecise
1669 // e.g. for small arcs the whole rectangle is WAY too large
1670 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( pAct
->GetRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1674 case( META_PIE_ACTION
):
1676 MetaPieAction
* pAct
= (MetaPieAction
*) pAction
;
1677 // FIXME: this is imprecise
1678 // e.g. for small arcs the whole rectangle is WAY too large
1679 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( pAct
->GetRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1683 case( META_CHORD_ACTION
):
1685 MetaChordAction
* pAct
= (MetaChordAction
*) pAction
;
1686 // FIXME: this is imprecise
1687 // e.g. for small arcs the whole rectangle is WAY too large
1688 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( pAct
->GetRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1692 case( META_POLYLINE_ACTION
):
1694 MetaPolyLineAction
* pAct
= (MetaPolyLineAction
*) pAction
;
1695 Rectangle
aRect( pAct
->GetPolygon().GetBoundRect() );
1696 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1700 case( META_POLYGON_ACTION
):
1702 MetaPolygonAction
* pAct
= (MetaPolygonAction
*) pAction
;
1703 Rectangle
aRect( pAct
->GetPolygon().GetBoundRect() );
1704 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1708 case( META_POLYPOLYGON_ACTION
):
1710 MetaPolyPolygonAction
* pAct
= (MetaPolyPolygonAction
*) pAction
;
1711 Rectangle
aRect( pAct
->GetPolyPolygon().GetBoundRect() );
1712 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1716 case( META_TEXT_ACTION
):
1718 MetaTextAction
* pAct
= (MetaTextAction
*) pAction
;
1720 // hdu said base = index
1721 aMapVDev
.GetTextBoundRect( aRect
, pAct
->GetText(), pAct
->GetIndex(), pAct
->GetIndex(), pAct
->GetLen() );
1722 Point
aPt( pAct
->GetPoint() );
1723 aRect
.Move( aPt
.X(), aPt
.Y() );
1724 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1728 case( META_TEXTARRAY_ACTION
):
1730 MetaTextArrayAction
* pAct
= (MetaTextArrayAction
*) pAction
;
1732 // hdu said base = index
1733 aMapVDev
.GetTextBoundRect( aRect
, pAct
->GetText(), pAct
->GetIndex(), pAct
->GetIndex(), pAct
->GetLen(),
1734 0, pAct
->GetDXArray() );
1735 Point
aPt( pAct
->GetPoint() );
1736 aRect
.Move( aPt
.X(), aPt
.Y() );
1737 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1741 case( META_STRETCHTEXT_ACTION
):
1743 MetaStretchTextAction
* pAct
= (MetaStretchTextAction
*) pAction
;
1745 // hdu said base = index
1746 aMapVDev
.GetTextBoundRect( aRect
, pAct
->GetText(), pAct
->GetIndex(), pAct
->GetIndex(), pAct
->GetLen(),
1747 pAct
->GetWidth(), NULL
);
1748 Point
aPt( pAct
->GetPoint() );
1749 aRect
.Move( aPt
.X(), aPt
.Y() );
1750 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1754 case( META_TEXTLINE_ACTION
):
1756 MetaTextLineAction
* pAct
= (MetaTextLineAction
*) pAction
;
1757 // measure a test string to get ascend and descent right
1758 static const sal_Unicode pStr
[] = { 0xc4, 0x67, 0 };
1759 String
aStr( pStr
);
1762 aMapVDev
.GetTextBoundRect( aRect
, aStr
, 0, 0, aStr
.Len(), 0, NULL
);
1763 Point
aPt( pAct
->GetStartPoint() );
1764 aRect
.Move( aPt
.X(), aPt
.Y() );
1765 aRect
.Right() = aRect
.Left() + pAct
->GetWidth();
1766 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1770 case( META_BMPSCALE_ACTION
):
1772 MetaBmpScaleAction
* pAct
= (MetaBmpScaleAction
*) pAction
;
1773 Rectangle
aRect( pAct
->GetPoint(), pAct
->GetSize() );
1774 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1778 case( META_BMPSCALEPART_ACTION
):
1780 MetaBmpScalePartAction
* pAct
= (MetaBmpScalePartAction
*) pAction
;
1781 Rectangle
aRect( pAct
->GetDestPoint(), pAct
->GetDestSize() );
1782 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1786 case( META_BMPEXSCALE_ACTION
):
1788 MetaBmpExScaleAction
* pAct
= (MetaBmpExScaleAction
*) pAction
;
1789 Rectangle
aRect( pAct
->GetPoint(), pAct
->GetSize() );
1790 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1794 case( META_BMPEXSCALEPART_ACTION
):
1796 MetaBmpExScalePartAction
* pAct
= (MetaBmpExScalePartAction
*) pAction
;
1797 Rectangle
aRect( pAct
->GetDestPoint(), pAct
->GetDestSize() );
1798 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1802 case( META_GRADIENT_ACTION
):
1804 MetaGradientAction
* pAct
= (MetaGradientAction
*) pAction
;
1805 Rectangle
aRect( pAct
->GetRect() );
1806 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1810 case( META_GRADIENTEX_ACTION
):
1812 MetaGradientExAction
* pAct
= (MetaGradientExAction
*) pAction
;
1813 Rectangle
aRect( pAct
->GetPolyPolygon().GetBoundRect() );
1814 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1818 case( META_COMMENT_ACTION
):
1824 case( META_HATCH_ACTION
):
1826 MetaHatchAction
* pAct
= (MetaHatchAction
*) pAction
;
1827 Rectangle
aRect( pAct
->GetPolyPolygon().GetBoundRect() );
1828 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1832 case( META_TRANSPARENT_ACTION
):
1834 MetaTransparentAction
* pAct
= (MetaTransparentAction
*) pAction
;
1835 Rectangle
aRect( pAct
->GetPolyPolygon().GetBoundRect() );
1836 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1840 case( META_FLOATTRANSPARENT_ACTION
):
1842 MetaFloatTransparentAction
* pAct
= (MetaFloatTransparentAction
*) pAction
;
1843 GDIMetaFile
aTransMtf( pAct
->GetGDIMetaFile() );
1844 // get the bound rect of the contained metafile
1845 Rectangle
aRect( aTransMtf
.GetBoundRect( i_rReference
) );
1846 // scale the rect now on the assumption that the correct top left of the metafile
1847 // (not its bounds !) is (0,0)
1848 Size
aPSize( aTransMtf
.GetPrefSize() );
1849 aPSize
= aMapVDev
.LogicToLogic( aPSize
, aTransMtf
.GetPrefMapMode(), aMapVDev
.GetMapMode() );
1850 Size
aActSize( pAct
->GetSize() );
1851 double fX
= double(aActSize
.Width())/double(aPSize
.Width());
1852 double fY
= double(aActSize
.Height())/double(aPSize
.Height());
1853 aRect
.Left() = long(double(aRect
.Left())*fX
);
1854 aRect
.Right() = long(double(aRect
.Right())*fX
);
1855 aRect
.Top() = long(double(aRect
.Top())*fY
);
1856 aRect
.Bottom() = long(double(aRect
.Bottom())*fY
);
1858 // transform the rect to current VDev state
1859 aRect
= aMapVDev
.LogicToLogic( aRect
, aTransMtf
.GetPrefMapMode(), aMapVDev
.GetMapMode() );
1861 ImplActionBounds( aBound
, aRect
, aClipStack
);
1865 case( META_EPS_ACTION
):
1867 MetaEPSAction
* pAct
= (MetaEPSAction
*) pAction
;
1868 Rectangle
aRect( pAct
->GetPoint(), pAct
->GetSize() );
1869 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1873 case( META_CLIPREGION_ACTION
):
1875 MetaClipRegionAction
* pAct
= (MetaClipRegionAction
*) pAction
;
1876 if( pAct
->IsClipping() )
1877 aClipStack
.back() = aMapVDev
.LogicToLogic( pAct
->GetRegion().GetBoundRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() );
1879 aClipStack
.back() = Rectangle();
1883 case( META_ISECTRECTCLIPREGION_ACTION
):
1885 MetaISectRectClipRegionAction
* pAct
= (MetaISectRectClipRegionAction
*) pAction
;
1886 Rectangle
aRect( aMapVDev
.LogicToLogic( pAct
->GetRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ) );
1887 if( aClipStack
.back().IsEmpty() )
1888 aClipStack
.back() = aRect
;
1890 aClipStack
.back().Intersection( aRect
);
1894 case( META_ISECTREGIONCLIPREGION_ACTION
):
1896 MetaISectRegionClipRegionAction
* pAct
= (MetaISectRegionClipRegionAction
*) pAction
;
1897 Rectangle
aRect( aMapVDev
.LogicToLogic( pAct
->GetRegion().GetBoundRect(), aMapVDev
.GetMapMode(), GetPrefMapMode() ) );
1898 if( aClipStack
.back().IsEmpty() )
1899 aClipStack
.back() = aRect
;
1901 aClipStack
.back().Intersection( aRect
);
1905 case( META_BMP_ACTION
):
1907 MetaBmpAction
* pAct
= (MetaBmpAction
*) pAction
;
1908 Rectangle
aRect( pAct
->GetPoint(), aMapVDev
.PixelToLogic( pAct
->GetBitmap().GetSizePixel() ) );
1909 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1913 case( META_BMPEX_ACTION
):
1915 MetaBmpExAction
* pAct
= (MetaBmpExAction
*) pAction
;
1916 Rectangle
aRect( pAct
->GetPoint(), aMapVDev
.PixelToLogic( pAct
->GetBitmapEx().GetSizePixel() ) );
1917 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1921 case( META_MASK_ACTION
):
1923 MetaMaskAction
* pAct
= (MetaMaskAction
*) pAction
;
1924 Rectangle
aRect( pAct
->GetPoint(), aMapVDev
.PixelToLogic( pAct
->GetBitmap().GetSizePixel() ) );
1925 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1929 case( META_MASKSCALE_ACTION
):
1931 MetaMaskScalePartAction
* pAct
= (MetaMaskScalePartAction
*) pAction
;
1932 Rectangle
aRect( pAct
->GetDestPoint(), pAct
->GetDestSize() );
1933 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1937 case( META_MASKSCALEPART_ACTION
):
1939 MetaMaskScalePartAction
* pAct
= (MetaMaskScalePartAction
*) pAction
;
1940 Rectangle
aRect( pAct
->GetDestPoint(), pAct
->GetDestSize() );
1941 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1945 case( META_WALLPAPER_ACTION
):
1947 MetaWallpaperAction
* pAct
= (MetaWallpaperAction
*) pAction
;
1948 Rectangle
aRect( pAct
->GetRect() );
1949 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1953 case( META_TEXTRECT_ACTION
):
1955 MetaTextRectAction
* pAct
= (MetaTextRectAction
*) pAction
;
1956 Rectangle
aRect( pAct
->GetRect() );
1957 ImplActionBounds( aBound
, aMapVDev
.LogicToLogic( aRect
, aMapVDev
.GetMapMode(), GetPrefMapMode() ), aClipStack
);
1961 case( META_MOVECLIPREGION_ACTION
):
1963 MetaMoveClipRegionAction
* pAct
= (MetaMoveClipRegionAction
*) pAction
;
1964 if( ! aClipStack
.back().IsEmpty() )
1966 Size
aDelta( pAct
->GetHorzMove(), pAct
->GetVertMove() );
1967 aDelta
= aMapVDev
.LogicToLogic( aDelta
, aMapVDev
.GetMapMode(), GetPrefMapMode() );
1968 aClipStack
.back().Move( aDelta
.Width(), aDelta
.Width() );
1975 pAction
->Execute( &aMapVDev
);
1977 if( nActionType
== META_PUSH_ACTION
)
1979 MetaPushAction
* pAct
= (MetaPushAction
*) pAction
;
1980 aPushFlagStack
.push_back( pAct
->GetFlags() );
1981 if( (aPushFlagStack
.back() & PUSH_CLIPREGION
) != 0 )
1983 Rectangle
aRect( aClipStack
.back() );
1984 aClipStack
.push_back( aRect
);
1987 else if( nActionType
== META_POP_ACTION
)
1990 if( ! aPushFlagStack
.empty() )
1992 if( (aPushFlagStack
.back() & PUSH_CLIPREGION
) != 0 )
1994 if( aClipStack
.size() > 1 )
1995 aClipStack
.pop_back();
1997 aPushFlagStack
.pop_back();
2007 // ------------------------------------------------------------------------
2009 Color
GDIMetaFile::ImplColAdjustFnc( const Color
& rColor
, const void* pColParam
)
2011 return Color( rColor
.GetTransparency(),
2012 ( (const ImplColAdjustParam
*) pColParam
)->pMapR
[ rColor
.GetRed() ],
2013 ( (const ImplColAdjustParam
*) pColParam
)->pMapG
[ rColor
.GetGreen() ],
2014 ( (const ImplColAdjustParam
*) pColParam
)->pMapB
[ rColor
.GetBlue() ] );
2018 // ------------------------------------------------------------------------
2020 BitmapEx
GDIMetaFile::ImplBmpAdjustFnc( const BitmapEx
& rBmpEx
, const void* pBmpParam
)
2022 const ImplBmpAdjustParam
* p
= (const ImplBmpAdjustParam
*) pBmpParam
;
2023 BitmapEx
aRet( rBmpEx
);
2025 aRet
.Adjust( p
->nLuminancePercent
, p
->nContrastPercent
,
2026 p
->nChannelRPercent
, p
->nChannelGPercent
, p
->nChannelBPercent
,
2027 p
->fGamma
, p
->bInvert
);
2032 // ------------------------------------------------------------------------
2034 Color
GDIMetaFile::ImplColConvertFnc( const Color
& rColor
, const void* pColParam
)
2036 BYTE cLum
= rColor
.GetLuminance();
2038 if( MTF_CONVERSION_1BIT_THRESHOLD
== ( (const ImplColConvertParam
*) pColParam
)->eConversion
)
2039 cLum
= ( cLum
< 128 ) ? 0 : 255;
2041 return Color( rColor
.GetTransparency(), cLum
, cLum
, cLum
);
2044 // ------------------------------------------------------------------------
2046 BitmapEx
GDIMetaFile::ImplBmpConvertFnc( const BitmapEx
& rBmpEx
, const void* pBmpParam
)
2048 BitmapEx
aRet( rBmpEx
);
2050 aRet
.Convert( ( (const ImplBmpConvertParam
*) pBmpParam
)->eConversion
);
2055 // ------------------------------------------------------------------------
2057 Color
GDIMetaFile::ImplColMonoFnc( const Color
&, const void* pColParam
)
2059 return( ( (const ImplColMonoParam
*) pColParam
)->aColor
);
2062 // ------------------------------------------------------------------------
2064 BitmapEx
GDIMetaFile::ImplBmpMonoFnc( const BitmapEx
& rBmpEx
, const void* pBmpParam
)
2066 BitmapPalette
aPal( 3 );
2068 aPal
[ 0 ] = Color( COL_BLACK
);
2069 aPal
[ 1 ] = Color( COL_WHITE
);
2070 aPal
[ 2 ] = ( (const ImplBmpMonoParam
*) pBmpParam
)->aColor
;
2072 Bitmap
aBmp( rBmpEx
.GetSizePixel(), 4, &aPal
);
2073 aBmp
.Erase( ( (const ImplBmpMonoParam
*) pBmpParam
)->aColor
);
2075 if( rBmpEx
.IsAlpha() )
2076 return BitmapEx( aBmp
, rBmpEx
.GetAlpha() );
2077 else if( rBmpEx
.IsTransparent() )
2078 return BitmapEx( aBmp
, rBmpEx
.GetMask() );
2083 // ------------------------------------------------------------------------
2085 Color
GDIMetaFile::ImplColReplaceFnc( const Color
& rColor
, const void* pColParam
)
2087 const ULONG nR
= rColor
.GetRed(), nG
= rColor
.GetGreen(), nB
= rColor
.GetBlue();
2089 for( ULONG i
= 0; i
< ( (const ImplColReplaceParam
*) pColParam
)->nCount
; i
++ )
2091 if( ( ( (const ImplColReplaceParam
*) pColParam
)->pMinR
[ i
] <= nR
) &&
2092 ( ( (const ImplColReplaceParam
*) pColParam
)->pMaxR
[ i
] >= nR
) &&
2093 ( ( (const ImplColReplaceParam
*) pColParam
)->pMinG
[ i
] <= nG
) &&
2094 ( ( (const ImplColReplaceParam
*) pColParam
)->pMaxG
[ i
] >= nG
) &&
2095 ( ( (const ImplColReplaceParam
*) pColParam
)->pMinB
[ i
] <= nB
) &&
2096 ( ( (const ImplColReplaceParam
*) pColParam
)->pMaxB
[ i
] >= nB
) )
2098 return( ( (const ImplColReplaceParam
*) pColParam
)->pDstCols
[ i
] );
2105 // ------------------------------------------------------------------------
2107 BitmapEx
GDIMetaFile::ImplBmpReplaceFnc( const BitmapEx
& rBmpEx
, const void* pBmpParam
)
2109 const ImplBmpReplaceParam
* p
= (const ImplBmpReplaceParam
*) pBmpParam
;
2110 BitmapEx
aRet( rBmpEx
);
2112 aRet
.Replace( p
->pSrcCols
, p
->pDstCols
, p
->nCount
, p
->pTols
);
2117 // ------------------------------------------------------------------------
2119 void GDIMetaFile::ImplExchangeColors( ColorExchangeFnc pFncCol
, const void* pColParam
,
2120 BmpExchangeFnc pFncBmp
, const void* pBmpParam
)
2124 aMtf
.aPrefSize
= aPrefSize
;
2125 aMtf
.aPrefMapMode
= aPrefMapMode
;
2127 for( MetaAction
* pAction
= (MetaAction
*) First(); pAction
; pAction
= (MetaAction
*) Next() )
2129 const USHORT nType
= pAction
->GetType();
2133 case( META_PIXEL_ACTION
):
2135 MetaPixelAction
* pAct
= (MetaPixelAction
*) pAction
;
2136 aMtf
.Insert( new MetaPixelAction( pAct
->GetPoint(), pFncCol( pAct
->GetColor(), pColParam
) ), LIST_APPEND
);
2140 case( META_LINECOLOR_ACTION
):
2142 MetaLineColorAction
* pAct
= (MetaLineColorAction
*) pAction
;
2144 if( !pAct
->IsSetting() )
2147 pAct
= new MetaLineColorAction( pFncCol( pAct
->GetColor(), pColParam
), TRUE
);
2149 aMtf
.Insert( pAct
, LIST_APPEND
);
2153 case( META_FILLCOLOR_ACTION
):
2155 MetaFillColorAction
* pAct
= (MetaFillColorAction
*) pAction
;
2157 if( !pAct
->IsSetting() )
2160 pAct
= new MetaFillColorAction( pFncCol( pAct
->GetColor(), pColParam
), TRUE
);
2162 aMtf
.Insert( pAct
, LIST_APPEND
);
2166 case( META_TEXTCOLOR_ACTION
):
2168 MetaTextColorAction
* pAct
= (MetaTextColorAction
*) pAction
;
2169 aMtf
.Insert( new MetaTextColorAction( pFncCol( pAct
->GetColor(), pColParam
) ), LIST_APPEND
);
2173 case( META_TEXTFILLCOLOR_ACTION
):
2175 MetaTextFillColorAction
* pAct
= (MetaTextFillColorAction
*) pAction
;
2177 if( !pAct
->IsSetting() )
2180 pAct
= new MetaTextFillColorAction( pFncCol( pAct
->GetColor(), pColParam
), TRUE
);
2182 aMtf
.Insert( pAct
, LIST_APPEND
);
2186 case( META_TEXTLINECOLOR_ACTION
):
2188 MetaTextLineColorAction
* pAct
= (MetaTextLineColorAction
*) pAction
;
2190 if( !pAct
->IsSetting() )
2193 pAct
= new MetaTextLineColorAction( pFncCol( pAct
->GetColor(), pColParam
), TRUE
);
2195 aMtf
.Insert( pAct
, LIST_APPEND
);
2199 case( META_OVERLINECOLOR_ACTION
):
2201 MetaOverlineColorAction
* pAct
= (MetaOverlineColorAction
*) pAction
;
2203 if( !pAct
->IsSetting() )
2206 pAct
= new MetaOverlineColorAction( pFncCol( pAct
->GetColor(), pColParam
), TRUE
);
2208 aMtf
.Insert( pAct
, LIST_APPEND
);
2212 case( META_FONT_ACTION
):
2214 MetaFontAction
* pAct
= (MetaFontAction
*) pAction
;
2215 Font
aFont( pAct
->GetFont() );
2217 aFont
.SetColor( pFncCol( aFont
.GetColor(), pColParam
) );
2218 aFont
.SetFillColor( pFncCol( aFont
.GetFillColor(), pColParam
) );
2219 aMtf
.Insert( new MetaFontAction( aFont
), LIST_APPEND
);
2223 case( META_WALLPAPER_ACTION
):
2225 MetaWallpaperAction
* pAct
= (MetaWallpaperAction
*) pAction
;
2226 Wallpaper
aWall( pAct
->GetWallpaper() );
2227 const Rectangle
& rRect
= pAct
->GetRect();
2229 aWall
.SetColor( pFncCol( aWall
.GetColor(), pColParam
) );
2231 if( aWall
.IsBitmap() )
2232 aWall
.SetBitmap( pFncBmp( aWall
.GetBitmap(), pBmpParam
) );
2234 if( aWall
.IsGradient() )
2236 Gradient
aGradient( aWall
.GetGradient() );
2238 aGradient
.SetStartColor( pFncCol( aGradient
.GetStartColor(), pColParam
) );
2239 aGradient
.SetEndColor( pFncCol( aGradient
.GetEndColor(), pColParam
) );
2240 aWall
.SetGradient( aGradient
);
2243 aMtf
.Insert( new MetaWallpaperAction( rRect
, aWall
), LIST_APPEND
);
2247 case( META_BMP_ACTION
):
2248 case( META_BMPEX_ACTION
):
2249 case( META_MASK_ACTION
):
2251 DBG_ERROR( "Don't use bitmap actions of this type in metafiles!" );
2255 case( META_BMPSCALE_ACTION
):
2257 MetaBmpScaleAction
* pAct
= (MetaBmpScaleAction
*) pAction
;
2258 aMtf
.Insert( new MetaBmpScaleAction( pAct
->GetPoint(), pAct
->GetSize(),
2259 pFncBmp( pAct
->GetBitmap(), pBmpParam
).GetBitmap() ),
2264 case( META_BMPSCALEPART_ACTION
):
2266 MetaBmpScalePartAction
* pAct
= (MetaBmpScalePartAction
*) pAction
;
2267 aMtf
.Insert( new MetaBmpScalePartAction( pAct
->GetDestPoint(), pAct
->GetDestSize(),
2268 pAct
->GetSrcPoint(), pAct
->GetSrcSize(),
2269 pFncBmp( pAct
->GetBitmap(), pBmpParam
).GetBitmap() ),
2274 case( META_BMPEXSCALE_ACTION
):
2276 MetaBmpExScaleAction
* pAct
= (MetaBmpExScaleAction
*) pAction
;
2277 aMtf
.Insert( new MetaBmpExScaleAction( pAct
->GetPoint(), pAct
->GetSize(),
2278 pFncBmp( pAct
->GetBitmapEx(), pBmpParam
) ),
2283 case( META_BMPEXSCALEPART_ACTION
):
2285 MetaBmpExScalePartAction
* pAct
= (MetaBmpExScalePartAction
*) pAction
;
2286 aMtf
.Insert( new MetaBmpExScalePartAction( pAct
->GetDestPoint(), pAct
->GetDestSize(),
2287 pAct
->GetSrcPoint(), pAct
->GetSrcSize(),
2288 pFncBmp( pAct
->GetBitmapEx(), pBmpParam
) ),
2293 case( META_MASKSCALE_ACTION
):
2295 MetaMaskScaleAction
* pAct
= (MetaMaskScaleAction
*) pAction
;
2296 aMtf
.Insert( new MetaMaskScaleAction( pAct
->GetPoint(), pAct
->GetSize(),
2298 pFncCol( pAct
->GetColor(), pColParam
) ),
2303 case( META_MASKSCALEPART_ACTION
):
2305 MetaMaskScalePartAction
* pAct
= (MetaMaskScalePartAction
*) pAction
;
2306 aMtf
.Insert( new MetaMaskScalePartAction( pAct
->GetDestPoint(), pAct
->GetDestSize(),
2307 pAct
->GetSrcPoint(), pAct
->GetSrcSize(),
2309 pFncCol( pAct
->GetColor(), pColParam
) ),
2314 case( META_GRADIENT_ACTION
):
2316 MetaGradientAction
* pAct
= (MetaGradientAction
*) pAction
;
2317 Gradient
aGradient( pAct
->GetGradient() );
2319 aGradient
.SetStartColor( pFncCol( aGradient
.GetStartColor(), pColParam
) );
2320 aGradient
.SetEndColor( pFncCol( aGradient
.GetEndColor(), pColParam
) );
2321 aMtf
.Insert( new MetaGradientAction( pAct
->GetRect(), aGradient
), LIST_APPEND
);
2325 case( META_GRADIENTEX_ACTION
):
2327 MetaGradientExAction
* pAct
= (MetaGradientExAction
*) pAction
;
2328 Gradient
aGradient( pAct
->GetGradient() );
2330 aGradient
.SetStartColor( pFncCol( aGradient
.GetStartColor(), pColParam
) );
2331 aGradient
.SetEndColor( pFncCol( aGradient
.GetEndColor(), pColParam
) );
2332 aMtf
.Insert( new MetaGradientExAction( pAct
->GetPolyPolygon(), aGradient
), LIST_APPEND
);
2336 case( META_HATCH_ACTION
):
2338 MetaHatchAction
* pAct
= (MetaHatchAction
*) pAction
;
2339 Hatch
aHatch( pAct
->GetHatch() );
2341 aHatch
.SetColor( pFncCol( aHatch
.GetColor(), pColParam
) );
2342 aMtf
.Insert( new MetaHatchAction( pAct
->GetPolyPolygon(), aHatch
), LIST_APPEND
);
2346 case( META_FLOATTRANSPARENT_ACTION
):
2348 MetaFloatTransparentAction
* pAct
= (MetaFloatTransparentAction
*) pAction
;
2349 GDIMetaFile
aTransMtf( pAct
->GetGDIMetaFile() );
2351 aTransMtf
.ImplExchangeColors( pFncCol
, pColParam
, pFncBmp
, pBmpParam
);
2352 aMtf
.Insert( new MetaFloatTransparentAction( aTransMtf
,
2353 pAct
->GetPoint(), pAct
->GetSize(),
2354 pAct
->GetGradient() ),
2359 case( META_EPS_ACTION
):
2361 MetaEPSAction
* pAct
= (MetaEPSAction
*) pAction
;
2362 GDIMetaFile
aSubst( pAct
->GetSubstitute() );
2364 aSubst
.ImplExchangeColors( pFncCol
, pColParam
, pFncBmp
, pBmpParam
);
2365 aMtf
.Insert( new MetaEPSAction( pAct
->GetPoint(), pAct
->GetSize(),
2366 pAct
->GetLink(), aSubst
),
2373 pAction
->Duplicate();
2374 aMtf
.Insert( pAction
, LIST_APPEND
);
2383 // ------------------------------------------------------------------------
2385 void GDIMetaFile::Adjust( short nLuminancePercent
, short nContrastPercent
,
2386 short nChannelRPercent
, short nChannelGPercent
,
2387 short nChannelBPercent
, double fGamma
, BOOL bInvert
)
2389 // nothing to do? => return quickly
2390 if( nLuminancePercent
|| nContrastPercent
||
2391 nChannelRPercent
|| nChannelGPercent
|| nChannelBPercent
||
2392 ( fGamma
!= 1.0 ) || bInvert
)
2394 double fM
, fROff
, fGOff
, fBOff
, fOff
;
2395 ImplColAdjustParam aColParam
;
2396 ImplBmpAdjustParam aBmpParam
;
2398 aColParam
.pMapR
= new BYTE
[ 256 ];
2399 aColParam
.pMapG
= new BYTE
[ 256 ];
2400 aColParam
.pMapB
= new BYTE
[ 256 ];
2403 if( nContrastPercent
>= 0 )
2404 fM
= 128.0 / ( 128.0 - 1.27 * MinMax( nContrastPercent
, 0L, 100L ) );
2406 fM
= ( 128.0 + 1.27 * MinMax( nContrastPercent
, -100L, 0L ) ) / 128.0;
2408 // total offset = luminance offset + contrast offset
2409 fOff
= MinMax( nLuminancePercent
, -100L, 100L ) * 2.55 + 128.0 - fM
* 128.0;
2411 // channel offset = channel offset + total offset
2412 fROff
= nChannelRPercent
* 2.55 + fOff
;
2413 fGOff
= nChannelGPercent
* 2.55 + fOff
;
2414 fBOff
= nChannelBPercent
* 2.55 + fOff
;
2416 // calculate gamma value
2417 fGamma
= ( fGamma
<= 0.0 || fGamma
> 10.0 ) ? 1.0 : ( 1.0 / fGamma
);
2418 const BOOL bGamma
= ( fGamma
!= 1.0 );
2420 // create mapping table
2421 for( long nX
= 0L; nX
< 256L; nX
++ )
2423 aColParam
.pMapR
[ nX
] = (BYTE
) MinMax( FRound( nX
* fM
+ fROff
), 0L, 255L );
2424 aColParam
.pMapG
[ nX
] = (BYTE
) MinMax( FRound( nX
* fM
+ fGOff
), 0L, 255L );
2425 aColParam
.pMapB
[ nX
] = (BYTE
) MinMax( FRound( nX
* fM
+ fBOff
), 0L, 255L );
2429 aColParam
.pMapR
[ nX
] = GAMMA( aColParam
.pMapR
[ nX
], fGamma
);
2430 aColParam
.pMapG
[ nX
] = GAMMA( aColParam
.pMapG
[ nX
], fGamma
);
2431 aColParam
.pMapB
[ nX
] = GAMMA( aColParam
.pMapB
[ nX
], fGamma
);
2436 aColParam
.pMapR
[ nX
] = ~aColParam
.pMapR
[ nX
];
2437 aColParam
.pMapG
[ nX
] = ~aColParam
.pMapG
[ nX
];
2438 aColParam
.pMapB
[ nX
] = ~aColParam
.pMapB
[ nX
];
2442 aBmpParam
.nLuminancePercent
= nLuminancePercent
;
2443 aBmpParam
.nContrastPercent
= nContrastPercent
;
2444 aBmpParam
.nChannelRPercent
= nChannelRPercent
;
2445 aBmpParam
.nChannelGPercent
= nChannelGPercent
;
2446 aBmpParam
.nChannelBPercent
= nChannelBPercent
;
2447 aBmpParam
.fGamma
= fGamma
;
2448 aBmpParam
.bInvert
= bInvert
;
2450 // do color adjustment
2451 ImplExchangeColors( ImplColAdjustFnc
, &aColParam
, ImplBmpAdjustFnc
, &aBmpParam
);
2453 delete[] aColParam
.pMapR
;
2454 delete[] aColParam
.pMapG
;
2455 delete[] aColParam
.pMapB
;
2459 // ------------------------------------------------------------------------
2461 void GDIMetaFile::Convert( MtfConversion eConversion
)
2463 // nothing to do? => return quickly
2464 if( eConversion
!= MTF_CONVERSION_NONE
)
2466 ImplColConvertParam aColParam
;
2467 ImplBmpConvertParam aBmpParam
;
2469 aColParam
.eConversion
= eConversion
;
2470 aBmpParam
.eConversion
= ( MTF_CONVERSION_1BIT_THRESHOLD
== eConversion
) ? BMP_CONVERSION_1BIT_THRESHOLD
: BMP_CONVERSION_8BIT_GREYS
;
2472 ImplExchangeColors( ImplColConvertFnc
, &aColParam
, ImplBmpConvertFnc
, &aBmpParam
);
2476 // ------------------------------------------------------------------------
2478 void GDIMetaFile::ReplaceColors( const Color
& rSearchColor
, const Color
& rReplaceColor
, ULONG nTol
)
2480 ReplaceColors( &rSearchColor
, &rReplaceColor
, 1, &nTol
);
2483 // ------------------------------------------------------------------------
2485 void GDIMetaFile::ReplaceColors( const Color
* pSearchColors
, const Color
* pReplaceColors
, ULONG nColorCount
, ULONG
* pTols
)
2487 ImplColReplaceParam aColParam
;
2488 ImplBmpReplaceParam aBmpParam
;
2490 aColParam
.pMinR
= new ULONG
[ nColorCount
];
2491 aColParam
.pMaxR
= new ULONG
[ nColorCount
];
2492 aColParam
.pMinG
= new ULONG
[ nColorCount
];
2493 aColParam
.pMaxG
= new ULONG
[ nColorCount
];
2494 aColParam
.pMinB
= new ULONG
[ nColorCount
];
2495 aColParam
.pMaxB
= new ULONG
[ nColorCount
];
2497 for( ULONG i
= 0; i
< nColorCount
; i
++ )
2499 const long nTol
= pTols
? ( pTols
[ i
] * 255 ) / 100 : 0;
2502 nVal
= pSearchColors
[ i
].GetRed();
2503 aColParam
.pMinR
[ i
] = (ULONG
) Max( nVal
- nTol
, 0L );
2504 aColParam
.pMaxR
[ i
] = (ULONG
) Min( nVal
+ nTol
, 255L );
2506 nVal
= pSearchColors
[ i
].GetGreen();
2507 aColParam
.pMinG
[ i
] = (ULONG
) Max( nVal
- nTol
, 0L );
2508 aColParam
.pMaxG
[ i
] = (ULONG
) Min( nVal
+ nTol
, 255L );
2510 nVal
= pSearchColors
[ i
].GetBlue();
2511 aColParam
.pMinB
[ i
] = (ULONG
) Max( nVal
- nTol
, 0L );
2512 aColParam
.pMaxB
[ i
] = (ULONG
) Min( nVal
+ nTol
, 255L );
2515 aColParam
.pDstCols
= pReplaceColors
;
2516 aColParam
.nCount
= nColorCount
;
2518 aBmpParam
.pSrcCols
= pSearchColors
;
2519 aBmpParam
.pDstCols
= pReplaceColors
;
2520 aBmpParam
.nCount
= nColorCount
;
2521 aBmpParam
.pTols
= pTols
;
2523 ImplExchangeColors( ImplColReplaceFnc
, &aColParam
, ImplBmpReplaceFnc
, &aBmpParam
);
2525 delete[] aColParam
.pMinR
;
2526 delete[] aColParam
.pMaxR
;
2527 delete[] aColParam
.pMinG
;
2528 delete[] aColParam
.pMaxG
;
2529 delete[] aColParam
.pMinB
;
2530 delete[] aColParam
.pMaxB
;
2533 // ------------------------------------------------------------------------
2535 GDIMetaFile
GDIMetaFile::GetMonochromeMtf( const Color
& rColor
) const
2537 GDIMetaFile
aRet( *this );
2539 ImplColMonoParam aColParam
;
2540 ImplBmpMonoParam aBmpParam
;
2542 aColParam
.aColor
= rColor
;
2543 aBmpParam
.aColor
= rColor
;
2545 aRet
.ImplExchangeColors( ImplColMonoFnc
, &aColParam
, ImplBmpMonoFnc
, &aBmpParam
);
2550 // ------------------------------------------------------------------------
2552 ULONG
GDIMetaFile::GetChecksum() const
2555 SvMemoryStream
aMemStm( 65535, 65535 );
2556 ImplMetaWriteData aWriteData
; aWriteData
.meActualCharSet
= aMemStm
.GetStreamCharSet();
2561 for( ULONG i
= 0, nObjCount
= GetActionCount(); i
< nObjCount
; i
++ )
2563 MetaAction
* pAction
= GetAction( i
);
2565 switch( pAction
->GetType() )
2567 case( META_BMP_ACTION
):
2569 MetaBmpAction
* pAct
= (MetaBmpAction
*) pAction
;
2571 ShortToSVBT16( pAct
->GetType(), aBT16
);
2572 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2574 UInt32ToSVBT32( pAct
->GetBitmap().GetChecksum(), aBT32
);
2575 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2577 UInt32ToSVBT32( pAct
->GetPoint().X(), aBT32
);
2578 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2580 UInt32ToSVBT32( pAct
->GetPoint().Y(), aBT32
);
2581 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2585 case( META_BMPSCALE_ACTION
):
2587 MetaBmpScaleAction
* pAct
= (MetaBmpScaleAction
*) pAction
;
2589 ShortToSVBT16( pAct
->GetType(), aBT16
);
2590 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2592 UInt32ToSVBT32( pAct
->GetBitmap().GetChecksum(), aBT32
);
2593 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2595 UInt32ToSVBT32( pAct
->GetPoint().X(), aBT32
);
2596 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2598 UInt32ToSVBT32( pAct
->GetPoint().Y(), aBT32
);
2599 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2601 UInt32ToSVBT32( pAct
->GetSize().Width(), aBT32
);
2602 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2604 UInt32ToSVBT32( pAct
->GetSize().Height(), aBT32
);
2605 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2609 case( META_BMPSCALEPART_ACTION
):
2611 MetaBmpScalePartAction
* pAct
= (MetaBmpScalePartAction
*) pAction
;
2613 ShortToSVBT16( pAct
->GetType(), aBT16
);
2614 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2616 UInt32ToSVBT32( pAct
->GetBitmap().GetChecksum(), aBT32
);
2617 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2619 UInt32ToSVBT32( pAct
->GetDestPoint().X(), aBT32
);
2620 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2622 UInt32ToSVBT32( pAct
->GetDestPoint().Y(), aBT32
);
2623 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2625 UInt32ToSVBT32( pAct
->GetDestSize().Width(), aBT32
);
2626 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2628 UInt32ToSVBT32( pAct
->GetDestSize().Height(), aBT32
);
2629 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2631 UInt32ToSVBT32( pAct
->GetSrcPoint().X(), aBT32
);
2632 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2634 UInt32ToSVBT32( pAct
->GetSrcPoint().Y(), aBT32
);
2635 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2637 UInt32ToSVBT32( pAct
->GetSrcSize().Width(), aBT32
);
2638 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2640 UInt32ToSVBT32( pAct
->GetSrcSize().Height(), aBT32
);
2641 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2645 case( META_BMPEX_ACTION
):
2647 MetaBmpExAction
* pAct
= (MetaBmpExAction
*) pAction
;
2649 ShortToSVBT16( pAct
->GetType(), aBT16
);
2650 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2652 UInt32ToSVBT32( pAct
->GetBitmapEx().GetChecksum(), aBT32
);
2653 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2655 UInt32ToSVBT32( pAct
->GetPoint().X(), aBT32
);
2656 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2658 UInt32ToSVBT32( pAct
->GetPoint().Y(), aBT32
);
2659 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2663 case( META_BMPEXSCALE_ACTION
):
2665 MetaBmpExScaleAction
* pAct
= (MetaBmpExScaleAction
*) pAction
;
2667 ShortToSVBT16( pAct
->GetType(), aBT16
);
2668 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2670 UInt32ToSVBT32( pAct
->GetBitmapEx().GetChecksum(), aBT32
);
2671 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2673 UInt32ToSVBT32( pAct
->GetPoint().X(), aBT32
);
2674 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2676 UInt32ToSVBT32( pAct
->GetPoint().Y(), aBT32
);
2677 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2679 UInt32ToSVBT32( pAct
->GetSize().Width(), aBT32
);
2680 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2682 UInt32ToSVBT32( pAct
->GetSize().Height(), aBT32
);
2683 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2687 case( META_BMPEXSCALEPART_ACTION
):
2689 MetaBmpExScalePartAction
* pAct
= (MetaBmpExScalePartAction
*) pAction
;
2691 ShortToSVBT16( pAct
->GetType(), aBT16
);
2692 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2694 UInt32ToSVBT32( pAct
->GetBitmapEx().GetChecksum(), aBT32
);
2695 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2697 UInt32ToSVBT32( pAct
->GetDestPoint().X(), aBT32
);
2698 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2700 UInt32ToSVBT32( pAct
->GetDestPoint().Y(), aBT32
);
2701 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2703 UInt32ToSVBT32( pAct
->GetDestSize().Width(), aBT32
);
2704 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2706 UInt32ToSVBT32( pAct
->GetDestSize().Height(), aBT32
);
2707 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2709 UInt32ToSVBT32( pAct
->GetSrcPoint().X(), aBT32
);
2710 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2712 UInt32ToSVBT32( pAct
->GetSrcPoint().Y(), aBT32
);
2713 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2715 UInt32ToSVBT32( pAct
->GetSrcSize().Width(), aBT32
);
2716 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2718 UInt32ToSVBT32( pAct
->GetSrcSize().Height(), aBT32
);
2719 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2723 case( META_MASK_ACTION
):
2725 MetaMaskAction
* pAct
= (MetaMaskAction
*) pAction
;
2727 ShortToSVBT16( pAct
->GetType(), aBT16
);
2728 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2730 UInt32ToSVBT32( pAct
->GetBitmap().GetChecksum(), aBT32
);
2731 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2733 UInt32ToSVBT32( pAct
->GetColor().GetColor(), aBT32
);
2734 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2736 UInt32ToSVBT32( pAct
->GetPoint().X(), aBT32
);
2737 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2739 UInt32ToSVBT32( pAct
->GetPoint().Y(), aBT32
);
2740 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2744 case( META_MASKSCALE_ACTION
):
2746 MetaMaskScaleAction
* pAct
= (MetaMaskScaleAction
*) pAction
;
2748 ShortToSVBT16( pAct
->GetType(), aBT16
);
2749 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2751 UInt32ToSVBT32( pAct
->GetBitmap().GetChecksum(), aBT32
);
2752 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2754 UInt32ToSVBT32( pAct
->GetColor().GetColor(), aBT32
);
2755 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2757 UInt32ToSVBT32( pAct
->GetPoint().X(), aBT32
);
2758 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2760 UInt32ToSVBT32( pAct
->GetPoint().Y(), aBT32
);
2761 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2763 UInt32ToSVBT32( pAct
->GetSize().Width(), aBT32
);
2764 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2766 UInt32ToSVBT32( pAct
->GetSize().Height(), aBT32
);
2767 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2771 case( META_MASKSCALEPART_ACTION
):
2773 MetaMaskScalePartAction
* pAct
= (MetaMaskScalePartAction
*) pAction
;
2775 ShortToSVBT16( pAct
->GetType(), aBT16
);
2776 nCrc
= rtl_crc32( nCrc
, aBT16
, 2 );
2778 UInt32ToSVBT32( pAct
->GetBitmap().GetChecksum(), aBT32
);
2779 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2781 UInt32ToSVBT32( pAct
->GetColor().GetColor(), aBT32
);
2782 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2784 UInt32ToSVBT32( pAct
->GetDestPoint().X(), aBT32
);
2785 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2787 UInt32ToSVBT32( pAct
->GetDestPoint().Y(), aBT32
);
2788 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2790 UInt32ToSVBT32( pAct
->GetDestSize().Width(), aBT32
);
2791 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2793 UInt32ToSVBT32( pAct
->GetDestSize().Height(), aBT32
);
2794 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2796 UInt32ToSVBT32( pAct
->GetSrcPoint().X(), aBT32
);
2797 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2799 UInt32ToSVBT32( pAct
->GetSrcPoint().Y(), aBT32
);
2800 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2802 UInt32ToSVBT32( pAct
->GetSrcSize().Width(), aBT32
);
2803 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2805 UInt32ToSVBT32( pAct
->GetSrcSize().Height(), aBT32
);
2806 nCrc
= rtl_crc32( nCrc
, aBT32
, 4 );
2810 case META_EPS_ACTION
:
2812 MetaEPSAction
* pAct
= (MetaEPSAction
*) pAction
;
2813 nCrc
= rtl_crc32( nCrc
, pAct
->GetLink().GetData(), pAct
->GetLink().GetDataSize() );
2819 pAction
->Write( aMemStm
, &aWriteData
);
2820 nCrc
= rtl_crc32( nCrc
, aMemStm
.GetData(), aMemStm
.Tell() );
2830 // ------------------------------------------------------------------------
2832 ULONG
GDIMetaFile::GetSizeBytes() const
2834 ULONG nSizeBytes
= 0;
2836 for( ULONG i
= 0, nObjCount
= GetActionCount(); i
< nObjCount
; ++i
)
2838 MetaAction
* pAction
= GetAction( i
);
2840 // default action size is set to 32 (=> not the exact value)
2843 // add sizes for large action content
2844 switch( pAction
->GetType() )
2846 case( META_BMP_ACTION
): nSizeBytes
+= ( (MetaBmpAction
*) pAction
)->GetBitmap().GetSizeBytes(); break;
2847 case( META_BMPSCALE_ACTION
): nSizeBytes
+= ( (MetaBmpScaleAction
*) pAction
)->GetBitmap().GetSizeBytes(); break;
2848 case( META_BMPSCALEPART_ACTION
): nSizeBytes
+= ( (MetaBmpScalePartAction
*) pAction
)->GetBitmap().GetSizeBytes(); break;
2850 case( META_BMPEX_ACTION
): nSizeBytes
+= ( (MetaBmpExAction
*) pAction
)->GetBitmapEx().GetSizeBytes(); break;
2851 case( META_BMPEXSCALE_ACTION
): nSizeBytes
+= ( (MetaBmpExScaleAction
*) pAction
)->GetBitmapEx().GetSizeBytes(); break;
2852 case( META_BMPEXSCALEPART_ACTION
): nSizeBytes
+= ( (MetaBmpExScalePartAction
*) pAction
)->GetBitmapEx().GetSizeBytes(); break;
2854 case( META_MASK_ACTION
): nSizeBytes
+= ( (MetaMaskAction
*) pAction
)->GetBitmap().GetSizeBytes(); break;
2855 case( META_MASKSCALE_ACTION
): nSizeBytes
+= ( (MetaMaskScaleAction
*) pAction
)->GetBitmap().GetSizeBytes(); break;
2856 case( META_MASKSCALEPART_ACTION
): nSizeBytes
+= ( (MetaMaskScalePartAction
*) pAction
)->GetBitmap().GetSizeBytes(); break;
2858 case( META_POLYLINE_ACTION
): nSizeBytes
+= ( ( (MetaPolyLineAction
*) pAction
)->GetPolygon().GetSize() * sizeof( Point
) ); break;
2859 case( META_POLYGON_ACTION
): nSizeBytes
+= ( ( (MetaPolygonAction
*) pAction
)->GetPolygon().GetSize() * sizeof( Point
) ); break;
2860 case( META_POLYPOLYGON_ACTION
):
2862 const PolyPolygon
& rPolyPoly
= ( (MetaPolyPolygonAction
*) pAction
)->GetPolyPolygon();
2864 for( USHORT n
= 0; n
< rPolyPoly
.Count(); ++n
)
2865 nSizeBytes
+= ( rPolyPoly
[ n
].GetSize() * sizeof( Point
) );
2869 case( META_TEXT_ACTION
): nSizeBytes
+= ( ( (MetaTextAction
*) pAction
)->GetText().Len() * sizeof( sal_Unicode
) ); break;
2870 case( META_STRETCHTEXT_ACTION
): nSizeBytes
+= ( ( (MetaStretchTextAction
*) pAction
)->GetText().Len() * sizeof( sal_Unicode
) ); break;
2871 case( META_TEXTRECT_ACTION
): nSizeBytes
+= ( ( (MetaTextRectAction
*) pAction
)->GetText().Len() * sizeof( sal_Unicode
) ); break;
2872 case( META_TEXTARRAY_ACTION
):
2874 MetaTextArrayAction
* pTextArrayAction
= (MetaTextArrayAction
*) pAction
;
2876 nSizeBytes
+= ( pTextArrayAction
->GetText().Len() * sizeof( sal_Unicode
) );
2878 if( pTextArrayAction
->GetDXArray() )
2879 nSizeBytes
+= ( pTextArrayAction
->GetLen() << 2 );
2888 return( nSizeBytes
);
2891 // ------------------------------------------------------------------------
2893 SvStream
& operator>>( SvStream
& rIStm
, GDIMetaFile
& rGDIMetaFile
)
2895 if( !rIStm
.GetError() )
2898 ULONG nStmPos
= rIStm
.Tell();
2899 USHORT nOldFormat
= rIStm
.GetNumberFormatInt();
2901 rIStm
.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
2905 rIStm
.Read( aId
, 6 );
2907 if ( !strcmp( aId
, "VCLMTF" ) )
2910 VersionCompat
* pCompat
;
2911 MetaAction
* pAction
;
2912 UINT32 nStmCompressMode
= 0;
2915 pCompat
= new VersionCompat( rIStm
, STREAM_READ
);
2917 rIStm
>> nStmCompressMode
;
2918 rIStm
>> rGDIMetaFile
.aPrefMapMode
;
2919 rIStm
>> rGDIMetaFile
.aPrefSize
;
2924 ImplMetaReadData aReadData
;
2925 aReadData
.meActualCharSet
= rIStm
.GetStreamCharSet();
2927 for( UINT32 nAction
= 0UL; ( nAction
< nCount
) && !rIStm
.IsEof(); nAction
++ )
2929 pAction
= MetaAction::ReadMetaAction( rIStm
, &aReadData
);
2932 rGDIMetaFile
.AddAction( pAction
);
2937 // to avoid possible compiler optimizations => new/delete
2938 rIStm
.Seek( nStmPos
);
2939 delete( new SVMConverter( rIStm
, rGDIMetaFile
, CONVERT_FROM_SVM1
) );
2943 if( rIStm
.GetError() )
2945 rGDIMetaFile
.Clear();
2946 rIStm
.Seek( nStmPos
);
2949 rIStm
.SetNumberFormatInt( nOldFormat
);
2955 // ------------------------------------------------------------------------
2957 SvStream
& operator<<( SvStream
& rOStm
, const GDIMetaFile
& rGDIMetaFile
)
2959 if( !rOStm
.GetError() )
2961 if( rOStm
.GetVersion() >= SOFFICE_FILEFORMAT_50
)
2962 ((GDIMetaFile
&) rGDIMetaFile
).Write( rOStm
);
2964 delete( new SVMConverter( rOStm
, (GDIMetaFile
&) rGDIMetaFile
, CONVERT_TO_SVM1
) );
2970 // ------------------------------------------------------------------------
2972 SvStream
& GDIMetaFile::Read( SvStream
& rIStm
)
2980 // ------------------------------------------------------------------------
2982 SvStream
& GDIMetaFile::Write( SvStream
& rOStm
)
2984 VersionCompat
* pCompat
;
2985 const UINT32 nStmCompressMode
= rOStm
.GetCompressMode();
2986 USHORT nOldFormat
= rOStm
.GetNumberFormatInt();
2988 rOStm
.SetNumberFormatInt( NUMBERFORMAT_INT_LITTLEENDIAN
);
2989 rOStm
.Write( "VCLMTF", 6 );
2991 pCompat
= new VersionCompat( rOStm
, STREAM_WRITE
, 1 );
2993 rOStm
<< nStmCompressMode
;
2994 rOStm
<< aPrefMapMode
;
2996 rOStm
<< (UINT32
) GetActionCount();
3000 ImplMetaWriteData aWriteData
;
3001 aWriteData
.meActualCharSet
= rOStm
.GetStreamCharSet();
3003 MetaAction
* pAct
= (MetaAction
*)First();
3006 pAct
->Write( rOStm
, &aWriteData
);
3007 pAct
= (MetaAction
*)Next();
3010 rOStm
.SetNumberFormatInt( nOldFormat
);
3015 // ------------------------------------------------------------------------
3017 BOOL
GDIMetaFile::CreateThumbnail( sal_uInt32 nMaximumExtent
,
3019 const BitmapEx
* pOverlay
,
3020 const Rectangle
* pOverlayRect
) const
3022 // the implementation is provided by KA
3024 // initialization seems to be complicated but is used to avoid rounding errors
3025 VirtualDevice aVDev
;
3026 const Point aNullPt
;
3027 const Point
aTLPix( aVDev
.LogicToPixel( aNullPt
, GetPrefMapMode() ) );
3028 const Point
aBRPix( aVDev
.LogicToPixel( Point( GetPrefSize().Width() - 1, GetPrefSize().Height() - 1 ), GetPrefMapMode() ) );
3029 Size
aDrawSize( aVDev
.LogicToPixel( GetPrefSize(), GetPrefMapMode() ) );
3030 Size
aSizePix( labs( aBRPix
.X() - aTLPix
.X() ) + 1, labs( aBRPix
.Y() - aTLPix
.Y() ) + 1 );
3033 if ( !rBmpEx
.IsEmpty() )
3036 // determine size that has the same aspect ratio as image size and
3037 // fits into the rectangle determined by nMaximumExtent
3038 if ( aSizePix
.Width() && aSizePix
.Height()
3039 && ( sal::static_int_cast
< unsigned long >(aSizePix
.Width()) >
3041 sal::static_int_cast
< unsigned long >(aSizePix
.Height()) >
3044 const Size
aOldSizePix( aSizePix
);
3045 double fWH
= static_cast< double >( aSizePix
.Width() ) / aSizePix
.Height();
3049 aSizePix
.Width() = FRound( nMaximumExtent
* fWH
);
3050 aSizePix
.Height() = nMaximumExtent
;
3054 aSizePix
.Width() = nMaximumExtent
;
3055 aSizePix
.Height() = FRound( nMaximumExtent
/ fWH
);
3058 aDrawSize
.Width() = FRound( ( static_cast< double >( aDrawSize
.Width() ) * aSizePix
.Width() ) / aOldSizePix
.Width() );
3059 aDrawSize
.Height() = FRound( ( static_cast< double >( aDrawSize
.Height() ) * aSizePix
.Height() ) / aOldSizePix
.Height() );
3064 Rectangle aOverlayRect
;
3066 // calculate addigtional positions and sizes if an overlay image is used
3069 aFullSize
= Size( nMaximumExtent
, nMaximumExtent
);
3070 aOverlayRect
= Rectangle( aNullPt
, aFullSize
);
3072 aOverlayRect
.Intersection( pOverlayRect
? *pOverlayRect
: Rectangle( aNullPt
, pOverlay
->GetSizePixel() ) );
3074 if ( !aOverlayRect
.IsEmpty() )
3075 aBackPosPix
= Point( ( nMaximumExtent
- aSizePix
.Width() ) >> 1, ( nMaximumExtent
- aSizePix
.Height() ) >> 1 );
3081 aFullSize
= aSizePix
;
3085 // draw image(s) into VDev and get resulting image
3086 if ( aVDev
.SetOutputSizePixel( aFullSize
) )
3088 // draw metafile into VDev
3089 const_cast<GDIMetaFile
*>(this)->WindStart();
3090 const_cast<GDIMetaFile
*>(this)->Play( &aVDev
, aBackPosPix
, aDrawSize
);
3092 // draw overlay if neccessary
3094 aVDev
.DrawBitmapEx( aOverlayRect
.TopLeft(), aOverlayRect
.GetSize(), *pOverlay
);
3097 Bitmap
aBmp( aVDev
.GetBitmap( aNullPt
, aVDev
.GetOutputSizePixel() ) );
3099 // assure that we have a true color image
3100 if ( aBmp
.GetBitCount() != 24 )
3101 aBmp
.Convert( BMP_CONVERSION_24BIT
);
3103 // create resulting mask bitmap with metafile output set to black
3104 GDIMetaFile
aMonchromeMtf( GetMonochromeMtf( COL_BLACK
) );
3105 aVDev
.DrawWallpaper( Rectangle( aNullPt
, aSizePix
), Wallpaper( Color( COL_WHITE
) ) );
3106 aMonchromeMtf
.WindStart();
3107 aMonchromeMtf
.Play( &aVDev
, aBackPosPix
, aDrawSize
);
3109 // watch for overlay mask
3112 Bitmap
aOverlayMergeBmp( aVDev
.GetBitmap( aOverlayRect
.TopLeft(), aOverlayRect
.GetSize() ) );
3114 // create ANDed resulting mask at overlay area
3115 if ( pOverlay
->IsTransparent() )
3116 aVDev
.DrawBitmap( aOverlayRect
.TopLeft(), aOverlayRect
.GetSize(), pOverlay
->GetMask() );
3119 aVDev
.SetLineColor( COL_BLACK
);
3120 aVDev
.SetFillColor( COL_BLACK
);
3121 aVDev
.DrawRect( aOverlayRect
);
3124 aOverlayMergeBmp
.CombineSimple( aVDev
.GetBitmap( aOverlayRect
.TopLeft(), aOverlayRect
.GetSize() ), BMP_COMBINE_AND
);
3125 aVDev
.DrawBitmap( aOverlayRect
.TopLeft(), aOverlayRect
.GetSize(), aOverlayMergeBmp
);
3128 rBmpEx
= BitmapEx( aBmp
, aVDev
.GetBitmap( aNullPt
, aVDev
.GetOutputSizePixel() ) );
3131 return !rBmpEx
.IsEmpty();
3134 void GDIMetaFile::UseCanvas( BOOL _bUseCanvas
)
3136 bUseCanvas
= _bUseCanvas
;
3139 // ------------------------------------------------------------------------
3141 MetaCommentAction
* makePluggableRendererAction( const rtl::OUString
& rRendererServiceName
,
3142 const rtl::OUString
& rGraphicServiceName
,
3144 sal_uInt32 nDataSize
)
3146 const BYTE
* pData
=(BYTE
*)_pData
;
3148 // data gets copied twice, unfortunately
3149 rtl::OString
aRendererServiceName(
3150 rRendererServiceName
.getStr(),
3151 rRendererServiceName
.getLength(),
3152 RTL_TEXTENCODING_ASCII_US
);
3153 rtl::OString
aGraphicServiceName(
3154 rGraphicServiceName
.getStr(),
3155 rGraphicServiceName
.getLength(),
3156 RTL_TEXTENCODING_ASCII_US
);
3158 std::vector
<sal_uInt8
> aMem(
3159 aRendererServiceName
.getLength()+
3160 aGraphicServiceName
.getLength()+2+nDataSize
);
3161 sal_uInt8
* pMem
=&aMem
[0];
3163 std::copy(aRendererServiceName
.getStr(),
3164 aRendererServiceName
.getStr()+aRendererServiceName
.getLength()+1,
3166 pMem
+=aRendererServiceName
.getLength()+1;
3167 std::copy(aGraphicServiceName
.getStr(),
3168 aGraphicServiceName
.getStr()+aGraphicServiceName
.getLength()+1,
3170 pMem
+=aGraphicServiceName
.getLength()+1;
3172 std::copy(pData
,pData
+nDataSize
,
3175 return new MetaCommentAction(
3176 "DELEGATE_PLUGGABLE_RENDERER",