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 : :
30 : : #include <tools/debug.hxx>
31 : : #include <tools/poly.hxx>
32 : :
33 : : #include <vcl/svapp.hxx>
34 : : #include <vcl/ctrl.hxx>
35 : : #include <vcl/region.hxx>
36 : : #include <vcl/virdev.hxx>
37 : : #include <vcl/window.hxx>
38 : : #include <vcl/metaact.hxx>
39 : : #include <vcl/gdimtf.hxx>
40 : : #include <vcl/print.hxx>
41 : : #include <vcl/outdev.hxx>
42 : : #include <vcl/unowrap.hxx>
43 : : // declare system types in sysdata.hxx
44 : : #include <svsys.h>
45 : : #include <vcl/sysdata.hxx>
46 : :
47 : : #include <salgdi.hxx>
48 : : #include <sallayout.hxx>
49 : : #include <salframe.hxx>
50 : : #include <salvd.hxx>
51 : : #include <salprn.hxx>
52 : : #include <svdata.hxx>
53 : : #include <window.h>
54 : : #include <outdev.h>
55 : : #include <region.h>
56 : : #include <outdata.hxx>
57 : :
58 : : #include <basegfx/point/b2dpoint.hxx>
59 : : #include <basegfx/vector/b2dvector.hxx>
60 : : #include <basegfx/polygon/b2dpolygon.hxx>
61 : : #include <basegfx/polygon/b2dpolypolygon.hxx>
62 : : #include <basegfx/matrix/b2dhommatrix.hxx>
63 : : #include <basegfx/polygon/b2dpolygontools.hxx>
64 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
65 : : #include <basegfx/polygon/b2dlinegeometry.hxx>
66 : :
67 : : #include <com/sun/star/awt/XGraphics.hpp>
68 : : #include <com/sun/star/uno/Sequence.hxx>
69 : : #include <com/sun/star/rendering/XCanvas.hpp>
70 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
71 : : #include <vcl/unohelp.hxx>
72 : :
73 : : #include <numeric>
74 : :
75 : : using namespace ::com::sun::star;
76 : :
77 : : DBG_NAME( OutputDevice )
78 : : DBG_NAME( Polygon )
79 : : DBG_NAME( PolyPolygon )
80 : : DBG_NAMEEX( Region )
81 : :
82 : : // -----------------------------------------------------------------------
83 : :
84 : : #ifdef DBG_UTIL
85 : : const char* ImplDbgCheckOutputDevice( const void* pObj )
86 : : {
87 : : DBG_TESTSOLARMUTEX();
88 : :
89 : : const OutputDevice* pOutDev = (OutputDevice*)pObj;
90 : :
91 : : if ( (pOutDev->GetOutDevType() != OUTDEV_DONTKNOW) &&
92 : : (pOutDev->GetOutDevType() != OUTDEV_WINDOW) &&
93 : : (pOutDev->GetOutDevType() != OUTDEV_PRINTER) &&
94 : : (pOutDev->GetOutDevType() != OUTDEV_VIRDEV) )
95 : : return "OutputDevice data overwrite";
96 : :
97 : : return NULL;
98 : : }
99 : : #endif
100 : :
101 : : // =======================================================================
102 : :
103 : : #define OUTDEV_POLYPOLY_STACKBUF 32
104 : :
105 : : // =======================================================================
106 : :
107 : : struct ImplObjStack
108 : : {
109 : : ImplObjStack* mpPrev;
110 : : MapMode* mpMapMode;
111 : : Region* mpClipRegion;
112 : : Color* mpLineColor;
113 : : Color* mpFillColor;
114 : : Font* mpFont;
115 : : Color* mpTextColor;
116 : : Color* mpTextFillColor;
117 : : Color* mpTextLineColor;
118 : : Color* mpOverlineColor;
119 : : Point* mpRefPoint;
120 : : TextAlign meTextAlign;
121 : : RasterOp meRasterOp;
122 : : sal_uLong mnTextLayoutMode;
123 : : LanguageType meTextLanguage;
124 : : sal_uInt16 mnFlags;
125 : : };
126 : :
127 : : // -----------------------------------------------------------------------
128 : :
129 : 1004685 : static void ImplDeleteObjStack( ImplObjStack* pObjStack )
130 : : {
131 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_LINECOLOR )
132 : : {
133 [ + + ]: 240711 : if ( pObjStack->mpLineColor )
134 : 180607 : delete pObjStack->mpLineColor;
135 : : }
136 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_FILLCOLOR )
137 : : {
138 [ + + ]: 197792 : if ( pObjStack->mpFillColor )
139 : 188586 : delete pObjStack->mpFillColor;
140 : : }
141 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_FONT )
142 [ + - ]: 177255 : delete pObjStack->mpFont;
143 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_TEXTCOLOR )
144 : 161289 : delete pObjStack->mpTextColor;
145 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_TEXTFILLCOLOR )
146 : : {
147 [ + + ]: 67816 : if ( pObjStack->mpTextFillColor )
148 : 820 : delete pObjStack->mpTextFillColor;
149 : : }
150 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_TEXTLINECOLOR )
151 : : {
152 [ + + ]: 67816 : if ( pObjStack->mpTextLineColor )
153 : 940 : delete pObjStack->mpTextLineColor;
154 : : }
155 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_OVERLINECOLOR )
156 : : {
157 [ + + ]: 67816 : if ( pObjStack->mpOverlineColor )
158 : 934 : delete pObjStack->mpOverlineColor;
159 : : }
160 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_MAPMODE )
161 : : {
162 [ + + ]: 224503 : if ( pObjStack->mpMapMode )
163 [ + - ]: 162255 : delete pObjStack->mpMapMode;
164 : : }
165 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_CLIPREGION )
166 : : {
167 [ + + ]: 523866 : if ( pObjStack->mpClipRegion )
168 [ + - ]: 264065 : delete pObjStack->mpClipRegion;
169 : : }
170 [ + + ]: 1004685 : if ( pObjStack->mnFlags & PUSH_REFPOINT )
171 : : {
172 [ - + ]: 67816 : if ( pObjStack->mpRefPoint )
173 : 0 : delete pObjStack->mpRefPoint;
174 : : }
175 : :
176 : 1004685 : delete pObjStack;
177 : 1004685 : }
178 : :
179 : : // -----------------------------------------------------------------------
180 : :
181 : 405141 : bool OutputDevice::ImplIsAntiparallel() const
182 : : {
183 : 405141 : bool bRet = false;
184 [ + - ]: 405141 : if( ImplGetGraphics() )
185 : : {
186 [ + + ][ + - : 1200042 : if( ( (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && ! IsRTLEnabled() ) ||
+ + + + ]
[ + + ]
187 : 794901 : ( ! (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) && IsRTLEnabled() ) )
188 : : {
189 : 2046 : bRet = true;
190 : : }
191 : : }
192 : 405141 : return bRet;
193 : : }
194 : :
195 : : // -----------------------------------------------------------------------
196 : :
197 : :
198 : 415321 : bool OutputDevice::ImplSelectClipRegion( const Region& rRegion, SalGraphics* pGraphics )
199 : : {
200 : : DBG_TESTSOLARMUTEX();
201 : :
202 [ + + ]: 415321 : if( !pGraphics )
203 : : {
204 [ - + ]: 414922 : if( !mpGraphics )
205 [ # # ]: 0 : if( !ImplGetGraphics() )
206 : 0 : return false;
207 : 414922 : pGraphics = mpGraphics;
208 : : }
209 : :
210 : 415321 : bool bClipRegion = pGraphics->SetClipRegion( rRegion, this );
211 : : OSL_ENSURE( bClipRegion, "OutputDevice::ImplSelectClipRegion() - can't cerate region" );
212 : 415321 : return bClipRegion;
213 : : }
214 : :
215 : :
216 : : // =======================================================================
217 : :
218 : 6822 : Polygon ImplSubdivideBezier( const Polygon& rPoly )
219 : : {
220 : 6822 : Polygon aPoly;
221 : :
222 : : // #100127# Use adaptive subdivide instead of fixed 25 segments
223 [ + - ]: 6822 : rPoly.AdaptiveSubdivide( aPoly );
224 : :
225 : 6822 : return aPoly;
226 : : }
227 : :
228 : : // =======================================================================
229 : :
230 : 1830 : PolyPolygon ImplSubdivideBezier( const PolyPolygon& rPolyPoly )
231 : : {
232 : 1830 : sal_uInt16 i, nPolys = rPolyPoly.Count();
233 : 1830 : PolyPolygon aPolyPoly( nPolys );
234 [ + + ]: 6443 : for( i=0; i<nPolys; ++i )
235 [ + - ][ + - ]: 4613 : aPolyPoly.Insert( ImplSubdivideBezier( rPolyPoly.GetObject(i) ) );
[ + - ][ + - ]
236 : :
237 : 1830 : return aPolyPoly;
238 : : }
239 : :
240 : : // =======================================================================
241 : :
242 : : // #100127# Extracted from OutputDevice::DrawPolyPolygon()
243 : 290719 : void OutputDevice::ImplDrawPolyPolygon( sal_uInt16 nPoly, const PolyPolygon& rPolyPoly )
244 : : {
245 : : // AW: This crashes on empty PolyPolygons, avoid that
246 [ + - ]: 290719 : if(!nPoly)
247 : 290719 : return;
248 : :
249 : : sal_uInt32 aStackAry1[OUTDEV_POLYPOLY_STACKBUF];
250 : : PCONSTSALPOINT aStackAry2[OUTDEV_POLYPOLY_STACKBUF];
251 : : sal_uInt8* aStackAry3[OUTDEV_POLYPOLY_STACKBUF];
252 : : sal_uInt32* pPointAry;
253 : : PCONSTSALPOINT* pPointAryAry;
254 : : const sal_uInt8** pFlagAryAry;
255 : 290719 : sal_uInt16 i = 0, j = 0, last = 0;
256 : 290719 : sal_Bool bHaveBezier = sal_False;
257 [ - + ]: 290719 : if ( nPoly > OUTDEV_POLYPOLY_STACKBUF )
258 : : {
259 [ # # ]: 0 : pPointAry = new sal_uInt32[nPoly];
260 [ # # ]: 0 : pPointAryAry = new PCONSTSALPOINT[nPoly];
261 [ # # ]: 0 : pFlagAryAry = new const sal_uInt8*[nPoly];
262 : : }
263 : : else
264 : : {
265 : 290719 : pPointAry = aStackAry1;
266 : 290719 : pPointAryAry = aStackAry2;
267 : 290719 : pFlagAryAry = (const sal_uInt8**)aStackAry3;
268 : : }
269 [ + + ]: 321192 : do
270 : : {
271 [ + - ]: 321192 : const Polygon& rPoly = rPolyPoly.GetObject( i );
272 [ + - ]: 321192 : sal_uInt16 nSize = rPoly.GetSize();
273 [ + - ]: 321192 : if ( nSize )
274 : : {
275 : 321192 : pPointAry[j] = nSize;
276 [ + - ]: 321192 : pPointAryAry[j] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
277 [ + - ]: 321192 : pFlagAryAry[j] = rPoly.GetConstFlagAry();
278 : 321192 : last = i;
279 : :
280 [ + + ]: 321192 : if( pFlagAryAry[j] )
281 : 5863 : bHaveBezier = sal_True;
282 : :
283 : 321192 : ++j;
284 : : }
285 : :
286 : 321192 : ++i;
287 : : }
288 : : while ( i < nPoly );
289 : :
290 [ + + ]: 290719 : if ( j == 1 )
291 : : {
292 : : // #100127# Forward beziers to sal, if any
293 [ + + ]: 262366 : if( bHaveBezier )
294 : : {
295 [ + - ][ + - ]: 1494 : if( !mpGraphics->DrawPolygonBezier( *pPointAry, *pPointAryAry, *pFlagAryAry, this ) )
296 : : {
297 [ + - ][ + - ]: 1494 : Polygon aPoly = ImplSubdivideBezier( rPolyPoly.GetObject( last ) );
298 [ + - ][ + - ]: 1494 : mpGraphics->DrawPolygon( aPoly.GetSize(), (const SalPoint*)aPoly.GetConstPointAry(), this );
[ + - ][ + - ]
299 : : }
300 : : }
301 : : else
302 : : {
303 [ + - ]: 260872 : mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
304 : : }
305 : : }
306 : : else
307 : : {
308 : : // #100127# Forward beziers to sal, if any
309 [ + + ]: 28353 : if( bHaveBezier )
310 : : {
311 [ + - ][ + - ]: 1830 : if( !mpGraphics->DrawPolyPolygonBezier( j, pPointAry, pPointAryAry, pFlagAryAry, this ) )
312 : : {
313 [ + - ]: 1830 : PolyPolygon aPolyPoly = ImplSubdivideBezier( rPolyPoly );
314 [ + - ][ + - ]: 1830 : ImplDrawPolyPolygon( aPolyPoly.Count(), aPolyPoly );
[ + - ]
315 : : }
316 : : }
317 : : else
318 : : {
319 [ + - ]: 26523 : mpGraphics->DrawPolyPolygon( j, pPointAry, pPointAryAry, this );
320 : : }
321 : : }
322 : :
323 [ - + ]: 290719 : if ( pPointAry != aStackAry1 )
324 : : {
325 [ # # ]: 0 : delete[] pPointAry;
326 [ # # ]: 0 : delete[] pPointAryAry;
327 [ # # ]: 290719 : delete[] pFlagAryAry;
328 : : }
329 : : }
330 : :
331 : : // =======================================================================
332 : :
333 : 215106 : OutputDevice::OutputDevice() :
334 : : maRegion( REGION_NULL ),
335 : : maFillColor( COL_WHITE ),
336 : : maTextLineColor( COL_TRANSPARENT ),
337 [ + - ][ + - ]: 215106 : maSettings( Application::GetSettings() )
[ + - ][ + - ]
[ + - ][ + - ]
338 : : {
339 : : DBG_CTOR( OutputDevice, ImplDbgCheckOutputDevice );
340 : :
341 : 215106 : mpGraphics = NULL;
342 : 215106 : mpUnoGraphicsList = NULL;
343 : 215106 : mpPrevGraphics = NULL;
344 : 215106 : mpNextGraphics = NULL;
345 : 215106 : mpMetaFile = NULL;
346 : 215106 : mpFontEntry = NULL;
347 : 215106 : mpFontCache = NULL;
348 : 215106 : mpFontList = NULL;
349 : 215106 : mpGetDevFontList = NULL;
350 : 215106 : mpGetDevSizeList = NULL;
351 : 215106 : mpObjStack = NULL;
352 : 215106 : mpOutDevData = NULL;
353 : 215106 : mpPDFWriter = NULL;
354 : 215106 : mpAlphaVDev = NULL;
355 : 215106 : mpExtOutDevData = NULL;
356 : 215106 : mnOutOffX = 0;
357 : 215106 : mnOutOffY = 0;
358 : 215106 : mnOutWidth = 0;
359 : 215106 : mnOutHeight = 0;
360 : 215106 : mnDPIX = 0;
361 : 215106 : mnDPIY = 0;
362 : 215106 : mnTextOffX = 0;
363 : 215106 : mnTextOffY = 0;
364 : 215106 : mnOutOffOrigX = 0;
365 : 215106 : mnOutOffLogicX = 0;
366 : 215106 : mnOutOffOrigY = 0;
367 : 215106 : mnOutOffLogicY = 0;
368 : 215106 : mnEmphasisAscent = 0;
369 : 215106 : mnEmphasisDescent = 0;
370 : 215106 : mnDrawMode = 0;
371 : 215106 : mnTextLayoutMode = TEXT_LAYOUT_DEFAULT;
372 [ + - ][ - + ]: 215106 : if( Application::GetSettings().GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
[ + - ]
373 : 0 : mnTextLayoutMode = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
374 : 215106 : meOutDevType = OUTDEV_DONTKNOW;
375 : 215106 : meOutDevViewType = OUTDEV_VIEWTYPE_DONTKNOW;
376 : 215106 : mbMap = sal_False;
377 : 215106 : mbMapIsDefault = sal_True;
378 : 215106 : mbClipRegion = sal_False;
379 : 215106 : mbBackground = sal_False;
380 : 215106 : mbOutput = sal_True;
381 : 215106 : mbDevOutput = sal_False;
382 : 215106 : mbOutputClipped = sal_False;
383 : 215106 : maTextColor = Color( COL_BLACK );
384 : 215106 : maOverlineColor = Color( COL_TRANSPARENT );
385 [ + - ]: 215106 : meTextAlign = maFont.GetAlign();
386 : 215106 : meRasterOp = ROP_OVERPAINT;
387 : 215106 : mnAntialiasing = 0;
388 : 215106 : meTextLanguage = 0; // TODO: get default from configuration?
389 : 215106 : mbLineColor = sal_True;
390 : 215106 : mbFillColor = sal_True;
391 : 215106 : mbInitLineColor = sal_True;
392 : 215106 : mbInitFillColor = sal_True;
393 : 215106 : mbInitFont = sal_True;
394 : 215106 : mbInitTextColor = sal_True;
395 : 215106 : mbInitClipRegion = sal_True;
396 : 215106 : mbClipRegionSet = sal_False;
397 : 215106 : mbKerning = sal_False;
398 : 215106 : mbNewFont = sal_True;
399 : 215106 : mbTextLines = sal_False;
400 : 215106 : mbTextSpecial = sal_False;
401 : 215106 : mbRefPoint = sal_False;
402 : 215106 : mbEnableRTL = sal_False; // mirroring must be explicitly allowed (typically for windows only)
403 : :
404 : : // struct ImplMapRes
405 : 215106 : maMapRes.mnMapOfsX = 0;
406 : 215106 : maMapRes.mnMapOfsY = 0;
407 : 215106 : maMapRes.mnMapScNumX = 1;
408 : 215106 : maMapRes.mnMapScNumY = 1;
409 : 215106 : maMapRes.mnMapScDenomX = 1;
410 : 215106 : maMapRes.mnMapScDenomY = 1;
411 : : // struct ImplThresholdRes
412 : 215106 : maThresRes.mnThresLogToPixX = 0;
413 : 215106 : maThresRes.mnThresLogToPixY = 0;
414 : 215106 : maThresRes.mnThresPixToLogX = 0;
415 : 215106 : maThresRes.mnThresPixToLogY = 0;
416 : 215106 : }
417 : :
418 : : // -----------------------------------------------------------------------
419 : :
420 [ + - ][ + - ]: 210745 : OutputDevice::~OutputDevice()
[ + - ][ + - ]
[ + - ]
421 : : {
422 : : DBG_DTOR( OutputDevice, ImplDbgCheckOutputDevice );
423 : :
424 [ + + ]: 210745 : if ( GetUnoGraphicsList() )
425 : : {
426 [ + - ]: 2201 : UnoWrapperBase* pWrapper = Application::GetUnoWrapper( sal_False );
427 [ + - ]: 2201 : if ( pWrapper )
428 [ + - ]: 2201 : pWrapper->ReleaseAllGraphics( this );
429 [ + - ]: 2201 : delete mpUnoGraphicsList;
430 : 2201 : mpUnoGraphicsList = NULL;
431 : : }
432 : :
433 [ + + ]: 210745 : if ( mpOutDevData )
434 [ + - ]: 3548 : ImplDeInitOutDevData();
435 : :
436 : 210745 : ImplObjStack* pData = mpObjStack;
437 [ - + ]: 210745 : if ( pData )
438 : : {
439 : : SAL_WARN( "vcl.gdi", "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
440 [ # # ]: 0 : while ( pData )
441 : : {
442 : 0 : ImplObjStack* pTemp = pData;
443 : 0 : pData = pData->mpPrev;
444 [ # # ]: 0 : ImplDeleteObjStack( pTemp );
445 : : }
446 : : }
447 : :
448 : : // release the active font instance
449 [ - + ]: 210745 : if( mpFontEntry )
450 [ # # ]: 0 : mpFontCache->Release( mpFontEntry );
451 : : // remove cached results of GetDevFontList/GetDevSizeList
452 : : // TODO: use smart pointers for them
453 [ - + ]: 210745 : if( mpGetDevFontList )
454 [ # # ]: 0 : delete mpGetDevFontList;
455 [ - + ]: 210745 : if( mpGetDevSizeList )
456 [ # # ][ # # ]: 0 : delete mpGetDevSizeList;
457 : :
458 : : // release ImplFontCache specific to this OutputDevice
459 : : // TODO: refcount ImplFontCache
460 [ + + ][ + + ]: 423256 : if( mpFontCache
[ + - ][ + + ]
461 [ + - ]: 210638 : && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
462 [ + - ]: 1873 : && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
463 : : {
464 [ + - ][ + - ]: 1873 : delete mpFontCache;
465 : 1873 : mpFontCache = NULL;
466 : : }
467 : :
468 : : // release ImplFontList specific to this OutputDevice
469 : : // TODO: refcount ImplFontList
470 [ + - ][ + + ]: 423470 : if( mpFontList
[ + - ][ + + ]
471 [ + - ]: 210745 : && (mpFontList != ImplGetSVData()->maGDIData.mpScreenFontList)
472 [ + - ]: 1980 : && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
473 : : {
474 [ + - ]: 1980 : mpFontList->Clear();
475 [ + - ][ + - ]: 1980 : delete mpFontList;
476 : 1980 : mpFontList = NULL;
477 : : }
478 : :
479 [ + + ][ + - ]: 210745 : delete mpAlphaVDev;
480 [ - + ]: 210745 : }
481 : :
482 : 7317 : bool OutputDevice::supportsOperation( OutDevSupportType eType ) const
483 : : {
484 [ - + ]: 7317 : if( !mpGraphics )
485 [ # # ]: 0 : if( !ImplGetGraphics() )
486 : 0 : return false;
487 : 7317 : const bool bHasSupport = mpGraphics->supportsOperation( eType );
488 : 7317 : return bHasSupport;
489 : : }
490 : :
491 : : // -----------------------------------------------------------------------
492 : :
493 : 54735 : void OutputDevice::EnableRTL( sal_Bool bEnable )
494 : : {
495 : 54735 : mbEnableRTL = (bEnable != 0);
496 [ + + ]: 54735 : if( meOutDevType == OUTDEV_VIRDEV )
497 : : {
498 : : // virdevs default to not mirroring, they will only be set to mirroring
499 : : // under rare circumstances in the UI, eg the valueset control
500 : : // because each virdev has its own SalGraphics we can safely switch the SalGraphics here
501 : : // ...hopefully
502 [ + - ]: 30494 : if( ImplGetGraphics() )
503 [ + + ]: 30494 : mpGraphics->SetLayout( mbEnableRTL ? SAL_LAYOUT_BIDI_RTL : 0 );
504 : : }
505 : :
506 : : // convenience: for controls also switch layout mode
507 [ + - ][ + + ]: 54735 : if( dynamic_cast<Control*>(this) != 0 )
508 [ + + ]: 17815 : SetLayoutMode( bEnable ? TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT : TEXT_LAYOUT_BIDI_LTR | TEXT_LAYOUT_TEXTORIGIN_LEFT);
509 : :
510 [ - + ]: 54735 : Window* pWin = dynamic_cast<Window*>(this);
511 [ + + ]: 54735 : if( pWin )
512 : 24241 : pWin->StateChanged( STATE_CHANGE_MIRRORING );
513 : :
514 [ + + ]: 54735 : if( mpAlphaVDev )
515 : 10762 : mpAlphaVDev->EnableRTL( bEnable );
516 : 54735 : }
517 : :
518 : 465584 : sal_Bool OutputDevice::ImplHasMirroredGraphics()
519 : : {
520 : : // HOTFIX for #i55719#
521 [ - + ]: 465584 : if( meOutDevType == OUTDEV_PRINTER )
522 : 0 : return sal_False;
523 : :
524 [ + - ][ + + ]: 465584 : return ( ImplGetGraphics() && (mpGraphics->GetLayout() & SAL_LAYOUT_BIDI_RTL) );
525 : : }
526 : :
527 : : // note: the coordiantes to be remirrored are in frame coordiantes !
528 : :
529 : 18 : void OutputDevice::ImplReMirror( Point &rPoint ) const
530 : : {
531 : 18 : rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
532 : 18 : }
533 : 20 : void OutputDevice::ImplReMirror( Rectangle &rRect ) const
534 : : {
535 : 20 : long nWidth = rRect.nRight - rRect.nLeft;
536 : :
537 : : //long lc_x = rRect.nLeft - mnOutOffX; // normalize
538 : : //lc_x = mnOutWidth - nWidth - 1 - lc_x; // mirror
539 : : //rRect.nLeft = lc_x + mnOutOffX; // re-normalize
540 : :
541 : 20 : rRect.nLeft = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.nLeft + mnOutOffX;
542 : 20 : rRect.nRight = rRect.nLeft + nWidth;
543 : 20 : }
544 : 550 : void OutputDevice::ImplReMirror( Region &rRegion ) const
545 : : {
546 : : long nX;
547 : : long nY;
548 : : long nWidth;
549 : : long nHeight;
550 : : ImplRegionInfo aInfo;
551 : : sal_Bool bRegionRect;
552 [ + - ]: 550 : Region aMirroredRegion;
553 : :
554 [ + - ]: 550 : bRegionRect = rRegion.ImplGetFirstRect( aInfo, nX, nY, nWidth, nHeight );
555 [ + + ]: 562 : while ( bRegionRect )
556 : : {
557 [ + - ]: 12 : Rectangle aRect( Point(nX, nY), Size(nWidth, nHeight) );
558 : 12 : ImplReMirror( aRect );
559 [ + - ]: 12 : aMirroredRegion.Union( aRect );
560 [ + - ]: 12 : bRegionRect = rRegion.ImplGetNextRect( aInfo, nX, nY, nWidth, nHeight );
561 : : }
562 [ + - ][ + - ]: 550 : rRegion = aMirroredRegion;
563 : 550 : }
564 : :
565 : :
566 : : // -----------------------------------------------------------------------
567 : :
568 : 1074632 : int OutputDevice::ImplGetGraphics() const
569 : : {
570 : : DBG_TESTSOLARMUTEX();
571 : :
572 [ + + ]: 1074632 : if ( mpGraphics )
573 : 847817 : return sal_True;
574 : :
575 : 226815 : mbInitLineColor = sal_True;
576 : 226815 : mbInitFillColor = sal_True;
577 : 226815 : mbInitFont = sal_True;
578 : 226815 : mbInitTextColor = sal_True;
579 : 226815 : mbInitClipRegion = sal_True;
580 : :
581 : 226815 : ImplSVData* pSVData = ImplGetSVData();
582 [ + + ]: 226815 : if ( meOutDevType == OUTDEV_WINDOW )
583 : : {
584 : 131808 : Window* pWindow = (Window*)this;
585 : :
586 : 131808 : mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
587 : : // try harder if no wingraphics was available directly
588 [ - + ]: 131808 : if ( !mpGraphics )
589 : : {
590 : : // find another output device in the same frame
591 : 0 : OutputDevice* pReleaseOutDev = pSVData->maGDIData.mpLastWinGraphics;
592 [ # # ]: 0 : while ( pReleaseOutDev )
593 : : {
594 [ # # ]: 0 : if ( ((Window*)pReleaseOutDev)->mpWindowImpl->mpFrame == pWindow->mpWindowImpl->mpFrame )
595 : 0 : break;
596 : 0 : pReleaseOutDev = pReleaseOutDev->mpPrevGraphics;
597 : : }
598 : :
599 [ # # ]: 0 : if ( pReleaseOutDev )
600 : : {
601 : : // steal the wingraphics from the other outdev
602 : 0 : mpGraphics = pReleaseOutDev->mpGraphics;
603 : 0 : pReleaseOutDev->ImplReleaseGraphics( sal_False );
604 : : }
605 : : else
606 : : {
607 : : // if needed retry after releasing least recently used wingraphics
608 [ # # ]: 0 : while ( !mpGraphics )
609 : : {
610 [ # # ]: 0 : if ( !pSVData->maGDIData.mpLastWinGraphics )
611 : 0 : break;
612 : 0 : pSVData->maGDIData.mpLastWinGraphics->ImplReleaseGraphics();
613 : 0 : mpGraphics = pWindow->mpWindowImpl->mpFrame->GetGraphics();
614 : : }
615 : : }
616 : : }
617 : :
618 : : // update global LRU list of wingraphics
619 [ + - ]: 131808 : if ( mpGraphics )
620 : : {
621 : 131808 : mpNextGraphics = pSVData->maGDIData.mpFirstWinGraphics;
622 : 131808 : pSVData->maGDIData.mpFirstWinGraphics = const_cast<OutputDevice*>(this);
623 [ + + ]: 131808 : if ( mpNextGraphics )
624 : 131563 : mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
625 [ + + ]: 131808 : if ( !pSVData->maGDIData.mpLastWinGraphics )
626 : 245 : pSVData->maGDIData.mpLastWinGraphics = const_cast<OutputDevice*>(this);
627 : : }
628 : : }
629 [ + + ]: 95007 : else if ( meOutDevType == OUTDEV_VIRDEV )
630 : : {
631 : 94869 : const VirtualDevice* pVirDev = (const VirtualDevice*)this;
632 : :
633 [ + - ]: 94869 : if ( pVirDev->mpVirDev )
634 : : {
635 : 94869 : mpGraphics = pVirDev->mpVirDev->GetGraphics();
636 : : // if needed retry after releasing least recently used virtual device graphics
637 [ - + ]: 94869 : while ( !mpGraphics )
638 : : {
639 [ # # ]: 0 : if ( !pSVData->maGDIData.mpLastVirGraphics )
640 : 0 : break;
641 : 0 : pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
642 : 0 : mpGraphics = pVirDev->mpVirDev->GetGraphics();
643 : : }
644 : : // update global LRU list of virtual device graphics
645 [ + - ]: 94869 : if ( mpGraphics )
646 : : {
647 : 94869 : mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
648 : 94869 : pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
649 [ + + ]: 94869 : if ( mpNextGraphics )
650 : 94546 : mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
651 [ + + ]: 94869 : if ( !pSVData->maGDIData.mpLastVirGraphics )
652 : 323 : pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
653 : : }
654 : : }
655 : : }
656 [ + - ]: 138 : else if ( meOutDevType == OUTDEV_PRINTER )
657 : : {
658 : 138 : const Printer* pPrinter = (const Printer*)this;
659 : :
660 [ - + ]: 138 : if ( pPrinter->mpJobGraphics )
661 : 0 : mpGraphics = pPrinter->mpJobGraphics;
662 [ + + ]: 138 : else if ( pPrinter->mpDisplayDev )
663 : : {
664 : 26 : const VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
665 : 26 : mpGraphics = pVirDev->mpVirDev->GetGraphics();
666 : : // if needed retry after releasing least recently used virtual device graphics
667 [ - + ]: 26 : while ( !mpGraphics )
668 : : {
669 [ # # ]: 0 : if ( !pSVData->maGDIData.mpLastVirGraphics )
670 : 0 : break;
671 : 0 : pSVData->maGDIData.mpLastVirGraphics->ImplReleaseGraphics();
672 : 0 : mpGraphics = pVirDev->mpVirDev->GetGraphics();
673 : : }
674 : : // update global LRU list of virtual device graphics
675 [ + - ]: 26 : if ( mpGraphics )
676 : : {
677 : 26 : mpNextGraphics = pSVData->maGDIData.mpFirstVirGraphics;
678 : 26 : pSVData->maGDIData.mpFirstVirGraphics = const_cast<OutputDevice*>(this);
679 [ + - ]: 26 : if ( mpNextGraphics )
680 : 26 : mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
681 [ - + ]: 26 : if ( !pSVData->maGDIData.mpLastVirGraphics )
682 : 0 : pSVData->maGDIData.mpLastVirGraphics = const_cast<OutputDevice*>(this);
683 : : }
684 : : }
685 : : else
686 : : {
687 : 112 : mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
688 : : // if needed retry after releasing least recently used printer graphics
689 [ - + ]: 112 : while ( !mpGraphics )
690 : : {
691 [ # # ]: 0 : if ( !pSVData->maGDIData.mpLastPrnGraphics )
692 : 0 : break;
693 : 0 : pSVData->maGDIData.mpLastPrnGraphics->ImplReleaseGraphics();
694 : 0 : mpGraphics = pPrinter->mpInfoPrinter->GetGraphics();
695 : : }
696 : : // update global LRU list of printer graphics
697 [ + - ]: 112 : if ( mpGraphics )
698 : : {
699 : 112 : mpNextGraphics = pSVData->maGDIData.mpFirstPrnGraphics;
700 : 112 : pSVData->maGDIData.mpFirstPrnGraphics = const_cast<OutputDevice*>(this);
701 [ + + ]: 112 : if ( mpNextGraphics )
702 : 18 : mpNextGraphics->mpPrevGraphics = const_cast<OutputDevice*>(this);
703 [ + + ]: 112 : if ( !pSVData->maGDIData.mpLastPrnGraphics )
704 : 94 : pSVData->maGDIData.mpLastPrnGraphics = const_cast<OutputDevice*>(this);
705 : : }
706 : : }
707 : : }
708 : :
709 [ + - ]: 226815 : if ( mpGraphics )
710 : : {
711 [ + - ][ - + ]: 226815 : mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
712 : 226815 : mpGraphics->setAntiAliasB2DDraw(mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW);
713 : 226815 : return sal_True;
714 : : }
715 : :
716 : 1074632 : return sal_False;
717 : : }
718 : :
719 : : // -----------------------------------------------------------------------
720 : :
721 : 361194 : void OutputDevice::ImplReleaseGraphics( sal_Bool bRelease )
722 : : {
723 : : DBG_TESTSOLARMUTEX();
724 : :
725 [ + + ]: 361194 : if ( !mpGraphics )
726 : 361194 : return;
727 : :
728 : : // release the fonts of the physically released graphics device
729 [ + - ]: 222826 : if( bRelease )
730 : : {
731 : : #ifndef UNX
732 : : // HACK to fix an urgent P1 printing issue fast
733 : : // WinSalPrinter does not respect GetGraphics/ReleaseGraphics conventions
734 : : // so Printer::mpGraphics often points to a dead WinSalGraphics
735 : : // TODO: fix WinSalPrinter's GetGraphics/ReleaseGraphics handling
736 : : if( meOutDevType != OUTDEV_PRINTER )
737 : : #endif
738 : 222826 : mpGraphics->ReleaseFonts();
739 : :
740 : 222826 : mbNewFont = true;
741 : 222826 : mbInitFont = true;
742 : :
743 [ + + ]: 222826 : if ( mpFontEntry )
744 : : {
745 : 51604 : mpFontCache->Release( mpFontEntry );
746 : 51604 : mpFontEntry = NULL;
747 : : }
748 : :
749 [ + + ]: 222826 : if ( mpGetDevFontList )
750 : : {
751 [ + - ]: 2807 : delete mpGetDevFontList;
752 : 2807 : mpGetDevFontList = NULL;
753 : : }
754 : :
755 [ + + ]: 222826 : if ( mpGetDevSizeList )
756 : : {
757 [ + - ]: 939 : delete mpGetDevSizeList;
758 : 939 : mpGetDevSizeList = NULL;
759 : : }
760 : : }
761 : :
762 : 222826 : ImplSVData* pSVData = ImplGetSVData();
763 [ + + ]: 222826 : if ( meOutDevType == OUTDEV_WINDOW )
764 : : {
765 : 128497 : Window* pWindow = (Window*)this;
766 : :
767 [ + - ]: 128497 : if ( bRelease )
768 : 128497 : pWindow->mpWindowImpl->mpFrame->ReleaseGraphics( mpGraphics );
769 : : // remove from global LRU list of window graphics
770 [ + + ]: 128497 : if ( mpPrevGraphics )
771 : 106766 : mpPrevGraphics->mpNextGraphics = mpNextGraphics;
772 : : else
773 : 21731 : pSVData->maGDIData.mpFirstWinGraphics = mpNextGraphics;
774 [ + + ]: 128497 : if ( mpNextGraphics )
775 : 128321 : mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
776 : : else
777 : 176 : pSVData->maGDIData.mpLastWinGraphics = mpPrevGraphics;
778 : : }
779 [ + + ]: 94329 : else if ( meOutDevType == OUTDEV_VIRDEV )
780 : : {
781 : 94195 : VirtualDevice* pVirDev = (VirtualDevice*)this;
782 : :
783 [ + - ]: 94195 : if ( bRelease )
784 : 94195 : pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
785 : : // remove from global LRU list of virtual device graphics
786 [ + + ]: 94195 : if ( mpPrevGraphics )
787 : 22914 : mpPrevGraphics->mpNextGraphics = mpNextGraphics;
788 : : else
789 : 71281 : pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
790 [ + + ]: 94195 : if ( mpNextGraphics )
791 : 93716 : mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
792 : : else
793 : 479 : pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
794 : : }
795 [ + - ]: 134 : else if ( meOutDevType == OUTDEV_PRINTER )
796 : : {
797 : 134 : Printer* pPrinter = (Printer*)this;
798 : :
799 [ + - ]: 134 : if ( !pPrinter->mpJobGraphics )
800 : : {
801 [ + + ]: 134 : if ( pPrinter->mpDisplayDev )
802 : : {
803 : 24 : VirtualDevice* pVirDev = pPrinter->mpDisplayDev;
804 [ + - ]: 24 : if ( bRelease )
805 : 24 : pVirDev->mpVirDev->ReleaseGraphics( mpGraphics );
806 : : // remove from global LRU list of virtual device graphics
807 [ + + ]: 24 : if ( mpPrevGraphics )
808 : 3 : mpPrevGraphics->mpNextGraphics = mpNextGraphics;
809 : : else
810 : 21 : pSVData->maGDIData.mpFirstVirGraphics = mpNextGraphics;
811 [ + - ]: 24 : if ( mpNextGraphics )
812 : 24 : mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
813 : : else
814 : 0 : pSVData->maGDIData.mpLastVirGraphics = mpPrevGraphics;
815 : : }
816 : : else
817 : : {
818 [ + - ]: 110 : if ( bRelease )
819 : 110 : pPrinter->mpInfoPrinter->ReleaseGraphics( mpGraphics );
820 : : // remove from global LRU list of printer graphics
821 [ + + ]: 110 : if ( mpPrevGraphics )
822 : 3 : mpPrevGraphics->mpNextGraphics = mpNextGraphics;
823 : : else
824 : 107 : pSVData->maGDIData.mpFirstPrnGraphics = mpNextGraphics;
825 [ + + ]: 110 : if ( mpNextGraphics )
826 : 15 : mpNextGraphics->mpPrevGraphics = mpPrevGraphics;
827 : : else
828 : 95 : pSVData->maGDIData.mpLastPrnGraphics = mpPrevGraphics;
829 : : }
830 : : }
831 : : }
832 : :
833 : 222826 : mpGraphics = NULL;
834 : 222826 : mpPrevGraphics = NULL;
835 : 222826 : mpNextGraphics = NULL;
836 : : }
837 : :
838 : : // -----------------------------------------------------------------------
839 : :
840 : 3645 : void OutputDevice::ImplInitOutDevData()
841 : : {
842 [ + - ]: 3645 : if ( !mpOutDevData )
843 : : {
844 [ + - ]: 3645 : mpOutDevData = new ImplOutDevData;
845 : 3645 : mpOutDevData->mpRotateDev = NULL;
846 : 3645 : mpOutDevData->mpRecordLayout = NULL;
847 : :
848 : : // #i75163#
849 : 3645 : mpOutDevData->mpViewTransform = NULL;
850 : 3645 : mpOutDevData->mpInverseViewTransform = NULL;
851 : : }
852 : 3645 : }
853 : :
854 : : // -----------------------------------------------------------------------
855 : :
856 : : // #i75163#
857 : 229304 : void OutputDevice::ImplInvalidateViewTransform()
858 : : {
859 [ + + ]: 229304 : if(mpOutDevData)
860 : : {
861 [ + + ]: 139181 : if(mpOutDevData->mpViewTransform)
862 : : {
863 [ + - ]: 48976 : delete mpOutDevData->mpViewTransform;
864 : 48976 : mpOutDevData->mpViewTransform = NULL;
865 : : }
866 : :
867 [ + + ]: 139181 : if(mpOutDevData->mpInverseViewTransform)
868 : : {
869 [ + - ]: 25656 : delete mpOutDevData->mpInverseViewTransform;
870 : 25656 : mpOutDevData->mpInverseViewTransform = NULL;
871 : : }
872 : : }
873 : 229304 : }
874 : :
875 : : // -----------------------------------------------------------------------
876 : :
877 : 3385448 : sal_Bool OutputDevice::ImplIsRecordLayout() const
878 : : {
879 [ + + ][ + + ]: 3385448 : return mpOutDevData && mpOutDevData->mpRecordLayout;
880 : : }
881 : :
882 : : // -----------------------------------------------------------------------
883 : :
884 : 3548 : void OutputDevice::ImplDeInitOutDevData()
885 : : {
886 [ + - ]: 3548 : if ( mpOutDevData )
887 : : {
888 [ - + ]: 3548 : if ( mpOutDevData->mpRotateDev )
889 [ # # ]: 0 : delete mpOutDevData->mpRotateDev;
890 : :
891 : : // #i75163#
892 : 3548 : ImplInvalidateViewTransform();
893 : :
894 [ + - ]: 3548 : delete mpOutDevData;
895 : : }
896 : 3548 : }
897 : :
898 : : // -----------------------------------------------------------------------
899 : :
900 : 648263 : void OutputDevice::ImplInitLineColor()
901 : : {
902 : : DBG_TESTSOLARMUTEX();
903 : :
904 [ + + ]: 648263 : if( mbLineColor )
905 : : {
906 [ - + ]: 319471 : if( ROP_0 == meRasterOp )
907 : 0 : mpGraphics->SetROPLineColor( SAL_ROP_0 );
908 [ - + ]: 319471 : else if( ROP_1 == meRasterOp )
909 : 0 : mpGraphics->SetROPLineColor( SAL_ROP_1 );
910 [ - + ]: 319471 : else if( ROP_INVERT == meRasterOp )
911 : 0 : mpGraphics->SetROPLineColor( SAL_ROP_INVERT );
912 : : else
913 : 319471 : mpGraphics->SetLineColor( ImplColorToSal( maLineColor ) );
914 : : }
915 : : else
916 : 328792 : mpGraphics->SetLineColor();
917 : :
918 : 648263 : mbInitLineColor = sal_False;
919 : 648263 : }
920 : :
921 : : // -----------------------------------------------------------------------
922 : :
923 : 546424 : void OutputDevice::ImplInitFillColor()
924 : : {
925 : : DBG_TESTSOLARMUTEX();
926 : :
927 [ + + ]: 546424 : if( mbFillColor )
928 : : {
929 [ + + ]: 538610 : if( ROP_0 == meRasterOp )
930 : 235 : mpGraphics->SetROPFillColor( SAL_ROP_0 );
931 [ - + ]: 538375 : else if( ROP_1 == meRasterOp )
932 : 0 : mpGraphics->SetROPFillColor( SAL_ROP_1 );
933 [ - + ]: 538375 : else if( ROP_INVERT == meRasterOp )
934 : 0 : mpGraphics->SetROPFillColor( SAL_ROP_INVERT );
935 : : else
936 : 538375 : mpGraphics->SetFillColor( ImplColorToSal( maFillColor ) );
937 : : }
938 : : else
939 : 7814 : mpGraphics->SetFillColor();
940 : :
941 : 546424 : mbInitFillColor = sal_False;
942 : 546424 : }
943 : :
944 : : // -----------------------------------------------------------------------
945 : :
946 : 700660 : void OutputDevice::ImplInitClipRegion()
947 : : {
948 : : DBG_TESTSOLARMUTEX();
949 : :
950 [ + + ]: 700660 : if ( GetOutDevType() == OUTDEV_WINDOW )
951 : : {
952 : 532334 : Window* pWindow = (Window*)this;
953 [ + - ]: 532334 : Region aRegion;
954 : :
955 : : // Hintergrund-Sicherung zuruecksetzen
956 [ - + ]: 532334 : if ( pWindow->mpWindowImpl->mpFrameData->mpFirstBackWin )
957 [ # # ]: 0 : pWindow->ImplInvalidateAllOverlapBackgrounds();
958 [ + + ]: 532334 : if ( pWindow->mpWindowImpl->mbInPaint )
959 [ + - ]: 507222 : aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
960 : : else
961 : : {
962 [ + - ][ + - ]: 25112 : aRegion = *(pWindow->ImplGetWinChildClipRegion());
963 : : // --- RTL -- only this region is in frame coordinates, so re-mirror it
964 : : // the mpWindowImpl->mpPaintRegion above is already correct (see ImplCallPaint()) !
965 [ + - ][ + + ]: 25112 : if( ImplIsAntiparallel() )
966 [ + - ]: 538 : ImplReMirror ( aRegion );
967 : : }
968 [ + + ]: 532334 : if ( mbClipRegion )
969 [ + - ][ + - ]: 301142 : aRegion.Intersect( ImplPixelToDevicePixel( maRegion ) );
[ + - ]
970 [ + - ][ + + ]: 532334 : if ( aRegion.IsEmpty() )
971 : 155016 : mbOutputClipped = sal_True;
972 : : else
973 : : {
974 : 377318 : mbOutputClipped = sal_False;
975 [ + - ]: 377318 : ImplSelectClipRegion( aRegion );
976 : : }
977 [ + - ]: 532334 : mbClipRegionSet = sal_True;
978 : : }
979 : : else
980 : : {
981 [ + + ]: 168326 : if ( mbClipRegion )
982 : : {
983 [ + + ]: 37810 : if ( maRegion.IsEmpty() )
984 : 206 : mbOutputClipped = sal_True;
985 : : else
986 : : {
987 : 37604 : mbOutputClipped = sal_False;
988 : :
989 : : // #102532# Respect output offset also for clip region
990 [ + - ]: 37604 : Region aRegion( ImplPixelToDevicePixel( maRegion ) );
991 : 37604 : const bool bClipDeviceBounds( ! GetPDFWriter()
992 [ + - ][ + - ]: 37604 : && GetOutDevType() != OUTDEV_PRINTER );
993 [ + - ]: 37604 : if( bClipDeviceBounds )
994 : : {
995 : : // Perform actual rect clip against outdev
996 : : // dimensions, to generate empty clips whenever one of the
997 : : // values is completely off the device.
998 : : Rectangle aDeviceBounds( mnOutOffX, mnOutOffY,
999 : 37604 : mnOutOffX+GetOutputWidthPixel()-1,
1000 [ + - ]: 75208 : mnOutOffY+GetOutputHeightPixel()-1 );
1001 [ + - ]: 37604 : aRegion.Intersect( aDeviceBounds );
1002 : : }
1003 [ + - ][ + - ]: 37604 : ImplSelectClipRegion( aRegion );
1004 : : }
1005 : :
1006 : 37810 : mbClipRegionSet = sal_True;
1007 : : }
1008 : : else
1009 : : {
1010 [ + + ]: 130516 : if ( mbClipRegionSet )
1011 : : {
1012 : 9383 : mpGraphics->ResetClipRegion();
1013 : 9383 : mbClipRegionSet = sal_False;
1014 : : }
1015 : :
1016 : 130516 : mbOutputClipped = sal_False;
1017 : : }
1018 : : }
1019 : :
1020 : 700660 : mbInitClipRegion = sal_False;
1021 : 700660 : }
1022 : :
1023 : : // -----------------------------------------------------------------------
1024 : :
1025 : 640708 : void OutputDevice::ImplSetClipRegion( const Region* pRegion )
1026 : : {
1027 : : DBG_TESTSOLARMUTEX();
1028 : :
1029 [ + + ]: 640708 : if ( !pRegion )
1030 : : {
1031 [ + + ]: 307852 : if ( mbClipRegion )
1032 : : {
1033 [ + - ]: 270714 : maRegion = Region( REGION_NULL );
1034 : 270714 : mbClipRegion = sal_False;
1035 : 270714 : mbInitClipRegion = sal_True;
1036 : : }
1037 : : }
1038 : : else
1039 : : {
1040 : 332856 : maRegion = *pRegion;
1041 : 332856 : mbClipRegion = sal_True;
1042 : 332856 : mbInitClipRegion = sal_True;
1043 : : }
1044 : 640708 : }
1045 : :
1046 : : // -----------------------------------------------------------------------
1047 : :
1048 : 46736 : void OutputDevice::SetClipRegion()
1049 : : {
1050 : : OSL_TRACE( "OutputDevice::SetClipRegion()" );
1051 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1052 : :
1053 [ + + ]: 46736 : if ( mpMetaFile )
1054 [ + - ][ + - ]: 32 : mpMetaFile->AddAction( new MetaClipRegionAction( Region(), sal_False ) );
[ + - ]
1055 : :
1056 : 46736 : ImplSetClipRegion( NULL );
1057 : :
1058 [ + + ]: 46736 : if( mpAlphaVDev )
1059 : 32 : mpAlphaVDev->SetClipRegion();
1060 : 46736 : }
1061 : :
1062 : : // -----------------------------------------------------------------------
1063 : :
1064 : 70106 : void OutputDevice::SetClipRegion( const Region& rRegion )
1065 : : {
1066 : : OSL_TRACE( "OutputDevice::SetClipRegion( rRegion )" );
1067 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1068 : : DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
1069 : :
1070 [ + + ]: 70106 : if ( mpMetaFile )
1071 [ + - ]: 10859 : mpMetaFile->AddAction( new MetaClipRegionAction( rRegion, sal_True ) );
1072 : :
1073 [ + + ]: 70106 : if ( rRegion.GetType() == REGION_NULL )
1074 : 1315 : ImplSetClipRegion( NULL );
1075 : : else
1076 : : {
1077 [ + - ]: 68791 : Region aRegion = LogicToPixel( rRegion );
1078 [ + - ][ + - ]: 68791 : ImplSetClipRegion( &aRegion );
1079 : : }
1080 : :
1081 [ + + ]: 70106 : if( mpAlphaVDev )
1082 : 10850 : mpAlphaVDev->SetClipRegion( rRegion );
1083 : 70106 : }
1084 : :
1085 : : // -----------------------------------------------------------------------
1086 : :
1087 : 16563 : Region OutputDevice::GetClipRegion() const
1088 : : {
1089 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1090 : :
1091 : 16563 : return PixelToLogic( maRegion );
1092 : : }
1093 : :
1094 : : // -----------------------------------------------------------------------
1095 : :
1096 : 132441 : Region OutputDevice::GetActiveClipRegion() const
1097 : : {
1098 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1099 : :
1100 [ + - ]: 132441 : if ( GetOutDevType() == OUTDEV_WINDOW )
1101 : : {
1102 [ + - ]: 132441 : Region aRegion( REGION_NULL );
1103 : 132441 : Window* pWindow = (Window*)this;
1104 [ + - ]: 132441 : if ( pWindow->mpWindowImpl->mbInPaint )
1105 : : {
1106 [ + - ]: 132441 : aRegion = *(pWindow->mpWindowImpl->mpPaintRegion);
1107 [ + - ]: 132441 : aRegion.Move( -mnOutOffX, -mnOutOffY );
1108 : : }
1109 [ - + ]: 132441 : if ( mbClipRegion )
1110 [ # # ]: 0 : aRegion.Intersect( maRegion );
1111 [ + - ][ + - ]: 132441 : return PixelToLogic( aRegion );
1112 : : }
1113 : : else
1114 : 132441 : return GetClipRegion();
1115 : : }
1116 : :
1117 : : // -----------------------------------------------------------------------
1118 : :
1119 : 0 : void OutputDevice::MoveClipRegion( long nHorzMove, long nVertMove )
1120 : : {
1121 : : OSL_TRACE( "OutputDevice::MoveClipRegion()" );
1122 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1123 : :
1124 [ # # ]: 0 : if ( mbClipRegion )
1125 : : {
1126 [ # # ]: 0 : if( mpMetaFile )
1127 [ # # ]: 0 : mpMetaFile->AddAction( new MetaMoveClipRegionAction( nHorzMove, nVertMove ) );
1128 : :
1129 : : maRegion.Move( ImplLogicWidthToDevicePixel( nHorzMove ),
1130 : 0 : ImplLogicHeightToDevicePixel( nVertMove ) );
1131 : 0 : mbInitClipRegion = sal_True;
1132 : : }
1133 : :
1134 [ # # ]: 0 : if( mpAlphaVDev )
1135 : 0 : mpAlphaVDev->MoveClipRegion( nHorzMove, nVertMove );
1136 : 0 : }
1137 : :
1138 : : // -----------------------------------------------------------------------
1139 : :
1140 : 285701 : void OutputDevice::IntersectClipRegion( const Rectangle& rRect )
1141 : : {
1142 : : OSL_TRACE( "OutputDevice::IntersectClipRegion( rRect )" );
1143 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1144 : :
1145 [ + + ]: 285701 : if ( mpMetaFile )
1146 [ + - ][ + - ]: 7964 : mpMetaFile->AddAction( new MetaISectRectClipRegionAction( rRect ) );
[ + - ]
1147 : :
1148 [ + - ]: 285701 : Rectangle aRect = LogicToPixel( rRect );
1149 [ + - ]: 285701 : maRegion.Intersect( aRect );
1150 : 285701 : mbClipRegion = sal_True;
1151 : 285701 : mbInitClipRegion = sal_True;
1152 : :
1153 [ + + ]: 285701 : if( mpAlphaVDev )
1154 [ + - ]: 1744 : mpAlphaVDev->IntersectClipRegion( rRect );
1155 : 285701 : }
1156 : :
1157 : : // -----------------------------------------------------------------------
1158 : :
1159 : 179223 : void OutputDevice::IntersectClipRegion( const Region& rRegion )
1160 : : {
1161 : : OSL_TRACE( "OutputDevice::IntersectClipRegion( rRegion )" );
1162 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1163 : : DBG_CHKOBJ( &rRegion, Region, ImplDbgTestRegion );
1164 : :
1165 : 179223 : RegionType eType = rRegion.GetType();
1166 : :
1167 [ + - ]: 179223 : if ( eType != REGION_NULL )
1168 : : {
1169 [ + + ]: 179223 : if ( mpMetaFile )
1170 [ + - ][ + - ]: 652 : mpMetaFile->AddAction( new MetaISectRegionClipRegionAction( rRegion ) );
[ + - ]
1171 : :
1172 [ + - ]: 179223 : Region aRegion = LogicToPixel( rRegion );
1173 [ + - ]: 179223 : maRegion.Intersect( aRegion );
1174 : 179223 : mbClipRegion = sal_True;
1175 [ + - ]: 179223 : mbInitClipRegion = sal_True;
1176 : : }
1177 : :
1178 [ + + ]: 179223 : if( mpAlphaVDev )
1179 : 383 : mpAlphaVDev->IntersectClipRegion( rRegion );
1180 : 179223 : }
1181 : :
1182 : : // -----------------------------------------------------------------------
1183 : :
1184 : 159507 : void OutputDevice::SetDrawMode( sal_uLong nDrawMode )
1185 : : {
1186 : : OSL_TRACE( "OutputDevice::SetDrawMode( %lx )", nDrawMode );
1187 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1188 : :
1189 : 159507 : mnDrawMode = nDrawMode;
1190 : :
1191 [ - + ]: 159507 : if( mpAlphaVDev )
1192 : 0 : mpAlphaVDev->SetDrawMode( nDrawMode );
1193 : 159507 : }
1194 : :
1195 : : // -----------------------------------------------------------------------
1196 : :
1197 : 114575 : void OutputDevice::SetRasterOp( RasterOp eRasterOp )
1198 : : {
1199 : : OSL_TRACE( "OutputDevice::SetRasterOp( %d )", (int)eRasterOp );
1200 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1201 : :
1202 [ + + ]: 114575 : if ( mpMetaFile )
1203 [ + - ]: 10852 : mpMetaFile->AddAction( new MetaRasterOpAction( eRasterOp ) );
1204 : :
1205 [ + + ]: 114575 : if ( meRasterOp != eRasterOp )
1206 : : {
1207 : 6214 : meRasterOp = eRasterOp;
1208 : 6214 : mbInitLineColor = mbInitFillColor = sal_True;
1209 : :
1210 [ - + ][ # # ]: 6214 : if( mpGraphics || ImplGetGraphics() )
[ + - ]
1211 [ + - ][ + + ]: 6214 : mpGraphics->SetXORMode( (ROP_INVERT == meRasterOp) || (ROP_XOR == meRasterOp), ROP_INVERT == meRasterOp );
1212 : : }
1213 : :
1214 [ + + ]: 114575 : if( mpAlphaVDev )
1215 : 21568 : mpAlphaVDev->SetRasterOp( eRasterOp );
1216 : 114575 : }
1217 : :
1218 : : // -----------------------------------------------------------------------
1219 : :
1220 : 781914 : void OutputDevice::SetLineColor()
1221 : : {
1222 : : OSL_TRACE( "OutputDevice::SetLineColor()" );
1223 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1224 : :
1225 [ + + ]: 781914 : if ( mpMetaFile )
1226 [ + - ][ + - ]: 20608 : mpMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
[ + - ]
1227 : :
1228 [ + + ]: 781914 : if ( mbLineColor )
1229 : : {
1230 : 362868 : mbInitLineColor = sal_True;
1231 : 362868 : mbLineColor = sal_False;
1232 : 362868 : maLineColor = Color( COL_TRANSPARENT );
1233 : : }
1234 : :
1235 [ + + ]: 781914 : if( mpAlphaVDev )
1236 : 14194 : mpAlphaVDev->SetLineColor();
1237 : 781914 : }
1238 : :
1239 : : // -----------------------------------------------------------------------
1240 : :
1241 : 1682393 : Color OutputDevice::ImplDrawModeToColor( const Color& rColor ) const
1242 : : {
1243 : 1682393 : Color aColor( rColor );
1244 : 1682393 : sal_uLong nDrawMode = GetDrawMode();
1245 : :
1246 [ - + ]: 1682393 : if( nDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
1247 : : DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE |
1248 : : DRAWMODE_SETTINGSLINE ) )
1249 : : {
1250 [ # # ]: 0 : if( !ImplIsColorTransparent( aColor ) )
1251 : : {
1252 [ # # ]: 0 : if( nDrawMode & DRAWMODE_BLACKLINE )
1253 : : {
1254 : 0 : aColor = Color( COL_BLACK );
1255 : : }
1256 [ # # ]: 0 : else if( nDrawMode & DRAWMODE_WHITELINE )
1257 : : {
1258 : 0 : aColor = Color( COL_WHITE );
1259 : : }
1260 [ # # ]: 0 : else if( nDrawMode & DRAWMODE_GRAYLINE )
1261 : : {
1262 : 0 : const sal_uInt8 cLum = aColor.GetLuminance();
1263 : 0 : aColor = Color( cLum, cLum, cLum );
1264 : : }
1265 [ # # ]: 0 : else if( nDrawMode & DRAWMODE_SETTINGSLINE )
1266 : : {
1267 : 0 : aColor = GetSettings().GetStyleSettings().GetFontColor();
1268 : : }
1269 : :
1270 [ # # ]: 0 : if( nDrawMode & DRAWMODE_GHOSTEDLINE )
1271 : : {
1272 : 0 : aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
1273 : 0 : ( aColor.GetGreen() >> 1 ) | 0x80,
1274 : 0 : ( aColor.GetBlue() >> 1 ) | 0x80);
1275 : : }
1276 : : }
1277 : : }
1278 : 1682393 : return aColor;
1279 : : }
1280 : :
1281 : :
1282 : 1374475 : void OutputDevice::SetLineColor( const Color& rColor )
1283 : : {
1284 : : OSL_TRACE( "OutputDevice::SetLineColor( %lx )", rColor.GetColor() );
1285 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1286 : :
1287 [ + - ]: 1374475 : Color aColor = ImplDrawModeToColor( rColor );
1288 : :
1289 [ + + ]: 1374475 : if( mpMetaFile )
1290 [ + - ][ + - ]: 58819 : mpMetaFile->AddAction( new MetaLineColorAction( aColor, sal_True ) );
[ + - ]
1291 : :
1292 [ + + ]: 1374475 : if( ImplIsColorTransparent( aColor ) )
1293 : : {
1294 [ + + ]: 34028 : if ( mbLineColor )
1295 : : {
1296 : 9079 : mbInitLineColor = sal_True;
1297 : 9079 : mbLineColor = sal_False;
1298 : 9079 : maLineColor = Color( COL_TRANSPARENT );
1299 : : }
1300 : : }
1301 : : else
1302 : : {
1303 [ + + ]: 1340447 : if( maLineColor != aColor )
1304 : : {
1305 : 813371 : mbInitLineColor = sal_True;
1306 : 813371 : mbLineColor = sal_True;
1307 : 813371 : maLineColor = aColor;
1308 : : }
1309 : : }
1310 : :
1311 [ + + ]: 1374475 : if( mpAlphaVDev )
1312 [ + - ]: 63969 : mpAlphaVDev->SetLineColor( COL_BLACK );
1313 : 1374475 : }
1314 : :
1315 : : // -----------------------------------------------------------------------
1316 : :
1317 : 354634 : void OutputDevice::SetFillColor()
1318 : : {
1319 : : OSL_TRACE( "OutputDevice::SetFillColor()" );
1320 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1321 : :
1322 [ + + ]: 354634 : if ( mpMetaFile )
1323 [ + - ][ + - ]: 14737 : mpMetaFile->AddAction( new MetaFillColorAction( Color(), sal_False ) );
[ + - ]
1324 : :
1325 [ + + ]: 354634 : if ( mbFillColor )
1326 : : {
1327 : 70653 : mbInitFillColor = sal_True;
1328 : 70653 : mbFillColor = sal_False;
1329 : 70653 : maFillColor = Color( COL_TRANSPARENT );
1330 : : }
1331 : :
1332 [ + + ]: 354634 : if( mpAlphaVDev )
1333 : 2951 : mpAlphaVDev->SetFillColor();
1334 : 354634 : }
1335 : :
1336 : : // -----------------------------------------------------------------------
1337 : :
1338 : 1376020 : void OutputDevice::SetFillColor( const Color& rColor )
1339 : : {
1340 : : OSL_TRACE( "OutputDevice::SetFillColor( %lx )", rColor.GetColor() );
1341 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1342 : :
1343 : 1376020 : Color aColor( rColor );
1344 : :
1345 [ - + ]: 1376020 : if( mnDrawMode & ( DRAWMODE_BLACKFILL | DRAWMODE_WHITEFILL |
1346 : : DRAWMODE_GRAYFILL | DRAWMODE_NOFILL |
1347 : : DRAWMODE_GHOSTEDFILL | DRAWMODE_SETTINGSFILL ) )
1348 : : {
1349 [ # # ]: 0 : if( !ImplIsColorTransparent( aColor ) )
1350 : : {
1351 [ # # ]: 0 : if( mnDrawMode & DRAWMODE_BLACKFILL )
1352 : : {
1353 : 0 : aColor = Color( COL_BLACK );
1354 : : }
1355 [ # # ]: 0 : else if( mnDrawMode & DRAWMODE_WHITEFILL )
1356 : : {
1357 : 0 : aColor = Color( COL_WHITE );
1358 : : }
1359 [ # # ]: 0 : else if( mnDrawMode & DRAWMODE_GRAYFILL )
1360 : : {
1361 [ # # ]: 0 : const sal_uInt8 cLum = aColor.GetLuminance();
1362 : 0 : aColor = Color( cLum, cLum, cLum );
1363 : : }
1364 [ # # ]: 0 : else if( mnDrawMode & DRAWMODE_NOFILL )
1365 : : {
1366 : 0 : aColor = Color( COL_TRANSPARENT );
1367 : : }
1368 [ # # ]: 0 : else if( mnDrawMode & DRAWMODE_SETTINGSFILL )
1369 : : {
1370 : 0 : aColor = GetSettings().GetStyleSettings().GetWindowColor();
1371 : : }
1372 : :
1373 [ # # ]: 0 : if( mnDrawMode & DRAWMODE_GHOSTEDFILL )
1374 : : {
1375 : 0 : aColor = Color( (aColor.GetRed() >> 1) | 0x80,
1376 : 0 : (aColor.GetGreen() >> 1) | 0x80,
1377 : 0 : (aColor.GetBlue() >> 1) | 0x80);
1378 : : }
1379 : : }
1380 : : }
1381 : :
1382 [ + + ]: 1376020 : if ( mpMetaFile )
1383 [ + - ][ + - ]: 43474 : mpMetaFile->AddAction( new MetaFillColorAction( aColor, sal_True ) );
[ + - ]
1384 : :
1385 [ + + ]: 1376020 : if ( ImplIsColorTransparent( aColor ) )
1386 : : {
1387 [ + + ]: 19827 : if ( mbFillColor )
1388 : : {
1389 : 17996 : mbInitFillColor = sal_True;
1390 : 17996 : mbFillColor = sal_False;
1391 : 17996 : maFillColor = Color( COL_TRANSPARENT );
1392 : : }
1393 : : }
1394 : : else
1395 : : {
1396 [ + + ]: 1356193 : if ( maFillColor != aColor )
1397 : : {
1398 : 620550 : mbInitFillColor = sal_True;
1399 : 620550 : mbFillColor = sal_True;
1400 : 620550 : maFillColor = aColor;
1401 : : }
1402 : : }
1403 : :
1404 [ + + ]: 1376020 : if( mpAlphaVDev )
1405 [ + - ]: 58554 : mpAlphaVDev->SetFillColor( COL_BLACK );
1406 : 1376020 : }
1407 : :
1408 : : // -----------------------------------------------------------------------
1409 : :
1410 : 50341 : void OutputDevice::SetBackground()
1411 : : {
1412 : : OSL_TRACE( "OutputDevice::SetBackground()" );
1413 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1414 : :
1415 [ + - ]: 50341 : maBackground = Wallpaper();
1416 : 50341 : mbBackground = sal_False;
1417 : :
1418 [ - + ]: 50341 : if( mpAlphaVDev )
1419 : 0 : mpAlphaVDev->SetBackground();
1420 : 50341 : }
1421 : :
1422 : : // -----------------------------------------------------------------------
1423 : :
1424 : 337129 : void OutputDevice::SetBackground( const Wallpaper& rBackground )
1425 : : {
1426 : : OSL_TRACE( "OutputDevice::SetBackground( rBackground )" );
1427 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1428 : :
1429 : 337129 : maBackground = rBackground;
1430 : :
1431 [ + + ]: 337129 : if( rBackground.GetStyle() == WALLPAPER_NULL )
1432 : 1799 : mbBackground = sal_False;
1433 : : else
1434 : 335330 : mbBackground = sal_True;
1435 : :
1436 [ - + ]: 337129 : if( mpAlphaVDev )
1437 : 0 : mpAlphaVDev->SetBackground( rBackground );
1438 : 337129 : }
1439 : :
1440 : : // -----------------------------------------------------------------------
1441 : :
1442 : 110908 : void OutputDevice::SetRefPoint()
1443 : : {
1444 : : OSL_TRACE( "OutputDevice::SetRefPoint()" );
1445 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1446 : :
1447 [ + + ]: 110908 : if ( mpMetaFile )
1448 [ + - ][ + - ]: 10762 : mpMetaFile->AddAction( new MetaRefPointAction( Point(), sal_False ) );
[ + - ]
1449 : :
1450 : 110908 : mbRefPoint = sal_False;
1451 : 110908 : maRefPoint.X() = maRefPoint.Y() = 0L;
1452 : :
1453 [ + + ]: 110908 : if( mpAlphaVDev )
1454 : 21568 : mpAlphaVDev->SetRefPoint();
1455 : 110908 : }
1456 : :
1457 : : // -----------------------------------------------------------------------
1458 : :
1459 : 0 : void OutputDevice::SetRefPoint( const Point& rRefPoint )
1460 : : {
1461 : : OSL_TRACE( "OutputDevice::SetRefPoint( rRefPoint )" );
1462 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1463 : :
1464 [ # # ]: 0 : if ( mpMetaFile )
1465 [ # # ]: 0 : mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, sal_True ) );
1466 : :
1467 : 0 : mbRefPoint = sal_True;
1468 : 0 : maRefPoint = rRefPoint;
1469 : :
1470 [ # # ]: 0 : if( mpAlphaVDev )
1471 : 0 : mpAlphaVDev->SetRefPoint( rRefPoint );
1472 : 0 : }
1473 : :
1474 : : // -----------------------------------------------------------------------
1475 : :
1476 : 936312 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt )
1477 : : {
1478 : : OSL_TRACE( "OutputDevice::DrawLine()" );
1479 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1480 : :
1481 [ + + ]: 936312 : if ( mpMetaFile )
1482 [ + - ][ + - ]: 46463 : mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt ) );
[ + - ]
1483 : :
1484 [ + + ][ + - ]: 936312 : if ( !IsDeviceOutputNecessary() || !mbLineColor || ImplIsRecordLayout() )
[ + + ][ + + ]
1485 : : return;
1486 : :
1487 [ + + ]: 930906 : if ( !mpGraphics )
1488 : : {
1489 [ + - ][ + - ]: 2572 : if ( !ImplGetGraphics() )
1490 : : return;
1491 : : }
1492 : :
1493 [ + + ]: 930906 : if ( mbInitClipRegion )
1494 [ + - ]: 52638 : ImplInitClipRegion();
1495 [ + + ]: 930906 : if ( mbOutputClipped )
1496 : : return;
1497 : :
1498 [ + + ]: 883579 : if ( mbInitLineColor )
1499 [ + - ]: 243357 : ImplInitLineColor();
1500 : :
1501 : : // #i101598# support AA and snap for lines, too
1502 [ - + ][ # # : 883579 : if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
# # # # ]
[ - + ]
1503 [ # # ]: 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1504 : 0 : && ROP_OVERPAINT == GetRasterOp()
1505 : 0 : && IsLineColor())
1506 : : {
1507 : : // at least transform with double precision to device coordinates; this will
1508 : : // avoid pixel snap of single, appended lines
1509 [ # # ]: 0 : const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
1510 : 0 : const basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
1511 [ # # ]: 0 : basegfx::B2DPolygon aB2DPolyLine;
1512 : :
1513 [ # # ]: 0 : aB2DPolyLine.append(basegfx::B2DPoint(rStartPt.X(), rStartPt.Y()));
1514 [ # # ]: 0 : aB2DPolyLine.append(basegfx::B2DPoint(rEndPt.X(), rEndPt.Y()));
1515 [ # # ]: 0 : aB2DPolyLine.transform( aTransform );
1516 : :
1517 [ # # ]: 0 : if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
1518 : : {
1519 [ # # ][ # # ]: 0 : aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
[ # # ]
1520 : : }
1521 : :
1522 [ # # ][ # # ]: 0 : if( mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this))
1523 : : {
1524 : : return;
1525 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ]
1526 : : }
1527 : :
1528 [ + - ]: 883579 : const Point aStartPt(ImplLogicToDevicePixel(rStartPt));
1529 [ + - ]: 883579 : const Point aEndPt(ImplLogicToDevicePixel(rEndPt));
1530 : :
1531 [ + - ]: 883579 : mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
1532 : :
1533 [ + + ]: 883579 : if( mpAlphaVDev )
1534 [ + - ]: 936312 : mpAlphaVDev->DrawLine( rStartPt, rEndPt );
1535 : : }
1536 : :
1537 : : // -----------------------------------------------------------------------
1538 : :
1539 : 0 : void OutputDevice::impPaintLineGeometryWithEvtlExpand(
1540 : : const LineInfo& rInfo,
1541 : : basegfx::B2DPolyPolygon aLinePolyPolygon)
1542 : : {
1543 : : const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
1544 [ # # ]: 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1545 : 0 : && ROP_OVERPAINT == GetRasterOp()
1546 [ # # ]: 0 : && IsLineColor());
[ # # # # ]
[ # # ]
1547 [ # # ]: 0 : basegfx::B2DPolyPolygon aFillPolyPolygon;
1548 : 0 : const bool bDashUsed(LINE_DASH == rInfo.GetStyle());
1549 : 0 : const bool bLineWidthUsed(rInfo.GetWidth() > 1);
1550 : :
1551 [ # # ][ # # ]: 0 : if(bDashUsed && aLinePolyPolygon.count())
[ # # ][ # # ]
1552 : : {
1553 [ # # ]: 0 : ::std::vector< double > fDotDashArray;
1554 : 0 : const double fDashLen(rInfo.GetDashLen());
1555 : 0 : const double fDotLen(rInfo.GetDotLen());
1556 : 0 : const double fDistance(rInfo.GetDistance());
1557 : :
1558 [ # # ]: 0 : for(sal_uInt16 a(0); a < rInfo.GetDashCount(); a++)
1559 : : {
1560 [ # # ]: 0 : fDotDashArray.push_back(fDashLen);
1561 [ # # ]: 0 : fDotDashArray.push_back(fDistance);
1562 : : }
1563 : :
1564 [ # # ]: 0 : for(sal_uInt16 b(0); b < rInfo.GetDotCount(); b++)
1565 : : {
1566 [ # # ]: 0 : fDotDashArray.push_back(fDotLen);
1567 [ # # ]: 0 : fDotDashArray.push_back(fDistance);
1568 : : }
1569 : :
1570 [ # # ]: 0 : const double fAccumulated(::std::accumulate(fDotDashArray.begin(), fDotDashArray.end(), 0.0));
1571 : :
1572 [ # # ]: 0 : if(fAccumulated > 0.0)
1573 : : {
1574 [ # # ]: 0 : basegfx::B2DPolyPolygon aResult;
1575 : :
1576 [ # # ][ # # ]: 0 : for(sal_uInt32 c(0); c < aLinePolyPolygon.count(); c++)
1577 : : {
1578 [ # # ]: 0 : basegfx::B2DPolyPolygon aLineTraget;
1579 : : basegfx::tools::applyLineDashing(
1580 : : aLinePolyPolygon.getB2DPolygon(c),
1581 : : fDotDashArray,
1582 [ # # ][ # # ]: 0 : &aLineTraget);
[ # # ]
1583 [ # # ]: 0 : aResult.append(aLineTraget);
1584 [ # # ]: 0 : }
1585 : :
1586 [ # # ][ # # ]: 0 : aLinePolyPolygon = aResult;
1587 : 0 : }
1588 : : }
1589 : :
1590 [ # # ][ # # ]: 0 : if(bLineWidthUsed && aLinePolyPolygon.count())
[ # # ][ # # ]
1591 : : {
1592 : 0 : const double fHalfLineWidth((rInfo.GetWidth() * 0.5) + 0.5);
1593 : :
1594 [ # # ][ # # ]: 0 : if(aLinePolyPolygon.areControlPointsUsed())
1595 : : {
1596 : : // #i110768# When area geometry has to be created, do not
1597 : : // use the fallback bezier decomposition inside createAreaGeometry,
1598 : : // but one that is at least as good as ImplSubdivideBezier was.
1599 : : // There, Polygon::AdaptiveSubdivide was used with default parameter
1600 : : // 1.0 as quality index.
1601 [ # # ][ # # ]: 0 : aLinePolyPolygon = basegfx::tools::adaptiveSubdivideByDistance(aLinePolyPolygon, 1.0);
[ # # ]
1602 : : }
1603 : :
1604 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
1605 : : {
1606 : : aFillPolyPolygon.append(basegfx::tools::createAreaGeometry(
1607 : : aLinePolyPolygon.getB2DPolygon(a),
1608 : : fHalfLineWidth,
1609 [ # # ][ # # ]: 0 : rInfo.GetLineJoin()));
[ # # ][ # # ]
[ # # ]
1610 : : }
1611 : :
1612 [ # # ]: 0 : aLinePolyPolygon.clear();
1613 : : }
1614 : :
1615 : 0 : GDIMetaFile* pOldMetaFile = mpMetaFile;
1616 : 0 : mpMetaFile = NULL;
1617 : :
1618 [ # # ][ # # ]: 0 : if(aLinePolyPolygon.count())
1619 : : {
1620 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0); a < aLinePolyPolygon.count(); a++)
1621 : : {
1622 [ # # ]: 0 : const basegfx::B2DPolygon aCandidate(aLinePolyPolygon.getB2DPolygon(a));
1623 : 0 : bool bDone(false);
1624 : :
1625 [ # # ]: 0 : if(bTryAA)
1626 : : {
1627 [ # # ]: 0 : bDone = mpGraphics->DrawPolyLine( aCandidate, 0.0, basegfx::B2DVector(1.0,1.0), basegfx::B2DLINEJOIN_NONE, this);
1628 : : }
1629 : :
1630 [ # # ]: 0 : if(!bDone)
1631 : : {
1632 [ # # ]: 0 : const Polygon aPolygon(aCandidate);
1633 [ # # ][ # # ]: 0 : mpGraphics->DrawPolyLine(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
[ # # ][ # # ]
1634 : : }
1635 [ # # ]: 0 : }
1636 : : }
1637 : :
1638 [ # # ][ # # ]: 0 : if(aFillPolyPolygon.count())
1639 : : {
1640 : 0 : const Color aOldLineColor( maLineColor );
1641 : 0 : const Color aOldFillColor( maFillColor );
1642 : :
1643 [ # # ]: 0 : SetLineColor();
1644 [ # # ]: 0 : ImplInitLineColor();
1645 [ # # ]: 0 : SetFillColor( aOldLineColor );
1646 [ # # ]: 0 : ImplInitFillColor();
1647 : :
1648 : 0 : bool bDone(false);
1649 : :
1650 [ # # ]: 0 : if(bTryAA)
1651 : : {
1652 [ # # ]: 0 : bDone = mpGraphics->DrawPolyPolygon(aFillPolyPolygon, 0.0, this);
1653 : : }
1654 : :
1655 [ # # ]: 0 : if(!bDone)
1656 : : {
1657 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0); a < aFillPolyPolygon.count(); a++)
1658 : : {
1659 [ # # ][ # # ]: 0 : const Polygon aPolygon(aFillPolyPolygon.getB2DPolygon(a));
[ # # ]
1660 [ # # ][ # # ]: 0 : mpGraphics->DrawPolygon(aPolygon.GetSize(), (const SalPoint*)aPolygon.GetConstPointAry(), this);
[ # # ]
1661 [ # # ]: 0 : }
1662 : : }
1663 : :
1664 [ # # ]: 0 : SetFillColor( aOldFillColor );
1665 [ # # ]: 0 : SetLineColor( aOldLineColor );
1666 : : }
1667 : :
1668 [ # # ]: 0 : mpMetaFile = pOldMetaFile;
1669 : 0 : }
1670 : :
1671 : : // -----------------------------------------------------------------------
1672 : :
1673 : 0 : void OutputDevice::DrawLine( const Point& rStartPt, const Point& rEndPt,
1674 : : const LineInfo& rLineInfo )
1675 : : {
1676 : : OSL_TRACE( "OutputDevice::DrawLine()" );
1677 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1678 : :
1679 [ # # ]: 0 : if ( rLineInfo.IsDefault() )
1680 : : {
1681 [ # # ]: 0 : DrawLine( rStartPt, rEndPt );
1682 : : return;
1683 : : }
1684 : :
1685 [ # # ]: 0 : if ( mpMetaFile )
1686 [ # # ][ # # ]: 0 : mpMetaFile->AddAction( new MetaLineAction( rStartPt, rEndPt, rLineInfo ) );
[ # # ]
1687 : :
1688 [ # # ][ # # ]: 0 : if ( !IsDeviceOutputNecessary() || !mbLineColor || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
[ # # ][ # # ]
[ # # ]
1689 : : return;
1690 : :
1691 [ # # ][ # # ]: 0 : if( !mpGraphics && !ImplGetGraphics() )
[ # # ][ # # ]
1692 : : return;
1693 : :
1694 [ # # ]: 0 : if ( mbInitClipRegion )
1695 [ # # ]: 0 : ImplInitClipRegion();
1696 : :
1697 [ # # ]: 0 : if ( mbOutputClipped )
1698 : : return;
1699 : :
1700 [ # # ]: 0 : const Point aStartPt( ImplLogicToDevicePixel( rStartPt ) );
1701 [ # # ]: 0 : const Point aEndPt( ImplLogicToDevicePixel( rEndPt ) );
1702 [ # # ]: 0 : const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
1703 : 0 : const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
1704 : 0 : const bool bLineWidthUsed(aInfo.GetWidth() > 1);
1705 : :
1706 [ # # ]: 0 : if ( mbInitLineColor )
1707 [ # # ]: 0 : ImplInitLineColor();
1708 : :
1709 [ # # ][ # # ]: 0 : if(bDashUsed || bLineWidthUsed)
1710 : : {
1711 [ # # ]: 0 : basegfx::B2DPolygon aLinePolygon;
1712 [ # # ]: 0 : aLinePolygon.append(basegfx::B2DPoint(aStartPt.X(), aStartPt.Y()));
1713 [ # # ]: 0 : aLinePolygon.append(basegfx::B2DPoint(aEndPt.X(), aEndPt.Y()));
1714 : :
1715 [ # # ][ # # ]: 0 : impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aLinePolygon));
[ # # ][ # # ]
1716 : : }
1717 : : else
1718 : : {
1719 [ # # ]: 0 : mpGraphics->DrawLine( aStartPt.X(), aStartPt.Y(), aEndPt.X(), aEndPt.Y(), this );
1720 : : }
1721 : :
1722 [ # # ]: 0 : if( mpAlphaVDev )
1723 [ # # ][ # # ]: 0 : mpAlphaVDev->DrawLine( rStartPt, rEndPt, rLineInfo );
1724 : : }
1725 : :
1726 : : // -----------------------------------------------------------------------
1727 : :
1728 : 571234 : void OutputDevice::DrawRect( const Rectangle& rRect )
1729 : : {
1730 : : OSL_TRACE( "OutputDevice::DrawRect()" );
1731 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1732 : :
1733 [ + + ]: 571234 : if ( mpMetaFile )
1734 [ + - ][ + - ]: 20372 : mpMetaFile->AddAction( new MetaRectAction( rRect ) );
[ + - ]
1735 : :
1736 [ + + ][ + + ]: 571234 : if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || ImplIsRecordLayout() )
[ + + ][ + + ]
[ + + ]
1737 : : return;
1738 : :
1739 [ + - ]: 554146 : Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
1740 : :
1741 [ + - ][ + + ]: 554146 : if ( aRect.IsEmpty() )
1742 : : return;
1743 [ + - ]: 538910 : aRect.Justify();
1744 : :
1745 [ + + ]: 538910 : if ( !mpGraphics )
1746 : : {
1747 [ + - ][ + - ]: 95487 : if ( !ImplGetGraphics() )
1748 : : return;
1749 : : }
1750 : :
1751 [ + + ]: 538910 : if ( mbInitClipRegion )
1752 [ + - ]: 192664 : ImplInitClipRegion();
1753 [ + + ]: 538910 : if ( mbOutputClipped )
1754 : : return;
1755 : :
1756 [ + + ]: 527677 : if ( mbInitLineColor )
1757 [ + - ]: 315596 : ImplInitLineColor();
1758 [ + + ]: 527677 : if ( mbInitFillColor )
1759 [ + - ]: 276173 : ImplInitFillColor();
1760 : :
1761 [ + - ][ + - ]: 527677 : mpGraphics->DrawRect( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(), this );
[ + - ]
1762 : :
1763 [ + + ]: 527677 : if( mpAlphaVDev )
1764 [ + - ]: 571234 : mpAlphaVDev->DrawRect( rRect );
1765 : : }
1766 : :
1767 : : // -----------------------------------------------------------------------
1768 : :
1769 : 29634 : void OutputDevice::DrawPolyLine( const Polygon& rPoly )
1770 : : {
1771 : : OSL_TRACE( "OutputDevice::DrawPolyLine()" );
1772 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1773 : : DBG_CHKOBJ( &rPoly, Polygon, NULL );
1774 : :
1775 [ - + ]: 29634 : if( mpMetaFile )
1776 [ # # ][ # # ]: 0 : mpMetaFile->AddAction( new MetaPolyLineAction( rPoly ) );
[ # # ]
1777 : :
1778 [ + - ]: 29634 : sal_uInt16 nPoints = rPoly.GetSize();
1779 : :
1780 [ + - ][ + - ]: 29634 : if ( !IsDeviceOutputNecessary() || !mbLineColor || (nPoints < 2) || ImplIsRecordLayout() )
[ + - ][ - + ]
[ + - ]
1781 : : return;
1782 : :
1783 : : // we need a graphics
1784 [ - + ]: 29634 : if ( !mpGraphics )
1785 [ # # ][ # # ]: 0 : if ( !ImplGetGraphics() )
1786 : : return;
1787 : :
1788 [ + + ]: 29634 : if ( mbInitClipRegion )
1789 [ + - ]: 1076 : ImplInitClipRegion();
1790 [ + - ]: 29634 : if ( mbOutputClipped )
1791 : : return;
1792 : :
1793 [ + + ]: 29634 : if ( mbInitLineColor )
1794 [ + - ]: 5127 : ImplInitLineColor();
1795 : :
1796 : : const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
1797 [ # # ]: 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1798 : 0 : && ROP_OVERPAINT == GetRasterOp()
1799 [ - + ]: 29634 : && IsLineColor());
[ # # # # ]
[ # # ]
1800 : :
1801 : : // use b2dpolygon drawing if possible
1802 [ - + ][ # # ]: 29634 : if(bTryAA && ImpTryDrawPolyLineDirect(rPoly.getB2DPolygon(), 0.0, basegfx::B2DLINEJOIN_NONE))
[ # # ][ # # ]
[ - + ][ # # ]
[ - + # # ]
1803 : : {
1804 [ # # ]: 0 : basegfx::B2DPolygon aB2DPolyLine(rPoly.getB2DPolygon());
1805 [ # # ]: 0 : const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
1806 : 0 : const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
1807 : :
1808 : : // transform the polygon
1809 [ # # ]: 0 : aB2DPolyLine.transform( aTransform );
1810 : :
1811 [ # # ]: 0 : if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
1812 : : {
1813 [ # # ][ # # ]: 0 : aB2DPolyLine = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyLine);
[ # # ]
1814 : : }
1815 : :
1816 [ # # ][ # # ]: 0 : if(mpGraphics->DrawPolyLine( aB2DPolyLine, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this))
1817 : : {
1818 : : return;
1819 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
[ # # ]
1820 : : }
1821 : :
1822 [ + - ]: 29634 : Polygon aPoly = ImplLogicToDevicePixel( rPoly );
1823 [ + - ]: 29634 : const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
1824 : :
1825 : : // #100127# Forward beziers to sal, if any
1826 [ + - ][ - + ]: 29634 : if( aPoly.HasFlags() )
1827 : : {
1828 [ # # ]: 0 : const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
1829 [ # # ][ # # ]: 0 : if( !mpGraphics->DrawPolyLineBezier( nPoints, pPtAry, pFlgAry, this ) )
1830 : : {
1831 [ # # ][ # # ]: 0 : aPoly = ImplSubdivideBezier(aPoly);
[ # # ]
1832 [ # # ]: 0 : pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
1833 [ # # ][ # # ]: 0 : mpGraphics->DrawPolyLine( aPoly.GetSize(), pPtAry, this );
1834 : : }
1835 : : }
1836 : : else
1837 : : {
1838 [ + - ]: 29634 : mpGraphics->DrawPolyLine( nPoints, pPtAry, this );
1839 : : }
1840 : :
1841 [ + + ]: 29634 : if( mpAlphaVDev )
1842 [ + - ][ + - ]: 29634 : mpAlphaVDev->DrawPolyLine( rPoly );
1843 : : }
1844 : :
1845 : : // -----------------------------------------------------------------------
1846 : :
1847 : 0 : void OutputDevice::DrawPolyLine( const Polygon& rPoly, const LineInfo& rLineInfo )
1848 : : {
1849 : : OSL_TRACE( "OutputDevice::DrawPolyLine()" );
1850 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1851 : : DBG_CHKOBJ( &rPoly, Polygon, NULL );
1852 : :
1853 [ # # ]: 0 : if ( rLineInfo.IsDefault() )
1854 : : {
1855 : 0 : DrawPolyLine( rPoly );
1856 : 0 : return;
1857 : : }
1858 : :
1859 : : // #i101491#
1860 : : // Try direct Fallback to B2D-Version of DrawPolyLine
1861 [ # # # # ]: 0 : if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
[ # # ]
1862 : 0 : && LINE_SOLID == rLineInfo.GetStyle())
1863 : : {
1864 [ # # ]: 0 : DrawPolyLine( rPoly.getB2DPolygon(), (double)rLineInfo.GetWidth(), rLineInfo.GetLineJoin());
1865 : 0 : return;
1866 : : }
1867 : :
1868 [ # # ]: 0 : if ( mpMetaFile )
1869 [ # # ]: 0 : mpMetaFile->AddAction( new MetaPolyLineAction( rPoly, rLineInfo ) );
1870 : :
1871 : 0 : ImpDrawPolyLineWithLineInfo(rPoly, rLineInfo);
1872 : : }
1873 : :
1874 : 191315 : void OutputDevice::ImpDrawPolyLineWithLineInfo(const Polygon& rPoly, const LineInfo& rLineInfo)
1875 : : {
1876 [ + - ]: 191315 : sal_uInt16 nPoints(rPoly.GetSize());
1877 : :
1878 [ + + ][ + - ]: 191315 : if ( !IsDeviceOutputNecessary() || !mbLineColor || ( nPoints < 2 ) || ( LINE_NONE == rLineInfo.GetStyle() ) || ImplIsRecordLayout() )
[ + - ][ + - ]
[ - + ][ + + ]
1879 : : return;
1880 : :
1881 [ + - ]: 184807 : Polygon aPoly = ImplLogicToDevicePixel( rPoly );
1882 : :
1883 : : // #100127# LineInfo is not curve-safe, subdivide always
1884 : : //
1885 : : // What shall this mean? It's wrong to subdivide here when the
1886 : : // polygon is a fat line. In that case, the painted geometry
1887 : : // WILL be much different.
1888 : : // I also have no idea how this could be related to the given ID
1889 : : // which reads 'consolidate boost versions' in the task description.
1890 : : // Removing.
1891 : : //
1892 : : //if( aPoly.HasFlags() )
1893 : : //{
1894 : : // aPoly = ImplSubdivideBezier( aPoly );
1895 : : // nPoints = aPoly.GetSize();
1896 : : //}
1897 : :
1898 : : // we need a graphics
1899 [ - + ][ # # ]: 184807 : if ( !mpGraphics && !ImplGetGraphics() )
[ # # ][ - + ]
1900 : : return;
1901 : :
1902 [ - + ]: 184807 : if ( mbInitClipRegion )
1903 [ # # ]: 0 : ImplInitClipRegion();
1904 : :
1905 [ - + ]: 184807 : if ( mbOutputClipped )
1906 : : return;
1907 : :
1908 [ - + ]: 184807 : if ( mbInitLineColor )
1909 [ # # ]: 0 : ImplInitLineColor();
1910 : :
1911 [ + - ]: 184807 : const LineInfo aInfo( ImplLogicToDevicePixel( rLineInfo ) );
1912 : 184807 : const bool bDashUsed(LINE_DASH == aInfo.GetStyle());
1913 : 184807 : const bool bLineWidthUsed(aInfo.GetWidth() > 1);
1914 : :
1915 [ - + ][ + - ]: 184807 : if(bDashUsed || bLineWidthUsed)
1916 : : {
1917 [ # # ][ # # ]: 0 : impPaintLineGeometryWithEvtlExpand(aInfo, basegfx::B2DPolyPolygon(aPoly.getB2DPolygon()));
[ # # ][ # # ]
[ # # ]
1918 : : }
1919 : : else
1920 : : {
1921 : : // #100127# the subdivision HAS to be done here since only a pointer
1922 : : // to an array of points is given to the DrawPolyLine method, there is
1923 : : // NO way to find out there that it's a curve.
1924 [ + - ][ + + ]: 184807 : if( aPoly.HasFlags() )
1925 : : {
1926 [ + - ][ + - ]: 715 : aPoly = ImplSubdivideBezier( aPoly );
[ + - ]
1927 [ + - ]: 715 : nPoints = aPoly.GetSize();
1928 : : }
1929 : :
1930 [ + - ][ + - ]: 184807 : mpGraphics->DrawPolyLine(nPoints, (const SalPoint*)aPoly.GetConstPointAry(), this);
1931 : : }
1932 : :
1933 [ - + ]: 184807 : if( mpAlphaVDev )
1934 [ # # ][ + - ]: 191315 : mpAlphaVDev->DrawPolyLine( rPoly, rLineInfo );
[ + - ][ + - ]
1935 : : }
1936 : :
1937 : : // -----------------------------------------------------------------------
1938 : :
1939 : 61373 : void OutputDevice::DrawPolygon( const Polygon& rPoly )
1940 : : {
1941 : : OSL_TRACE( "OutputDevice::DrawPolygon()" );
1942 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
1943 : : DBG_CHKOBJ( &rPoly, Polygon, NULL );
1944 : :
1945 [ + + ]: 61373 : if( mpMetaFile )
1946 [ + - ][ + - ]: 18 : mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
[ + - ]
1947 : :
1948 [ + - ]: 61373 : sal_uInt16 nPoints = rPoly.GetSize();
1949 : :
1950 [ + - ][ + + ]: 61373 : if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || (nPoints < 2) || ImplIsRecordLayout() )
[ + - ][ + - ]
[ - + ][ + - ]
1951 : : return;
1952 : :
1953 : : // we need a graphics
1954 [ - + ]: 61373 : if ( !mpGraphics )
1955 [ # # ][ # # ]: 0 : if ( !ImplGetGraphics() )
1956 : : return;
1957 : :
1958 [ + + ]: 61373 : if ( mbInitClipRegion )
1959 [ + - ]: 339 : ImplInitClipRegion();
1960 [ + - ]: 61373 : if ( mbOutputClipped )
1961 : : return;
1962 : :
1963 [ + + ]: 61373 : if ( mbInitLineColor )
1964 [ + - ]: 2837 : ImplInitLineColor();
1965 [ + + ]: 61373 : if ( mbInitFillColor )
1966 [ + - ]: 3625 : ImplInitFillColor();
1967 : :
1968 : : // use b2dpolygon drawing if possible
1969 [ - + ][ # # : 61373 : if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
# # # # #
# ][ - + ]
1970 [ # # ]: 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
1971 : 0 : && ROP_OVERPAINT == GetRasterOp()
1972 : 0 : && (IsLineColor() || IsFillColor()))
1973 : : {
1974 [ # # ]: 0 : const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
1975 [ # # ]: 0 : basegfx::B2DPolygon aB2DPolygon(rPoly.getB2DPolygon());
1976 : 0 : bool bSuccess(true);
1977 : :
1978 : : // transform the polygon and ensure closed
1979 [ # # ]: 0 : aB2DPolygon.transform(aTransform);
1980 [ # # ]: 0 : aB2DPolygon.setClosed(true);
1981 : :
1982 [ # # ]: 0 : if(IsFillColor())
1983 : : {
1984 [ # # ][ # # ]: 0 : bSuccess = mpGraphics->DrawPolyPolygon(basegfx::B2DPolyPolygon(aB2DPolygon), 0.0, this);
[ # # ]
1985 : : }
1986 : :
1987 [ # # ][ # # ]: 0 : if(bSuccess && IsLineColor())
[ # # ]
1988 : : {
1989 : 0 : const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
1990 : :
1991 [ # # ]: 0 : if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
1992 : : {
1993 [ # # ][ # # ]: 0 : aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
[ # # ]
1994 : : }
1995 : :
1996 [ # # ]: 0 : bSuccess = mpGraphics->DrawPolyLine( aB2DPolygon, 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this);
1997 : : }
1998 : :
1999 [ # # ]: 0 : if(bSuccess)
2000 : : {
2001 : : return;
2002 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
2003 : : }
2004 : :
2005 [ + - ]: 61373 : Polygon aPoly = ImplLogicToDevicePixel( rPoly );
2006 [ + - ]: 61373 : const SalPoint* pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
2007 : :
2008 : : // #100127# Forward beziers to sal, if any
2009 [ + - ][ - + ]: 61373 : if( aPoly.HasFlags() )
2010 : : {
2011 [ # # ]: 0 : const sal_uInt8* pFlgAry = aPoly.GetConstFlagAry();
2012 [ # # ][ # # ]: 0 : if( !mpGraphics->DrawPolygonBezier( nPoints, pPtAry, pFlgAry, this ) )
2013 : : {
2014 [ # # ][ # # ]: 0 : aPoly = ImplSubdivideBezier(aPoly);
[ # # ]
2015 [ # # ]: 0 : pPtAry = (const SalPoint*)aPoly.GetConstPointAry();
2016 [ # # ][ # # ]: 0 : mpGraphics->DrawPolygon( aPoly.GetSize(), pPtAry, this );
2017 : : }
2018 : : }
2019 : : else
2020 : : {
2021 [ + - ]: 61373 : mpGraphics->DrawPolygon( nPoints, pPtAry, this );
2022 : : }
2023 [ + + ]: 61373 : if( mpAlphaVDev )
2024 [ + - ][ + - ]: 61373 : mpAlphaVDev->DrawPolygon( rPoly );
2025 : : }
2026 : :
2027 : : // -----------------------------------------------------------------------
2028 : :
2029 : 72739 : void OutputDevice::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
2030 : : {
2031 : : OSL_TRACE( "OutputDevice::DrawPolyPolygon()" );
2032 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2033 : : DBG_CHKOBJ( &rPolyPoly, PolyPolygon, NULL );
2034 : :
2035 [ - + ]: 72739 : if( mpMetaFile )
2036 [ # # ]: 0 : mpMetaFile->AddAction( new MetaPolyPolygonAction( rPolyPoly ) );
2037 : :
2038 : 72739 : sal_uInt16 nPoly = rPolyPoly.Count();
2039 : :
2040 [ + + ][ + - ]: 72739 : if ( !IsDeviceOutputNecessary() || (!mbLineColor && !mbFillColor) || !nPoly || ImplIsRecordLayout() )
[ + - ][ - + ]
[ - + ][ + - ]
2041 : 0 : return;
2042 : :
2043 : : // we need a graphics
2044 [ - + ]: 72739 : if ( !mpGraphics )
2045 [ # # ]: 0 : if ( !ImplGetGraphics() )
2046 : 0 : return;
2047 : :
2048 [ + + ]: 72739 : if ( mbInitClipRegion )
2049 : 393 : ImplInitClipRegion();
2050 [ - + ]: 72739 : if ( mbOutputClipped )
2051 : 0 : return;
2052 : :
2053 [ + + ]: 72739 : if ( mbInitLineColor )
2054 : 12651 : ImplInitLineColor();
2055 [ + + ]: 72739 : if ( mbInitFillColor )
2056 : 39889 : ImplInitFillColor();
2057 : :
2058 : : // use b2dpolygon drawing if possible
2059 [ - + # # : 72739 : if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
# # # # #
# ][ - + ]
2060 : 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
2061 : 0 : && ROP_OVERPAINT == GetRasterOp()
2062 : 0 : && (IsLineColor() || IsFillColor()))
2063 : : {
2064 [ # # ]: 0 : const ::basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
2065 [ # # ]: 0 : basegfx::B2DPolyPolygon aB2DPolyPolygon(rPolyPoly.getB2DPolyPolygon());
2066 : 0 : bool bSuccess(true);
2067 : :
2068 : : // transform the polygon and ensure closed
2069 [ # # ]: 0 : aB2DPolyPolygon.transform(aTransform);
2070 [ # # ]: 0 : aB2DPolyPolygon.setClosed(true);
2071 : :
2072 [ # # ]: 0 : if(IsFillColor())
2073 : : {
2074 [ # # ]: 0 : bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
2075 : : }
2076 : :
2077 [ # # ][ # # ]: 0 : if(bSuccess && IsLineColor())
[ # # ]
2078 : : {
2079 : 0 : const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
2080 : :
2081 [ # # ]: 0 : if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
2082 : : {
2083 [ # # ][ # # ]: 0 : aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
[ # # ]
2084 : : }
2085 : :
2086 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0); bSuccess && a < aB2DPolyPolygon.count(); a++)
[ # # ][ # # ]
2087 : : {
2088 [ # # ][ # # ]: 0 : bSuccess = mpGraphics->DrawPolyLine( aB2DPolyPolygon.getB2DPolygon(a), 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this);
[ # # ]
2089 : 0 : }
2090 : : }
2091 : :
2092 [ # # ]: 0 : if(bSuccess)
2093 : : {
2094 : : return;
2095 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
2096 : : }
2097 : :
2098 [ + + ]: 72739 : if ( nPoly == 1 )
2099 : : {
2100 : : // #100127# Map to DrawPolygon
2101 [ + - ][ + - ]: 48249 : Polygon aPoly = rPolyPoly.GetObject( 0 );
2102 [ + - ][ + - ]: 48249 : if( aPoly.GetSize() >= 2 )
2103 : : {
2104 : 48249 : GDIMetaFile* pOldMF = mpMetaFile;
2105 : 48249 : mpMetaFile = NULL;
2106 : :
2107 [ + - ]: 48249 : DrawPolygon( aPoly );
2108 : :
2109 : 48249 : mpMetaFile = pOldMF;
2110 [ + - ]: 48249 : }
2111 : : }
2112 : : else
2113 : : {
2114 : : // #100127# moved real PolyPolygon draw to separate method,
2115 : : // have to call recursively, avoiding duplicate
2116 : : // ImplLogicToDevicePixel calls
2117 [ + - ]: 24490 : ImplDrawPolyPolygon( nPoly, ImplLogicToDevicePixel( rPolyPoly ) );
2118 : : }
2119 [ + + ]: 72739 : if( mpAlphaVDev )
2120 : 72739 : mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
2121 : : }
2122 : :
2123 : : // -----------------------------------------------------------------------
2124 : :
2125 : 186 : void OutputDevice::DrawPolygon( const ::basegfx::B2DPolygon& rB2DPolygon)
2126 : : {
2127 : : // AW: Do NOT paint empty polygons
2128 [ + - ]: 186 : if(rB2DPolygon.count())
2129 : : {
2130 [ + - ]: 186 : ::basegfx::B2DPolyPolygon aPP( rB2DPolygon );
2131 [ + - ][ + - ]: 186 : DrawPolyPolygon( aPP );
2132 : : }
2133 : 186 : }
2134 : :
2135 : : // -----------------------------------------------------------------------
2136 : : // Caution: This method is nearly the same as
2137 : : // OutputDevice::DrawTransparent( const basegfx::B2DPolyPolygon& rB2DPolyPoly, double fTransparency),
2138 : : // so when changes are made here do not forget to make change sthere, too
2139 : :
2140 : 264346 : void OutputDevice::DrawPolyPolygon( const basegfx::B2DPolyPolygon& rB2DPolyPoly )
2141 : : {
2142 : : OSL_TRACE( "OutputDevice::DrawPolyPolygon(B2D&)" );
2143 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2144 : :
2145 : :
2146 [ + + ]: 264346 : if( mpMetaFile )
2147 [ + - ][ + - ]: 1381 : mpMetaFile->AddAction( new MetaPolyPolygonAction( PolyPolygon( rB2DPolyPoly ) ) );
[ + - ]
2148 : :
2149 : : // call helper
2150 : 264346 : ImpDrawPolyPolygonWithB2DPolyPolygon(rB2DPolyPoly);
2151 : 264346 : }
2152 : :
2153 : 264406 : void OutputDevice::ImpDrawPolyPolygonWithB2DPolyPolygon(const basegfx::B2DPolyPolygon& rB2DPolyPoly)
2154 : : {
2155 : : // AW: Do NOT paint empty PolyPolygons
2156 [ + - ][ + + ]: 264406 : if(!rB2DPolyPoly.count())
2157 : : return;
2158 : :
2159 : : // we need a graphics
2160 [ - + ]: 264399 : if( !mpGraphics )
2161 [ # # ][ # # ]: 0 : if( !ImplGetGraphics() )
2162 : : return;
2163 : :
2164 [ + + ]: 264399 : if( mbInitClipRegion )
2165 [ + - ]: 1018 : ImplInitClipRegion();
2166 [ + - ]: 264399 : if( mbOutputClipped )
2167 : : return;
2168 : :
2169 [ + + ]: 264399 : if( mbInitLineColor )
2170 [ + - ]: 15534 : ImplInitLineColor();
2171 [ + + ]: 264399 : if( mbInitFillColor )
2172 [ + - ]: 226614 : ImplInitFillColor();
2173 : :
2174 [ - + ][ # # : 264399 : if((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
# # # # #
# ][ - + ]
2175 [ # # ]: 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
2176 : 0 : && ROP_OVERPAINT == GetRasterOp()
2177 : 0 : && (IsLineColor() || IsFillColor()))
2178 : : {
2179 [ # # ]: 0 : const basegfx::B2DHomMatrix aTransform(ImplGetDeviceTransformation());
2180 [ # # ]: 0 : basegfx::B2DPolyPolygon aB2DPolyPolygon(rB2DPolyPoly);
2181 : 0 : bool bSuccess(true);
2182 : :
2183 : : // transform the polygon and ensure closed
2184 [ # # ]: 0 : aB2DPolyPolygon.transform(aTransform);
2185 [ # # ]: 0 : aB2DPolyPolygon.setClosed(true);
2186 : :
2187 [ # # ]: 0 : if(IsFillColor())
2188 : : {
2189 [ # # ]: 0 : bSuccess = mpGraphics->DrawPolyPolygon(aB2DPolyPolygon, 0.0, this);
2190 : : }
2191 : :
2192 [ # # ][ # # ]: 0 : if(bSuccess && IsLineColor())
[ # # ]
2193 : : {
2194 : 0 : const ::basegfx::B2DVector aB2DLineWidth( 1.0, 1.0 );
2195 : :
2196 [ # # ]: 0 : if(mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
2197 : : {
2198 [ # # ][ # # ]: 0 : aB2DPolyPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolyPolygon);
[ # # ]
2199 : : }
2200 : :
2201 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0);bSuccess && a < aB2DPolyPolygon.count(); a++)
[ # # ][ # # ]
2202 : : {
2203 [ # # ][ # # ]: 0 : bSuccess = mpGraphics->DrawPolyLine( aB2DPolyPolygon.getB2DPolygon(a), 0.0, aB2DLineWidth, basegfx::B2DLINEJOIN_NONE, this);
[ # # ]
2204 : 0 : }
2205 : : }
2206 : :
2207 [ # # ]: 0 : if(bSuccess)
2208 : : {
2209 : : return;
2210 [ # # ][ # # ]: 0 : }
[ # # ][ # # ]
2211 : : }
2212 : :
2213 : : // fallback to old polygon drawing if needed
2214 [ + - ]: 264399 : const PolyPolygon aToolsPolyPolygon( rB2DPolyPoly );
2215 [ + - ]: 264399 : const PolyPolygon aPixelPolyPolygon = ImplLogicToDevicePixel( aToolsPolyPolygon );
2216 [ + - ][ + - ]: 264406 : ImplDrawPolyPolygon( aPixelPolyPolygon.Count(), aPixelPolyPolygon );
[ + - ][ + - ]
2217 : : }
2218 : :
2219 : : // -----------------------------------------------------------------------
2220 : :
2221 : 0 : bool OutputDevice::ImpTryDrawPolyLineDirect(
2222 : : const basegfx::B2DPolygon& rB2DPolygon,
2223 : : double fLineWidth,
2224 : : basegfx::B2DLineJoin eLineJoin)
2225 : : {
2226 [ # # ]: 0 : const basegfx::B2DHomMatrix aTransform = ImplGetDeviceTransformation();
2227 : 0 : basegfx::B2DVector aB2DLineWidth(1.0, 1.0);
2228 : :
2229 : : // transform the line width if used
2230 [ # # ]: 0 : if( fLineWidth != 0.0 )
2231 : : {
2232 [ # # ][ # # ]: 0 : aB2DLineWidth = aTransform * ::basegfx::B2DVector( fLineWidth, fLineWidth );
2233 : : }
2234 : :
2235 : : // transform the polygon
2236 [ # # ]: 0 : basegfx::B2DPolygon aB2DPolygon(rB2DPolygon);
2237 [ # # ]: 0 : aB2DPolygon.transform(aTransform);
2238 : :
2239 [ # # ][ # # ]: 0 : if((mnAntialiasing & ANTIALIASING_PIXELSNAPHAIRLINE)
[ # # ]
2240 [ # # ]: 0 : && aB2DPolygon.count() < 1000)
2241 : : {
2242 : : // #i98289#, #i101491#
2243 : : // better to remove doubles on device coordinates. Also assume from a given amount
2244 : : // of points that the single edges are not long enough to smooth
2245 [ # # ]: 0 : aB2DPolygon.removeDoublePoints();
2246 [ # # ][ # # ]: 0 : aB2DPolygon = basegfx::tools::snapPointsOfHorizontalOrVerticalEdges(aB2DPolygon);
[ # # ]
2247 : : }
2248 : :
2249 : : // draw the polyline
2250 [ # # ][ # # ]: 0 : return mpGraphics->DrawPolyLine( aB2DPolygon, 0.0, aB2DLineWidth, eLineJoin, this);
[ # # ]
2251 : : }
2252 : :
2253 : 191375 : void OutputDevice::DrawPolyLine(
2254 : : const basegfx::B2DPolygon& rB2DPolygon,
2255 : : double fLineWidth,
2256 : : basegfx::B2DLineJoin eLineJoin)
2257 : : {
2258 : : OSL_TRACE( "OutputDevice::DrawPolyLine(B2D&)" );
2259 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2260 : : (void)eLineJoin; // ATM used in UNX, but not in WNT, access it for warning-free
2261 : :
2262 [ + + ]: 191375 : if( mpMetaFile )
2263 : : {
2264 [ + - ]: 6568 : LineInfo aLineInfo;
2265 [ + + ]: 6568 : if( fLineWidth != 0.0 )
2266 [ + - ]: 60 : aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
2267 [ + - ]: 6568 : const Polygon aToolsPolygon( rB2DPolygon );
2268 [ + - ][ + - ]: 6568 : mpMetaFile->AddAction( new MetaPolyLineAction( aToolsPolygon, aLineInfo ) );
[ + - ][ + - ]
[ + - ]
2269 : : }
2270 : :
2271 : :
2272 : : // AW: Do NOT paint empty PolyPolygons
2273 [ - + ]: 191375 : if(!rB2DPolygon.count())
2274 : 0 : return;
2275 : :
2276 : : // we need a graphics
2277 [ - + ]: 191375 : if( !mpGraphics )
2278 [ # # ]: 0 : if( !ImplGetGraphics() )
2279 : 0 : return;
2280 : :
2281 [ + + ]: 191375 : if( mbInitClipRegion )
2282 : 13125 : ImplInitClipRegion();
2283 [ - + ]: 191375 : if( mbOutputClipped )
2284 : 0 : return;
2285 : :
2286 [ + + ]: 191375 : if( mbInitLineColor )
2287 : 22563 : ImplInitLineColor();
2288 : :
2289 : : const bool bTryAA((mnAntialiasing & ANTIALIASING_ENABLE_B2DDRAW)
2290 : 0 : && mpGraphics->supportsOperation(OutDevSupport_B2DDraw)
2291 : 0 : && ROP_OVERPAINT == GetRasterOp()
2292 [ - + # # : 191375 : && IsLineColor());
# # ][ # # ]
2293 : :
2294 : : // use b2dpolygon drawing if possible
2295 [ - + ][ # # ]: 191375 : if(bTryAA && ImpTryDrawPolyLineDirect(rB2DPolygon, fLineWidth, eLineJoin))
[ - + ]
2296 : : {
2297 : 0 : return;
2298 : : }
2299 : :
2300 : : // #i101491#
2301 : : // no output yet; fallback to geometry decomposition and use filled polygon paint
2302 : : // when line is fat and not too complex. ImpDrawPolyPolygonWithB2DPolyPolygon
2303 : : // will do internal needed AA checks etc.
2304 [ + + + - : 191495 : if(fLineWidth >= 2.5
+ - ][ + + ]
2305 : 60 : && rB2DPolygon.count()
2306 : 60 : && rB2DPolygon.count() <= 1000)
2307 : : {
2308 : 60 : const double fHalfLineWidth((fLineWidth * 0.5) + 0.5);
2309 : : const basegfx::B2DPolyPolygon aAreaPolyPolygon(basegfx::tools::createAreaGeometry(
2310 [ + - ]: 60 : rB2DPolygon, fHalfLineWidth, eLineJoin));
2311 : :
2312 : 60 : const Color aOldLineColor(maLineColor);
2313 : 60 : const Color aOldFillColor(maFillColor);
2314 : :
2315 [ + - ]: 60 : SetLineColor();
2316 [ + - ]: 60 : ImplInitLineColor();
2317 [ + - ]: 60 : SetFillColor(aOldLineColor);
2318 [ + - ]: 60 : ImplInitFillColor();
2319 : :
2320 : : // draw usig a loop; else the topology will paint a PolyPolygon
2321 [ + - ][ + + ]: 120 : for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
2322 : : {
2323 : : ImpDrawPolyPolygonWithB2DPolyPolygon(
2324 [ + - ][ + - ]: 60 : basegfx::B2DPolyPolygon(aAreaPolyPolygon.getB2DPolygon(a)));
[ + - ][ + - ]
[ + - ]
2325 : : }
2326 : :
2327 [ + - ]: 60 : SetLineColor(aOldLineColor);
2328 [ + - ]: 60 : ImplInitLineColor();
2329 [ + - ]: 60 : SetFillColor(aOldFillColor);
2330 [ + - ]: 60 : ImplInitFillColor();
2331 : :
2332 [ - + ]: 60 : if(bTryAA)
2333 : : {
2334 : : // when AA it is necessary to also paint the filled polygon's outline
2335 : : // to avoid optical gaps
2336 [ # # ][ # # ]: 0 : for(sal_uInt32 a(0); a < aAreaPolyPolygon.count(); a++)
2337 : : {
2338 [ # # ][ # # ]: 0 : ImpTryDrawPolyLineDirect(aAreaPolyPolygon.getB2DPolygon(a), 0.0, basegfx::B2DLINEJOIN_NONE);
[ # # ]
2339 : : }
2340 [ + - ]: 60 : }
2341 : : }
2342 : : else
2343 : : {
2344 : : // fallback to old polygon drawing if needed
2345 [ + - ]: 191315 : const Polygon aToolsPolygon( rB2DPolygon );
2346 [ + - ]: 191315 : LineInfo aLineInfo;
2347 [ - + ]: 191315 : if( fLineWidth != 0.0 )
2348 [ # # ]: 0 : aLineInfo.SetWidth( static_cast<long>(fLineWidth+0.5) );
2349 [ + - ][ + - ]: 191375 : ImpDrawPolyLineWithLineInfo( aToolsPolygon, aLineInfo );
[ + - ]
2350 : : }
2351 : : }
2352 : :
2353 : : // -----------------------------------------------------------------------
2354 : :
2355 : 0 : sal_uInt32 OutputDevice::GetGCStackDepth() const
2356 : : {
2357 : 0 : const ImplObjStack* pData = mpObjStack;
2358 : 0 : sal_uInt32 nDepth = 0;
2359 [ # # ]: 0 : while( pData )
2360 : : {
2361 : 0 : nDepth++;
2362 : 0 : pData = pData->mpPrev;
2363 : : }
2364 : 0 : return nDepth;
2365 : : }
2366 : :
2367 : : // -----------------------------------------------------------------------
2368 : :
2369 : 1004685 : void OutputDevice::Push( sal_uInt16 nFlags )
2370 : : {
2371 : : OSL_TRACE( "OutputDevice::Push()" );
2372 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2373 : :
2374 [ + + ]: 1004685 : if ( mpMetaFile )
2375 [ + - ]: 85696 : mpMetaFile->AddAction( new MetaPushAction( nFlags ) );
2376 : :
2377 : 1004685 : ImplObjStack* pData = new ImplObjStack;
2378 : 1004685 : pData->mpPrev = mpObjStack;
2379 : 1004685 : mpObjStack = pData;
2380 : :
2381 : 1004685 : pData->mnFlags = nFlags;
2382 : :
2383 [ + + ]: 1004685 : if ( nFlags & PUSH_LINECOLOR )
2384 : : {
2385 [ + + ]: 240711 : if ( mbLineColor )
2386 : 180607 : pData->mpLineColor = new Color( maLineColor );
2387 : : else
2388 : 60104 : pData->mpLineColor = NULL;
2389 : : }
2390 [ + + ]: 1004685 : if ( nFlags & PUSH_FILLCOLOR )
2391 : : {
2392 [ + + ]: 197792 : if ( mbFillColor )
2393 : 188586 : pData->mpFillColor = new Color( maFillColor );
2394 : : else
2395 : 9206 : pData->mpFillColor = NULL;
2396 : : }
2397 [ + + ]: 1004685 : if ( nFlags & PUSH_FONT )
2398 [ + - ]: 177255 : pData->mpFont = new Font( maFont );
2399 [ + + ]: 1004685 : if ( nFlags & PUSH_TEXTCOLOR )
2400 : 161289 : pData->mpTextColor = new Color( GetTextColor() );
2401 [ + + ]: 1004685 : if ( nFlags & PUSH_TEXTFILLCOLOR )
2402 : : {
2403 [ + + ]: 67816 : if ( IsTextFillColor() )
2404 [ + - ]: 820 : pData->mpTextFillColor = new Color( GetTextFillColor() );
2405 : : else
2406 : 66996 : pData->mpTextFillColor = NULL;
2407 : : }
2408 [ + + ]: 1004685 : if ( nFlags & PUSH_TEXTLINECOLOR )
2409 : : {
2410 [ + + ]: 67816 : if ( IsTextLineColor() )
2411 : 940 : pData->mpTextLineColor = new Color( GetTextLineColor() );
2412 : : else
2413 : 66876 : pData->mpTextLineColor = NULL;
2414 : : }
2415 [ + + ]: 1004685 : if ( nFlags & PUSH_OVERLINECOLOR )
2416 : : {
2417 [ + + ]: 67816 : if ( IsOverlineColor() )
2418 : 934 : pData->mpOverlineColor = new Color( GetOverlineColor() );
2419 : : else
2420 : 66882 : pData->mpOverlineColor = NULL;
2421 : : }
2422 [ + + ]: 1004685 : if ( nFlags & PUSH_TEXTALIGN )
2423 : 67816 : pData->meTextAlign = GetTextAlign();
2424 [ + + ]: 1004685 : if( nFlags & PUSH_TEXTLAYOUTMODE )
2425 : 309569 : pData->mnTextLayoutMode = GetLayoutMode();
2426 [ + + ]: 1004685 : if( nFlags & PUSH_TEXTLANGUAGE )
2427 : 308371 : pData->meTextLanguage = GetDigitLanguage();
2428 [ + + ]: 1004685 : if ( nFlags & PUSH_RASTEROP )
2429 : 68051 : pData->meRasterOp = GetRasterOp();
2430 [ + + ]: 1004685 : if ( nFlags & PUSH_MAPMODE )
2431 : : {
2432 [ + + ]: 224503 : if ( mbMap )
2433 [ + - ]: 162255 : pData->mpMapMode = new MapMode( maMapMode );
2434 : : else
2435 : 62248 : pData->mpMapMode = NULL;
2436 : : }
2437 [ + + ]: 1004685 : if ( nFlags & PUSH_CLIPREGION )
2438 : : {
2439 [ + + ]: 523866 : if ( mbClipRegion )
2440 [ + - ]: 264065 : pData->mpClipRegion = new Region( maRegion );
2441 : : else
2442 : 259801 : pData->mpClipRegion = NULL;
2443 : : }
2444 [ + + ]: 1004685 : if ( nFlags & PUSH_REFPOINT )
2445 : : {
2446 [ - + ]: 67816 : if ( mbRefPoint )
2447 : 0 : pData->mpRefPoint = new Point( maRefPoint );
2448 : : else
2449 : 67816 : pData->mpRefPoint = NULL;
2450 : : }
2451 : :
2452 [ + + ]: 1004685 : if( mpAlphaVDev )
2453 : 24077 : mpAlphaVDev->Push();
2454 : 1004685 : }
2455 : :
2456 : : // -----------------------------------------------------------------------
2457 : :
2458 : 1004685 : void OutputDevice::Pop()
2459 : : {
2460 : : OSL_TRACE( "OutputDevice::Pop()" );
2461 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2462 : :
2463 [ + + ]: 1004685 : if( mpMetaFile )
2464 [ + - ]: 85696 : mpMetaFile->AddAction( new MetaPopAction() );
2465 : :
2466 : 1004685 : GDIMetaFile* pOldMetaFile = mpMetaFile;
2467 : 1004685 : ImplObjStack* pData = mpObjStack;
2468 : 1004685 : mpMetaFile = NULL;
2469 : :
2470 [ - + ]: 1004685 : if ( !pData )
2471 : : {
2472 : : SAL_WARN( "vcl.gdi", "OutputDevice::Pop() without OutputDevice::Push()" );
2473 : 1004685 : return;
2474 : : }
2475 : :
2476 [ + + ]: 1004685 : if( mpAlphaVDev )
2477 : 24077 : mpAlphaVDev->Pop();
2478 : :
2479 : 1004685 : mpObjStack = pData->mpPrev;
2480 : :
2481 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_LINECOLOR )
2482 : : {
2483 [ + + ]: 240711 : if ( pData->mpLineColor )
2484 : 180607 : SetLineColor( *pData->mpLineColor );
2485 : : else
2486 : 60104 : SetLineColor();
2487 : : }
2488 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_FILLCOLOR )
2489 : : {
2490 [ + + ]: 197792 : if ( pData->mpFillColor )
2491 : 188586 : SetFillColor( *pData->mpFillColor );
2492 : : else
2493 : 9206 : SetFillColor();
2494 : : }
2495 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_FONT )
2496 : 177255 : SetFont( *pData->mpFont );
2497 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_TEXTCOLOR )
2498 : 161289 : SetTextColor( *pData->mpTextColor );
2499 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_TEXTFILLCOLOR )
2500 : : {
2501 [ + + ]: 67816 : if ( pData->mpTextFillColor )
2502 : 820 : SetTextFillColor( *pData->mpTextFillColor );
2503 : : else
2504 : 66996 : SetTextFillColor();
2505 : : }
2506 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_TEXTLINECOLOR )
2507 : : {
2508 [ + + ]: 67816 : if ( pData->mpTextLineColor )
2509 : 940 : SetTextLineColor( *pData->mpTextLineColor );
2510 : : else
2511 : 66876 : SetTextLineColor();
2512 : : }
2513 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_OVERLINECOLOR )
2514 : : {
2515 [ + + ]: 67816 : if ( pData->mpOverlineColor )
2516 : 934 : SetOverlineColor( *pData->mpOverlineColor );
2517 : : else
2518 : 66882 : SetOverlineColor();
2519 : : }
2520 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_TEXTALIGN )
2521 : 67816 : SetTextAlign( pData->meTextAlign );
2522 [ + + ]: 1004685 : if( pData->mnFlags & PUSH_TEXTLAYOUTMODE )
2523 : 309569 : SetLayoutMode( pData->mnTextLayoutMode );
2524 [ + + ]: 1004685 : if( pData->mnFlags & PUSH_TEXTLANGUAGE )
2525 : 308371 : SetDigitLanguage( pData->meTextLanguage );
2526 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_RASTEROP )
2527 : 68051 : SetRasterOp( pData->meRasterOp );
2528 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_MAPMODE )
2529 : : {
2530 [ + + ]: 224503 : if ( pData->mpMapMode )
2531 : 162255 : SetMapMode( *pData->mpMapMode );
2532 : : else
2533 : 62248 : SetMapMode();
2534 : : }
2535 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_CLIPREGION )
2536 : 523866 : ImplSetClipRegion( pData->mpClipRegion );
2537 [ + + ]: 1004685 : if ( pData->mnFlags & PUSH_REFPOINT )
2538 : : {
2539 [ - + ]: 67816 : if ( pData->mpRefPoint )
2540 : 0 : SetRefPoint( *pData->mpRefPoint );
2541 : : else
2542 : 67816 : SetRefPoint();
2543 : : }
2544 : :
2545 : 1004685 : ImplDeleteObjStack( pData );
2546 : :
2547 : 1004685 : mpMetaFile = pOldMetaFile;
2548 : : }
2549 : :
2550 : : // -----------------------------------------------------------------------
2551 : :
2552 : 49170 : void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
2553 : : {
2554 : 49170 : mpMetaFile = pMtf;
2555 : 49170 : }
2556 : :
2557 : : // -----------------------------------------------------------------------
2558 : :
2559 : 41418 : void OutputDevice::EnableOutput( sal_Bool bEnable )
2560 : : {
2561 : 41418 : mbOutput = (bEnable != 0);
2562 : :
2563 [ - + ]: 41418 : if( mpAlphaVDev )
2564 : 0 : mpAlphaVDev->EnableOutput( bEnable );
2565 : 41418 : }
2566 : :
2567 : : // -----------------------------------------------------------------------
2568 : :
2569 : 195510 : void OutputDevice::SetSettings( const AllSettings& rSettings )
2570 : : {
2571 : 195510 : maSettings = rSettings;
2572 : :
2573 [ - + ]: 195510 : if( mpAlphaVDev )
2574 : 0 : mpAlphaVDev->SetSettings( rSettings );
2575 : 195510 : }
2576 : :
2577 : : // -----------------------------------------------------------------------
2578 : :
2579 : 366340 : sal_uInt16 OutputDevice::GetBitCount() const
2580 : : {
2581 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2582 : :
2583 [ + + ]: 366340 : if ( meOutDevType == OUTDEV_VIRDEV )
2584 : 183340 : return ((VirtualDevice*)this)->mnBitCount;
2585 : :
2586 : : // we need a graphics
2587 [ - + ]: 183000 : if ( !mpGraphics )
2588 : : {
2589 [ # # ]: 0 : if ( !((OutputDevice*)this)->ImplGetGraphics() )
2590 : 0 : return 0;
2591 : : }
2592 : :
2593 : 366340 : return (sal_uInt16)mpGraphics->GetBitCount();
2594 : : }
2595 : :
2596 : : // -----------------------------------------------------------------------
2597 : :
2598 : 0 : sal_uInt16 OutputDevice::GetAlphaBitCount() const
2599 : : {
2600 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2601 : :
2602 [ # # ][ # # ]: 0 : if ( meOutDevType == OUTDEV_VIRDEV &&
2603 : : mpAlphaVDev != NULL )
2604 : : {
2605 : 0 : return mpAlphaVDev->GetBitCount();
2606 : : }
2607 : :
2608 : 0 : return 0;
2609 : : }
2610 : :
2611 : : // -----------------------------------------------------------------------
2612 : :
2613 : 449 : sal_uLong OutputDevice::GetColorCount() const
2614 : : {
2615 : : DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
2616 : :
2617 : 449 : const sal_uInt16 nBitCount = GetBitCount();
2618 [ + - ]: 449 : return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) );
2619 : : }
2620 : :
2621 : : // -----------------------------------------------------------------------
2622 : :
2623 : 0 : sal_Bool OutputDevice::HasAlpha()
2624 : : {
2625 : 0 : return mpAlphaVDev != NULL;
2626 : : }
2627 : :
2628 : : // -----------------------------------------------------------------------
2629 : :
2630 : 20511 : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics > OutputDevice::CreateUnoGraphics()
2631 : : {
2632 : 20511 : UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
2633 [ + - ]: 20511 : return pWrapper ? pWrapper->CreateGraphics( this ) : ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics >();
2634 : : }
2635 : :
2636 : : // -----------------------------------------------------------------------
2637 : :
2638 : 0 : SystemGraphicsData OutputDevice::GetSystemGfxData() const
2639 : : {
2640 [ # # ]: 0 : if ( !mpGraphics )
2641 : : {
2642 [ # # ]: 0 : if ( !ImplGetGraphics() )
2643 : 0 : return SystemGraphicsData();
2644 : : }
2645 : :
2646 : 0 : return mpGraphics->GetGraphicsData();
2647 : : }
2648 : :
2649 : : // -----------------------------------------------------------------------
2650 : :
2651 : 0 : ::com::sun::star::uno::Any OutputDevice::GetSystemGfxDataAny() const
2652 : : {
2653 : 0 : ::com::sun::star::uno::Any aRet;
2654 [ # # ]: 0 : const SystemGraphicsData aSysData = GetSystemGfxData();
2655 : : ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( (sal_Int8*)&aSysData,
2656 [ # # ]: 0 : aSysData.nSize );
2657 : :
2658 [ # # ][ # # ]: 0 : return uno::makeAny(aSeq);
2659 : : }
2660 : :
2661 : : // -----------------------------------------------------------------------
2662 : :
2663 : 0 : ::com::sun::star::uno::Reference< ::com::sun::star::rendering::XCanvas > OutputDevice::GetCanvas() const
2664 : : {
2665 [ # # ]: 0 : uno::Sequence< uno::Any > aArg(6);
2666 : :
2667 [ # # ][ # # ]: 0 : aArg[ 0 ] = uno::makeAny( reinterpret_cast<sal_Int64>(this) );
2668 [ # # ][ # # ]: 0 : aArg[ 2 ] = uno::makeAny( ::com::sun::star::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
2669 [ # # ][ # # ]: 0 : aArg[ 3 ] = uno::makeAny( sal_False );
2670 [ # # ][ # # ]: 0 : aArg[ 5 ] = GetSystemGfxDataAny();
2671 : :
2672 [ # # ]: 0 : uno::Reference<lang::XMultiServiceFactory> xFactory = vcl::unohelper::GetMultiServiceFactory();
2673 : :
2674 : 0 : uno::Reference<rendering::XCanvas> xCanvas;
2675 : :
2676 : : // Create canvas instance with window handle
2677 : : // =========================================
2678 [ # # ]: 0 : if ( xFactory.is() )
2679 : : {
2680 : : static uno::Reference<lang::XMultiServiceFactory> xCanvasFactory(
2681 [ # # ]: 0 : xFactory->createInstance(
2682 : : OUString( RTL_CONSTASCII_USTRINGPARAM(
2683 : : "com.sun.star."
2684 : 0 : "rendering.CanvasFactory") ) ),
2685 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ][ # # ]
[ # # ][ # # ]
2686 [ # # ]: 0 : if(xCanvasFactory.is())
2687 : : {
2688 : : xCanvas.set(
2689 [ # # ]: 0 : xCanvasFactory->createInstanceWithArguments(
2690 : : OUString( RTL_CONSTASCII_USTRINGPARAM(
2691 : : "com.sun.star.rendering.Canvas" )),
2692 : 0 : aArg ),
2693 [ # # ][ # # ]: 0 : uno::UNO_QUERY );
[ # # ]
2694 : : }
2695 : : }
2696 : :
2697 [ # # ]: 0 : return xCanvas;
2698 : : }
2699 : :
2700 : : // -----------------------------------------------------------------------
2701 : :
2702 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|