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: winmtf.cxx,v $
10 * $Revision: 1.54.136.2 $
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_svtools.hxx"
36 #include <vcl/metaact.hxx>
37 #include <vcl/graphictools.hxx>
38 #include <vcl/metric.hxx>
39 #include <rtl/tencinfo.h>
41 // ------------------------------------------------------------------------
44 //#define EMFP_DEBUG(x) x
46 #define WIN_MTF_MAX_POLYPOLYCOUNT 16
48 void WinMtfClipPath::ImpUpdateType()
50 if ( !aPolyPoly
.Count() )
52 else if ( aPolyPoly
.IsRect() )
57 bNeedsUpdate
= sal_True
;
60 void WinMtfClipPath::IntersectClipRect( const Rectangle
& rRect
)
62 if ( !aPolyPoly
.Count() )
63 aPolyPoly
= Polygon( rRect
);
64 else if ( aPolyPoly
.Count() < WIN_MTF_MAX_POLYPOLYCOUNT
)
66 Polygon
aPolygon( rRect
);
67 PolyPolygon aIntersection
;
68 PolyPolygon
aPolyPolyRect( aPolygon
);
69 aPolyPoly
.GetIntersection( aPolyPolyRect
, aIntersection
);
70 aPolyPoly
= aIntersection
;
75 void WinMtfClipPath::ExcludeClipRect( const Rectangle
& rRect
)
77 if ( aPolyPoly
.Count() && ( aPolyPoly
.Count() < WIN_MTF_MAX_POLYPOLYCOUNT
) )
79 Polygon
aPolygon( rRect
);
80 PolyPolygon
aPolyPolyRect( aPolygon
);
81 PolyPolygon aDifference
;
82 aPolyPoly
.GetDifference( aPolyPolyRect
, aDifference
);
83 aPolyPoly
= aDifference
;
88 void WinMtfClipPath::SetClipPath( const PolyPolygon
& rPolyPolygon
, sal_Int32 nClippingMode
)
90 if ( !rPolyPolygon
.Count() )
91 aPolyPoly
= rPolyPolygon
;
92 else if ( rPolyPolygon
.Count() < WIN_MTF_MAX_POLYPOLYCOUNT
)
94 PolyPolygon aNewClipPath
;
96 // #115345# Watch out for empty aPolyPoly here - conceptually,
97 // an empty clip path is a rectangle of infinite size, but it
98 // is represented by an empty aPolyPoly. When intersecting
99 // rPolyPolygon with this _empty_ aPolyPoly, set algebra
100 // guarantees wrong results.
101 switch ( nClippingMode
)
104 // #115345# clip stays empty, when ORing an arbitrary
105 // rPolyPolygon. Thus, we can save us the unnecessary
107 if( aPolyPoly
.Count() )
108 aPolyPoly
.GetUnion( rPolyPolygon
, aNewClipPath
);
112 // #115345# Cannot handle this case, for the time being
113 aPolyPoly
.GetXOR( rPolyPolygon
, aNewClipPath
);
117 // #115345# Cannot handle this case, for the time being
118 aPolyPoly
.GetDifference( rPolyPolygon
, aNewClipPath
);
121 // #115345# Clip becomes rPolyPolygon, when ANDing
122 // with an arbitrary rPolyPolygon
123 if( aPolyPoly
.Count() )
124 aPolyPoly
.GetIntersection( rPolyPolygon
, aNewClipPath
);
126 aNewClipPath
= rPolyPolygon
;
129 aNewClipPath
= rPolyPolygon
;
132 aPolyPoly
= aNewClipPath
;
137 void WinMtfClipPath::MoveClipRegion( const Size
& rSize
)
139 aPolyPoly
.Move( rSize
.Width(), rSize
.Height() );
140 bNeedsUpdate
= sal_True
;
143 // ------------------------------------------------------------------------
145 void WinMtfPathObj::AddPoint( const Point
& rPoint
)
148 Insert( Polygon(), POLYPOLY_APPEND
);
149 Polygon
& rPoly
= ((PolyPolygon
&)*this)[ Count() - 1 ];
150 rPoly
.Insert( rPoly
.GetSize(), rPoint
, POLY_NORMAL
);
154 void WinMtfPathObj::AddPolyLine( const Polygon
& rPolyLine
)
157 Insert( Polygon(), POLYPOLY_APPEND
);
158 Polygon
& rPoly
= ((PolyPolygon
&)*this)[ Count() - 1 ];
159 rPoly
.Insert( rPoly
.GetSize(), rPolyLine
);
163 void WinMtfPathObj::AddPolygon( const Polygon
& rPoly
)
165 Insert( rPoly
, POLYPOLY_APPEND
);
169 void WinMtfPathObj::AddPolyPolygon( const PolyPolygon
& rPolyPoly
)
171 sal_uInt16 i
, nCount
= rPolyPoly
.Count();
172 for ( i
= 0; i
< nCount
; i
++ )
173 Insert( rPolyPoly
[ i
], POLYPOLY_APPEND
);
177 void WinMtfPathObj::ClosePath()
181 Polygon
& rPoly
= ((PolyPolygon
&)*this)[ Count() - 1 ];
182 if ( rPoly
.GetSize() > 2 )
184 Point
aFirst( rPoly
[ 0 ] );
185 if ( aFirst
!= rPoly
[ rPoly
.GetSize() - 1 ] )
186 rPoly
.Insert( rPoly
.GetSize(), aFirst
, POLY_NORMAL
);
192 // ------------------------------------------------------------------------
194 WinMtfFontStyle::WinMtfFontStyle( LOGFONTW
& rFont
)
197 if ( ( rFont
.lfCharSet
== OEM_CHARSET
) || ( rFont
.lfCharSet
== DEFAULT_CHARSET
) )
198 eCharSet
= gsl_getSystemTextEncoding();
200 eCharSet
= rtl_getTextEncodingFromWindowsCharset( rFont
.lfCharSet
);
201 if ( eCharSet
== RTL_TEXTENCODING_DONTKNOW
)
202 eCharSet
= gsl_getSystemTextEncoding();
203 aFont
.SetCharSet( eCharSet
);
204 aFont
.SetName( rFont
.alfFaceName
);
206 switch ( rFont
.lfPitchAndFamily
& 0xf0 )
209 eFamily
= FAMILY_ROMAN
;
213 eFamily
= FAMILY_SWISS
;
217 eFamily
= FAMILY_MODERN
;
221 eFamily
= FAMILY_SCRIPT
;
225 eFamily
= FAMILY_DECORATIVE
;
229 eFamily
= FAMILY_DONTKNOW
;
232 aFont
.SetFamily( eFamily
);
235 switch ( rFont
.lfPitchAndFamily
& 0x0f )
238 ePitch
= PITCH_FIXED
;
244 ePitch
= PITCH_VARIABLE
;
247 aFont
.SetPitch( ePitch
);
250 if( rFont
.lfWeight
<= FW_THIN
)
251 eWeight
= WEIGHT_THIN
;
252 else if( rFont
.lfWeight
<= FW_ULTRALIGHT
)
253 eWeight
= WEIGHT_ULTRALIGHT
;
254 else if( rFont
.lfWeight
<= FW_LIGHT
)
255 eWeight
= WEIGHT_LIGHT
;
256 else if( rFont
.lfWeight
< FW_MEDIUM
)
257 eWeight
= WEIGHT_NORMAL
;
258 else if( rFont
.lfWeight
== FW_MEDIUM
)
259 eWeight
= WEIGHT_MEDIUM
;
260 else if( rFont
.lfWeight
<= FW_SEMIBOLD
)
261 eWeight
= WEIGHT_SEMIBOLD
;
262 else if( rFont
.lfWeight
<= FW_BOLD
)
263 eWeight
= WEIGHT_BOLD
;
264 else if( rFont
.lfWeight
<= FW_ULTRABOLD
)
265 eWeight
= WEIGHT_ULTRABOLD
;
267 eWeight
= WEIGHT_BLACK
;
268 aFont
.SetWeight( eWeight
);
271 aFont
.SetItalic( ITALIC_NORMAL
);
273 if( rFont
.lfUnderline
)
274 aFont
.SetUnderline( UNDERLINE_SINGLE
);
276 if( rFont
.lfStrikeOut
)
277 aFont
.SetStrikeout( STRIKEOUT_SINGLE
);
279 if ( rFont
.lfOrientation
)
280 aFont
.SetOrientation( (short)rFont
.lfOrientation
);
282 aFont
.SetOrientation( (short)rFont
.lfEscapement
);
284 Size
aFontSize( Size( rFont
.lfWidth
, rFont
.lfHeight
) );
285 if ( rFont
.lfHeight
> 0 )
287 // converting the cell height into a font height
289 aFont
.SetSize( aFontSize
);
290 aVDev
.SetFont( aFont
);
291 FontMetric
aMetric( aVDev
.GetFontMetric() );
292 long nHeight
= aMetric
.GetAscent() + aMetric
.GetDescent();
295 double fHeight
= ((double)aFontSize
.Height() * rFont
.lfHeight
) / nHeight
;
296 aFontSize
.Height() = (sal_Int32
)( fHeight
+ 0.5 );
299 else if ( aFontSize
.Height() < 0 )
300 aFontSize
.Height() *= -1;
302 if ( !rFont
.lfWidth
)
305 aFont
.SetSize( aFontSize
);
306 aVDev
.SetFont( aFont
);
307 FontMetric
aMetric( aVDev
.GetFontMetric() );
308 aFontSize
.Width() = aMetric
.GetWidth();
311 aFont
.SetSize( aFontSize
);
314 // ------------------------------------------------------------------------
316 #ifdef WIN_MTF_ASSERT
317 void WinMtfAssertHandler( const sal_Char
* pAction
, sal_uInt32 nFlags
)
319 static sal_Bool bOnlyOnce
;
320 static sal_Int32 nAssertCount
;
322 if ( nFlags
& WIN_MTF_ASSERT_INIT
)
324 if ( nFlags
& WIN_MTF_ASSERT_ONCE
)
325 bOnlyOnce
= sal_True
;
326 if ( nFlags
& WIN_MTF_ASSERT_MIFE
)
328 if ( ( nAssertCount
== 0 ) || ( bOnlyOnce
== sal_False
) )
330 ByteString
aText( "WMF/EMF Import: " );
333 ByteString
aAction( pAction
);
334 aText
.Append( aAction
);
336 aText
.Append( " needs to be implemented (SJ)" );
337 DBG_ASSERT( 0, aText
.GetBuffer() );
344 // ------------------------------------------------------------------------
346 WinMtf::WinMtf( WinMtfOutput
* pWinMtfOutput
, SvStream
& rStreamWMF
, FilterConfigItem
* pConfigItem
) :
347 pOut ( pWinMtfOutput
),
348 pWMF ( &rStreamWMF
),
349 pFilterConfigItem ( pConfigItem
)
351 #ifdef WIN_MTF_ASSERT
352 // we want to assert not implemented features, but we do this
353 // only once, so that nobody is handicaped by getting too much assertions
354 // I hope this will bring more testdocuments, without support of these
355 // testdocuments the implementation of missing features won't be possible. (SJ)
356 WinMtfAssertHandler( NULL
, WIN_MTF_ASSERT_INIT
| WIN_MTF_ASSERT_ONCE
);
359 SvLockBytes
*pLB
= pWMF
->GetLockBytes();
361 pLB
->SetSynchronMode( TRUE
);
363 nStartPos
= pWMF
->Tell();
365 pOut
->SetDevOrg( Point() );
366 if ( pFilterConfigItem
)
368 xStatusIndicator
= pFilterConfigItem
->GetStatusIndicator();
369 if ( xStatusIndicator
.is() )
372 xStatusIndicator
->start( aMsg
, 100 );
377 // ------------------------------------------------------------------------
383 if ( xStatusIndicator
.is() )
384 xStatusIndicator
->end();
387 // ------------------------------------------------------------------------
389 void WinMtf::Callback( USHORT nPercent
)
391 if ( xStatusIndicator
.is() )
392 xStatusIndicator
->setValue( nPercent
);
395 // ------------------------------------------------------------------------
397 Color
WinMtf::ReadColor()
401 return Color( (BYTE
)nColor
, (BYTE
)( nColor
>> 8 ), (BYTE
)( nColor
>> 16 ) );
404 //-----------------------------------------------------------------------------------
405 //-----------------------------------------------------------------------------------
406 //-----------------------------------------------------------------------------------
408 Point
WinMtfOutput::ImplMap( const Point
& rPt
)
410 if ( mnWinExtX
&& mnWinExtY
)
412 double fX2
, fX
= rPt
.X();
413 double fY2
, fY
= rPt
.Y();
415 fX2
= fX
* maXForm
.eM11
+ fY
* maXForm
.eM21
+ maXForm
.eDx
;
416 fY2
= fX
* maXForm
.eM12
+ fY
* maXForm
.eM22
+ maXForm
.eDy
;
418 if ( mnGfxMode
== GM_COMPATIBLE
)
425 if( mnDevWidth
!= 1 || mnDevHeight
!= 1 ) {
426 fX2
*= 2540.0/mnUnitsPerInch
;
427 fY2
*= 2540.0/mnUnitsPerInch
;
431 fX2
*= (double)mnMillX
* 100.0 / (double)mnPixX
;
432 fY2
*= (double)mnMillY
* 100.0 / (double)mnPixY
;
482 fY2
+= mnDevOrgY
; // fX2, fY2 now in device units
483 fX2
*= (double)mnMillX
* 100.0 / (double)mnPixX
;
484 fY2
*= (double)mnMillY
* 100.0 / (double)mnPixY
;
488 fX2
-= mrclFrame
.Left();
489 fY2
-= mrclFrame
.Top();
491 return Point( FRound( fX2
), FRound( fY2
) );
497 // ------------------------------------------------------------------------
499 Size
WinMtfOutput::ImplMap( const Size
& rSz
)
501 if ( mnWinExtX
&& mnWinExtY
)
503 double fWidth
= rSz
.Width() * maXForm
.eM11
;
504 double fHeight
= rSz
.Height() * maXForm
.eM22
;
506 if ( mnGfxMode
== GM_COMPATIBLE
)
511 if( mnDevWidth
!= 1 && mnDevHeight
!= 1 ) {
512 fWidth
*= 2540.0/mnUnitsPerInch
;
513 fHeight
*= 2540.0/mnUnitsPerInch
;
515 fWidth
*= (double)mnMillX
* 100 / (double)mnPixX
;
516 fHeight
*= (double)mnMillY
* 100 / (double)mnPixY
;
545 fHeight
/= mnWinExtY
;
546 fWidth
*= mnDevWidth
;
547 fHeight
*= mnDevHeight
;
548 fWidth
*= (double)mnMillX
* 100 / (double)mnPixX
;
549 fHeight
*= (double)mnMillY
* 100 / (double)mnPixY
;
554 return Size( FRound( fWidth
), FRound( fHeight
) );
560 //-----------------------------------------------------------------------------------
562 Rectangle
WinMtfOutput::ImplMap( const Rectangle
& rRect
)
564 return Rectangle( ImplMap( rRect
.TopLeft() ), ImplMap( rRect
.GetSize() ) );
567 //-----------------------------------------------------------------------------------
569 void WinMtfOutput::ImplMap( Font
& rFont
)
571 // !!! HACK: Wir setzen die Breite jetzt immer auf Null,
572 // da OS die Breite unterschiedlich interpretieren;
573 // muss spaeter in SV portabel gemacht werden ( KA 08.02.96 )
574 Size aFontSize
= ImplMap ( rFont
.GetSize() );
576 if( aFontSize
.Height() < 0 )
577 aFontSize
.Height() *= -1;
579 rFont
.SetSize( aFontSize
);
581 if( ( mnWinExtX
* mnWinExtY
) < 0 )
582 rFont
.SetOrientation( 3600 - rFont
.GetOrientation() );
585 //-----------------------------------------------------------------------------------
587 Polygon
& WinMtfOutput::ImplMap( Polygon
& rPolygon
)
589 UINT16 nPoints
= rPolygon
.GetSize();
590 for ( UINT16 i
= 0; i
< nPoints
; i
++ )
592 rPolygon
[ i
] = ImplMap( rPolygon
[ i
] );
597 //-----------------------------------------------------------------------------------
599 PolyPolygon
& WinMtfOutput::ImplMap( PolyPolygon
& rPolyPolygon
)
601 UINT16 nPolys
= rPolyPolygon
.Count();
602 for ( UINT16 i
= 0; i
< nPolys
; ImplMap( rPolyPolygon
[ i
++ ] ) ) ;
606 //-----------------------------------------------------------------------------------
608 void WinMtfOutput::SelectObject( INT32 nIndex
)
610 GDIObj
* pGDIObj
= NULL
;
612 if ( nIndex
& ENHMETA_STOCK_OBJECT
)
613 pGDIObj
= new GDIObj();
616 nIndex
&= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
618 if ( (UINT32
)nIndex
< vGDIObj
.size() )
619 pGDIObj
= vGDIObj
[ nIndex
];
622 if( pGDIObj
== NULL
)
625 if ( nIndex
& ENHMETA_STOCK_OBJECT
)
627 UINT16 nStockId
= (BYTE
)nIndex
;
632 pGDIObj
->Set( GDI_BRUSH
, new WinMtfFillStyle( Color( COL_WHITE
) ) );
637 pGDIObj
->Set( GDI_BRUSH
, new WinMtfFillStyle( Color( COL_LIGHTGRAY
) ) );
643 pGDIObj
->Set( GDI_BRUSH
, new WinMtfFillStyle( Color( COL_GRAY
) ) );
648 pGDIObj
->Set( GDI_BRUSH
, new WinMtfFillStyle( Color( COL_BLACK
) ) );
653 pGDIObj
->Set( GDI_BRUSH
, new WinMtfFillStyle( Color( COL_TRANSPARENT
), TRUE
) );
658 pGDIObj
->Set( GDI_PEN
, new WinMtfLineStyle( Color( COL_WHITE
) ) );
663 pGDIObj
->Set( GDI_PEN
, new WinMtfLineStyle( Color( COL_BLACK
) ) );
668 pGDIObj
->Set( GDI_PEN
, new WinMtfLineStyle( Color( COL_TRANSPARENT
), TRUE
) );
675 if ( pGDIObj
->pStyle
)
677 switch( pGDIObj
->eType
)
680 maLineStyle
= (WinMtfLineStyle
*)pGDIObj
->pStyle
;
684 maFillStyle
= (WinMtfFillStyle
*)pGDIObj
->pStyle
;
685 mbFillStyleSelected
= sal_True
;
689 maFont
= ((WinMtfFontStyle
*)pGDIObj
->pStyle
)->aFont
;
692 break; // -Wall many options not handled.
695 if ( nIndex
& ENHMETA_STOCK_OBJECT
)
699 //-----------------------------------------------------------------------------------
701 void WinMtfOutput::SetFont( const Font
& rFont
)
706 //-----------------------------------------------------------------------------------
708 const Font
& WinMtfOutput::GetFont() const
713 //-----------------------------------------------------------------------------------
715 void WinMtfOutput::SetTextLayoutMode( const sal_uInt32 nTextLayoutMode
)
717 mnTextLayoutMode
= nTextLayoutMode
;
720 //-----------------------------------------------------------------------------------
722 sal_uInt32
WinMtfOutput::GetTextLayoutMode() const
724 return mnTextLayoutMode
;
727 //-----------------------------------------------------------------------------------
729 void WinMtfOutput::SetBkMode( UINT32 nMode
)
734 //-----------------------------------------------------------------------------------
736 void WinMtfOutput::SetBkColor( const Color
& rColor
)
741 //-----------------------------------------------------------------------------------
743 void WinMtfOutput::SetTextColor( const Color
& rColor
)
745 maTextColor
= rColor
;
748 //-----------------------------------------------------------------------------------
750 void WinMtfOutput::SetTextAlign( UINT32 nAlign
)
752 mnTextAlign
= nAlign
;
755 //-----------------------------------------------------------------------------------
757 void WinMtfOutput::ImplResizeObjectArry( UINT32 nNewEntrys
)
759 sal_uInt32 i
= vGDIObj
.size();
760 vGDIObj
.resize( nNewEntrys
);
761 for ( ; i
< nNewEntrys
; i
++ )
765 //-----------------------------------------------------------------------------------
767 void WinMtfOutput::ImplDrawClippedPolyPolygon( const PolyPolygon
& rPolyPoly
)
769 if ( rPolyPoly
.Count() )
771 ImplSetNonPersistentLineColorTransparenz();
772 if ( rPolyPoly
.Count() == 1 )
774 if ( rPolyPoly
.IsRect() )
775 mpGDIMetaFile
->AddAction( new MetaRectAction( rPolyPoly
.GetBoundRect() ) );
778 Polygon
aPoly( rPolyPoly
[ 0 ] );
779 sal_uInt16 nCount
= aPoly
.GetSize();
782 if ( aPoly
[ nCount
- 1 ] != aPoly
[ 0 ] )
784 Point
aPoint( aPoly
[ 0 ] );
785 aPoly
.Insert( nCount
, aPoint
);
787 mpGDIMetaFile
->AddAction( new MetaPolygonAction( aPoly
) );
792 mpGDIMetaFile
->AddAction( new MetaPolyPolygonAction( rPolyPoly
) );
797 //-----------------------------------------------------------------------------------
799 void WinMtfOutput::CreateObject( GDIObjectType eType
, void* pStyle
)
803 if ( eType
== GDI_FONT
)
805 ImplMap( ((WinMtfFontStyle
*)pStyle
)->aFont
);
806 if (!((WinMtfFontStyle
*)pStyle
)->aFont
.GetHeight() )
807 ((WinMtfFontStyle
*)pStyle
)->aFont
.SetHeight( 423 ); // defaulting to 12pt
809 else if ( eType
== GDI_PEN
)
811 Size
aSize( ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.GetWidth(), 0 );
812 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetWidth( ImplMap( aSize
).Width() );
813 if ( ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.GetStyle() == LINE_DASH
)
816 long nDotLen
= ImplMap( aSize
).Width();
817 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetDistance( nDotLen
);
818 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetDotLen( nDotLen
);
819 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetDashLen( nDotLen
* 4 );
824 for ( nIndex
= 0; nIndex
< vGDIObj
.size(); nIndex
++ )
826 if ( vGDIObj
[ nIndex
] == NULL
)
829 if ( nIndex
== vGDIObj
.size() )
830 ImplResizeObjectArry( vGDIObj
.size() + 16 );
832 vGDIObj
[ nIndex
] = new GDIObj( eType
, pStyle
);
835 //-----------------------------------------------------------------------------------
837 void WinMtfOutput::CreateObject( INT32 nIndex
, GDIObjectType eType
, void* pStyle
)
839 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
841 nIndex
&= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
844 if ( eType
== GDI_FONT
)
845 ImplMap( ((WinMtfFontStyle
*)pStyle
)->aFont
);
846 else if ( eType
== GDI_PEN
)
848 Size
aSize( ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.GetWidth(), 0 );
849 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetWidth( ImplMap( aSize
).Width() );
850 if ( ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.GetStyle() == LINE_DASH
)
853 long nDotLen
= ImplMap( aSize
).Width();
854 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetDistance( nDotLen
);
855 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetDotLen( nDotLen
);
856 ((WinMtfLineStyle
*)pStyle
)->aLineInfo
.SetDashLen( nDotLen
* 4 );
860 if ( (UINT32
)nIndex
>= vGDIObj
.size() )
861 ImplResizeObjectArry( nIndex
+ 16 );
863 if ( vGDIObj
[ nIndex
] != NULL
)
864 delete vGDIObj
[ nIndex
];
866 vGDIObj
[ nIndex
] = new GDIObj( eType
, pStyle
);
873 delete (WinMtfLineStyle
*)pStyle
;
876 delete (WinMtfFillStyle
*)pStyle
;
879 delete (WinMtfFontStyle
*)pStyle
;
883 DBG_ERROR( "unsupported style not deleted" );
889 //-----------------------------------------------------------------------------------
891 void WinMtfOutput::DeleteObject( sal_Int32 nIndex
)
893 if ( ( nIndex
& ENHMETA_STOCK_OBJECT
) == 0 )
895 if ( (sal_uInt32
)nIndex
< vGDIObj
.size() )
897 delete vGDIObj
[ nIndex
];
898 vGDIObj
[ nIndex
] = NULL
;
903 //-----------------------------------------------------------------------------------
905 void WinMtfOutput::IntersectClipRect( const Rectangle
& rRect
)
907 aClipPath
.IntersectClipRect( ImplMap( rRect
) );
910 //-----------------------------------------------------------------------------------
912 void WinMtfOutput::ExcludeClipRect( const Rectangle
& rRect
)
914 aClipPath
.ExcludeClipRect( ImplMap( rRect
) );
917 //-----------------------------------------------------------------------------------
919 void WinMtfOutput::MoveClipRegion( const Size
& rSize
)
921 aClipPath
.MoveClipRegion( ImplMap( rSize
) );
924 void WinMtfOutput::SetClipPath( const PolyPolygon
& rPolyPolygon
, sal_Int32 nClippingMode
, sal_Bool bIsMapped
)
927 aClipPath
.SetClipPath( rPolyPolygon
, nClippingMode
);
930 PolyPolygon
aPP( rPolyPolygon
);
931 aClipPath
.SetClipPath( ImplMap( aPP
), nClippingMode
);
935 //-----------------------------------------------------------------------------------
936 //-----------------------------------------------------------------------------------
937 //-----------------------------------------------------------------------------------
939 WinMtfOutput::WinMtfOutput( GDIMetaFile
& rGDIMetaFile
) :
940 mnLatestTextAlign ( 0 ),
941 mnTextAlign ( TA_LEFT
| TA_TOP
| TA_NOUPDATECP
),
942 maLatestBkColor ( 0x12345678 ),
943 maBkColor ( COL_WHITE
),
944 mnLatestTextLayoutMode( TEXT_LAYOUT_DEFAULT
),
945 mnTextLayoutMode ( TEXT_LAYOUT_DEFAULT
),
946 mnLatestBkMode ( 0 ),
948 meLatestRasterOp ( ROP_INVERT
),
949 meRasterOp ( ROP_OVERPAINT
),
950 maActPos ( Point() ),
951 mbNopMode ( sal_False
),
952 mbFillStyleSelected ( sal_False
),
953 mnGfxMode ( GM_COMPATIBLE
),
954 mnMapMode ( MM_TEXT
),
955 mnUnitsPerInch ( 96 ),
968 mpGDIMetaFile ( &rGDIMetaFile
)
970 mpGDIMetaFile
->AddAction( new MetaPushAction( PUSH_CLIPREGION
) ); // The original clipregion has to be on top
971 // of the stack so it can always be restored
972 // this is necessary to be able to support
973 // SetClipRgn( NULL ) and similar ClipRgn actions (SJ)
975 maFont
.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Arial" )) ); // sj: #i57205#, we do have some scaling problems if using
976 maFont
.SetCharSet( gsl_getSystemTextEncoding() ); // the default font then most times a x11 font is used, we
977 maFont
.SetHeight( 423 ); // will prevent this defining a font
979 maLatestLineStyle
.aLineColor
= Color( 0x12, 0x34, 0x56 );
980 maLatestFillStyle
.aFillColor
= Color( 0x12, 0x34, 0x56 );
982 mnRop
= R2_BLACK
+ 1;
983 SetRasterOp( R2_BLACK
);
986 //-----------------------------------------------------------------------------------
988 WinMtfOutput::~WinMtfOutput()
990 mpGDIMetaFile
->AddAction( new MetaPopAction() );
991 mpGDIMetaFile
->SetPrefMapMode( MAP_100TH_MM
);
992 if ( mrclFrame
.IsEmpty() )
993 mpGDIMetaFile
->SetPrefSize( Size( mnDevWidth
, mnDevHeight
) );
995 mpGDIMetaFile
->SetPrefSize( mrclFrame
.GetSize() );
997 for ( UINT32 i
= 0; i
< vGDIObj
.size(); i
++ )
1001 //-----------------------------------------------------------------------------------
1003 void WinMtfOutput::UpdateClipRegion()
1005 if ( aClipPath
.bNeedsUpdate
)
1007 aClipPath
.bNeedsUpdate
= sal_False
;
1009 mpGDIMetaFile
->AddAction( new MetaPopAction() ); // taking the orignal clipregion
1010 mpGDIMetaFile
->AddAction( new MetaPushAction( PUSH_CLIPREGION
) ); //
1012 switch ( aClipPath
.GetType() )
1017 // we will not generate a RegionClipRegion Action, because this action
1018 // cannot be saved to the wmf format - saving to wmf always happens
1019 // if the placeholder graphic for ole objects is generated. (SJ)
1021 // Region aClipRegion( aClipPath.GetClipPath() );
1022 // mpGDIMetaFile->AddAction( new MetaISectRegionClipRegionAction( aClipRegion ) );
1024 Rectangle
aClipRect( aClipPath
.GetClipPath().GetBoundRect() );
1025 mpGDIMetaFile
->AddAction( new MetaISectRectClipRegionAction( aClipRect
) );
1029 break; // -Wall not handled.
1034 //-----------------------------------------------------------------------------------
1036 void WinMtfOutput::ImplSetNonPersistentLineColorTransparenz()
1038 Color
aColor( COL_TRANSPARENT
);
1039 WinMtfLineStyle
aTransparentLine( aColor
, TRUE
);
1040 if ( ! ( maLatestLineStyle
== aTransparentLine
) )
1042 maLatestLineStyle
= aTransparentLine
;
1043 mpGDIMetaFile
->AddAction( new MetaLineColorAction( aTransparentLine
.aLineColor
, !aTransparentLine
.bTransparent
) );
1047 //-----------------------------------------------------------------------------------
1049 void WinMtfOutput::UpdateLineStyle()
1051 if (!( maLatestLineStyle
== maLineStyle
) )
1053 maLatestLineStyle
= maLineStyle
;
1054 mpGDIMetaFile
->AddAction( new MetaLineColorAction( maLineStyle
.aLineColor
, !maLineStyle
.bTransparent
) );
1058 //-----------------------------------------------------------------------------------
1060 void WinMtfOutput::UpdateFillStyle()
1062 if ( !mbFillStyleSelected
) // SJ: #i57205# taking care of bkcolor if no brush is selected
1063 maFillStyle
= WinMtfFillStyle( maBkColor
, mnBkMode
== TRANSPARENT
);
1064 if (!( maLatestFillStyle
== maFillStyle
) )
1066 maLatestFillStyle
= maFillStyle
;
1067 if (maFillStyle
.aType
== FillStyleSolid
)
1068 mpGDIMetaFile
->AddAction( new MetaFillColorAction( maFillStyle
.aFillColor
, !maFillStyle
.bTransparent
) );
1072 //-----------------------------------------------------------------------------------
1074 sal_uInt32
WinMtfOutput::SetRasterOp( UINT32 nRasterOp
)
1076 sal_uInt32 nRetROP
= mnRop
;
1077 if ( nRasterOp
!= mnRop
)
1080 static WinMtfFillStyle aNopFillStyle
;
1081 static WinMtfLineStyle aNopLineStyle
;
1083 if ( mbNopMode
&& ( nRasterOp
!= R2_NOP
) )
1084 { // beim uebergang von R2_NOP auf anderen Modus
1085 // gesetzten Pen und Brush aktivieren
1086 maFillStyle
= aNopFillStyle
;
1087 maLineStyle
= aNopLineStyle
;
1088 mbNopMode
= sal_False
;
1093 meRasterOp
= ROP_INVERT
;
1097 meRasterOp
= ROP_XOR
;
1102 meRasterOp
= ROP_OVERPAINT
;
1103 if( mbNopMode
== sal_False
)
1105 aNopFillStyle
= maFillStyle
;
1106 aNopLineStyle
= maLineStyle
;
1107 maFillStyle
= WinMtfFillStyle( Color( COL_TRANSPARENT
), TRUE
);
1108 maLineStyle
= WinMtfLineStyle( Color( COL_TRANSPARENT
), TRUE
);
1109 mbNopMode
= sal_True
;
1115 meRasterOp
= ROP_OVERPAINT
;
1119 if ( nRetROP
!= nRasterOp
)
1120 mpGDIMetaFile
->AddAction( new MetaRasterOpAction( meRasterOp
) );
1124 //-----------------------------------------------------------------------------------
1126 void WinMtfOutput::StrokeAndFillPath( sal_Bool bStroke
, sal_Bool bFill
)
1128 if ( aPathObj
.Count() )
1137 mpGDIMetaFile
->AddAction( new MetaPushAction( PUSH_LINECOLOR
) );
1138 mpGDIMetaFile
->AddAction( new MetaLineColorAction( Color(), FALSE
) );
1140 if ( aPathObj
.Count() == 1 )
1141 mpGDIMetaFile
->AddAction( new MetaPolygonAction( aPathObj
.GetObject( 0 ) ) );
1143 mpGDIMetaFile
->AddAction( new MetaPolyPolygonAction( aPathObj
) );
1146 mpGDIMetaFile
->AddAction( new MetaPopAction() );
1150 sal_uInt16 i
, nCount
= aPathObj
.Count();
1151 for ( i
= 0; i
< nCount
; i
++ )
1152 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( aPathObj
[ i
], maLineStyle
.aLineInfo
) );
1158 //-----------------------------------------------------------------------------------
1160 void WinMtfOutput::DrawPixel( const Point
& rSource
, const Color
& rColor
)
1162 mpGDIMetaFile
->AddAction( new MetaPixelAction( ImplMap( rSource
), rColor
) );
1165 //-----------------------------------------------------------------------------------
1167 void WinMtfOutput::MoveTo( const Point
& rPoint
, sal_Bool bRecordPath
)
1169 Point
aDest( ImplMap( rPoint
) );
1171 aPathObj
.AddPoint( aDest
);
1175 //-----------------------------------------------------------------------------------
1177 void WinMtfOutput::LineTo( const Point
& rPoint
, sal_Bool bRecordPath
)
1181 Point
aDest( ImplMap( rPoint
) );
1183 aPathObj
.AddPoint( aDest
);
1187 mpGDIMetaFile
->AddAction( new MetaLineAction( maActPos
, aDest
, maLineStyle
.aLineInfo
) );
1192 //-----------------------------------------------------------------------------------
1194 void WinMtfOutput::DrawLine( const Point
& rSource
, const Point
& rDest
)
1198 mpGDIMetaFile
->AddAction( new MetaLineAction( ImplMap( rSource
), ImplMap( rDest
), maLineStyle
.aLineInfo
) );
1201 //-----------------------------------------------------------------------------------
1203 void WinMtfOutput::DrawRect( const Rectangle
& rRect
, BOOL bEdge
)
1208 if ( aClipPath
.GetType() == COMPLEX
)
1210 Polygon
aPoly( ImplMap( rRect
) );
1211 PolyPolygon
aPolyPolyRect( aPoly
);
1213 aClipPath
.GetClipPath().GetIntersection( aPolyPolyRect
, aDest
);
1214 ImplDrawClippedPolyPolygon( aDest
);
1220 if ( maLineStyle
.aLineInfo
.GetWidth() || ( maLineStyle
.aLineInfo
.GetStyle() == LINE_DASH
) )
1222 ImplSetNonPersistentLineColorTransparenz();
1223 mpGDIMetaFile
->AddAction( new MetaRectAction( ImplMap( rRect
) ) );
1225 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect
) ),maLineStyle
.aLineInfo
) );
1230 mpGDIMetaFile
->AddAction( new MetaRectAction( ImplMap( rRect
) ) );
1235 ImplSetNonPersistentLineColorTransparenz();
1236 mpGDIMetaFile
->AddAction( new MetaRectAction( ImplMap( rRect
) ) );
1241 //-----------------------------------------------------------------------------------
1243 void WinMtfOutput::DrawRoundRect( const Rectangle
& rRect
, const Size
& rSize
)
1248 mpGDIMetaFile
->AddAction( new MetaRoundRectAction( ImplMap( rRect
), labs( ImplMap( rSize
).Width() ), labs( ImplMap( rSize
).Height() ) ) );
1251 //-----------------------------------------------------------------------------------
1253 void WinMtfOutput::DrawEllipse( const Rectangle
& rRect
)
1258 if ( maLineStyle
.aLineInfo
.GetWidth() || ( maLineStyle
.aLineInfo
.GetStyle() == LINE_DASH
) )
1260 Point
aCenter( ImplMap( rRect
.Center() ) );
1261 Size
aRad( ImplMap( Size( rRect
.GetWidth() / 2, rRect
.GetHeight() / 2 ) ) );
1263 ImplSetNonPersistentLineColorTransparenz();
1264 mpGDIMetaFile
->AddAction( new MetaEllipseAction( ImplMap( rRect
) ) );
1266 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( Polygon( aCenter
, aRad
.Width(), aRad
.Height() ), maLineStyle
.aLineInfo
) );
1271 mpGDIMetaFile
->AddAction( new MetaEllipseAction( ImplMap( rRect
) ) );
1275 //-----------------------------------------------------------------------------------
1277 void WinMtfOutput::DrawArc( const Rectangle
& rRect
, const Point
& rStart
, const Point
& rEnd
, BOOL bTo
)
1283 Rectangle
aRect( ImplMap( rRect
) );
1284 Point
aStart( ImplMap( rStart
) );
1285 Point
aEnd( ImplMap( rEnd
) );
1287 if ( maLineStyle
.aLineInfo
.GetWidth() || ( maLineStyle
.aLineInfo
.GetStyle() == LINE_DASH
) )
1289 if ( aStart
== aEnd
)
1290 { // SJ: #i53768# if start & end is identical, then we have to draw a full ellipse
1291 Point
aCenter( aRect
.Center() );
1292 Size
aRad( aRect
.GetWidth() / 2, aRect
.GetHeight() / 2 );
1294 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( Polygon( aCenter
, aRad
.Width(), aRad
.Height() ), maLineStyle
.aLineInfo
) );
1297 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( Polygon( aRect
, aStart
, aEnd
, POLY_ARC
), maLineStyle
.aLineInfo
) );
1300 mpGDIMetaFile
->AddAction( new MetaArcAction( aRect
, aStart
, aEnd
) );
1306 //-----------------------------------------------------------------------------------
1308 void WinMtfOutput::DrawPie( const Rectangle
& rRect
, const Point
& rStart
, const Point
& rEnd
)
1313 Rectangle
aRect( ImplMap( rRect
) );
1314 Point
aStart( ImplMap( rStart
) );
1315 Point
aEnd( ImplMap( rEnd
) );
1317 if ( maLineStyle
.aLineInfo
.GetWidth() || ( maLineStyle
.aLineInfo
.GetStyle() == LINE_DASH
) )
1319 ImplSetNonPersistentLineColorTransparenz();
1320 mpGDIMetaFile
->AddAction( new MetaPieAction( aRect
, aStart
, aEnd
) );
1322 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( Polygon( aRect
, aStart
, aEnd
, POLY_PIE
), maLineStyle
.aLineInfo
) );
1327 mpGDIMetaFile
->AddAction( new MetaPieAction( aRect
, aStart
, aEnd
) );
1331 //-----------------------------------------------------------------------------------
1333 void WinMtfOutput::DrawChord( const Rectangle
& rRect
, const Point
& rStart
, const Point
& rEnd
)
1338 Rectangle
aRect( ImplMap( rRect
) );
1339 Point
aStart( ImplMap( rStart
) );
1340 Point
aEnd( ImplMap( rEnd
) );
1342 if ( maLineStyle
.aLineInfo
.GetWidth() || ( maLineStyle
.aLineInfo
.GetStyle() == LINE_DASH
) )
1344 ImplSetNonPersistentLineColorTransparenz();
1345 mpGDIMetaFile
->AddAction( new MetaChordAction( aRect
, aStart
, aEnd
) );
1347 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( Polygon( aRect
, aStart
, aEnd
, POLY_CHORD
), maLineStyle
.aLineInfo
) );
1352 mpGDIMetaFile
->AddAction( new MetaChordAction( aRect
, aStart
, aEnd
) );
1356 //-----------------------------------------------------------------------------------
1358 void WinMtfOutput::DrawPolygon( Polygon
& rPolygon
, sal_Bool bRecordPath
)
1361 ImplMap( rPolygon
);
1363 aPathObj
.AddPolygon( rPolygon
);
1368 if ( aClipPath
.GetType() == COMPLEX
)
1370 PolyPolygon
aPolyPoly( rPolygon
);
1372 aClipPath
.GetClipPath().GetIntersection( aPolyPoly
, aDest
);
1373 ImplDrawClippedPolyPolygon( aDest
);
1377 if ( maLineStyle
.aLineInfo
.GetWidth() || ( maLineStyle
.aLineInfo
.GetStyle() == LINE_DASH
) )
1379 USHORT nCount
= rPolygon
.GetSize();
1382 if ( rPolygon
[ nCount
- 1 ] != rPolygon
[ 0 ] )
1384 Point
aPoint( rPolygon
[ 0 ] );
1385 rPolygon
.Insert( nCount
, aPoint
);
1388 ImplSetNonPersistentLineColorTransparenz();
1389 mpGDIMetaFile
->AddAction( new MetaPolygonAction( rPolygon
) );
1391 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( rPolygon
, maLineStyle
.aLineInfo
) );
1397 if (maLatestFillStyle
.aType
!= FillStylePattern
)
1398 mpGDIMetaFile
->AddAction( new MetaPolygonAction( rPolygon
) );
1400 SvtGraphicFill aFill
= SvtGraphicFill( PolyPolygon( rPolygon
),
1403 SvtGraphicFill::fillNonZero
,
1404 SvtGraphicFill::fillTexture
,
1405 SvtGraphicFill::Transform(),
1407 SvtGraphicFill::hatchSingle
,
1409 SvtGraphicFill::gradientLinear
,
1413 Graphic (maLatestFillStyle
.aBmp
) );
1415 SvMemoryStream aMemStm
;
1419 mpGDIMetaFile
->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
1420 static_cast<const BYTE
*>(aMemStm
.GetData()),
1421 aMemStm
.Seek( STREAM_SEEK_TO_END
) ) );
1422 mpGDIMetaFile
->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_END" ) );
1430 //-----------------------------------------------------------------------------------
1432 void WinMtfOutput::DrawPolyPolygon( PolyPolygon
& rPolyPolygon
, sal_Bool bRecordPath
)
1436 ImplMap( rPolyPolygon
);
1439 aPathObj
.AddPolyPolygon( rPolyPolygon
);
1444 if ( aClipPath
.GetType() == COMPLEX
)
1447 aClipPath
.GetClipPath().GetIntersection( rPolyPolygon
, aDest
);
1448 ImplDrawClippedPolyPolygon( aDest
);
1453 mpGDIMetaFile
->AddAction( new MetaPolyPolygonAction( rPolyPolygon
) );
1458 //-----------------------------------------------------------------------------------
1460 void WinMtfOutput::DrawPolyLine( Polygon
& rPolygon
, sal_Bool bTo
, sal_Bool bRecordPath
)
1464 ImplMap( rPolygon
);
1467 rPolygon
[ 0 ] = maActPos
;
1468 maActPos
= rPolygon
[ rPolygon
.GetSize() - 1 ];
1471 aPathObj
.AddPolyLine( rPolygon
);
1475 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( rPolygon
, maLineStyle
.aLineInfo
) );
1479 //-----------------------------------------------------------------------------------
1481 void WinMtfOutput::DrawPolyBezier( Polygon
& rPolygon
, sal_Bool bTo
, sal_Bool bRecordPath
)
1485 sal_uInt16 nPoints
= rPolygon
.GetSize();
1486 if ( ( nPoints
>= 4 ) && ( ( ( nPoints
- 4 ) % 3 ) == 0 ) )
1488 ImplMap( rPolygon
);
1491 rPolygon
[ 0 ] = maActPos
;
1492 maActPos
= rPolygon
[ nPoints
- 1 ];
1495 for ( i
= 0; ( i
+ 2 ) < nPoints
; )
1497 rPolygon
.SetFlags( i
++, POLY_NORMAL
);
1498 rPolygon
.SetFlags( i
++, POLY_CONTROL
);
1499 rPolygon
.SetFlags( i
++, POLY_CONTROL
);
1502 aPathObj
.AddPolyLine( rPolygon
);
1506 mpGDIMetaFile
->AddAction( new MetaPolyLineAction( rPolygon
, maLineStyle
.aLineInfo
) );
1511 //-----------------------------------------------------------------------------------
1513 void WinMtfOutput::DrawText( Point
& rPosition
, String
& rText
, sal_Int32
* pDXArry
, sal_Bool bRecordPath
, sal_Int32 nGfxMode
)
1517 VirtualDevice
* pVDev
= NULL
;
1519 rPosition
= ImplMap( rPosition
);
1521 sal_Int32 nOldGfxMode
= GetGfxMode();
1522 SetGfxMode( GM_COMPATIBLE
);
1525 sal_Int32 i
, nSum
, nLen
= rText
.Len();
1527 for( i
= 0, nSum
= 0; i
< nLen
; i
++ )
1529 sal_Int32 nTemp
= ImplMap( Size( pDXArry
[ i
], 0 ) ).Width();
1531 pDXArry
[ i
] = nSum
;
1534 if ( mnLatestTextLayoutMode
!= mnTextLayoutMode
)
1536 mnLatestTextLayoutMode
= mnTextLayoutMode
;
1537 mpGDIMetaFile
->AddAction( new MetaLayoutModeAction( mnTextLayoutMode
) );
1539 SetGfxMode( nGfxMode
);
1540 sal_Bool bChangeFont
= sal_False
;
1541 if ( mnLatestTextAlign
!= mnTextAlign
)
1543 bChangeFont
= sal_True
;
1544 mnLatestTextAlign
= mnTextAlign
;
1545 TextAlign eTextAlign
;
1546 if ( ( mnTextAlign
& TA_BASELINE
) == TA_BASELINE
)
1547 eTextAlign
= ALIGN_BASELINE
;
1548 else if( ( mnTextAlign
& TA_BOTTOM
) == TA_BOTTOM
)
1549 eTextAlign
= ALIGN_BOTTOM
;
1551 eTextAlign
= ALIGN_TOP
;
1552 mpGDIMetaFile
->AddAction( new MetaTextAlignAction( eTextAlign
) );
1554 if ( maLatestTextColor
!= maTextColor
)
1556 bChangeFont
= sal_True
;
1557 maLatestTextColor
= maTextColor
;
1558 mpGDIMetaFile
->AddAction( new MetaTextColorAction( maTextColor
) );
1560 sal_Bool bChangeFillColor
= sal_False
;
1561 if ( maLatestBkColor
!= maBkColor
)
1563 bChangeFillColor
= sal_True
;
1564 maLatestBkColor
= maBkColor
;
1566 if ( mnLatestBkMode
!= mnBkMode
)
1568 bChangeFillColor
= sal_True
;
1569 mnLatestBkMode
= mnBkMode
;
1571 if ( bChangeFillColor
)
1573 bChangeFont
= sal_True
;
1574 mpGDIMetaFile
->AddAction( new MetaTextFillColorAction( maFont
.GetFillColor(), !maFont
.IsTransparent() ) );
1576 Font
aTmp( maFont
);
1577 aTmp
.SetColor( maTextColor
);
1578 aTmp
.SetFillColor( maBkColor
);
1580 if( mnBkMode
== TRANSPARENT
)
1581 maFont
.SetTransparent( sal_True
);
1583 maFont
.SetTransparent( sal_False
);
1585 if ( ( mnTextAlign
& TA_BASELINE
) == TA_BASELINE
)
1586 aTmp
.SetAlign( ALIGN_BASELINE
);
1587 else if( ( mnTextAlign
& TA_BOTTOM
) == TA_BOTTOM
)
1588 aTmp
.SetAlign( ALIGN_BOTTOM
);
1590 aTmp
.SetAlign( ALIGN_TOP
);
1592 if ( nGfxMode
== GM_ADVANCED
)
1594 // check whether there is a font rotation applied via transformation
1595 Point
aP1( ImplMap( Point() ) );
1596 Point
aP2( ImplMap( Point( 0, 100 ) ) );
1599 double fX
= aP2
.X();
1600 double fY
= aP2
.Y();
1603 double fOrientation
= acos( fX
/ sqrt( fX
* fX
+ fY
* fY
) ) * 57.29577951308;
1605 fOrientation
= 360 - fOrientation
;
1608 fOrientation
+= aTmp
.GetOrientation();
1609 aTmp
.SetOrientation( sal_Int16( fOrientation
) );
1613 if( mnTextAlign
& ( TA_UPDATECP
| TA_RIGHT_CENTER
) )
1616 pVDev
= new VirtualDevice
;
1617 sal_Int32 nTextWidth
;
1618 pVDev
->SetMapMode( MapMode( MAP_100TH_MM
) );
1619 pVDev
->SetFont( maFont
);
1622 UINT32 nLen
= rText
.Len();
1623 nTextWidth
= pVDev
->GetTextWidth( rText
.GetChar( (sal_uInt16
)( nLen
- 1 ) ) );
1625 nTextWidth
+= pDXArry
[ nLen
- 2 ];
1628 nTextWidth
= pVDev
->GetTextWidth( rText
);
1630 if( mnTextAlign
& TA_UPDATECP
)
1631 rPosition
= maActPos
;
1633 if ( mnTextAlign
& TA_RIGHT_CENTER
)
1635 double fLenght
= ( ( mnTextAlign
& TA_RIGHT_CENTER
) == TA_RIGHT
) ? nTextWidth
: nTextWidth
>> 1;
1636 rPosition
.X() -= (sal_Int32
)( fLenght
* cos( maFont
.GetOrientation() * F_PI1800
) );
1637 rPosition
.Y() -= (sal_Int32
)(-( fLenght
* sin( maFont
.GetOrientation() * F_PI1800
) ) );
1640 if( mnTextAlign
& TA_UPDATECP
)
1641 maActPos
.X() = rPosition
.X() + nTextWidth
;
1643 if ( bChangeFont
|| ( maLatestFont
!= aTmp
) )
1645 maLatestFont
= aTmp
;
1646 mpGDIMetaFile
->AddAction( new MetaFontAction( aTmp
) );
1647 mpGDIMetaFile
->AddAction( new MetaTextAlignAction( aTmp
.GetAlign() ) );
1648 mpGDIMetaFile
->AddAction( new MetaTextColorAction( aTmp
.GetColor() ) );
1649 mpGDIMetaFile
->AddAction( new MetaTextFillColorAction( aTmp
.GetFillColor(), !aTmp
.IsTransparent() ) );
1657 /* because text without dx array is badly scaled, we
1658 will create such an array if necessary */
1659 sal_Int32
* pDX
= pDXArry
;
1662 pDX
= new sal_Int32
[ rText
.Len() ];
1664 pVDev
= new VirtualDevice
;
1665 pVDev
->SetMapMode( MAP_100TH_MM
);
1666 pVDev
->SetFont( maLatestFont
);
1667 pVDev
->GetTextArray( rText
, pDX
, 0, STRING_LEN
);
1669 mpGDIMetaFile
->AddAction( new MetaTextArrayAction( rPosition
, rText
, pDX
, 0, STRING_LEN
) );
1670 if ( !pDXArry
) // this means we have created our own array
1671 delete[] pDX
; // which must be deleted
1673 SetGfxMode( nOldGfxMode
);
1677 //-----------------------------------------------------------------------------------
1679 void WinMtfOutput::ImplDrawBitmap( const Point
& rPos
, const Size
& rSize
, const BitmapEx rBitmap
)
1681 BitmapEx
aBmpEx( rBitmap
);
1682 if ( aClipPath
.GetType() == COMPLEX
)
1684 VirtualDevice aVDev
;
1685 MapMode
aMapMode( MAP_100TH_MM
);
1686 aMapMode
.SetOrigin( Point( -rPos
.X(), -rPos
.Y() ) );
1687 const Size
aOutputSizePixel( aVDev
.LogicToPixel( rSize
, aMapMode
) );
1688 const Size
aSizePixel( rBitmap
.GetSizePixel() );
1689 if ( aOutputSizePixel
.Width() && aOutputSizePixel
.Height() )
1691 aMapMode
.SetScaleX( Fraction( aSizePixel
.Width(), aOutputSizePixel
.Width() ) );
1692 aMapMode
.SetScaleY( Fraction( aSizePixel
.Height(), aOutputSizePixel
.Height() ) );
1694 aVDev
.SetMapMode( aMapMode
);
1695 aVDev
.SetOutputSizePixel( aSizePixel
);
1696 aVDev
.SetFillColor( Color( COL_BLACK
) );
1697 const PolyPolygon
aClip( aClipPath
.GetClipPath() );
1698 aVDev
.DrawPolyPolygon( aClip
);
1699 const Point aEmptyPoint
;
1701 // #i50672# Extract whole VDev content (to match size of rBitmap)
1702 aVDev
.EnableMapMode( FALSE
);
1703 Bitmap
aMask( aVDev
.GetBitmap( aEmptyPoint
, aSizePixel
).CreateMask( Color( COL_WHITE
) ) );
1705 if ( aBmpEx
.IsTransparent() )
1707 if ( rBitmap
.GetTransparentColor() == Color( COL_WHITE
) )
1708 aMask
.CombineSimple( rBitmap
.GetMask(), BMP_COMBINE_OR
);
1710 aMask
.CombineSimple( rBitmap
.GetMask(), BMP_COMBINE_AND
);
1711 aBmpEx
= BitmapEx( rBitmap
.GetBitmap(), aMask
);
1714 aBmpEx
= BitmapEx( rBitmap
.GetBitmap(), aMask
);
1716 if ( aBmpEx
.IsTransparent() )
1717 mpGDIMetaFile
->AddAction( new MetaBmpExScaleAction( rPos
, rSize
, aBmpEx
) );
1719 mpGDIMetaFile
->AddAction( new MetaBmpScaleAction( rPos
, rSize
, aBmpEx
.GetBitmap() ) );
1722 //-----------------------------------------------------------------------------------
1724 void WinMtfOutput::ResolveBitmapActions( List
& rSaveList
)
1728 sal_uInt32 nObjects
= rSaveList
.Count();
1729 sal_uInt32 nObjectsLeft
= nObjects
;
1731 while ( nObjectsLeft
)
1733 sal_uInt32 i
, nObjectsOfSameSize
= 0;
1734 sal_uInt32 nObjectStartIndex
= nObjects
- nObjectsLeft
;
1736 BSaveStruct
* pSave
= (BSaveStruct
*)rSaveList
.GetObject( nObjectStartIndex
);
1737 Rectangle
aRect( pSave
->aOutRect
);
1739 for ( i
= nObjectStartIndex
; i
< nObjects
; )
1741 nObjectsOfSameSize
++;
1742 if ( ++i
< nObjects
)
1744 pSave
= (BSaveStruct
*)rSaveList
.GetObject( i
);
1745 if ( pSave
->aOutRect
!= aRect
)
1749 Point
aPos( ImplMap( aRect
.TopLeft() ) );
1750 Size
aSize( ImplMap( aRect
.GetSize() ) );
1752 for ( i
= nObjectStartIndex
; i
< ( nObjectStartIndex
+ nObjectsOfSameSize
); i
++ )
1754 pSave
= (BSaveStruct
*)rSaveList
.GetObject( i
);
1756 sal_uInt32 nWinRop
= pSave
->nWinRop
;
1757 sal_uInt8 nRasterOperation
= (sal_uInt8
)( nWinRop
>> 16 );
1759 sal_uInt32 nUsed
= 0;
1760 if ( ( nRasterOperation
& 0xf ) != ( nRasterOperation
>> 4 ) )
1761 nUsed
|= 1; // pattern is used
1762 if ( ( nRasterOperation
& 0x33 ) != ( ( nRasterOperation
& 0xcc ) >> 2 ) )
1763 nUsed
|= 2; // source is used
1764 if ( ( nRasterOperation
& 0xaa ) != ( ( nRasterOperation
& 0x55 ) << 1 ) )
1765 nUsed
|= 4; // destination is used
1767 if ( (nUsed
& 1) && (( nUsed
& 2 ) == 0) && nWinRop
!= PATINVERT
)
1768 { // patterns aren't well supported yet
1769 sal_uInt32 nOldRop
= SetRasterOp( ROP_OVERPAINT
); // in this case nRasterOperation is either 0 or 0xff
1771 DrawRect( aRect
, FALSE
);
1772 SetRasterOp( nOldRop
);
1776 sal_Bool bDrawn
= sal_False
;
1778 if ( i
== nObjectStartIndex
) // optimizing, sometimes it is possible to create just one transparent bitmap
1780 if ( nObjectsOfSameSize
== 2 )
1782 BSaveStruct
* pSave2
= (BSaveStruct
*)rSaveList
.GetObject( i
+ 1 );
1783 if ( ( pSave
->aBmp
.GetPrefSize() == pSave2
->aBmp
.GetPrefSize() ) &&
1784 ( pSave
->aBmp
.GetPrefMapMode() == pSave2
->aBmp
.GetPrefMapMode() ) )
1786 // TODO: Strictly speaking, we should
1787 // check whether mask is monochrome, and
1788 // whether image is black (upper branch)
1789 // or white (lower branch). Otherwise, the
1790 // effect is not the same as a masked
1792 if ( ( nWinRop
== SRCPAINT
) && ( pSave2
->nWinRop
== SRCAND
) )
1794 Bitmap
aMask( pSave
->aBmp
); aMask
.Invert();
1795 BitmapEx
aBmpEx( pSave2
->aBmp
, aMask
);
1796 ImplDrawBitmap( aPos
, aSize
, aBmpEx
);
1800 // #i20085# This is just the other way
1801 // around as above. Only difference: mask
1803 else if ( ( nWinRop
== SRCAND
) && ( pSave2
->nWinRop
== SRCPAINT
) )
1805 Bitmap
aMask( pSave
->aBmp
);
1806 BitmapEx
aBmpEx( pSave2
->aBmp
, aMask
);
1807 ImplDrawBitmap( aPos
, aSize
, aBmpEx
);
1818 sal_uInt32 nOldRop
= SetRasterOp( R2_COPYPEN
);
1819 Bitmap
aBitmap( pSave
->aBmp
);
1820 sal_uInt32 nOperation
= ( nRasterOperation
& 0xf );
1821 switch( nOperation
)
1826 SetRasterOp( R2_XORPEN
);
1827 ImplDrawBitmap( aPos
, aSize
, aBitmap
);
1828 SetRasterOp( R2_COPYPEN
);
1829 Bitmap
aMask( aBitmap
);
1831 BitmapEx
aBmpEx( aBitmap
, aMask
);
1832 ImplDrawBitmap( aPos
, aSize
, aBmpEx
);
1833 if ( nOperation
== 0x1 )
1835 SetRasterOp( R2_NOT
);
1836 DrawRect( aRect
, FALSE
);
1843 Bitmap
aMask( aBitmap
);
1844 if ( ( nUsed
& 1 ) && ( nRasterOperation
& 0xb0 ) == 0xb0 ) // pattern used
1846 aBitmap
.Convert( BMP_CONVERSION_24BIT
);
1847 aBitmap
.Erase( maFillStyle
.aFillColor
);
1849 BitmapEx
aBmpEx( aBitmap
, aMask
);
1850 ImplDrawBitmap( aPos
, aSize
, aBmpEx
);
1851 if ( nOperation
== 0x7 )
1853 SetRasterOp( R2_NOT
);
1854 DrawRect( aRect
, FALSE
);
1862 SetRasterOp( R2_NOT
);
1863 DrawRect( aRect
, FALSE
);
1864 SetRasterOp( R2_COPYPEN
);
1865 Bitmap
aMask( aBitmap
);
1867 BitmapEx
aBmpEx( aBitmap
, aMask
);
1868 ImplDrawBitmap( aPos
, aSize
, aBmpEx
);
1869 SetRasterOp( R2_XORPEN
);
1870 ImplDrawBitmap( aPos
, aSize
, aBitmap
);
1871 if ( nOperation
== 0xb )
1873 SetRasterOp( R2_NOT
);
1874 DrawRect( aRect
, FALSE
);
1882 Bitmap
aMask( aBitmap
);
1884 BitmapEx
aBmpEx( aBitmap
, aMask
);
1885 ImplDrawBitmap( aPos
, aSize
, aBmpEx
);
1886 SetRasterOp( R2_XORPEN
);
1887 ImplDrawBitmap( aPos
, aSize
, aBitmap
);
1888 if ( nOperation
== 0xd )
1890 SetRasterOp( R2_NOT
);
1891 DrawRect( aRect
, FALSE
);
1898 SetRasterOp( R2_XORPEN
);
1899 ImplDrawBitmap( aPos
, aSize
, aBitmap
);
1900 if ( nOperation
== 0x9 )
1902 SetRasterOp( R2_NOT
);
1903 DrawRect( aRect
, FALSE
);
1908 case 0x0 : // WHITENESS
1909 case 0xf : // BLACKNESS
1910 { // in this case nRasterOperation is either 0 or 0xff
1911 maFillStyle
= WinMtfFillStyle( Color( nRasterOperation
, nRasterOperation
, nRasterOperation
) );
1913 DrawRect( aRect
, FALSE
);
1917 case 0x3 : // only source is used
1920 if ( nRasterOperation
== 0x33 )
1922 ImplDrawBitmap( aPos
, aSize
, aBitmap
);
1926 case 0x5 : // only destination is used
1928 SetRasterOp( R2_NOT
);
1929 DrawRect( aRect
, FALSE
);
1931 case 0xa : // no operation
1934 SetRasterOp( nOldRop
);
1939 nObjectsLeft
-= nObjectsOfSameSize
;
1943 for ( pPtr
= rSaveList
.First(); pPtr
; pPtr
= rSaveList
.Next() )
1944 delete (BSaveStruct
*)pPtr
;
1948 //-----------------------------------------------------------------------------------
1950 void WinMtfOutput::SetDevOrg( const Point
& rPoint
)
1952 mnDevOrgX
= rPoint
.X();
1953 mnDevOrgY
= rPoint
.Y();
1956 //-----------------------------------------------------------------------------------
1958 void WinMtfOutput::SetDevOrgOffset( INT32 nXAdd
, INT32 nYAdd
)
1964 //-----------------------------------------------------------------------------------
1966 void WinMtfOutput::SetDevExt( const Size
& rSize
)
1968 if ( rSize
.Width() && rSize
.Height() )
1973 case MM_ANISOTROPIC
:
1975 mnDevWidth
= rSize
.Width();
1976 mnDevHeight
= rSize
.Height();
1982 //-----------------------------------------------------------------------------------
1984 void WinMtfOutput::ScaleDevExt( double fX
, double fY
)
1986 mnDevWidth
= FRound( mnDevWidth
* fX
);
1987 mnDevHeight
= FRound( mnDevHeight
* fY
);
1990 //-----------------------------------------------------------------------------------
1992 void WinMtfOutput::SetWinOrg( const Point
& rPoint
)
1994 mnWinOrgX
= rPoint
.X();
1995 mnWinOrgY
= rPoint
.Y();
1998 //-----------------------------------------------------------------------------------
2000 void WinMtfOutput::SetWinOrgOffset( INT32 nXAdd
, INT32 nYAdd
)
2006 //-----------------------------------------------------------------------------------
2008 void WinMtfOutput::SetWinExt( const Size
& rSize
)
2011 if( rSize
.Width() && rSize
.Height() )
2016 case MM_ANISOTROPIC
:
2018 mnWinExtX
= rSize
.Width();
2019 mnWinExtY
= rSize
.Height();
2025 //-----------------------------------------------------------------------------------
2027 void WinMtfOutput::ScaleWinExt( double fX
, double fY
)
2029 mnWinExtX
= FRound( mnWinExtX
* fX
);
2030 mnWinExtY
= FRound( mnWinExtY
* fY
);
2033 //-----------------------------------------------------------------------------------
2035 void WinMtfOutput::SetrclBounds( const Rectangle
& rRect
)
2040 //-----------------------------------------------------------------------------------
2042 void WinMtfOutput::SetrclFrame( const Rectangle
& rRect
)
2047 //-----------------------------------------------------------------------------------
2049 void WinMtfOutput::SetRefPix( const Size
& rSize
)
2051 mnPixX
= rSize
.Width();
2052 mnPixY
= rSize
.Height();
2055 //-----------------------------------------------------------------------------------
2057 void WinMtfOutput::SetRefMill( const Size
& rSize
)
2059 mnMillX
= rSize
.Width();
2060 mnMillY
= rSize
.Height();
2063 //-----------------------------------------------------------------------------------
2065 void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode
)
2067 mnMapMode
= nMapMode
;
2068 if ( nMapMode
== MM_TEXT
)
2070 mnWinExtX
= mnDevWidth
;
2071 mnWinExtY
= mnDevHeight
;
2073 else if ( mnMapMode
== MM_HIMETRIC
)
2075 mnWinExtX
= mnMillX
* 100;
2076 mnWinExtY
= mnMillY
* 100;
2080 //-----------------------------------------------------------------------------------
2082 void WinMtfOutput::SetUnitsPerInch( UINT16 nUnitsPerInch
)
2084 if( nUnitsPerInch
!= 0 )
2085 mnUnitsPerInch
= nUnitsPerInch
;
2088 //-----------------------------------------------------------------------------------
2090 void WinMtfOutput::SetWorldTransform( const XForm
& rXForm
)
2092 maXForm
.eM11
= rXForm
.eM11
;
2093 maXForm
.eM12
= rXForm
.eM12
;
2094 maXForm
.eM21
= rXForm
.eM21
;
2095 maXForm
.eM22
= rXForm
.eM22
;
2096 maXForm
.eDx
= rXForm
.eDx
;
2097 maXForm
.eDy
= rXForm
.eDy
;
2100 //-----------------------------------------------------------------------------------
2102 void WinMtfOutput::ModifyWorldTransform( const XForm
& rXForm
, UINT32 nMode
)
2108 maXForm
.eM11
= maXForm
.eM12
= maXForm
.eM21
= maXForm
.eM22
= 1.0f
;
2109 maXForm
.eDx
= maXForm
.eDx
= 0.0f
;
2113 case MWT_RIGHTMULTIPLY
:
2114 case MWT_LEFTMULTIPLY
:
2117 const XForm
* pRight
;
2119 if ( nMode
== MWT_LEFTMULTIPLY
)
2134 aF
[0][0] = pLeft
->eM11
;
2135 aF
[0][1] = pLeft
->eM12
;
2137 aF
[1][0] = pLeft
->eM21
;
2138 aF
[1][1] = pLeft
->eM22
;
2140 aF
[2][0] = pLeft
->eDx
;
2141 aF
[2][1] = pLeft
->eDy
;
2144 bF
[0][0] = pRight
->eM11
;
2145 bF
[0][1] = pRight
->eM12
;
2147 bF
[1][0] = pRight
->eM21
;
2148 bF
[1][1] = pRight
->eM22
;
2150 bF
[2][0] = pRight
->eDx
;
2151 bF
[2][1] = pRight
->eDy
;
2155 for ( i
= 0; i
< 3; i
++ )
2157 for ( j
= 0; j
< 3; j
++ )
2160 for ( k
= 0; k
< 3; k
++ )
2161 cF
[i
][j
] += aF
[i
][k
] * bF
[k
][j
];
2164 maXForm
.eM11
= cF
[0][0];
2165 maXForm
.eM12
= cF
[0][1];
2166 maXForm
.eM21
= cF
[1][0];
2167 maXForm
.eM22
= cF
[1][1];
2168 maXForm
.eDx
= cF
[2][0];
2169 maXForm
.eDy
= cF
[2][1];
2175 //-----------------------------------------------------------------------------------
2177 void WinMtfOutput::Push() // !! to be able to access the original ClipRegion it
2178 { // is not allowed to use the MetaPushAction()
2179 UpdateClipRegion(); // (the original clip region is on top of the stack) (SJ)
2180 SaveStructPtr
pSave( new SaveStruct
);
2182 pSave
->aLineStyle
= maLineStyle
;
2183 pSave
->aFillStyle
= maFillStyle
;
2185 pSave
->aFont
= maFont
;
2186 pSave
->aTextColor
= maTextColor
;
2187 pSave
->nTextAlign
= mnTextAlign
;
2188 pSave
->nTextLayoutMode
= mnTextLayoutMode
;
2189 pSave
->nMapMode
= mnMapMode
;
2190 pSave
->nGfxMode
= mnGfxMode
;
2191 pSave
->nBkMode
= mnBkMode
;
2192 pSave
->aBkColor
= maBkColor
;
2193 pSave
->bFillStyleSelected
= mbFillStyleSelected
;
2195 pSave
->aActPos
= maActPos
;
2196 pSave
->aXForm
= maXForm
;
2197 pSave
->eRasterOp
= meRasterOp
;
2199 pSave
->nWinOrgX
= mnWinOrgX
;
2200 pSave
->nWinOrgY
= mnWinOrgY
;
2201 pSave
->nWinExtX
= mnWinExtX
;
2202 pSave
->nWinExtY
= mnWinExtY
;
2203 pSave
->nDevOrgX
= mnDevOrgX
;
2204 pSave
->nDevOrgY
= mnDevOrgY
;
2205 pSave
->nDevWidth
= mnDevWidth
;
2206 pSave
->nDevHeight
= mnDevHeight
;
2208 pSave
->aPathObj
= aPathObj
;
2209 pSave
->aClipPath
= aClipPath
;
2211 vSaveStack
.push_back( pSave
);
2214 //-----------------------------------------------------------------------------------
2216 void WinMtfOutput::Pop()
2218 // Die aktuellen Daten vom Stack holen
2219 if( vSaveStack
.size() )
2221 // Die aktuelle Daten auf dem Stack sichern
2222 SaveStructPtr
pSave( vSaveStack
.back() );
2224 maLineStyle
= pSave
->aLineStyle
;
2225 maFillStyle
= pSave
->aFillStyle
;
2227 maFont
= pSave
->aFont
;
2228 maTextColor
= pSave
->aTextColor
;
2229 mnTextAlign
= pSave
->nTextAlign
;
2230 mnTextLayoutMode
= pSave
->nTextLayoutMode
;
2231 mnBkMode
= pSave
->nBkMode
;
2232 mnGfxMode
= pSave
->nGfxMode
;
2233 mnMapMode
= pSave
->nMapMode
;
2234 maBkColor
= pSave
->aBkColor
;
2235 mbFillStyleSelected
= pSave
->bFillStyleSelected
;
2237 maActPos
= pSave
->aActPos
;
2238 maXForm
= pSave
->aXForm
;
2239 meRasterOp
= pSave
->eRasterOp
;
2241 mnWinOrgX
= pSave
->nWinOrgX
;
2242 mnWinOrgY
= pSave
->nWinOrgY
;
2243 mnWinExtX
= pSave
->nWinExtX
;
2244 mnWinExtY
= pSave
->nWinExtY
;
2245 mnDevOrgX
= pSave
->nDevOrgX
;
2246 mnDevOrgY
= pSave
->nDevOrgY
;
2247 mnDevWidth
= pSave
->nDevWidth
;
2248 mnDevHeight
= pSave
->nDevHeight
;
2250 aPathObj
= pSave
->aPathObj
;
2251 if ( ! ( aClipPath
== pSave
->aClipPath
) )
2253 aClipPath
= pSave
->aClipPath
;
2254 aClipPath
.bNeedsUpdate
= sal_True
;
2256 if ( meLatestRasterOp
!= meRasterOp
)
2257 mpGDIMetaFile
->AddAction( new MetaRasterOpAction( meRasterOp
) );
2258 vSaveStack
.pop_back();
2262 void WinMtfOutput::PassEMFPlusHeaderInfo()
2264 EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS header info\n"));
2267 sal_Int32 nLeft
, nRight
, nTop
, nBottom
;
2269 nLeft
= mrclFrame
.Left();
2270 nTop
= mrclFrame
.Top();
2271 nRight
= mrclFrame
.Right();
2272 nBottom
= mrclFrame
.Bottom();
2275 mem
<< nLeft
<< nTop
<< nRight
<< nBottom
;
2276 mem
<< mnPixX
<< mnPixY
<< mnMillX
<< mnMillY
;
2283 // add transformation matrix to be used in vcl's metaact.cxx for
2284 // rotate and scale operations
2285 mem
<< one
<< zero
<< zero
<< one
<< zero
<< zero
;
2287 mpGDIMetaFile
->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const BYTE
*) mem
.GetData(), mem
.GetSize() ) );
2288 mpGDIMetaFile
->UseCanvas( TRUE
);
2291 void WinMtfOutput::PassEMFPlus( void* pBuffer
, UINT32 nLength
)
2293 EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS comment length %d\n", nLength
));
2294 mpGDIMetaFile
->AddAction( new MetaCommentAction( "EMF_PLUS", 0, static_cast<const BYTE
*>(pBuffer
), nLength
) );