Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "winmtf.hxx"
30 : : #include <basegfx/matrix/b2dhommatrix.hxx>
31 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
32 : : #include <vcl/metaact.hxx>
33 : : #include <vcl/graphictools.hxx>
34 : : #include <vcl/canvastools.hxx>
35 : : #include <vcl/metric.hxx>
36 : : #include <vcl/svapp.hxx>
37 : : #include <rtl/strbuf.hxx>
38 : : #include <rtl/tencinfo.h>
39 : :
40 : : // ------------------------------------------------------------------------
41 : :
42 : : #if OSL_DEBUG_LEVEL > 1
43 : : #define EMFP_DEBUG(x) x
44 : : #else
45 : : #define EMFP_DEBUG(x)
46 : : #endif
47 : :
48 : 9 : void WinMtfClipPath::intersectClipRect( const Rectangle& rRect )
49 : : {
50 : : maClip.intersectRange(
51 [ + - ]: 9 : vcl::unotools::b2DRectangleFromRectangle(rRect));
52 : 9 : }
53 : :
54 : 0 : void WinMtfClipPath::excludeClipRect( const Rectangle& rRect )
55 : : {
56 : : maClip.subtractRange(
57 [ # # ]: 0 : vcl::unotools::b2DRectangleFromRectangle(rRect));
58 : 0 : }
59 : :
60 : 9 : void WinMtfClipPath::setClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode )
61 : : {
62 : 9 : const basegfx::B2DPolyPolygon& rB2DPoly=rPolyPolygon.getB2DPolyPolygon();
63 [ - - - - : 9 : switch ( nClippingMode )
+ - ]
64 : : {
65 : : case RGN_OR :
66 [ # # ]: 0 : maClip.unionPolyPolygon(rB2DPoly);
67 : 0 : break;
68 : : case RGN_XOR :
69 [ # # ]: 0 : maClip.xorPolyPolygon(rB2DPoly);
70 : 0 : break;
71 : : case RGN_DIFF :
72 [ # # ]: 0 : maClip.subtractPolyPolygon(rB2DPoly);
73 : 0 : break;
74 : : case RGN_AND :
75 [ # # ]: 0 : maClip.intersectPolyPolygon(rB2DPoly);
76 : 0 : break;
77 : : case RGN_COPY :
78 [ + - ][ + - ]: 9 : maClip = basegfx::tools::B2DClipState(rB2DPoly);
[ + - ]
79 : 9 : break;
80 : 9 : }
81 : 9 : }
82 : :
83 : 0 : void WinMtfClipPath::moveClipRegion( const Size& rSize )
84 : : {
85 : : // what a weird concept. emulate, don't want this in B2DClipState
86 : : // API
87 [ # # ]: 0 : basegfx::B2DPolyPolygon aCurrClip=maClip.getClipPoly();
88 [ # # ]: 0 : basegfx::B2DHomMatrix aTranslate;
89 [ # # ]: 0 : aTranslate.translate(rSize.Width(), rSize.Height());
90 : :
91 [ # # ]: 0 : aCurrClip.transform(aTranslate);
92 [ # # ][ # # ]: 0 : maClip = basegfx::tools::B2DClipState( aCurrClip );
[ # # ][ # # ]
[ # # ]
93 : 0 : }
94 : :
95 : 9 : basegfx::B2DPolyPolygon WinMtfClipPath::getClipPath() const
96 : : {
97 : 9 : return maClip.getClipPoly();
98 : : }
99 : :
100 : : // ------------------------------------------------------------------------
101 : :
102 : 0 : void WinMtfPathObj::AddPoint( const Point& rPoint )
103 : : {
104 [ # # ]: 0 : if ( bClosed )
105 [ # # ]: 0 : Insert( Polygon(), POLYPOLY_APPEND );
106 : 0 : Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
107 : 0 : rPoly.Insert( rPoly.GetSize(), rPoint, POLY_NORMAL );
108 : 0 : bClosed = sal_False;
109 : 0 : }
110 : :
111 : 0 : void WinMtfPathObj::AddPolyLine( const Polygon& rPolyLine )
112 : : {
113 [ # # ]: 0 : if ( bClosed )
114 [ # # ]: 0 : Insert( Polygon(), POLYPOLY_APPEND );
115 : 0 : Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
116 : 0 : rPoly.Insert( rPoly.GetSize(), rPolyLine );
117 : 0 : bClosed = sal_False;
118 : 0 : }
119 : :
120 : 0 : void WinMtfPathObj::AddPolygon( const Polygon& rPoly )
121 : : {
122 : 0 : Insert( rPoly, POLYPOLY_APPEND );
123 : 0 : bClosed = sal_True;
124 : 0 : }
125 : :
126 : 0 : void WinMtfPathObj::AddPolyPolygon( const PolyPolygon& rPolyPoly )
127 : : {
128 : 0 : sal_uInt16 i, nCount = rPolyPoly.Count();
129 [ # # ]: 0 : for ( i = 0; i < nCount; i++ )
130 : 0 : Insert( rPolyPoly[ i ], POLYPOLY_APPEND );
131 : 0 : bClosed = sal_True;
132 : 0 : }
133 : :
134 : 0 : void WinMtfPathObj::ClosePath()
135 : : {
136 [ # # ]: 0 : if ( Count() )
137 : : {
138 : 0 : Polygon& rPoly = ((PolyPolygon&)*this)[ Count() - 1 ];
139 [ # # ]: 0 : if ( rPoly.GetSize() > 2 )
140 : : {
141 [ # # ]: 0 : Point aFirst( rPoly[ 0 ] );
142 [ # # ][ # # ]: 0 : if ( aFirst != rPoly[ rPoly.GetSize() - 1 ] )
[ # # ]
143 [ # # ][ # # ]: 0 : rPoly.Insert( rPoly.GetSize(), aFirst, POLY_NORMAL );
144 : : }
145 : : }
146 : 0 : bClosed = sal_True;
147 : 0 : }
148 : :
149 : : // ------------------------------------------------------------------------
150 : :
151 : 191 : WinMtfFontStyle::WinMtfFontStyle( LOGFONTW& rFont )
152 : : {
153 : : CharSet eCharSet;
154 [ + + ][ + - ]: 191 : if ( ( rFont.lfCharSet == OEM_CHARSET ) || ( rFont.lfCharSet == DEFAULT_CHARSET ) )
155 : 3 : eCharSet = RTL_TEXTENCODING_MS_1252;
156 : : else
157 [ + - ]: 188 : eCharSet = rtl_getTextEncodingFromWindowsCharset( rFont.lfCharSet );
158 [ - + ]: 191 : if ( eCharSet == RTL_TEXTENCODING_DONTKNOW )
159 : 0 : eCharSet = RTL_TEXTENCODING_MS_1252;
160 [ + - ]: 191 : aFont.SetCharSet( eCharSet );
161 [ + - ][ + - ]: 191 : aFont.SetName( rFont.alfFaceName );
162 : : FontFamily eFamily;
163 [ - + - - : 191 : switch ( rFont.lfPitchAndFamily & 0xf0 )
- + ]
164 : : {
165 : : case FF_ROMAN:
166 : 0 : eFamily = FAMILY_ROMAN;
167 : 0 : break;
168 : :
169 : : case FF_SWISS:
170 : 177 : eFamily = FAMILY_SWISS;
171 : 177 : break;
172 : :
173 : : case FF_MODERN:
174 : 0 : eFamily = FAMILY_MODERN;
175 : 0 : break;
176 : :
177 : : case FF_SCRIPT:
178 : 0 : eFamily = FAMILY_SCRIPT;
179 : 0 : break;
180 : :
181 : : case FF_DECORATIVE:
182 : 0 : eFamily = FAMILY_DECORATIVE;
183 : 0 : break;
184 : :
185 : : default:
186 : 14 : eFamily = FAMILY_DONTKNOW;
187 : 14 : break;
188 : : }
189 [ + - ]: 191 : aFont.SetFamily( eFamily );
190 : :
191 : : FontPitch ePitch;
192 [ - + ]: 191 : switch ( rFont.lfPitchAndFamily & 0x0f )
193 : : {
194 : : case FIXED_PITCH:
195 : 0 : ePitch = PITCH_FIXED;
196 : 0 : break;
197 : :
198 : : case DEFAULT_PITCH:
199 : : case VARIABLE_PITCH:
200 : : default:
201 : 191 : ePitch = PITCH_VARIABLE;
202 : 191 : break;
203 : : }
204 [ + - ]: 191 : aFont.SetPitch( ePitch );
205 : :
206 : : FontWeight eWeight;
207 [ - + ]: 191 : if( rFont.lfWeight <= FW_THIN )
208 : 0 : eWeight = WEIGHT_THIN;
209 [ - + ]: 191 : else if( rFont.lfWeight <= FW_ULTRALIGHT )
210 : 0 : eWeight = WEIGHT_ULTRALIGHT;
211 [ - + ]: 191 : else if( rFont.lfWeight <= FW_LIGHT )
212 : 0 : eWeight = WEIGHT_LIGHT;
213 [ + + ]: 191 : else if( rFont.lfWeight < FW_MEDIUM )
214 : 188 : eWeight = WEIGHT_NORMAL;
215 [ - + ]: 3 : else if( rFont.lfWeight == FW_MEDIUM )
216 : 0 : eWeight = WEIGHT_MEDIUM;
217 [ - + ]: 3 : else if( rFont.lfWeight <= FW_SEMIBOLD )
218 : 0 : eWeight = WEIGHT_SEMIBOLD;
219 [ + - ]: 3 : else if( rFont.lfWeight <= FW_BOLD )
220 : 3 : eWeight = WEIGHT_BOLD;
221 [ # # ]: 0 : else if( rFont.lfWeight <= FW_ULTRABOLD )
222 : 0 : eWeight = WEIGHT_ULTRABOLD;
223 : : else
224 : 0 : eWeight = WEIGHT_BLACK;
225 [ + - ]: 191 : aFont.SetWeight( eWeight );
226 : :
227 [ - + ]: 191 : if( rFont.lfItalic )
228 [ # # ]: 0 : aFont.SetItalic( ITALIC_NORMAL );
229 : :
230 [ - + ]: 191 : if( rFont.lfUnderline )
231 [ # # ]: 0 : aFont.SetUnderline( UNDERLINE_SINGLE );
232 : :
233 [ - + ]: 191 : if( rFont.lfStrikeOut )
234 [ # # ]: 0 : aFont.SetStrikeout( STRIKEOUT_SINGLE );
235 : :
236 [ - + ]: 191 : if ( rFont.lfOrientation )
237 [ # # ]: 0 : aFont.SetOrientation( (short)rFont.lfOrientation );
238 : : else
239 [ + - ]: 191 : aFont.SetOrientation( (short)rFont.lfEscapement );
240 : :
241 : 191 : Size aFontSize( Size( rFont.lfWidth, rFont.lfHeight ) );
242 [ - + ]: 191 : if ( rFont.lfHeight > 0 )
243 : : {
244 : : // converting the cell height into a font height
245 [ # # ]: 0 : VirtualDevice aVDev;
246 [ # # ]: 0 : aFont.SetSize( aFontSize );
247 [ # # ]: 0 : aVDev.SetFont( aFont );
248 [ # # ]: 0 : FontMetric aMetric( aVDev.GetFontMetric() );
249 [ # # ][ # # ]: 0 : long nHeight = aMetric.GetAscent() + aMetric.GetDescent();
250 [ # # ]: 0 : if ( nHeight )
251 : : {
252 : 0 : double fHeight = ((double)aFontSize.Height() * rFont.lfHeight ) / nHeight;
253 : 0 : aFontSize.Height() = (sal_Int32)( fHeight + 0.5 );
254 [ # # ][ # # ]: 0 : }
255 : : }
256 [ + - ]: 191 : else if ( aFontSize.Height() < 0 )
257 : 191 : aFontSize.Height() *= -1;
258 : :
259 [ + + ]: 191 : if ( !rFont.lfWidth )
260 : : {
261 [ + - ]: 185 : VirtualDevice aVDev;
262 [ + - ]: 185 : aFont.SetSize( aFontSize );
263 [ + - ]: 185 : aVDev.SetFont( aFont );
264 [ + - ]: 185 : FontMetric aMetric( aVDev.GetFontMetric() );
265 [ + - ][ + - ]: 185 : aFontSize.Width() = aMetric.GetWidth();
[ + - ]
266 : : }
267 : :
268 [ + - ]: 191 : aFont.SetSize( aFontSize );
269 : 191 : };
270 : :
271 : : // ------------------------------------------------------------------------
272 : :
273 : : #ifdef WIN_MTF_ASSERT
274 : : void WinMtfAssertHandler( const sal_Char* pAction, sal_uInt32 nFlags )
275 : : {
276 : : static sal_Bool bOnlyOnce;
277 : : static sal_Int32 nAssertCount;
278 : :
279 : : if ( nFlags & WIN_MTF_ASSERT_INIT )
280 : : nAssertCount = 0;
281 : : if ( nFlags & WIN_MTF_ASSERT_ONCE )
282 : : bOnlyOnce = sal_True;
283 : : if ( nFlags & WIN_MTF_ASSERT_MIFE )
284 : : {
285 : : if ( ( nAssertCount == 0 ) || ( bOnlyOnce == sal_False ) )
286 : : {
287 : : rtl::OStringBuffer aText(RTL_CONSTASCII_STRINGPARAM(
288 : : "WMF/EMF Import: "));
289 : : if (pAction)
290 : : aText.append(pAction);
291 : : aText.append(RTL_CONSTASCII_STRINGPARAM(
292 : : " needs to be implemented"));
293 : : DBG_ASSERT( 0, aText.getStr() );
294 : : }
295 : : nAssertCount++;
296 : : }
297 : : }
298 : : #endif
299 : :
300 : : // ------------------------------------------------------------------------
301 : :
302 : 74 : WinMtf::WinMtf( WinMtfOutput* pWinMtfOutput, SvStream& rStreamWMF, FilterConfigItem* pConfigItem ) :
303 : : pOut ( pWinMtfOutput ),
304 : : pWMF ( &rStreamWMF ),
305 : 74 : pFilterConfigItem ( pConfigItem )
306 : : {
307 : : #ifdef WIN_MTF_ASSERT
308 : : // we want to assert not implemented features, but we do this
309 : : // only once, so that nobody is handicaped by getting too much assertions
310 : : // I hope this will bring more testdocuments, without support of these
311 : : // testdocuments the implementation of missing features won't be possible. (SJ)
312 : : WinMtfAssertHandler( NULL, WIN_MTF_ASSERT_INIT | WIN_MTF_ASSERT_ONCE );
313 : : #endif
314 : :
315 : 74 : SvLockBytes *pLB = pWMF->GetLockBytes();
316 [ + + ]: 74 : if ( pLB )
317 [ + - ]: 3 : pLB->SetSynchronMode( sal_True );
318 : :
319 : 74 : nStartPos = pWMF->Tell();
320 : :
321 : 74 : pOut->SetDevOrg( Point() );
322 [ - + ]: 74 : if ( pFilterConfigItem )
323 : : {
324 [ # # ][ # # ]: 0 : xStatusIndicator = pFilterConfigItem->GetStatusIndicator();
325 [ # # ]: 0 : if ( xStatusIndicator.is() )
326 : : {
327 : 0 : rtl::OUString aMsg;
328 [ # # ][ # # ]: 0 : xStatusIndicator->start( aMsg, 100 );
329 : : }
330 : : }
331 : 74 : }
332 : :
333 : : // ------------------------------------------------------------------------
334 : :
335 : 74 : WinMtf::~WinMtf()
336 : : {
337 [ + - ][ + - ]: 74 : delete pOut;
338 : :
339 [ - + ]: 74 : if ( xStatusIndicator.is() )
340 [ # # ][ # # ]: 0 : xStatusIndicator->end();
341 : 74 : }
342 : :
343 : : // ------------------------------------------------------------------------
344 : :
345 : 249 : void WinMtf::Callback( sal_uInt16 nPercent )
346 : : {
347 [ - + ]: 249 : if ( xStatusIndicator.is() )
348 : 0 : xStatusIndicator->setValue( nPercent );
349 : 249 : }
350 : :
351 : : // ------------------------------------------------------------------------
352 : :
353 : 1035 : Color WinMtf::ReadColor()
354 : : {
355 : : sal_uInt32 nColor;
356 [ + - ]: 1035 : *pWMF >> nColor;
357 : 1035 : return Color( (sal_uInt8)nColor, (sal_uInt8)( nColor >> 8 ), (sal_uInt8)( nColor >> 16 ) );
358 : : };
359 : :
360 : : //-----------------------------------------------------------------------------------
361 : : //-----------------------------------------------------------------------------------
362 : : //-----------------------------------------------------------------------------------
363 : :
364 : 15036 : Point WinMtfOutput::ImplMap( const Point& rPt )
365 : : {
366 [ + - ][ + - ]: 15036 : if ( mnWinExtX && mnWinExtY )
367 : : {
368 : 15036 : double fX = rPt.X();
369 : 15036 : double fY = rPt.Y();
370 : :
371 : 15036 : double fX2 = fX * maXForm.eM11 + fY * maXForm.eM21 + maXForm.eDx;
372 : 15036 : double fY2 = fX * maXForm.eM12 + fY * maXForm.eM22 + maXForm.eDy;
373 : :
374 [ + - ]: 15036 : if ( mnGfxMode == GM_COMPATIBLE )
375 : : {
376 [ + - - - : 15036 : switch( mnMapMode )
- + ]
377 : : {
378 : : case MM_TEXT:
379 : 2331 : fX2 -= mnWinOrgX;
380 : 2331 : fY2 -= mnWinOrgY;
381 [ + - ][ - + ]: 2331 : if( mnDevWidth != 1 || mnDevHeight != 1 ) {
382 : 0 : fX2 *= 2540.0/mnUnitsPerInch;
383 : 0 : fY2 *= 2540.0/mnUnitsPerInch;
384 : : }
385 : 2331 : fX2 += mnDevOrgX;
386 : 2331 : fY2 += mnDevOrgY;
387 : 2331 : fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
388 : 2331 : fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
389 : :
390 : 2331 : break;
391 : : case MM_LOENGLISH :
392 : : {
393 : 0 : fX2 -= mnWinOrgX;
394 : 0 : fY2 = mnWinOrgY-fY2;
395 : 0 : fX2 *= 25.40;
396 : 0 : fY2 *= 25.40;
397 : 0 : fX2 += mnDevOrgX;
398 : 0 : fY2 += mnDevOrgY;
399 : : }
400 : 0 : break;
401 : : case MM_HIENGLISH :
402 : : {
403 : 0 : fX2 -= mnWinOrgX;
404 : 0 : fY2 = mnWinOrgY-fY2;
405 : 0 : fX2 *= 2.540;
406 : 0 : fY2 *= 2.540;
407 : 0 : fX2 += mnDevOrgX;
408 : 0 : fY2 += mnDevOrgY;
409 : : }
410 : 0 : break;
411 : : case MM_LOMETRIC :
412 : : {
413 : 0 : fX2 -= mnWinOrgX;
414 : 0 : fY2 = mnWinOrgY-fY2;
415 : 0 : fX2 *= 10;
416 : 0 : fY2 *= 10;
417 : 0 : fX2 += mnDevOrgX;
418 : 0 : fY2 += mnDevOrgY;
419 : : }
420 : 0 : break;
421 : : case MM_HIMETRIC :
422 : : {
423 : 0 : fX2 -= mnWinOrgX;
424 : 0 : fY2 = mnWinOrgY-fY2;
425 : 0 : fX2 += mnDevOrgX;
426 : 0 : fY2 += mnDevOrgY;
427 : : }
428 : 0 : break;
429 : : default :
430 : : {
431 : 12705 : fX2 -= mnWinOrgX;
432 : 12705 : fY2 -= mnWinOrgY;
433 : 12705 : fX2 /= mnWinExtX;
434 : 12705 : fY2 /= mnWinExtY;
435 : 12705 : fX2 *= mnDevWidth;
436 : 12705 : fY2 *= mnDevHeight;
437 : 12705 : fX2 += mnDevOrgX;
438 : 12705 : fY2 += mnDevOrgY; // fX2, fY2 now in device units
439 : 12705 : fX2 *= (double)mnMillX * 100.0 / (double)mnPixX;
440 : 12705 : fY2 *= (double)mnMillY * 100.0 / (double)mnPixY;
441 : : }
442 : 12705 : break;
443 : : }
444 : 15036 : fX2 -= mrclFrame.Left();
445 : 15036 : fY2 -= mrclFrame.Top();
446 : : }
447 : 15036 : return Point( FRound( fX2 ), FRound( fY2 ) );
448 : : }
449 : : else
450 : 15036 : return Point();
451 : : };
452 : :
453 : : // ------------------------------------------------------------------------
454 : :
455 : 1856 : Size WinMtfOutput::ImplMap( const Size& rSz )
456 : : {
457 [ + - ][ + - ]: 1856 : if ( mnWinExtX && mnWinExtY )
458 : : {
459 : 1856 : double fWidth = rSz.Width() * maXForm.eM11;
460 : 1856 : double fHeight = rSz.Height() * maXForm.eM22;
461 : :
462 [ + - ]: 1856 : if ( mnGfxMode == GM_COMPATIBLE )
463 : : {
464 [ + - - - : 1856 : switch( mnMapMode )
- + ]
465 : : {
466 : : case MM_TEXT:
467 [ - + ][ # # ]: 1413 : if( mnDevWidth != 1 && mnDevHeight != 1 ) {
468 : 0 : fWidth *= 2540.0/mnUnitsPerInch;
469 : 0 : fHeight*= 2540.0/mnUnitsPerInch;
470 : : } else {
471 : 1413 : fWidth *= (double)mnMillX * 100 / (double)mnPixX;
472 : 1413 : fHeight *= (double)mnMillY * 100 / (double)mnPixY;
473 : : }
474 : 1413 : break;
475 : : case MM_LOENGLISH :
476 : : {
477 : 0 : fWidth *= 25.40;
478 : 0 : fHeight*=-25.40;
479 : : }
480 : 0 : break;
481 : : case MM_HIENGLISH :
482 : : {
483 : 0 : fWidth *= 2.540;
484 : 0 : fHeight*=-2.540;
485 : : }
486 : 0 : break;
487 : : case MM_LOMETRIC :
488 : : {
489 : 0 : fWidth *= 10;
490 : 0 : fHeight*=-10;
491 : : }
492 : 0 : break;
493 : : case MM_HIMETRIC :
494 : : {
495 : 0 : fHeight *= -1;
496 : : }
497 : 0 : break;
498 : : default :
499 : : {
500 : 443 : fWidth /= mnWinExtX;
501 : 443 : fHeight /= mnWinExtY;
502 : 443 : fWidth *= mnDevWidth;
503 : 443 : fHeight *= mnDevHeight;
504 : 443 : fWidth *= (double)mnMillX * 100 / (double)mnPixX;
505 : 443 : fHeight *= (double)mnMillY * 100 / (double)mnPixY;
506 : : }
507 : 1856 : break;
508 : : }
509 : : }
510 : 1856 : return Size( FRound( fWidth ), FRound( fHeight ) );
511 : : }
512 : : else
513 : 1856 : return Size();
514 : : }
515 : :
516 : : //-----------------------------------------------------------------------------------
517 : :
518 : 146 : Rectangle WinMtfOutput::ImplMap( const Rectangle& rRect )
519 : : {
520 [ + - ]: 146 : return Rectangle( ImplMap( rRect.TopLeft() ), ImplMap( rRect.GetSize() ) );
521 : : }
522 : :
523 : : //-----------------------------------------------------------------------------------
524 : :
525 : 191 : void WinMtfOutput::ImplMap( Font& rFont )
526 : : {
527 : : // !!! HACK: Wir setzen die Breite jetzt immer auf Null,
528 : : // da OS die Breite unterschiedlich interpretieren;
529 : : // muss spaeter in SV portabel gemacht werden ( KA 08.02.96 )
530 [ + - ]: 191 : Size aFontSize = ImplMap ( rFont.GetSize() );
531 : :
532 [ + + ]: 191 : if( aFontSize.Height() < 0 )
533 : 3 : aFontSize.Height() *= -1;
534 : :
535 [ + - ]: 191 : rFont.SetSize( aFontSize );
536 : :
537 [ - + ]: 191 : if( ( mnWinExtX * mnWinExtY ) < 0 )
538 [ # # ][ # # ]: 0 : rFont.SetOrientation( 3600 - rFont.GetOrientation() );
539 : 191 : }
540 : :
541 : : //-----------------------------------------------------------------------------------
542 : :
543 : 585 : Polygon& WinMtfOutput::ImplMap( Polygon& rPolygon )
544 : : {
545 : 585 : sal_uInt16 nPoints = rPolygon.GetSize();
546 [ + + ]: 15168 : for ( sal_uInt16 i = 0; i < nPoints; i++ )
547 : : {
548 : 14583 : rPolygon[ i ] = ImplMap( rPolygon[ i ] );
549 : : }
550 : 585 : return rPolygon;
551 : : }
552 : :
553 : : //-----------------------------------------------------------------------------------
554 : :
555 : 9 : PolyPolygon& WinMtfOutput::ImplMap( PolyPolygon& rPolyPolygon )
556 : : {
557 : 9 : sal_uInt16 nPolys = rPolyPolygon.Count();
558 [ - + ]: 9 : for ( sal_uInt16 i = 0; i < nPolys; ImplMap( rPolyPolygon[ i++ ] ) ) ;
559 : 9 : return rPolyPolygon;
560 : : }
561 : :
562 : : //-----------------------------------------------------------------------------------
563 : :
564 : 2037 : void WinMtfOutput::SelectObject( sal_Int32 nIndex )
565 : : {
566 : 2037 : GDIObj* pGDIObj = NULL;
567 : :
568 [ + + ]: 2037 : if ( nIndex & ENHMETA_STOCK_OBJECT )
569 : 968 : pGDIObj = new GDIObj();
570 : : else
571 : : {
572 : 1069 : nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
573 : :
574 [ + - ]: 1069 : if ( (sal_uInt32)nIndex < vGDIObj.size() )
575 : 1069 : pGDIObj = vGDIObj[ nIndex ];
576 : : }
577 : :
578 [ + + ]: 2037 : if( pGDIObj == NULL )
579 : 2037 : return;
580 : :
581 [ + + ]: 2022 : if ( nIndex & ENHMETA_STOCK_OBJECT )
582 : : {
583 : 968 : sal_uInt16 nStockId = (sal_uInt8)nIndex;
584 [ + + + + : 968 : switch( nStockId )
- - + -
+ ]
585 : : {
586 : : case WHITE_BRUSH :
587 : : {
588 [ + - ][ + - ]: 11 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_WHITE ) ) );
589 : : }
590 : 11 : break;
591 : : case LTGRAY_BRUSH :
592 : : {
593 [ + - ][ + - ]: 189 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_LIGHTGRAY ) ) );
594 : : }
595 : 189 : break;
596 : : case GRAY_BRUSH :
597 : : case DKGRAY_BRUSH :
598 : : {
599 [ + - ][ + - ]: 9 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_GRAY ) ) );
600 : : }
601 : 9 : break;
602 : : case BLACK_BRUSH :
603 : : {
604 [ + - ][ + - ]: 9 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_BLACK ) ) );
605 : : }
606 : 9 : break;
607 : : case NULL_BRUSH :
608 : : {
609 [ # # ][ # # ]: 0 : pGDIObj->Set( GDI_BRUSH, new WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True ) );
610 : : }
611 : 0 : break;
612 : : case WHITE_PEN :
613 : : {
614 [ # # ][ # # ]: 0 : pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_WHITE ) ) );
615 : : }
616 : 0 : break;
617 : : case BLACK_PEN :
618 : : {
619 [ + - ][ + - ]: 582 : pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_BLACK ) ) );
620 : : }
621 : 582 : break;
622 : : case NULL_PEN :
623 : : {
624 [ # # ][ # # ]: 0 : pGDIObj->Set( GDI_PEN, new WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True ) );
625 : : }
626 : 0 : break;
627 : : default:
628 : 968 : break;
629 : : }
630 : : }
631 [ + + ]: 2022 : if ( pGDIObj->pStyle )
632 : : {
633 [ + + + - ]: 1854 : switch( pGDIObj->eType )
634 : : {
635 : : case GDI_PEN :
636 : 1215 : maLineStyle = (WinMtfLineStyle*)pGDIObj->pStyle;
637 : 1215 : break;
638 : : case GDI_BRUSH :
639 : : {
640 : 448 : maFillStyle = (WinMtfFillStyle*)pGDIObj->pStyle;
641 : 448 : mbFillStyleSelected = sal_True;
642 : : }
643 : 448 : break;
644 : : case GDI_FONT :
645 : 191 : maFont = ((WinMtfFontStyle*)pGDIObj->pStyle)->aFont;
646 : 191 : break;
647 : : default:
648 : 1854 : break; // -Wall many options not handled.
649 : : }
650 : : }
651 [ + + ]: 2022 : if ( nIndex & ENHMETA_STOCK_OBJECT )
652 [ + - ]: 968 : delete pGDIObj;
653 : : }
654 : :
655 : : //-----------------------------------------------------------------------------------
656 : :
657 : 0 : const Font& WinMtfOutput::GetFont() const
658 : : {
659 : 0 : return maFont;
660 : : }
661 : :
662 : : //-----------------------------------------------------------------------------------
663 : :
664 : 191 : void WinMtfOutput::SetTextLayoutMode( const sal_uInt32 nTextLayoutMode )
665 : : {
666 : 191 : mnTextLayoutMode = nTextLayoutMode;
667 : 191 : }
668 : :
669 : : //-----------------------------------------------------------------------------------
670 : :
671 : 32 : void WinMtfOutput::SetBkMode( sal_uInt32 nMode )
672 : : {
673 : 32 : mnBkMode = nMode;
674 : 32 : }
675 : :
676 : : //-----------------------------------------------------------------------------------
677 : :
678 : 20 : void WinMtfOutput::SetBkColor( const Color& rColor )
679 : : {
680 : 20 : maBkColor = rColor;
681 : 20 : }
682 : :
683 : : //-----------------------------------------------------------------------------------
684 : :
685 : 182 : void WinMtfOutput::SetTextColor( const Color& rColor )
686 : : {
687 : 182 : maTextColor = rColor;
688 : 182 : }
689 : :
690 : : //-----------------------------------------------------------------------------------
691 : :
692 : 173 : void WinMtfOutput::SetTextAlign( sal_uInt32 nAlign )
693 : : {
694 : 173 : mnTextAlign = nAlign;
695 : 173 : }
696 : :
697 : : //-----------------------------------------------------------------------------------
698 : :
699 : 47 : void WinMtfOutput::ImplResizeObjectArry( sal_uInt32 nNewEntrys )
700 : : {
701 : 47 : sal_uInt32 i = vGDIObj.size();
702 : 47 : vGDIObj.resize( nNewEntrys );
703 [ + + ]: 825 : for ( ; i < nNewEntrys ; i++ )
704 : 778 : vGDIObj[ i ] = NULL;
705 : 47 : }
706 : :
707 : : //-----------------------------------------------------------------------------------
708 : :
709 : 0 : void WinMtfOutput::ImplDrawClippedPolyPolygon( const PolyPolygon& rPolyPoly )
710 : : {
711 [ # # ]: 0 : if ( rPolyPoly.Count() )
712 : : {
713 : 0 : ImplSetNonPersistentLineColorTransparenz();
714 [ # # ]: 0 : if ( rPolyPoly.Count() == 1 )
715 : : {
716 [ # # ]: 0 : if ( rPolyPoly.IsRect() )
717 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaRectAction( rPolyPoly.GetBoundRect() ) );
[ # # ]
718 : : else
719 : : {
720 [ # # ][ # # ]: 0 : Polygon aPoly( rPolyPoly[ 0 ] );
721 [ # # ]: 0 : sal_uInt16 nCount = aPoly.GetSize();
722 [ # # ]: 0 : if ( nCount )
723 : : {
724 [ # # ][ # # ]: 0 : if ( aPoly[ nCount - 1 ] != aPoly[ 0 ] )
[ # # ]
725 : : {
726 [ # # ]: 0 : Point aPoint( aPoly[ 0 ] );
727 [ # # ]: 0 : aPoly.Insert( nCount, aPoint );
728 : : }
729 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolygonAction( aPoly ) );
[ # # ]
730 [ # # ]: 0 : }
731 : : }
732 : : }
733 : : else
734 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
735 : : }
736 : 0 : }
737 : :
738 : :
739 : : //-----------------------------------------------------------------------------------
740 : :
741 : 75 : void WinMtfOutput::CreateObject( GDIObjectType eType, void* pStyle )
742 : : {
743 [ + - ]: 75 : if ( pStyle )
744 : : {
745 [ + + ]: 75 : if ( eType == GDI_FONT )
746 : : {
747 : 6 : ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
748 [ - + ]: 6 : if (!((WinMtfFontStyle*)pStyle)->aFont.GetHeight() )
749 : 0 : ((WinMtfFontStyle*)pStyle)->aFont.SetHeight( 423 ); // defaulting to 12pt
750 : : }
751 [ + + ]: 69 : else if ( eType == GDI_PEN )
752 : : {
753 : 24 : Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
754 [ + - ]: 24 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
755 [ - + ]: 24 : if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
756 : : {
757 : 0 : aSize.Width() += 1;
758 : 0 : long nDotLen = ImplMap( aSize ).Width();
759 [ # # ]: 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
760 [ # # ]: 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
761 [ # # ]: 24 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
762 : : }
763 : : }
764 : : }
765 : : sal_uInt32 nIndex;
766 [ + + ]: 141 : for ( nIndex = 0; nIndex < vGDIObj.size(); nIndex++ )
767 : : {
768 [ + + ]: 120 : if ( vGDIObj[ nIndex ] == NULL )
769 : 54 : break;
770 : : }
771 [ + + ]: 75 : if ( nIndex == vGDIObj.size() )
772 : 21 : ImplResizeObjectArry( vGDIObj.size() + 16 );
773 : :
774 : 75 : vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
775 : 75 : }
776 : :
777 : : //-----------------------------------------------------------------------------------
778 : :
779 : 952 : void WinMtfOutput::CreateObject( sal_Int32 nIndex, GDIObjectType eType, void* pStyle )
780 : : {
781 [ + - ]: 952 : if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
782 : : {
783 : 952 : nIndex &= 0xffff; // zur Sicherheit: mehr als 65535 nicht zulassen
784 [ + - ]: 952 : if ( pStyle )
785 : : {
786 [ + + ]: 952 : if ( eType == GDI_FONT )
787 : 185 : ImplMap( ((WinMtfFontStyle*)pStyle)->aFont );
788 [ + + ]: 767 : else if ( eType == GDI_PEN )
789 : : {
790 : 585 : Size aSize( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetWidth(), 0 );
791 [ + - ]: 585 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetWidth( ImplMap( aSize ).Width() );
792 [ - + ]: 585 : if ( ((WinMtfLineStyle*)pStyle)->aLineInfo.GetStyle() == LINE_DASH )
793 : : {
794 : 0 : aSize.Width() += 1;
795 : 0 : long nDotLen = ImplMap( aSize ).Width();
796 [ # # ]: 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDistance( nDotLen );
797 [ # # ]: 0 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDotLen( nDotLen );
798 [ # # ]: 585 : ((WinMtfLineStyle*)pStyle)->aLineInfo.SetDashLen( nDotLen * 4 );
799 : : }
800 : : }
801 : : }
802 [ + + ]: 952 : if ( (sal_uInt32)nIndex >= vGDIObj.size() )
803 : 26 : ImplResizeObjectArry( nIndex + 16 );
804 : :
805 [ - + ]: 952 : if ( vGDIObj[ nIndex ] != NULL )
806 [ # # ]: 0 : delete vGDIObj[ nIndex ];
807 : :
808 : 952 : vGDIObj[ nIndex ] = new GDIObj( eType, pStyle );
809 : : }
810 : : else
811 : : {
812 [ # # # # ]: 0 : switch ( eType )
813 : : {
814 : : case GDI_PEN :
815 [ # # ]: 0 : delete (WinMtfLineStyle*)pStyle;
816 : 0 : break;
817 : : case GDI_BRUSH :
818 [ # # ]: 0 : delete (WinMtfFillStyle*)pStyle;
819 : 0 : break;
820 : : case GDI_FONT :
821 [ # # ]: 0 : delete (WinMtfFontStyle*)pStyle;
822 : 0 : break;
823 : :
824 : : default:
825 : : OSL_FAIL( "unsupported style not deleted" );
826 : 0 : break;
827 : : }
828 : : }
829 : 952 : }
830 : :
831 : : //-----------------------------------------------------------------------------------
832 : :
833 : 946 : void WinMtfOutput::DeleteObject( sal_Int32 nIndex )
834 : : {
835 [ + - ]: 946 : if ( ( nIndex & ENHMETA_STOCK_OBJECT ) == 0 )
836 : : {
837 [ + - ]: 946 : if ( (sal_uInt32)nIndex < vGDIObj.size() )
838 : : {
839 [ + - ]: 946 : delete vGDIObj[ nIndex ];
840 : 946 : vGDIObj[ nIndex ] = NULL;
841 : : }
842 : : }
843 : 946 : }
844 : :
845 : : //-----------------------------------------------------------------------------------
846 : :
847 : 9 : void WinMtfOutput::IntersectClipRect( const Rectangle& rRect )
848 : : {
849 : 9 : mbClipNeedsUpdate=true;
850 [ + - ]: 9 : aClipPath.intersectClipRect( ImplMap( rRect ) );
851 : 9 : }
852 : :
853 : : //-----------------------------------------------------------------------------------
854 : :
855 : 0 : void WinMtfOutput::ExcludeClipRect( const Rectangle& rRect )
856 : : {
857 : 0 : mbClipNeedsUpdate=true;
858 [ # # ]: 0 : aClipPath.excludeClipRect( ImplMap( rRect ) );
859 : 0 : }
860 : :
861 : : //-----------------------------------------------------------------------------------
862 : :
863 : 0 : void WinMtfOutput::MoveClipRegion( const Size& rSize )
864 : : {
865 : 0 : mbClipNeedsUpdate=true;
866 [ # # ]: 0 : aClipPath.moveClipRegion( ImplMap( rSize ) );
867 : 0 : }
868 : :
869 : 9 : void WinMtfOutput::SetClipPath( const PolyPolygon& rPolyPolygon, sal_Int32 nClippingMode, sal_Bool bIsMapped )
870 : : {
871 : 9 : mbClipNeedsUpdate=true;
872 [ - + ]: 9 : if ( bIsMapped )
873 : 0 : aClipPath.setClipPath( rPolyPolygon, nClippingMode );
874 : : else
875 : : {
876 [ + - ]: 9 : PolyPolygon aPP( rPolyPolygon );
877 [ + - ][ + - ]: 9 : aClipPath.setClipPath( ImplMap( aPP ), nClippingMode );
[ + - ]
878 : : }
879 : 9 : }
880 : :
881 : : //-----------------------------------------------------------------------------------
882 : : //-----------------------------------------------------------------------------------
883 : : //-----------------------------------------------------------------------------------
884 : :
885 : 74 : WinMtfOutput::WinMtfOutput( GDIMetaFile& rGDIMetaFile ) :
886 : : mnLatestTextAlign ( 0 ),
887 : : mnTextAlign ( TA_LEFT | TA_TOP | TA_NOUPDATECP ),
888 : : maLatestBkColor ( 0x12345678 ),
889 : : maBkColor ( COL_WHITE ),
890 : : mnLatestTextLayoutMode( TEXT_LAYOUT_DEFAULT ),
891 : : mnTextLayoutMode ( TEXT_LAYOUT_DEFAULT ),
892 : : mnLatestBkMode ( 0 ),
893 : : mnBkMode ( OPAQUE ),
894 : : meLatestRasterOp ( ROP_INVERT ),
895 : : meRasterOp ( ROP_OVERPAINT ),
896 : : maActPos ( Point() ),
897 : : mbNopMode ( sal_False ),
898 : : mbFillStyleSelected ( sal_False ),
899 : : mbClipNeedsUpdate ( true ),
900 : : mbComplexClip ( false ),
901 : : mnGfxMode ( GM_COMPATIBLE ),
902 : : mnMapMode ( MM_TEXT ),
903 : : mnUnitsPerInch ( 96 ),
904 : : mnDevOrgX ( 0 ),
905 : : mnDevOrgY ( 0 ),
906 : : mnDevWidth ( 1 ),
907 : : mnDevHeight ( 1 ),
908 : : mnWinOrgX ( 0 ),
909 : : mnWinOrgY ( 0 ),
910 : : mnWinExtX ( 1 ),
911 : : mnWinExtY ( 1 ),
912 : : mnPixX ( 100 ),
913 : : mnPixY ( 100 ),
914 : : mnMillX ( 1 ),
915 : : mnMillY ( 1 ),
916 [ + - ][ + - ]: 74 : mpGDIMetaFile ( &rGDIMetaFile )
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
917 : : {
918 [ + - ][ + - ]: 74 : mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) ); // The original clipregion has to be on top
[ + - ]
919 : : // of the stack so it can always be restored
920 : : // this is necessary to be able to support
921 : : // SetClipRgn( NULL ) and similar ClipRgn actions (SJ)
922 : :
923 [ + - ][ + - ]: 74 : maFont.SetName( String( RTL_CONSTASCII_USTRINGPARAM( "Arial" )) ); // sj: #i57205#, we do have some scaling problems if using
[ + - ][ + - ]
924 [ + - ]: 74 : maFont.SetCharSet( RTL_TEXTENCODING_MS_1252 ); // the default font then most times a x11 font is used, we
925 [ + - ]: 74 : maFont.SetHeight( 423 ); // will prevent this defining a font
926 : :
927 : 74 : maLatestLineStyle.aLineColor = Color( 0x12, 0x34, 0x56 );
928 : 74 : maLatestFillStyle.aFillColor = Color( 0x12, 0x34, 0x56 );
929 : :
930 : 74 : mnRop = R2_BLACK + 1;
931 [ + - ]: 74 : SetRasterOp( R2_BLACK );
932 : 74 : };
933 : :
934 : : //-----------------------------------------------------------------------------------
935 : :
936 [ + - ][ + - ]: 74 : WinMtfOutput::~WinMtfOutput()
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
937 : : {
938 [ + - ][ + - ]: 74 : mpGDIMetaFile->AddAction( new MetaPopAction() );
[ + - ]
939 [ + - ][ + - ]: 74 : mpGDIMetaFile->SetPrefMapMode( MAP_100TH_MM );
[ + - ]
940 [ + - ][ + + ]: 74 : if ( mrclFrame.IsEmpty() )
941 : 30 : mpGDIMetaFile->SetPrefSize( Size( mnDevWidth, mnDevHeight ) );
942 : : else
943 [ + - ]: 44 : mpGDIMetaFile->SetPrefSize( mrclFrame.GetSize() );
944 : :
945 [ + + ]: 852 : for ( sal_uInt32 i = 0; i < vGDIObj.size(); i++ )
946 [ + + ][ + - ]: 778 : delete vGDIObj[ i ];
947 [ - + ]: 148 : };
948 : :
949 : : //-----------------------------------------------------------------------------------
950 : :
951 : 1235 : void WinMtfOutput::UpdateClipRegion()
952 : : {
953 [ + + ]: 1235 : if ( mbClipNeedsUpdate )
954 : : {
955 : 50 : mbClipNeedsUpdate = false;
956 : 50 : mbComplexClip = false;
957 : :
958 [ + - ]: 50 : mpGDIMetaFile->AddAction( new MetaPopAction() ); // taking the orignal clipregion
959 [ + - ]: 50 : mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_CLIPREGION ) ); //
960 : :
961 : : // skip for 'no clipping at all' case
962 [ + + ]: 50 : if( !aClipPath.isEmpty() )
963 : : {
964 : 9 : const basegfx::B2DPolyPolygon& rClipPoly( aClipPath.getClipPath() );
965 : : mpGDIMetaFile->AddAction(
966 : : new MetaISectRectClipRegionAction(
967 : : vcl::unotools::rectangleFromB2DRectangle(
968 [ + - ][ + - ]: 9 : rClipPoly.getB2DRange())));
[ + - ][ + - ]
[ + - ]
969 : :
970 [ + - ]: 9 : mbComplexClip = rClipPoly.count() > 1
971 [ + - ][ + - ]: 9 : || !basegfx::tools::isRectangle(rClipPoly);
[ - + ]
972 : : }
973 : : }
974 : 1235 : }
975 : :
976 : : //-----------------------------------------------------------------------------------
977 : :
978 : 113 : void WinMtfOutput::ImplSetNonPersistentLineColorTransparenz()
979 : : {
980 : 113 : Color aColor( COL_TRANSPARENT);
981 [ + - ]: 113 : WinMtfLineStyle aTransparentLine( aColor, sal_True );
982 [ + - ][ + + ]: 113 : if ( ! ( maLatestLineStyle == aTransparentLine ) )
983 : : {
984 [ + - ]: 14 : maLatestLineStyle = aTransparentLine;
985 [ + - ][ + - ]: 14 : mpGDIMetaFile->AddAction( new MetaLineColorAction( aTransparentLine.aLineColor, !aTransparentLine.bTransparent ) );
[ + - ]
986 [ + - ]: 113 : }
987 : 113 : }
988 : :
989 : : //-----------------------------------------------------------------------------------
990 : :
991 : 612 : void WinMtfOutput::UpdateLineStyle()
992 : : {
993 [ + + ]: 612 : if (!( maLatestLineStyle == maLineStyle ) )
994 : : {
995 : 336 : maLatestLineStyle = maLineStyle;
996 [ + - ]: 336 : mpGDIMetaFile->AddAction( new MetaLineColorAction( maLineStyle.aLineColor, !maLineStyle.bTransparent ) );
997 : : }
998 : 612 : }
999 : :
1000 : : //-----------------------------------------------------------------------------------
1001 : :
1002 : 418 : void WinMtfOutput::UpdateFillStyle()
1003 : : {
1004 [ + + ]: 418 : if ( !mbFillStyleSelected ) // SJ: #i57205# taking care of bkcolor if no brush is selected
1005 [ + - ]: 3 : maFillStyle = WinMtfFillStyle( maBkColor, mnBkMode == TRANSPARENT );
1006 [ + + ]: 418 : if (!( maLatestFillStyle == maFillStyle ) )
1007 : : {
1008 : 158 : maLatestFillStyle = maFillStyle;
1009 [ + - ]: 158 : if (maFillStyle.aType == FillStyleSolid)
1010 [ + - ]: 158 : mpGDIMetaFile->AddAction( new MetaFillColorAction( maFillStyle.aFillColor, !maFillStyle.bTransparent ) );
1011 : : }
1012 : 418 : }
1013 : :
1014 : : //-----------------------------------------------------------------------------------
1015 : :
1016 : 504 : sal_uInt32 WinMtfOutput::SetRasterOp( sal_uInt32 nRasterOp )
1017 : : {
1018 : 504 : sal_uInt32 nRetROP = mnRop;
1019 [ + + ]: 504 : if ( nRasterOp != mnRop )
1020 : : {
1021 : 306 : mnRop = nRasterOp;
1022 [ + + ][ + - ]: 306 : static WinMtfFillStyle aNopFillStyle;
[ + - ][ # # ]
1023 [ + + ][ + - ]: 306 : static WinMtfLineStyle aNopLineStyle;
[ + - ][ # # ]
1024 : :
1025 [ - + ][ # # ]: 306 : if ( mbNopMode && ( nRasterOp != R2_NOP ) )
1026 : : { // beim uebergang von R2_NOP auf anderen Modus
1027 : : // gesetzten Pen und Brush aktivieren
1028 : 0 : maFillStyle = aNopFillStyle;
1029 : 0 : maLineStyle = aNopLineStyle;
1030 : 0 : mbNopMode = sal_False;
1031 : : }
1032 [ - - - + ]: 306 : switch( nRasterOp )
1033 : : {
1034 : : case R2_NOT:
1035 : 0 : meRasterOp = ROP_INVERT;
1036 : 0 : break;
1037 : :
1038 : : case R2_XORPEN:
1039 : 0 : meRasterOp = ROP_XOR;
1040 : 0 : break;
1041 : :
1042 : : case R2_NOP:
1043 : : {
1044 : 0 : meRasterOp = ROP_OVERPAINT;
1045 [ # # ]: 0 : if( mbNopMode == sal_False )
1046 : : {
1047 : 0 : aNopFillStyle = maFillStyle;
1048 : 0 : aNopLineStyle = maLineStyle;
1049 [ # # ][ # # ]: 0 : maFillStyle = WinMtfFillStyle( Color( COL_TRANSPARENT ), sal_True );
[ # # ]
1050 [ # # ][ # # ]: 0 : maLineStyle = WinMtfLineStyle( Color( COL_TRANSPARENT ), sal_True );
[ # # ]
1051 : 0 : mbNopMode = sal_True;
1052 : : }
1053 : : }
1054 : 0 : break;
1055 : :
1056 : : default:
1057 : 306 : meRasterOp = ROP_OVERPAINT;
1058 : 306 : break;
1059 : : }
1060 : : }
1061 [ + + ]: 504 : if ( nRetROP != nRasterOp )
1062 [ + - ]: 306 : mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
1063 : 504 : return nRetROP;
1064 : : };
1065 : :
1066 : : //-----------------------------------------------------------------------------------
1067 : :
1068 : 0 : void WinMtfOutput::StrokeAndFillPath( sal_Bool bStroke, sal_Bool bFill )
1069 : : {
1070 [ # # ]: 0 : if ( aPathObj.Count() )
1071 : : {
1072 : 0 : UpdateClipRegion();
1073 : 0 : UpdateLineStyle();
1074 : 0 : UpdateFillStyle();
1075 [ # # ]: 0 : if ( bFill )
1076 : : {
1077 [ # # ]: 0 : if ( !bStroke )
1078 : : {
1079 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPushAction( PUSH_LINECOLOR ) );
1080 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
[ # # ]
1081 : : }
1082 [ # # ]: 0 : if ( aPathObj.Count() == 1 )
1083 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolygonAction( aPathObj.GetObject( 0 ) ) );
1084 : : else
1085 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( aPathObj ) );
1086 : :
1087 [ # # ]: 0 : if ( !bStroke )
1088 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPopAction() );
1089 : : }
1090 : : else
1091 : : {
1092 : 0 : sal_uInt16 i, nCount = aPathObj.Count();
1093 [ # # ]: 0 : for ( i = 0; i < nCount; i++ )
1094 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( aPathObj[ i ], maLineStyle.aLineInfo ) );
1095 : : }
1096 : 0 : ClearPath();
1097 : : }
1098 : 0 : }
1099 : :
1100 : : //-----------------------------------------------------------------------------------
1101 : :
1102 : 0 : void WinMtfOutput::DrawPixel( const Point& rSource, const Color& rColor )
1103 : : {
1104 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPixelAction( ImplMap( rSource), rColor ) );
[ # # ]
1105 : 0 : }
1106 : :
1107 : : //-----------------------------------------------------------------------------------
1108 : :
1109 : 0 : void WinMtfOutput::MoveTo( const Point& rPoint, sal_Bool bRecordPath )
1110 : : {
1111 : 0 : Point aDest( ImplMap( rPoint ) );
1112 [ # # ]: 0 : if ( bRecordPath )
1113 [ # # ]: 0 : aPathObj.AddPoint( aDest );
1114 : 0 : maActPos = aDest;
1115 : 0 : }
1116 : :
1117 : : //-----------------------------------------------------------------------------------
1118 : :
1119 : 0 : void WinMtfOutput::LineTo( const Point& rPoint, sal_Bool bRecordPath )
1120 : : {
1121 [ # # ]: 0 : UpdateClipRegion();
1122 : :
1123 : 0 : Point aDest( ImplMap( rPoint ) );
1124 [ # # ]: 0 : if ( bRecordPath )
1125 [ # # ]: 0 : aPathObj.AddPoint( aDest );
1126 : : else
1127 : : {
1128 [ # # ]: 0 : UpdateLineStyle();
1129 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaLineAction( maActPos, aDest, maLineStyle.aLineInfo ) );
[ # # ]
1130 : : }
1131 : 0 : maActPos = aDest;
1132 : 0 : }
1133 : :
1134 : : //-----------------------------------------------------------------------------------
1135 : :
1136 : 137 : void WinMtfOutput::DrawRect( const Rectangle& rRect, sal_Bool bEdge )
1137 : : {
1138 : 137 : UpdateClipRegion();
1139 : 137 : UpdateFillStyle();
1140 : :
1141 [ - + ]: 137 : if ( mbComplexClip )
1142 : : {
1143 [ # # ][ # # ]: 0 : Polygon aPoly( ImplMap( rRect ) );
1144 [ # # ]: 0 : PolyPolygon aPolyPolyRect( aPoly );
1145 [ # # ]: 0 : PolyPolygon aDest;
1146 [ # # ][ # # ]: 0 : PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPolyRect, aDest );
[ # # ][ # # ]
[ # # ]
1147 [ # # ][ # # ]: 0 : ImplDrawClippedPolyPolygon( aDest );
[ # # ][ # # ]
1148 : : }
1149 : : else
1150 : : {
1151 [ + + ]: 137 : if ( bEdge )
1152 : : {
1153 [ + - ][ - + ]: 27 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
[ - + ]
1154 : : {
1155 : 0 : ImplSetNonPersistentLineColorTransparenz();
1156 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
[ # # ]
1157 : 0 : UpdateLineStyle();
1158 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( ImplMap( rRect ) ),maLineStyle.aLineInfo ) );
[ # # ][ # # ]
[ # # ]
1159 : : }
1160 : : else
1161 : : {
1162 : 27 : UpdateLineStyle();
1163 [ + - ][ + - ]: 27 : mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
[ + - ]
1164 : : }
1165 : : }
1166 : : else
1167 : : {
1168 : 110 : ImplSetNonPersistentLineColorTransparenz();
1169 [ + - ][ + - ]: 110 : mpGDIMetaFile->AddAction( new MetaRectAction( ImplMap( rRect ) ) );
[ + - ]
1170 : : }
1171 : : }
1172 : 137 : }
1173 : :
1174 : : //-----------------------------------------------------------------------------------
1175 : :
1176 : 0 : void WinMtfOutput::DrawRoundRect( const Rectangle& rRect, const Size& rSize )
1177 : : {
1178 : 0 : UpdateClipRegion();
1179 : 0 : UpdateLineStyle();
1180 : 0 : UpdateFillStyle();
1181 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaRoundRectAction( ImplMap( rRect ), labs( ImplMap( rSize ).Width() ), labs( ImplMap( rSize ).Height() ) ) );
[ # # ]
1182 : 0 : }
1183 : :
1184 : : //-----------------------------------------------------------------------------------
1185 : :
1186 : 0 : void WinMtfOutput::DrawEllipse( const Rectangle& rRect )
1187 : : {
1188 : 0 : UpdateClipRegion();
1189 : 0 : UpdateFillStyle();
1190 : :
1191 [ # # ][ # # ]: 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
[ # # ]
1192 : : {
1193 [ # # ]: 0 : Point aCenter( ImplMap( rRect.Center() ) );
1194 [ # # ][ # # ]: 0 : Size aRad( ImplMap( Size( rRect.GetWidth() / 2, rRect.GetHeight() / 2 ) ) );
1195 : :
1196 [ # # ]: 0 : ImplSetNonPersistentLineColorTransparenz();
1197 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
[ # # ][ # # ]
1198 [ # # ]: 0 : UpdateLineStyle();
1199 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
[ # # ][ # # ]
[ # # ]
1200 : : }
1201 : : else
1202 : : {
1203 : 0 : UpdateLineStyle();
1204 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaEllipseAction( ImplMap( rRect ) ) );
[ # # ]
1205 : : }
1206 : 0 : }
1207 : :
1208 : : //-----------------------------------------------------------------------------------
1209 : :
1210 : 0 : void WinMtfOutput::DrawArc( const Rectangle& rRect, const Point& rStart, const Point& rEnd, sal_Bool bTo )
1211 : : {
1212 [ # # ]: 0 : UpdateClipRegion();
1213 [ # # ]: 0 : UpdateLineStyle();
1214 [ # # ]: 0 : UpdateFillStyle();
1215 : :
1216 [ # # ]: 0 : Rectangle aRect( ImplMap( rRect ) );
1217 : 0 : Point aStart( ImplMap( rStart ) );
1218 : 0 : Point aEnd( ImplMap( rEnd ) );
1219 : :
1220 [ # # ][ # # ]: 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
[ # # ]
1221 : : {
1222 [ # # ]: 0 : if ( aStart == aEnd )
1223 : : { // SJ: #i53768# if start & end is identical, then we have to draw a full ellipse
1224 [ # # ]: 0 : Point aCenter( aRect.Center() );
1225 [ # # ][ # # ]: 0 : Size aRad( aRect.GetWidth() / 2, aRect.GetHeight() / 2 );
1226 : :
1227 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aCenter, aRad.Width(), aRad.Height() ), maLineStyle.aLineInfo ) );
[ # # ][ # # ]
[ # # ]
1228 : : }
1229 : : else
1230 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_ARC ), maLineStyle.aLineInfo ) );
[ # # ][ # # ]
[ # # ]
1231 : : }
1232 : : else
1233 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaArcAction( aRect, aStart, aEnd ) );
[ # # ]
1234 : :
1235 [ # # ]: 0 : if ( bTo )
1236 : 0 : maActPos = aEnd;
1237 : 0 : }
1238 : :
1239 : : //-----------------------------------------------------------------------------------
1240 : :
1241 : 0 : void WinMtfOutput::DrawPie( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
1242 : : {
1243 [ # # ]: 0 : UpdateClipRegion();
1244 [ # # ]: 0 : UpdateFillStyle();
1245 : :
1246 [ # # ]: 0 : Rectangle aRect( ImplMap( rRect ) );
1247 : 0 : Point aStart( ImplMap( rStart ) );
1248 : 0 : Point aEnd( ImplMap( rEnd ) );
1249 : :
1250 [ # # ][ # # ]: 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
[ # # ]
1251 : : {
1252 [ # # ]: 0 : ImplSetNonPersistentLineColorTransparenz();
1253 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
[ # # ]
1254 [ # # ]: 0 : UpdateLineStyle();
1255 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_PIE ), maLineStyle.aLineInfo ) );
[ # # ][ # # ]
[ # # ]
1256 : : }
1257 : : else
1258 : : {
1259 [ # # ]: 0 : UpdateLineStyle();
1260 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPieAction( aRect, aStart, aEnd ) );
[ # # ]
1261 : : }
1262 : 0 : }
1263 : :
1264 : : //-----------------------------------------------------------------------------------
1265 : :
1266 : 0 : void WinMtfOutput::DrawChord( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
1267 : : {
1268 [ # # ]: 0 : UpdateClipRegion();
1269 [ # # ]: 0 : UpdateFillStyle();
1270 : :
1271 [ # # ]: 0 : Rectangle aRect( ImplMap( rRect ) );
1272 : 0 : Point aStart( ImplMap( rStart ) );
1273 : 0 : Point aEnd( ImplMap( rEnd ) );
1274 : :
1275 [ # # ][ # # ]: 0 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
[ # # ]
1276 : : {
1277 [ # # ]: 0 : ImplSetNonPersistentLineColorTransparenz();
1278 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
[ # # ]
1279 [ # # ]: 0 : UpdateLineStyle();
1280 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( Polygon( aRect, aStart, aEnd, POLY_CHORD ), maLineStyle.aLineInfo ) );
[ # # ][ # # ]
[ # # ]
1281 : : }
1282 : : else
1283 : : {
1284 [ # # ]: 0 : UpdateLineStyle();
1285 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaChordAction( aRect, aStart, aEnd ) );
[ # # ]
1286 : : }
1287 : 0 : }
1288 : :
1289 : : //-----------------------------------------------------------------------------------
1290 : :
1291 : 171 : void WinMtfOutput::DrawPolygon( Polygon& rPolygon, sal_Bool bRecordPath )
1292 : : {
1293 : 171 : UpdateClipRegion();
1294 : 171 : ImplMap( rPolygon );
1295 [ - + ]: 171 : if ( bRecordPath )
1296 : 0 : aPathObj.AddPolygon( rPolygon );
1297 : : else
1298 : : {
1299 : 171 : UpdateFillStyle();
1300 : :
1301 [ - + ]: 171 : if ( mbComplexClip )
1302 : : {
1303 [ # # ]: 0 : PolyPolygon aPolyPoly( rPolygon );
1304 [ # # ]: 0 : PolyPolygon aDest;
1305 [ # # ][ # # ]: 0 : PolyPolygon(aClipPath.getClipPath()).GetIntersection( aPolyPoly, aDest );
[ # # ][ # # ]
[ # # ]
1306 [ # # ][ # # ]: 0 : ImplDrawClippedPolyPolygon( aDest );
[ # # ]
1307 : : }
1308 : : else
1309 : : {
1310 [ + + ][ - + ]: 171 : if ( maLineStyle.aLineInfo.GetWidth() || ( maLineStyle.aLineInfo.GetStyle() == LINE_DASH ) )
[ + + ]
1311 : : {
1312 : 3 : sal_uInt16 nCount = rPolygon.GetSize();
1313 [ + - ]: 3 : if ( nCount )
1314 : : {
1315 [ - + ]: 3 : if ( rPolygon[ nCount - 1 ] != rPolygon[ 0 ] )
1316 : : {
1317 [ # # ]: 0 : Point aPoint( rPolygon[ 0 ] );
1318 [ # # ]: 0 : rPolygon.Insert( nCount, aPoint );
1319 : : }
1320 : : }
1321 : 3 : ImplSetNonPersistentLineColorTransparenz();
1322 [ + - ]: 3 : mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
1323 : 3 : UpdateLineStyle();
1324 [ + - ]: 3 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
1325 : : }
1326 : : else
1327 : : {
1328 : 168 : UpdateLineStyle();
1329 : :
1330 [ + - ]: 168 : if (maLatestFillStyle.aType != FillStylePattern)
1331 [ + - ]: 168 : mpGDIMetaFile->AddAction( new MetaPolygonAction( rPolygon ) );
1332 : : else {
1333 : : SvtGraphicFill aFill = SvtGraphicFill( PolyPolygon( rPolygon ),
1334 : : Color(),
1335 : : 0.0,
1336 : : SvtGraphicFill::fillNonZero,
1337 : : SvtGraphicFill::fillTexture,
1338 : : SvtGraphicFill::Transform(),
1339 : : true,
1340 : : SvtGraphicFill::hatchSingle,
1341 : : Color(),
1342 : : SvtGraphicFill::gradientLinear,
1343 : : Color(),
1344 : : Color(),
1345 : : 0,
1346 [ # # ][ # # ]: 0 : Graphic (maLatestFillStyle.aBmp) );
[ # # ][ # # ]
[ # # ][ # # ]
1347 : :
1348 [ # # ]: 0 : SvMemoryStream aMemStm;
1349 : :
1350 [ # # ]: 0 : aMemStm << aFill;
1351 : :
1352 : : mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_BEGIN", 0,
1353 : : static_cast<const sal_uInt8*>(aMemStm.GetData()),
1354 [ # # ][ # # ]: 0 : aMemStm.Seek( STREAM_SEEK_TO_END ) ) );
[ # # ][ # # ]
[ # # ]
1355 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaCommentAction( "XPATHFILL_SEQ_END" ) );
[ # # ][ # # ]
[ # # ]
1356 : : }
1357 : :
1358 : : }
1359 : : }
1360 : : }
1361 : 171 : }
1362 : :
1363 : : //-----------------------------------------------------------------------------------
1364 : :
1365 : 0 : void WinMtfOutput::DrawPolyPolygon( PolyPolygon& rPolyPolygon, sal_Bool bRecordPath )
1366 : : {
1367 : 0 : UpdateClipRegion();
1368 : :
1369 : 0 : ImplMap( rPolyPolygon );
1370 : :
1371 [ # # ]: 0 : if ( bRecordPath )
1372 : 0 : aPathObj.AddPolyPolygon( rPolyPolygon );
1373 : : else
1374 : : {
1375 : 0 : UpdateFillStyle();
1376 : :
1377 [ # # ]: 0 : if ( mbComplexClip )
1378 : : {
1379 [ # # ]: 0 : PolyPolygon aDest;
1380 [ # # ][ # # ]: 0 : PolyPolygon(aClipPath.getClipPath()).GetIntersection( rPolyPolygon, aDest );
[ # # ][ # # ]
[ # # ]
1381 [ # # ][ # # ]: 0 : ImplDrawClippedPolyPolygon( aDest );
1382 : : }
1383 : : else
1384 : : {
1385 : 0 : UpdateLineStyle();
1386 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPolygon ) );
1387 : : }
1388 : : }
1389 : 0 : }
1390 : :
1391 : : //-----------------------------------------------------------------------------------
1392 : :
1393 : 414 : void WinMtfOutput::DrawPolyLine( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
1394 : : {
1395 : 414 : UpdateClipRegion();
1396 : :
1397 : 414 : ImplMap( rPolygon );
1398 [ - + ]: 414 : if ( bTo )
1399 : : {
1400 : 0 : rPolygon[ 0 ] = maActPos;
1401 : 0 : maActPos = rPolygon[ rPolygon.GetSize() - 1 ];
1402 : : }
1403 [ - + ]: 414 : if ( bRecordPath )
1404 : 0 : aPathObj.AddPolyLine( rPolygon );
1405 : : else
1406 : : {
1407 : 414 : UpdateLineStyle();
1408 [ + - ]: 414 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
1409 : : }
1410 : 414 : }
1411 : :
1412 : : //-----------------------------------------------------------------------------------
1413 : :
1414 : 0 : void WinMtfOutput::DrawPolyBezier( Polygon& rPolygon, sal_Bool bTo, sal_Bool bRecordPath )
1415 : : {
1416 : 0 : UpdateClipRegion();
1417 : :
1418 : 0 : sal_uInt16 nPoints = rPolygon.GetSize();
1419 [ # # ][ # # ]: 0 : if ( ( nPoints >= 4 ) && ( ( ( nPoints - 4 ) % 3 ) == 0 ) )
1420 : : {
1421 : 0 : ImplMap( rPolygon );
1422 [ # # ]: 0 : if ( bTo )
1423 : : {
1424 : 0 : rPolygon[ 0 ] = maActPos;
1425 : 0 : maActPos = rPolygon[ nPoints - 1 ];
1426 : : }
1427 : : sal_uInt16 i;
1428 [ # # ]: 0 : for ( i = 0; ( i + 2 ) < nPoints; )
1429 : : {
1430 : 0 : rPolygon.SetFlags( i++, POLY_NORMAL );
1431 : 0 : rPolygon.SetFlags( i++, POLY_CONTROL );
1432 : 0 : rPolygon.SetFlags( i++, POLY_CONTROL );
1433 : : }
1434 [ # # ]: 0 : if ( bRecordPath )
1435 : 0 : aPathObj.AddPolyLine( rPolygon );
1436 : : else
1437 : : {
1438 : 0 : UpdateLineStyle();
1439 [ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaPolyLineAction( rPolygon, maLineStyle.aLineInfo ) );
1440 : : }
1441 : : }
1442 : 0 : }
1443 : :
1444 : : //-----------------------------------------------------------------------------------
1445 : :
1446 : 191 : void WinMtfOutput::DrawText( Point& rPosition, String& rText, sal_Int32* pDXArry, sal_Bool bRecordPath, sal_Int32 nGfxMode )
1447 : : {
1448 [ + - ]: 191 : UpdateClipRegion();
1449 : :
1450 : 191 : VirtualDevice* pVDev = NULL;
1451 : :
1452 : 191 : rPosition = ImplMap( rPosition );
1453 : :
1454 : 191 : sal_Int32 nOldGfxMode = GetGfxMode();
1455 : 191 : SetGfxMode( GM_COMPATIBLE );
1456 [ + - ]: 191 : if ( pDXArry )
1457 : : {
1458 : 191 : sal_Int32 i, nSum, nLen = rText.Len();
1459 : :
1460 [ + + ]: 985 : for( i = 0, nSum = 0; i < nLen; i++ )
1461 : : {
1462 : 794 : sal_Int32 nTemp = ImplMap( Size( pDXArry[ i ], 0 ) ).Width();
1463 : 794 : nSum += nTemp;
1464 : 794 : pDXArry[ i ] = nSum;
1465 : : }
1466 : : }
1467 [ - + ]: 191 : if ( mnLatestTextLayoutMode != mnTextLayoutMode )
1468 : : {
1469 : 0 : mnLatestTextLayoutMode = mnTextLayoutMode;
1470 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaLayoutModeAction( mnTextLayoutMode ) );
[ # # ]
1471 : : }
1472 : 191 : SetGfxMode( nGfxMode );
1473 : 191 : sal_Bool bChangeFont = sal_False;
1474 [ + + ]: 191 : if ( mnLatestTextAlign != mnTextAlign )
1475 : : {
1476 : 9 : bChangeFont = sal_True;
1477 : 9 : mnLatestTextAlign = mnTextAlign;
1478 : : TextAlign eTextAlign;
1479 [ + - ]: 9 : if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
1480 : 9 : eTextAlign = ALIGN_BASELINE;
1481 [ # # ]: 0 : else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
1482 : 0 : eTextAlign = ALIGN_BOTTOM;
1483 : : else
1484 : 0 : eTextAlign = ALIGN_TOP;
1485 [ + - ][ + - ]: 9 : mpGDIMetaFile->AddAction( new MetaTextAlignAction( eTextAlign ) );
[ + - ]
1486 : : }
1487 [ - + ]: 191 : if ( maLatestTextColor != maTextColor )
1488 : : {
1489 : 0 : bChangeFont = sal_True;
1490 : 0 : maLatestTextColor = maTextColor;
1491 [ # # ][ # # ]: 0 : mpGDIMetaFile->AddAction( new MetaTextColorAction( maTextColor ) );
[ # # ]
1492 : : }
1493 : 191 : sal_Bool bChangeFillColor = sal_False;
1494 [ + + ]: 191 : if ( maLatestBkColor != maBkColor )
1495 : : {
1496 : 23 : bChangeFillColor = sal_True;
1497 : 23 : maLatestBkColor = maBkColor;
1498 : : }
1499 [ + + ]: 191 : if ( mnLatestBkMode != mnBkMode )
1500 : : {
1501 : 23 : bChangeFillColor = sal_True;
1502 : 23 : mnLatestBkMode = mnBkMode;
1503 : : }
1504 [ + + ]: 191 : if ( bChangeFillColor )
1505 : : {
1506 : 23 : bChangeFont = sal_True;
1507 [ + - ][ + - ]: 23 : mpGDIMetaFile->AddAction( new MetaTextFillColorAction( maFont.GetFillColor(), !maFont.IsTransparent() ) );
[ + - ][ + - ]
[ + - ]
1508 : : }
1509 [ + - ]: 191 : Font aTmp( maFont );
1510 [ + - ]: 191 : aTmp.SetColor( maTextColor );
1511 [ + - ]: 191 : aTmp.SetFillColor( maBkColor );
1512 : :
1513 [ + - ]: 191 : if( mnBkMode == TRANSPARENT )
1514 [ + - ]: 191 : aTmp.SetTransparent( sal_True );
1515 : : else
1516 [ # # ]: 0 : aTmp.SetTransparent( sal_False );
1517 : :
1518 [ + + ]: 191 : if ( ( mnTextAlign & TA_BASELINE) == TA_BASELINE )
1519 [ + - ]: 171 : aTmp.SetAlign( ALIGN_BASELINE );
1520 [ - + ]: 20 : else if( ( mnTextAlign & TA_BOTTOM) == TA_BOTTOM )
1521 [ # # ]: 0 : aTmp.SetAlign( ALIGN_BOTTOM );
1522 : : else
1523 [ + - ]: 20 : aTmp.SetAlign( ALIGN_TOP );
1524 : :
1525 [ - + ]: 191 : if ( nGfxMode == GM_ADVANCED )
1526 : : {
1527 : : // check whether there is a font rotation applied via transformation
1528 : 0 : Point aP1( ImplMap( Point() ) );
1529 : 0 : Point aP2( ImplMap( Point( 0, 100 ) ) );
1530 : 0 : aP2.X() -= aP1.X();
1531 : 0 : aP2.Y() -= aP1.Y();
1532 : 0 : double fX = aP2.X();
1533 : 0 : double fY = aP2.Y();
1534 [ # # ]: 0 : if ( fX )
1535 : : {
1536 : 0 : double fOrientation = acos( fX / sqrt( fX * fX + fY * fY ) ) * 57.29577951308;
1537 [ # # ]: 0 : if ( fY > 0 )
1538 : 0 : fOrientation = 360 - fOrientation;
1539 : 0 : fOrientation += 90;
1540 : 0 : fOrientation *= 10;
1541 [ # # ]: 0 : fOrientation += aTmp.GetOrientation();
1542 [ # # ]: 0 : aTmp.SetOrientation( sal_Int16( fOrientation ) );
1543 : : }
1544 : : }
1545 : :
1546 [ - + ]: 191 : if( mnTextAlign & ( TA_UPDATECP | TA_RIGHT_CENTER ) )
1547 : : {
1548 [ # # ]: 0 : if ( !pVDev )
1549 [ # # ][ # # ]: 0 : pVDev = new VirtualDevice;
1550 : : sal_Int32 nTextWidth;
1551 [ # # ][ # # ]: 0 : pVDev->SetMapMode( MapMode( MAP_100TH_MM ) );
[ # # ]
1552 [ # # ]: 0 : pVDev->SetFont( maFont );
1553 [ # # ]: 0 : if( pDXArry )
1554 : : {
1555 : 0 : sal_uInt32 nLen = rText.Len();
1556 [ # # ][ # # ]: 0 : nTextWidth = pVDev->GetTextWidth( rtl::OUString(rText.GetChar( (sal_uInt16)( nLen - 1 ) )) );
[ # # ]
1557 [ # # ]: 0 : if( nLen > 1 )
1558 : 0 : nTextWidth += pDXArry[ nLen - 2 ];
1559 : : }
1560 : : else
1561 [ # # ]: 0 : nTextWidth = pVDev->GetTextWidth( rText );
1562 : :
1563 [ # # ]: 0 : if( mnTextAlign & TA_UPDATECP )
1564 : 0 : rPosition = maActPos;
1565 : :
1566 [ # # ]: 0 : if ( mnTextAlign & TA_RIGHT_CENTER )
1567 : : {
1568 [ # # ]: 0 : double fLenght = ( ( mnTextAlign & TA_RIGHT_CENTER ) == TA_RIGHT ) ? nTextWidth : nTextWidth >> 1;
1569 [ # # ]: 0 : rPosition.X() -= (sal_Int32)( fLenght * cos( maFont.GetOrientation() * F_PI1800 ) );
1570 [ # # ]: 0 : rPosition.Y() -= (sal_Int32)(-( fLenght * sin( maFont.GetOrientation() * F_PI1800 ) ) );
1571 : : }
1572 : :
1573 [ # # ]: 0 : if( mnTextAlign & TA_UPDATECP )
1574 : 0 : maActPos.X() = rPosition.X() + nTextWidth;
1575 : : }
1576 [ + + ][ + - ]: 191 : if ( bChangeFont || ( maLatestFont != aTmp ) )
[ + + ][ + + ]
1577 : : {
1578 [ + - ]: 41 : maLatestFont = aTmp;
1579 [ + - ][ + - ]: 41 : mpGDIMetaFile->AddAction( new MetaFontAction( aTmp ) );
[ + - ]
1580 [ + - ][ + - ]: 41 : mpGDIMetaFile->AddAction( new MetaTextAlignAction( aTmp.GetAlign() ) );
[ + - ][ + - ]
1581 [ + - ][ + - ]: 41 : mpGDIMetaFile->AddAction( new MetaTextColorAction( aTmp.GetColor() ) );
[ + - ][ + - ]
1582 [ + - ][ + - ]: 41 : mpGDIMetaFile->AddAction( new MetaTextFillColorAction( aTmp.GetFillColor(), !aTmp.IsTransparent() ) );
[ + - ][ + - ]
[ + - ]
1583 : : }
1584 [ + - ]: 191 : if ( bRecordPath )
1585 : : {
1586 : : // ToDo
1587 : : }
1588 : : else
1589 : : {
1590 : : /* because text without dx array is badly scaled, we
1591 : : will create such an array if necessary */
1592 : 191 : sal_Int32* pDX = pDXArry;
1593 [ - + ]: 191 : if ( !pDXArry )
1594 : : {
1595 [ # # ]: 0 : SolarMutexGuard aGuard;
1596 : :
1597 [ # # ]: 0 : pDX = new sal_Int32[ rText.Len() ];
1598 [ # # ]: 0 : if ( !pVDev )
1599 [ # # ][ # # ]: 0 : pVDev = new VirtualDevice;
1600 [ # # ][ # # ]: 0 : pVDev->SetMapMode( MAP_100TH_MM );
[ # # ]
1601 [ # # ]: 0 : pVDev->SetFont( maLatestFont );
1602 [ # # ][ # # ]: 0 : pVDev->GetTextArray( rText, pDX, 0, STRING_LEN );
1603 : : }
1604 [ + - ][ + - ]: 191 : mpGDIMetaFile->AddAction( new MetaTextArrayAction( rPosition, rText, pDX, 0, STRING_LEN ) );
[ + - ][ + - ]
1605 [ - + ]: 191 : if ( !pDXArry ) // this means we have created our own array
1606 [ # # ]: 0 : delete[] pDX; // which must be deleted
1607 : : }
1608 : 191 : SetGfxMode( nOldGfxMode );
1609 [ # # ][ + - ]: 191 : delete pVDev;
[ - + ]
1610 : 191 : }
1611 : :
1612 : : //-----------------------------------------------------------------------------------
1613 : :
1614 : 6 : void WinMtfOutput::ImplDrawBitmap( const Point& rPos, const Size& rSize, const BitmapEx rBitmap )
1615 : : {
1616 [ + - ]: 6 : BitmapEx aBmpEx( rBitmap );
1617 [ - + ]: 6 : if ( mbComplexClip )
1618 : : {
1619 [ # # ]: 0 : VirtualDevice aVDev;
1620 [ # # ]: 0 : MapMode aMapMode( MAP_100TH_MM );
1621 [ # # ]: 0 : aMapMode.SetOrigin( Point( -rPos.X(), -rPos.Y() ) );
1622 [ # # ]: 0 : const Size aOutputSizePixel( aVDev.LogicToPixel( rSize, aMapMode ) );
1623 : 0 : const Size aSizePixel( rBitmap.GetSizePixel() );
1624 [ # # ][ # # ]: 0 : if ( aOutputSizePixel.Width() && aOutputSizePixel.Height() )
[ # # ]
1625 : : {
1626 [ # # ][ # # ]: 0 : aMapMode.SetScaleX( Fraction( aSizePixel.Width(), aOutputSizePixel.Width() ) );
1627 [ # # ][ # # ]: 0 : aMapMode.SetScaleY( Fraction( aSizePixel.Height(), aOutputSizePixel.Height() ) );
1628 : : }
1629 [ # # ]: 0 : aVDev.SetMapMode( aMapMode );
1630 [ # # ]: 0 : aVDev.SetOutputSizePixel( aSizePixel );
1631 [ # # ]: 0 : aVDev.SetFillColor( Color( COL_BLACK ) );
1632 [ # # ][ # # ]: 0 : const PolyPolygon aClip( aClipPath.getClipPath() );
[ # # ]
1633 [ # # ]: 0 : aVDev.DrawPolyPolygon( aClip );
1634 : 0 : const Point aEmptyPoint;
1635 : :
1636 : : // #i50672# Extract whole VDev content (to match size of rBitmap)
1637 [ # # ]: 0 : aVDev.EnableMapMode( sal_False );
1638 [ # # ][ # # ]: 0 : Bitmap aMask( aVDev.GetBitmap( aEmptyPoint, aSizePixel ).CreateMask( Color( COL_WHITE ) ) );
[ # # ]
1639 : :
1640 [ # # ][ # # ]: 0 : if ( aBmpEx.IsTransparent() )
1641 : : {
1642 [ # # ]: 0 : if ( rBitmap.GetTransparentColor() == Color( COL_WHITE ) )
1643 [ # # ][ # # ]: 0 : aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_OR );
[ # # ]
1644 : : else
1645 [ # # ][ # # ]: 0 : aMask.CombineSimple( rBitmap.GetMask(), BMP_COMBINE_AND );
[ # # ]
1646 [ # # ][ # # ]: 0 : aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
[ # # ][ # # ]
[ # # ]
1647 : : }
1648 : : else
1649 [ # # ][ # # ]: 0 : aBmpEx = BitmapEx( rBitmap.GetBitmap(), aMask );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1650 : : }
1651 [ + - ][ + - ]: 6 : if ( aBmpEx.IsTransparent() )
1652 [ + - ][ + - ]: 6 : mpGDIMetaFile->AddAction( new MetaBmpExScaleAction( rPos, rSize, aBmpEx ) );
[ + - ]
1653 : : else
1654 [ # # ][ # # ]: 6 : mpGDIMetaFile->AddAction( new MetaBmpScaleAction( rPos, rSize, aBmpEx.GetBitmap() ) );
[ # # ][ # # ]
[ # # ][ + - ]
1655 : 6 : }
1656 : :
1657 : : //-----------------------------------------------------------------------------------
1658 : :
1659 : 77 : void WinMtfOutput::ResolveBitmapActions( BSaveStructList_impl& rSaveList )
1660 : : {
1661 : 77 : UpdateClipRegion();
1662 : :
1663 : 77 : size_t nObjects = rSaveList.size();
1664 : 77 : size_t nObjectsLeft = nObjects;
1665 : :
1666 [ + + ]: 193 : while ( nObjectsLeft )
1667 : : {
1668 : : size_t i;
1669 : 116 : size_t nObjectsOfSameSize = 0;
1670 : 116 : size_t nObjectStartIndex = nObjects - nObjectsLeft;
1671 : :
1672 : 116 : BSaveStruct* pSave = rSaveList[ nObjectStartIndex ];
1673 : 116 : Rectangle aRect( pSave->aOutRect );
1674 : :
1675 [ + + ]: 199 : for ( i = nObjectStartIndex; i < nObjects; )
1676 : : {
1677 : 122 : nObjectsOfSameSize++;
1678 [ + + ]: 122 : if ( ++i < nObjects )
1679 : : {
1680 : 45 : pSave = rSaveList[ i ];
1681 [ + + ][ + - ]: 45 : if ( pSave->aOutRect != aRect )
1682 : 39 : break;
1683 : : }
1684 : : }
1685 : 116 : Point aPos( ImplMap( aRect.TopLeft() ) );
1686 [ + - ]: 116 : Size aSize( ImplMap( aRect.GetSize() ) );
1687 : :
1688 [ + + ]: 232 : for ( i = nObjectStartIndex; i < ( nObjectStartIndex + nObjectsOfSameSize ); i++ )
1689 : : {
1690 : 116 : pSave = rSaveList[ i ];
1691 : :
1692 : 116 : sal_uInt32 nWinRop = pSave->nWinRop;
1693 : 116 : sal_uInt8 nRasterOperation = (sal_uInt8)( nWinRop >> 16 );
1694 : :
1695 : 116 : sal_uInt32 nUsed = 0;
1696 [ + + ]: 116 : if ( ( nRasterOperation & 0xf ) != ( nRasterOperation >> 4 ) )
1697 : 110 : nUsed |= 1; // pattern is used
1698 [ + + ]: 116 : if ( ( nRasterOperation & 0x33 ) != ( ( nRasterOperation & 0xcc ) >> 2 ) )
1699 : 6 : nUsed |= 2; // source is used
1700 [ + + ]: 116 : if ( ( nRasterOperation & 0xaa ) != ( ( nRasterOperation & 0x55 ) << 1 ) )
1701 : 6 : nUsed |= 4; // destination is used
1702 : :
1703 [ + + ][ + - ]: 116 : if ( (nUsed & 1) && (( nUsed & 2 ) == 0) && nWinRop != PATINVERT )
[ + - ]
1704 : : { // patterns aren't well supported yet
1705 [ + - ]: 110 : sal_uInt32 nOldRop = SetRasterOp( ROP_OVERPAINT ); // in this case nRasterOperation is either 0 or 0xff
1706 [ + - ]: 110 : UpdateFillStyle();
1707 [ + - ]: 110 : DrawRect( aRect, sal_False );
1708 [ + - ]: 110 : SetRasterOp( nOldRop );
1709 : : }
1710 : : else
1711 : : {
1712 : 6 : sal_Bool bDrawn = sal_False;
1713 : :
1714 [ + - ]: 6 : if ( i == nObjectStartIndex ) // optimizing, sometimes it is possible to create just one transparent bitmap
1715 : : {
1716 [ + - ]: 6 : if ( nObjectsOfSameSize == 2 )
1717 : : {
1718 : 6 : BSaveStruct* pSave2 = rSaveList[ i + 1 ];
1719 [ + - ][ + - ]: 12 : if ( ( pSave->aBmp.GetPrefSize() == pSave2->aBmp.GetPrefSize() ) &&
[ + - ]
1720 [ + - ]: 6 : ( pSave->aBmp.GetPrefMapMode() == pSave2->aBmp.GetPrefMapMode() ) )
1721 : : {
1722 : : // TODO: Strictly speaking, we should
1723 : : // check whether mask is monochrome, and
1724 : : // whether image is black (upper branch)
1725 : : // or white (lower branch). Otherwise, the
1726 : : // effect is not the same as a masked
1727 : : // bitmap.
1728 [ + - ][ + - ]: 6 : if ( ( nWinRop == SRCPAINT ) && ( pSave2->nWinRop == SRCAND ) )
1729 : : {
1730 [ + - ][ + - ]: 6 : Bitmap aMask( pSave->aBmp ); aMask.Invert();
1731 [ + - ]: 6 : BitmapEx aBmpEx( pSave2->aBmp, aMask );
1732 [ + - ][ + - ]: 6 : ImplDrawBitmap( aPos, aSize, aBmpEx );
[ + - ]
1733 : 6 : bDrawn = sal_True;
1734 [ + - ][ + - ]: 6 : i++;
1735 : : }
1736 : : // #i20085# This is just the other way
1737 : : // around as above. Only difference: mask
1738 : : // is inverted
1739 [ # # ][ # # ]: 0 : else if ( ( nWinRop == SRCAND ) && ( pSave2->nWinRop == SRCPAINT ) )
1740 : : {
1741 [ # # ]: 0 : Bitmap aMask( pSave->aBmp );
1742 [ # # ]: 0 : BitmapEx aBmpEx( pSave2->aBmp, aMask );
1743 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
[ # # ]
1744 : 0 : bDrawn = sal_True;
1745 [ # # ][ # # ]: 6 : i++;
1746 : : }
1747 : : }
1748 : : }
1749 : : }
1750 : :
1751 [ - + ]: 6 : if ( !bDrawn )
1752 : : {
1753 [ # # ]: 0 : Push();
1754 [ # # ]: 0 : sal_uInt32 nOldRop = SetRasterOp( R2_COPYPEN );
1755 [ # # ]: 0 : Bitmap aBitmap( pSave->aBmp );
1756 : 0 : sal_uInt32 nOperation = ( nRasterOperation & 0xf );
1757 [ # # # # : 0 : switch( nOperation )
# # # # #
# ]
1758 : : {
1759 : : case 0x1 :
1760 : : case 0xe :
1761 : : {
1762 [ # # ]: 0 : SetRasterOp( R2_XORPEN );
1763 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
[ # # ]
1764 [ # # ]: 0 : SetRasterOp( R2_COPYPEN );
1765 [ # # ]: 0 : Bitmap aMask( aBitmap );
1766 [ # # ]: 0 : aMask.Invert();
1767 [ # # ]: 0 : BitmapEx aBmpEx( aBitmap, aMask );
1768 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
[ # # ]
1769 [ # # ]: 0 : if ( nOperation == 0x1 )
1770 : : {
1771 [ # # ]: 0 : SetRasterOp( R2_NOT );
1772 [ # # ]: 0 : DrawRect( aRect, sal_False );
1773 [ # # ][ # # ]: 0 : }
1774 : : }
1775 : 0 : break;
1776 : : case 0x7 :
1777 : : case 0x8 :
1778 : : {
1779 [ # # ]: 0 : Bitmap aMask( aBitmap );
1780 [ # # ][ # # ]: 0 : if ( ( nUsed & 1 ) && ( nRasterOperation & 0xb0 ) == 0xb0 ) // pattern used
1781 : : {
1782 [ # # ]: 0 : aBitmap.Convert( BMP_CONVERSION_24BIT );
1783 [ # # ]: 0 : aBitmap.Erase( maFillStyle.aFillColor );
1784 : : }
1785 [ # # ]: 0 : BitmapEx aBmpEx( aBitmap, aMask );
1786 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
[ # # ]
1787 [ # # ]: 0 : if ( nOperation == 0x7 )
1788 : : {
1789 [ # # ]: 0 : SetRasterOp( R2_NOT );
1790 [ # # ]: 0 : DrawRect( aRect, sal_False );
1791 [ # # ][ # # ]: 0 : }
1792 : : }
1793 : 0 : break;
1794 : :
1795 : : case 0x4 :
1796 : : case 0xb :
1797 : : {
1798 [ # # ]: 0 : SetRasterOp( R2_NOT );
1799 [ # # ]: 0 : DrawRect( aRect, sal_False );
1800 [ # # ]: 0 : SetRasterOp( R2_COPYPEN );
1801 [ # # ]: 0 : Bitmap aMask( aBitmap );
1802 [ # # ]: 0 : aBitmap.Invert();
1803 [ # # ]: 0 : BitmapEx aBmpEx( aBitmap, aMask );
1804 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
[ # # ]
1805 [ # # ]: 0 : SetRasterOp( R2_XORPEN );
1806 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
[ # # ]
1807 [ # # ]: 0 : if ( nOperation == 0xb )
1808 : : {
1809 [ # # ]: 0 : SetRasterOp( R2_NOT );
1810 [ # # ]: 0 : DrawRect( aRect, sal_False );
1811 [ # # ][ # # ]: 0 : }
1812 : : }
1813 : 0 : break;
1814 : :
1815 : : case 0x2 :
1816 : : case 0xd :
1817 : : {
1818 [ # # ]: 0 : Bitmap aMask( aBitmap );
1819 [ # # ]: 0 : aMask.Invert();
1820 [ # # ]: 0 : BitmapEx aBmpEx( aBitmap, aMask );
1821 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBmpEx );
[ # # ]
1822 [ # # ]: 0 : SetRasterOp( R2_XORPEN );
1823 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
[ # # ]
1824 [ # # ]: 0 : if ( nOperation == 0xd )
1825 : : {
1826 [ # # ]: 0 : SetRasterOp( R2_NOT );
1827 [ # # ]: 0 : DrawRect( aRect, sal_False );
1828 [ # # ][ # # ]: 0 : }
1829 : : }
1830 : 0 : break;
1831 : : case 0x6 :
1832 : : case 0x9 :
1833 : : {
1834 [ # # ]: 0 : SetRasterOp( R2_XORPEN );
1835 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
[ # # ]
1836 [ # # ]: 0 : if ( nOperation == 0x9 )
1837 : : {
1838 [ # # ]: 0 : SetRasterOp( R2_NOT );
1839 [ # # ]: 0 : DrawRect( aRect, sal_False );
1840 : : }
1841 : : }
1842 : 0 : break;
1843 : :
1844 : : case 0x0 : // WHITENESS
1845 : : case 0xf : // BLACKNESS
1846 : : { // in this case nRasterOperation is either 0 or 0xff
1847 [ # # ][ # # ]: 0 : maFillStyle = WinMtfFillStyle( Color( nRasterOperation, nRasterOperation, nRasterOperation ) );
[ # # ]
1848 [ # # ]: 0 : UpdateFillStyle();
1849 [ # # ]: 0 : DrawRect( aRect, sal_False );
1850 : : }
1851 : 0 : break;
1852 : :
1853 : : case 0x3 : // only source is used
1854 : : case 0xc :
1855 : : {
1856 [ # # ]: 0 : if ( nRasterOperation == 0x33 )
1857 [ # # ]: 0 : aBitmap.Invert();
1858 [ # # ][ # # ]: 0 : ImplDrawBitmap( aPos, aSize, aBitmap );
[ # # ]
1859 : : }
1860 : 0 : break;
1861 : :
1862 : : case 0x5 : // only destination is used
1863 : : {
1864 [ # # ]: 0 : SetRasterOp( R2_NOT );
1865 [ # # ]: 0 : DrawRect( aRect, sal_False );
1866 : : }
1867 : : case 0xa : // no operation
1868 : 0 : break;
1869 : : }
1870 [ # # ]: 0 : SetRasterOp( nOldRop );
1871 [ # # ][ # # ]: 0 : Pop();
1872 : : }
1873 : : }
1874 : : }
1875 : 116 : nObjectsLeft -= nObjectsOfSameSize;
1876 : : }
1877 : :
1878 [ + + ]: 199 : for( size_t i = 0, n = rSaveList.size(); i < n; ++i )
1879 [ + - ]: 122 : delete rSaveList[ i ];
1880 : 77 : rSaveList.clear();
1881 : 77 : }
1882 : :
1883 : : //-----------------------------------------------------------------------------------
1884 : :
1885 : 104 : void WinMtfOutput::SetDevOrg( const Point& rPoint )
1886 : : {
1887 : 104 : mnDevOrgX = rPoint.X();
1888 : 104 : mnDevOrgY = rPoint.Y();
1889 : 104 : }
1890 : :
1891 : : //-----------------------------------------------------------------------------------
1892 : :
1893 : 0 : void WinMtfOutput::SetDevOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
1894 : : {
1895 : 0 : mnDevOrgX += nXAdd;
1896 : 0 : mnDevOrgY += nYAdd;
1897 : 0 : }
1898 : :
1899 : : //-----------------------------------------------------------------------------------
1900 : :
1901 : 83 : void WinMtfOutput::SetDevExt( const Size& rSize )
1902 : : {
1903 [ + - ][ + - ]: 83 : if ( rSize.Width() && rSize.Height() )
[ + - ]
1904 : : {
1905 [ + - ]: 83 : switch( mnMapMode )
1906 : : {
1907 : : case MM_ISOTROPIC :
1908 : : case MM_ANISOTROPIC :
1909 : : {
1910 : 83 : mnDevWidth = rSize.Width();
1911 : 83 : mnDevHeight = rSize.Height();
1912 : : }
1913 : : }
1914 : : }
1915 : 83 : }
1916 : :
1917 : : //-----------------------------------------------------------------------------------
1918 : :
1919 : 9 : void WinMtfOutput::ScaleDevExt( double fX, double fY )
1920 : : {
1921 : 9 : mnDevWidth = FRound( mnDevWidth * fX );
1922 : 9 : mnDevHeight = FRound( mnDevHeight * fY );
1923 : 9 : }
1924 : :
1925 : : //-----------------------------------------------------------------------------------
1926 : :
1927 : 148 : void WinMtfOutput::SetWinOrg( const Point& rPoint )
1928 : : {
1929 : 148 : mnWinOrgX = rPoint.X();
1930 : 148 : mnWinOrgY = rPoint.Y();
1931 : 148 : }
1932 : :
1933 : : //-----------------------------------------------------------------------------------
1934 : :
1935 : 0 : void WinMtfOutput::SetWinOrgOffset( sal_Int32 nXAdd, sal_Int32 nYAdd )
1936 : : {
1937 : 0 : mnWinOrgX += nXAdd;
1938 : 0 : mnWinOrgY += nYAdd;
1939 : 0 : }
1940 : :
1941 : : //-----------------------------------------------------------------------------------
1942 : :
1943 : 156 : void WinMtfOutput::SetWinExt( const Size& rSize )
1944 : : {
1945 : :
1946 [ + - ][ + - ]: 156 : if( rSize.Width() && rSize.Height() )
[ + - ]
1947 : : {
1948 [ + + ]: 156 : switch( mnMapMode )
1949 : : {
1950 : : case MM_ISOTROPIC :
1951 : : case MM_ANISOTROPIC :
1952 : : {
1953 : 147 : mnWinExtX = rSize.Width();
1954 : 147 : mnWinExtY = rSize.Height();
1955 : : }
1956 : : }
1957 : : }
1958 : 156 : }
1959 : :
1960 : : //-----------------------------------------------------------------------------------
1961 : :
1962 : 0 : void WinMtfOutput::ScaleWinExt( double fX, double fY )
1963 : : {
1964 : 0 : mnWinExtX = FRound( mnWinExtX * fX );
1965 : 0 : mnWinExtY = FRound( mnWinExtY * fY );
1966 : 0 : }
1967 : :
1968 : : //-----------------------------------------------------------------------------------
1969 : :
1970 : 44 : void WinMtfOutput::SetrclBounds( const Rectangle& rRect )
1971 : : {
1972 : 44 : mrclBounds = rRect;
1973 : 44 : }
1974 : :
1975 : : //-----------------------------------------------------------------------------------
1976 : :
1977 : 44 : void WinMtfOutput::SetrclFrame( const Rectangle& rRect )
1978 : : {
1979 : 44 : mrclFrame = rRect;
1980 : 44 : }
1981 : :
1982 : : //-----------------------------------------------------------------------------------
1983 : :
1984 : 44 : void WinMtfOutput::SetRefPix( const Size& rSize )
1985 : : {
1986 : 44 : mnPixX = rSize.Width();
1987 : 44 : mnPixY = rSize.Height();
1988 : 44 : }
1989 : :
1990 : : //-----------------------------------------------------------------------------------
1991 : :
1992 : 44 : void WinMtfOutput::SetRefMill( const Size& rSize )
1993 : : {
1994 : 44 : mnMillX = rSize.Width();
1995 : 44 : mnMillY = rSize.Height();
1996 : 44 : }
1997 : :
1998 : : //-----------------------------------------------------------------------------------
1999 : :
2000 : 88 : void WinMtfOutput::SetMapMode( sal_uInt32 nMapMode )
2001 : : {
2002 : 88 : mnMapMode = nMapMode;
2003 [ + + ]: 88 : if ( nMapMode == MM_TEXT )
2004 : : {
2005 : 6 : mnWinExtX = mnDevWidth;
2006 : 6 : mnWinExtY = mnDevHeight;
2007 : : }
2008 [ - + ]: 82 : else if ( mnMapMode == MM_HIMETRIC )
2009 : : {
2010 : 0 : mnWinExtX = mnMillX * 100;
2011 : 0 : mnWinExtY = mnMillY * 100;
2012 : : }
2013 : 88 : }
2014 : :
2015 : : //-----------------------------------------------------------------------------------
2016 : :
2017 : 30 : void WinMtfOutput::SetUnitsPerInch( sal_uInt16 nUnitsPerInch )
2018 : : {
2019 [ + - ]: 30 : if( nUnitsPerInch != 0 )
2020 : 30 : mnUnitsPerInch = nUnitsPerInch;
2021 : 30 : }
2022 : :
2023 : : //-----------------------------------------------------------------------------------
2024 : :
2025 : 0 : void WinMtfOutput::SetWorldTransform( const XForm& rXForm )
2026 : : {
2027 : 0 : maXForm.eM11 = rXForm.eM11;
2028 : 0 : maXForm.eM12 = rXForm.eM12;
2029 : 0 : maXForm.eM21 = rXForm.eM21;
2030 : 0 : maXForm.eM22 = rXForm.eM22;
2031 : 0 : maXForm.eDx = rXForm.eDx;
2032 : 0 : maXForm.eDy = rXForm.eDy;
2033 : 0 : }
2034 : :
2035 : : //-----------------------------------------------------------------------------------
2036 : :
2037 : 0 : void WinMtfOutput::ModifyWorldTransform( const XForm& rXForm, sal_uInt32 nMode )
2038 : : {
2039 [ # # # ]: 0 : switch( nMode )
2040 : : {
2041 : : case MWT_IDENTITY :
2042 : : {
2043 : 0 : maXForm.eM11 = maXForm.eM12 = maXForm.eM21 = maXForm.eM22 = 1.0f;
2044 : 0 : maXForm.eDx = maXForm.eDy = 0.0f;
2045 : : }
2046 : 0 : break;
2047 : :
2048 : : case MWT_RIGHTMULTIPLY :
2049 : : case MWT_LEFTMULTIPLY :
2050 : : {
2051 : : const XForm* pLeft;
2052 : : const XForm* pRight;
2053 : :
2054 [ # # ]: 0 : if ( nMode == MWT_LEFTMULTIPLY )
2055 : : {
2056 : 0 : pLeft = &rXForm;
2057 : 0 : pRight = &maXForm;
2058 : : }
2059 : : else
2060 : : {
2061 : 0 : pLeft = &maXForm;
2062 : 0 : pRight = &rXForm;
2063 : : }
2064 : :
2065 : : float aF[3][3];
2066 : : float bF[3][3];
2067 : : float cF[3][3];
2068 : :
2069 : 0 : aF[0][0] = pLeft->eM11;
2070 : 0 : aF[0][1] = pLeft->eM12;
2071 : 0 : aF[0][2] = 0;
2072 : 0 : aF[1][0] = pLeft->eM21;
2073 : 0 : aF[1][1] = pLeft->eM22;
2074 : 0 : aF[1][2] = 0;
2075 : 0 : aF[2][0] = pLeft->eDx;
2076 : 0 : aF[2][1] = pLeft->eDy;
2077 : 0 : aF[2][2] = 1;
2078 : :
2079 : 0 : bF[0][0] = pRight->eM11;
2080 : 0 : bF[0][1] = pRight->eM12;
2081 : 0 : bF[0][2] = 0;
2082 : 0 : bF[1][0] = pRight->eM21;
2083 : 0 : bF[1][1] = pRight->eM22;
2084 : 0 : bF[1][2] = 0;
2085 : 0 : bF[2][0] = pRight->eDx;
2086 : 0 : bF[2][1] = pRight->eDy;
2087 : 0 : bF[2][2] = 1;
2088 : :
2089 : : int i, j, k;
2090 [ # # ]: 0 : for ( i = 0; i < 3; i++ )
2091 : : {
2092 [ # # ]: 0 : for ( j = 0; j < 3; j++ )
2093 : : {
2094 : 0 : cF[i][j] = 0;
2095 [ # # ]: 0 : for ( k = 0; k < 3; k++ )
2096 : 0 : cF[i][j] += aF[i][k] * bF[k][j];
2097 : : }
2098 : : }
2099 : 0 : maXForm.eM11 = cF[0][0];
2100 : 0 : maXForm.eM12 = cF[0][1];
2101 : 0 : maXForm.eM21 = cF[1][0];
2102 : 0 : maXForm.eM22 = cF[1][1];
2103 : 0 : maXForm.eDx = cF[2][0];
2104 : 0 : maXForm.eDy = cF[2][1];
2105 : : }
2106 : 0 : break;
2107 : : }
2108 : 0 : }
2109 : :
2110 : : //-----------------------------------------------------------------------------------
2111 : :
2112 : 245 : void WinMtfOutput::Push() // !! to be able to access the original ClipRegion it
2113 : : { // is not allowed to use the MetaPushAction()
2114 [ + - ]: 245 : UpdateClipRegion(); // (the original clip region is on top of the stack) (SJ)
2115 [ + - ][ + - ]: 245 : SaveStructPtr pSave( new SaveStruct );
[ + - ]
2116 : :
2117 [ + - ]: 245 : pSave->aLineStyle = maLineStyle;
2118 [ + - ]: 245 : pSave->aFillStyle = maFillStyle;
2119 : :
2120 [ + - ]: 245 : pSave->aFont = maFont;
2121 : 245 : pSave->aTextColor = maTextColor;
2122 : 245 : pSave->nTextAlign = mnTextAlign;
2123 : 245 : pSave->nTextLayoutMode = mnTextLayoutMode;
2124 : 245 : pSave->nMapMode = mnMapMode;
2125 : 245 : pSave->nGfxMode = mnGfxMode;
2126 : 245 : pSave->nBkMode = mnBkMode;
2127 : 245 : pSave->aBkColor = maBkColor;
2128 : 245 : pSave->bFillStyleSelected = mbFillStyleSelected;
2129 : :
2130 : 245 : pSave->aActPos = maActPos;
2131 : 245 : pSave->aXForm = maXForm;
2132 : 245 : pSave->eRasterOp = meRasterOp;
2133 : :
2134 : 245 : pSave->nWinOrgX = mnWinOrgX;
2135 : 245 : pSave->nWinOrgY = mnWinOrgY;
2136 : 245 : pSave->nWinExtX = mnWinExtX;
2137 : 245 : pSave->nWinExtY = mnWinExtY;
2138 : 245 : pSave->nDevOrgX = mnDevOrgX;
2139 : 245 : pSave->nDevOrgY = mnDevOrgY;
2140 : 245 : pSave->nDevWidth = mnDevWidth;
2141 : 245 : pSave->nDevHeight = mnDevHeight;
2142 : :
2143 [ + - ]: 245 : pSave->aPathObj = aPathObj;
2144 [ + - ]: 245 : pSave->aClipPath = aClipPath;
2145 : :
2146 [ + - ][ + - ]: 245 : vSaveStack.push_back( pSave );
2147 : 245 : }
2148 : :
2149 : : //-----------------------------------------------------------------------------------
2150 : :
2151 : 209 : void WinMtfOutput::Pop()
2152 : : {
2153 : : // Die aktuellen Daten vom Stack holen
2154 [ + - ]: 209 : if( !vSaveStack.empty() )
2155 : : {
2156 : : // Die aktuelle Daten auf dem Stack sichern
2157 [ + - ][ + - ]: 209 : SaveStructPtr pSave( vSaveStack.back() );
2158 : :
2159 [ + - ]: 209 : maLineStyle = pSave->aLineStyle;
2160 [ + - ]: 209 : maFillStyle = pSave->aFillStyle;
2161 : :
2162 [ + - ]: 209 : maFont = pSave->aFont;
2163 : 209 : maTextColor = pSave->aTextColor;
2164 : 209 : mnTextAlign = pSave->nTextAlign;
2165 : 209 : mnTextLayoutMode = pSave->nTextLayoutMode;
2166 : 209 : mnBkMode = pSave->nBkMode;
2167 : 209 : mnGfxMode = pSave->nGfxMode;
2168 : 209 : mnMapMode = pSave->nMapMode;
2169 : 209 : maBkColor = pSave->aBkColor;
2170 : 209 : mbFillStyleSelected = pSave->bFillStyleSelected;
2171 : :
2172 : 209 : maActPos = pSave->aActPos;
2173 : 209 : maXForm = pSave->aXForm;
2174 : 209 : meRasterOp = pSave->eRasterOp;
2175 : :
2176 : 209 : mnWinOrgX = pSave->nWinOrgX;
2177 : 209 : mnWinOrgY = pSave->nWinOrgY;
2178 : 209 : mnWinExtX = pSave->nWinExtX;
2179 : 209 : mnWinExtY = pSave->nWinExtY;
2180 : 209 : mnDevOrgX = pSave->nDevOrgX;
2181 : 209 : mnDevOrgY = pSave->nDevOrgY;
2182 : 209 : mnDevWidth = pSave->nDevWidth;
2183 : 209 : mnDevHeight = pSave->nDevHeight;
2184 : :
2185 [ + - ]: 209 : aPathObj = pSave->aPathObj;
2186 [ + - ][ + + ]: 209 : if ( ! ( aClipPath == pSave->aClipPath ) )
2187 : : {
2188 [ + - ]: 9 : aClipPath = pSave->aClipPath;
2189 : 9 : mbClipNeedsUpdate = true;
2190 : : }
2191 [ + - ]: 209 : if ( meLatestRasterOp != meRasterOp )
2192 [ + - ][ + - ]: 209 : mpGDIMetaFile->AddAction( new MetaRasterOpAction( meRasterOp ) );
[ + - ]
2193 [ + - ][ + - ]: 209 : vSaveStack.pop_back();
2194 : : }
2195 : 209 : }
2196 : :
2197 : 0 : void WinMtfOutput::AddFromGDIMetaFile( GDIMetaFile& rGDIMetaFile )
2198 : : {
2199 : 0 : rGDIMetaFile.Play( *mpGDIMetaFile, 0xFFFFFFFF );
2200 : 0 : }
2201 : :
2202 : 9 : void WinMtfOutput::PassEMFPlusHeaderInfo()
2203 : : {
2204 : : EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS header info\n"));
2205 : :
2206 [ + - ]: 9 : SvMemoryStream mem;
2207 : : sal_Int32 nLeft, nRight, nTop, nBottom;
2208 : :
2209 : 9 : nLeft = mrclFrame.Left();
2210 : 9 : nTop = mrclFrame.Top();
2211 : 9 : nRight = mrclFrame.Right();
2212 : 9 : nBottom = mrclFrame.Bottom();
2213 : :
2214 : : // emf header info
2215 [ + - ][ + - ]: 9 : mem << nLeft << nTop << nRight << nBottom;
[ + - ][ + - ]
2216 [ + - ][ + - ]: 9 : mem << mnPixX << mnPixY << mnMillX << mnMillY;
[ + - ][ + - ]
2217 : :
2218 : : float one, zero;
2219 : :
2220 : 9 : one = 1;
2221 : 9 : zero = 0;
2222 : :
2223 : : // add transformation matrix to be used in vcl's metaact.cxx for
2224 : : // rotate and scale operations
2225 [ + - ][ + - ]: 9 : mem << one << zero << zero << one << zero << zero;
[ + - ][ + - ]
[ + - ][ + - ]
2226 : :
2227 : : // need to flush the stream, otherwise GetEndOfData will return 0
2228 : : // on windows where the function parameters are probably resolved in reverse order
2229 [ + - ]: 9 : mem.Flush();
2230 : :
2231 [ + - ][ + - ]: 9 : mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS_HEADER_INFO", 0, (const sal_uInt8*) mem.GetData(), mem.GetEndOfData() ) );
[ + - ][ + - ]
2232 [ + - ][ + - ]: 9 : mpGDIMetaFile->UseCanvas( sal_True );
2233 : 9 : }
2234 : :
2235 : 201 : void WinMtfOutput::PassEMFPlus( void* pBuffer, sal_uInt32 nLength )
2236 : : {
2237 : : EMFP_DEBUG(printf ("\t\t\tadd EMF_PLUS comment length %04x\n",(unsigned int) nLength));
2238 [ + - ][ + - ]: 201 : mpGDIMetaFile->AddAction( new MetaCommentAction( "EMF_PLUS", 0, static_cast<const sal_uInt8*>(pBuffer), nLength ) );
[ + - ]
2239 : 201 : }
2240 : :
2241 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|