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 : :
32 : : #include <vcl/settings.hxx>
33 : : #include <vcl/svapp.hxx>
34 : : #include <vcl/wrkwin.hxx>
35 : : #include <vcl/virdev.hxx>
36 : :
37 : : #include <salinst.hxx>
38 : : #include <salgdi.hxx>
39 : : #include <salframe.hxx>
40 : : #include <salvd.hxx>
41 : : #include <outdev.h>
42 : : #include <svdata.hxx>
43 : :
44 : : using namespace ::com::sun::star::uno;
45 : :
46 : : // =======================================================================
47 : :
48 : 90687 : void VirtualDevice::ImplInitVirDev( const OutputDevice* pOutDev,
49 : : long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
50 : : {
51 [ - + ]: 90687 : if ( nDX < 1 )
52 : 0 : nDX = 1;
53 : :
54 [ - + ]: 90687 : if ( nDY < 1 )
55 : 0 : nDY = 1;
56 : :
57 : 90687 : ImplSVData* pSVData = ImplGetSVData();
58 : :
59 [ - + ]: 90687 : if ( !pOutDev )
60 : 0 : pOutDev = ImplGetDefaultWindow();
61 [ - + ]: 90687 : if( !pOutDev )
62 : 90687 : return;
63 : :
64 : : SalGraphics* pGraphics;
65 [ + + ]: 90687 : if ( !pOutDev->mpGraphics )
66 : 6626 : ((OutputDevice*)pOutDev)->ImplGetGraphics();
67 : 90687 : pGraphics = pOutDev->mpGraphics;
68 [ + - ]: 90687 : if ( pGraphics )
69 : 90687 : mpVirDev = pSVData->mpDefInst->CreateVirtualDevice( pGraphics, nDX, nDY, nBitCount, pData );
70 : : else
71 : 0 : mpVirDev = NULL;
72 [ - + ]: 90687 : if ( !mpVirDev )
73 : : {
74 : : // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
75 : : throw ::com::sun::star::uno::RuntimeException(
76 : : OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create system bitmap!" ) ),
77 [ # # ][ # # ]: 0 : ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
78 : : //GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
79 : : }
80 : :
81 [ + + ]: 90687 : mnBitCount = ( nBitCount ? nBitCount : pOutDev->GetBitCount() );
82 : 90687 : mnOutWidth = nDX;
83 : 90687 : mnOutHeight = nDY;
84 : 90687 : mbScreenComp = sal_True;
85 : 90687 : mnAlphaDepth = -1;
86 : :
87 : : // #i59315# init vdev size from system object, when passed a
88 : : // SystemGraphicsData. Otherwise, output size will always
89 : : // incorrectly stay at (1,1)
90 [ - + ][ # # ]: 90687 : if( pData && mpVirDev )
91 : 0 : mpVirDev->GetSize(mnOutWidth,mnOutHeight);
92 : :
93 [ + + ]: 90687 : if( mnBitCount < 8 )
94 : 7285 : SetAntialiasing( ANTIALIASING_DISABLE_TEXT );
95 : :
96 [ - + ]: 90687 : if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER )
97 : 0 : mbScreenComp = sal_False;
98 [ + + ]: 90687 : else if ( pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
99 : 34014 : mbScreenComp = ((VirtualDevice*)pOutDev)->mbScreenComp;
100 : :
101 : 90687 : meOutDevType = OUTDEV_VIRDEV;
102 : 90687 : mbDevOutput = sal_True;
103 : 90687 : mpFontList = pSVData->maGDIData.mpScreenFontList;
104 : 90687 : mpFontCache = pSVData->maGDIData.mpScreenFontCache;
105 : 90687 : mnDPIX = pOutDev->mnDPIX;
106 : 90687 : mnDPIY = pOutDev->mnDPIY;
107 : 90687 : maFont = pOutDev->maFont;
108 : :
109 [ + + ]: 90687 : if( maTextColor != pOutDev->maTextColor )
110 : : {
111 : 157 : maTextColor = pOutDev->maTextColor;
112 : 157 : mbInitTextColor = true;
113 : : }
114 : :
115 : : // Virtuelle Devices haben defaultmaessig einen weissen Hintergrund
116 [ + - ][ + - ]: 90687 : SetBackground( Wallpaper( Color( COL_WHITE ) ) );
[ + - ]
117 : :
118 : : // #i59283# don't erase user-provided surface
119 [ + - ]: 90687 : if( !pData )
120 : 90687 : Erase();
121 : :
122 : : // VirDev in Liste eintragen
123 : 90687 : mpNext = pSVData->maGDIData.mpFirstVirDev;
124 : 90687 : mpPrev = NULL;
125 [ + + ]: 90687 : if ( mpNext )
126 : 90364 : mpNext->mpPrev = this;
127 : : else
128 : 323 : pSVData->maGDIData.mpLastVirDev = this;
129 : 90687 : pSVData->maGDIData.mpFirstVirDev = this;
130 : : }
131 : :
132 : : // -----------------------------------------------------------------------
133 : :
134 : 45017 : VirtualDevice::VirtualDevice( sal_uInt16 nBitCount )
135 : : : mpVirDev( NULL ),
136 : 45017 : meRefDevMode( REFDEV_NONE )
137 : : {
138 : : SAL_WARN_IF( nBitCount > 1, "vcl.gdi",
139 : : "VirtualDevice::VirtualDevice(): Only 0 or 1 is for BitCount allowed" );
140 : : SAL_INFO( "vcl.gdi", "VirtualDevice::VirtualDevice( " << nBitCount << " )" );
141 : :
142 [ + - ][ + - ]: 45017 : ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount );
143 : 45017 : }
144 : :
145 : : // -----------------------------------------------------------------------
146 : :
147 : 34908 : VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, sal_uInt16 nBitCount )
148 : : : mpVirDev( NULL ),
149 : 34908 : meRefDevMode( REFDEV_NONE )
150 : : {
151 : : SAL_WARN_IF( nBitCount > 1, "vcl.gdi",
152 : : "VirtualDevice::VirtualDevice(): Only 0 or 1 is for BitCount allowed" );
153 : : SAL_INFO( "vcl.gdi", "VirtualDevice::VirtualDevice( " << nBitCount << " )" );
154 : :
155 [ + - ]: 34908 : ImplInitVirDev( &rCompDev, 1, 1, nBitCount );
156 : 34908 : }
157 : :
158 : : // -----------------------------------------------------------------------
159 : :
160 : 10762 : VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, sal_uInt16 nBitCount, sal_uInt16 nAlphaBitCount )
161 : : : mpVirDev( NULL ),
162 : 10762 : meRefDevMode( REFDEV_NONE )
163 : : {
164 : : SAL_WARN_IF( nBitCount > 1, "vcl.gdi",
165 : : "VirtualDevice::VirtualDevice(): Only 0 or 1 is for BitCount allowed" );
166 : : SAL_INFO( "vcl.gdi",
167 : : "VirtualDevice::VirtualDevice( " << nBitCount << ", " << nAlphaBitCount << " )" );
168 : :
169 [ + - ]: 10762 : ImplInitVirDev( &rCompDev, 1, 1, nBitCount );
170 : :
171 : : // Enable alpha channel
172 : 10762 : mnAlphaDepth = sal::static_int_cast<sal_Int8>(nAlphaBitCount);
173 : 10762 : }
174 : :
175 : : // -----------------------------------------------------------------------
176 : :
177 : 0 : VirtualDevice::VirtualDevice( const SystemGraphicsData *pData, sal_uInt16 nBitCount )
178 : : : mpVirDev( NULL ),
179 : 0 : meRefDevMode( REFDEV_NONE )
180 : : {
181 : : SAL_INFO( "vcl.gdi", "VirtualDevice::VirtualDevice( " << nBitCount << " )" );
182 : :
183 [ # # ][ # # ]: 0 : ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount, pData );
184 : 0 : }
185 : :
186 : : // -----------------------------------------------------------------------
187 : :
188 : 90013 : VirtualDevice::~VirtualDevice()
189 : : {
190 : : SAL_INFO( "vcl.gdi", "VirtualDevice::~VirtualDevice()" );
191 : :
192 [ + - ]: 90013 : ImplSVData* pSVData = ImplGetSVData();
193 : :
194 [ + - ]: 90013 : ImplReleaseGraphics();
195 : :
196 [ + - ]: 90013 : if ( mpVirDev )
197 [ + - ]: 90013 : pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
198 : :
199 : : // remove this VirtualDevice from the double-linked global list
200 [ + + ]: 90013 : if( mpPrev )
201 : 21067 : mpPrev->mpNext = mpNext;
202 : : else
203 : 68946 : pSVData->maGDIData.mpFirstVirDev = mpNext;
204 : :
205 [ + + ]: 90013 : if( mpNext )
206 : 89534 : mpNext->mpPrev = mpPrev;
207 : : else
208 : 479 : pSVData->maGDIData.mpLastVirDev = mpPrev;
209 [ - + ]: 132279 : }
210 : :
211 : : // -----------------------------------------------------------------------
212 : :
213 : 54320 : sal_Bool VirtualDevice::InnerImplSetOutputSizePixel( const Size& rNewSize, sal_Bool bErase, const basebmp::RawMemorySharedArray &pBuffer )
214 : : {
215 : : SAL_INFO( "vcl.gdi",
216 : : "VirtualDevice::InnerImplSetOutputSizePixel( " << rNewSize.Width() << ", "
217 : : << rNewSize.Height() << ", " << bErase << " )" );
218 : :
219 [ - + ]: 54320 : if ( !mpVirDev )
220 : 0 : return sal_False;
221 [ + + ]: 54320 : else if ( rNewSize == GetOutputSizePixel() )
222 : : {
223 [ + - ]: 3517 : if ( bErase )
224 : 3517 : Erase();
225 : : // Yeah, so trying to re-use a VirtualDevice but this time using a
226 : : // pre-allocated buffer won't work. Big deal.
227 : 3517 : return sal_True;
228 : : }
229 : :
230 : : sal_Bool bRet;
231 : 50803 : long nNewWidth = rNewSize.Width(), nNewHeight = rNewSize.Height();
232 : :
233 [ + + ]: 50803 : if ( nNewWidth < 1 )
234 : 159 : nNewWidth = 1;
235 : :
236 [ + + ]: 50803 : if ( nNewHeight < 1 )
237 : 273 : nNewHeight = 1;
238 : :
239 [ + + ]: 50803 : if ( bErase )
240 : : {
241 [ - + ]: 46621 : if ( pBuffer )
242 : 0 : bRet = mpVirDev->SetSizeUsingBuffer( nNewWidth, nNewHeight, pBuffer );
243 : : else
244 : 46621 : bRet = mpVirDev->SetSize( nNewWidth, nNewHeight );
245 : :
246 [ + - ]: 46621 : if ( bRet )
247 : : {
248 : 46621 : mnOutWidth = rNewSize.Width();
249 : 46621 : mnOutHeight = rNewSize.Height();
250 : 46621 : Erase();
251 : : }
252 : : }
253 : : else
254 : : {
255 : : SalVirtualDevice* pNewVirDev;
256 : 4182 : ImplSVData* pSVData = ImplGetSVData();
257 : :
258 : : // we need a graphics
259 [ - + ]: 4182 : if ( !mpGraphics )
260 : : {
261 [ # # ]: 0 : if ( !ImplGetGraphics() )
262 : 0 : return sal_False;
263 : : }
264 : :
265 : 4182 : pNewVirDev = pSVData->mpDefInst->CreateVirtualDevice( mpGraphics, nNewWidth, nNewHeight, mnBitCount );
266 [ + - ]: 4182 : if ( pNewVirDev )
267 : : {
268 : 4182 : SalGraphics* pGraphics = pNewVirDev->GetGraphics();
269 [ + - ]: 4182 : if ( pGraphics )
270 : : {
271 : : SalTwoRect aPosAry;
272 : : long nWidth;
273 : : long nHeight;
274 [ + + ]: 4182 : if ( mnOutWidth < nNewWidth )
275 : 4146 : nWidth = mnOutWidth;
276 : : else
277 : 36 : nWidth = nNewWidth;
278 [ + + ]: 4182 : if ( mnOutHeight < nNewHeight )
279 : 4148 : nHeight = mnOutHeight;
280 : : else
281 : 34 : nHeight = nNewHeight;
282 : 4182 : aPosAry.mnSrcX = 0;
283 : 4182 : aPosAry.mnSrcY = 0;
284 : 4182 : aPosAry.mnSrcWidth = nWidth;
285 : 4182 : aPosAry.mnSrcHeight = nHeight;
286 : 4182 : aPosAry.mnDestX = 0;
287 : 4182 : aPosAry.mnDestY = 0;
288 : 4182 : aPosAry.mnDestWidth = nWidth;
289 : 4182 : aPosAry.mnDestHeight = nHeight;
290 : :
291 [ + - ]: 4182 : pGraphics->CopyBits( &aPosAry, mpGraphics, this, this );
292 [ + - ]: 4182 : pNewVirDev->ReleaseGraphics( pGraphics );
293 [ + - ]: 4182 : ImplReleaseGraphics();
294 [ + - ]: 4182 : pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
295 : 4182 : mpVirDev = pNewVirDev;
296 : 4182 : mnOutWidth = rNewSize.Width();
297 : 4182 : mnOutHeight = rNewSize.Height();
298 : 4182 : bRet = sal_True;
299 : : }
300 : : else
301 : : {
302 : 0 : bRet = sal_False;
303 : 0 : pSVData->mpDefInst->DestroyVirtualDevice( pNewVirDev );
304 : : }
305 : : }
306 : : else
307 : 0 : bRet = sal_False;
308 : : }
309 : :
310 : 54320 : return bRet;
311 : : }
312 : :
313 : : // -----------------------------------------------------------------------
314 : :
315 : : // #i32109#: Fill opaque areas correctly (without relying on
316 : : // fill/linecolor state)
317 : 0 : void VirtualDevice::ImplFillOpaqueRectangle( const Rectangle& rRect )
318 : : {
319 : : // Set line and fill color to black (->opaque),
320 : : // fill rect with that (linecolor, too, because of
321 : : // those pesky missing pixel problems)
322 : 0 : Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
323 [ # # ]: 0 : SetLineColor( COL_BLACK );
324 [ # # ]: 0 : SetFillColor( COL_BLACK );
325 : 0 : DrawRect( rRect );
326 : 0 : Pop();
327 : 0 : }
328 : :
329 : : // -----------------------------------------------------------------------
330 : :
331 : 43558 : sal_Bool VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, sal_Bool bErase, const basebmp::RawMemorySharedArray &pBuffer )
332 : : {
333 [ + - ]: 43558 : if( InnerImplSetOutputSizePixel(rNewSize, bErase, pBuffer) )
334 : : {
335 [ + + ]: 43558 : if( mnAlphaDepth != -1 )
336 : : {
337 : : // #110958# Setup alpha bitmap
338 [ - + ][ # # ]: 10762 : if(mpAlphaVDev && mpAlphaVDev->GetOutputSizePixel() != rNewSize)
[ - + ][ - + ]
339 : : {
340 [ # # ]: 0 : delete mpAlphaVDev;
341 : 0 : mpAlphaVDev = 0L;
342 : : }
343 : :
344 [ + - ]: 10762 : if( !mpAlphaVDev )
345 : : {
346 [ + - ]: 10762 : mpAlphaVDev = new VirtualDevice( *this, mnAlphaDepth );
347 [ + - ]: 10762 : mpAlphaVDev->InnerImplSetOutputSizePixel(rNewSize, bErase, basebmp::RawMemorySharedArray() );
348 : : }
349 : :
350 : : // TODO: copy full outdev state to new one, here. Also needed in outdev2.cxx:DrawOutDev
351 [ + - ]: 10762 : if( GetLineColor() != Color( COL_TRANSPARENT ) )
352 [ + - ]: 10762 : mpAlphaVDev->SetLineColor( COL_BLACK );
353 : :
354 [ + - ]: 10762 : if( GetFillColor() != Color( COL_TRANSPARENT ) )
355 [ + - ]: 10762 : mpAlphaVDev->SetFillColor( COL_BLACK );
356 : :
357 : 10762 : mpAlphaVDev->SetMapMode( GetMapMode() );
358 : : }
359 : :
360 : 43558 : return sal_True;
361 : : }
362 : :
363 : 43558 : return sal_False;
364 : : }
365 : :
366 : 43558 : sal_Bool VirtualDevice::SetOutputSizePixel( const Size& rNewSize, sal_Bool bErase )
367 : : {
368 [ + - ]: 43558 : return ImplSetOutputSizePixel( rNewSize, bErase, basebmp::RawMemorySharedArray() );
369 : : }
370 : :
371 : 0 : sal_Bool VirtualDevice::SetOutputSizePixelScaleOffsetAndBuffer( const Size& rNewSize, const Fraction& rScale, const Point& rNewOffset, const basebmp::RawMemorySharedArray &pBuffer )
372 : : {
373 [ # # ]: 0 : if (pBuffer) {
374 [ # # ]: 0 : MapMode mm = GetMapMode();
375 [ # # ]: 0 : mm.SetOrigin( rNewOffset );
376 [ # # ]: 0 : mm.SetScaleX( rScale );
377 [ # # ]: 0 : mm.SetScaleY( rScale );
378 [ # # ][ # # ]: 0 : SetMapMode( mm );
379 : : }
380 : 0 : return ImplSetOutputSizePixel( rNewSize, sal_True, pBuffer);
381 : : }
382 : :
383 : : // -----------------------------------------------------------------------
384 : :
385 : 2004 : void VirtualDevice::SetReferenceDevice( RefDevMode i_eRefDevMode )
386 : : {
387 : 2004 : sal_Int32 nDPIX = 600, nDPIY = 600;
388 [ - + + - ]: 2004 : switch( i_eRefDevMode )
389 : : {
390 : : case REFDEV_NONE:
391 : : default:
392 : : DBG_ASSERT( sal_False, "VDev::SetRefDev illegal argument!" );
393 : 0 : break;
394 : : case REFDEV_MODE06:
395 : 25 : nDPIX = nDPIY = 600;
396 : 25 : break;
397 : : case REFDEV_MODE_MSO1:
398 : 1979 : nDPIX = nDPIY = 6*1440;
399 : 1979 : break;
400 : : case REFDEV_MODE_PDF1:
401 : 0 : nDPIX = nDPIY = 720;
402 : 0 : break;
403 : : }
404 : 2004 : ImplSetReferenceDevice( i_eRefDevMode, nDPIX, nDPIY );
405 : 2004 : }
406 : :
407 : 0 : void VirtualDevice::SetReferenceDevice( sal_Int32 i_nDPIX, sal_Int32 i_nDPIY )
408 : : {
409 : 0 : ImplSetReferenceDevice( REFDEV_CUSTOM, i_nDPIX, i_nDPIY );
410 : 0 : }
411 : :
412 : 2004 : void VirtualDevice::ImplSetReferenceDevice( RefDevMode i_eRefDevMode, sal_Int32 i_nDPIX, sal_Int32 i_nDPIY )
413 : : {
414 : 2004 : mnDPIX = i_nDPIX;
415 : 2004 : mnDPIY = i_nDPIY;
416 : :
417 : 2004 : EnableOutput( sal_False ); // prevent output on reference device
418 : 2004 : mbScreenComp = sal_False;
419 : :
420 : : // invalidate currently selected fonts
421 : 2004 : mbInitFont = sal_True;
422 : 2004 : mbNewFont = sal_True;
423 : :
424 : : // avoid adjusting font lists when already in refdev mode
425 : 2004 : sal_uInt8 nOldRefDevMode = meRefDevMode;
426 : 2004 : sal_uInt8 nOldCompatFlag = (sal_uInt8)meRefDevMode & REFDEV_FORCE_ZERO_EXTLEAD;
427 : 2004 : meRefDevMode = (sal_uInt8)(i_eRefDevMode | nOldCompatFlag);
428 [ - + ]: 2004 : if( (nOldRefDevMode ^ nOldCompatFlag) != REFDEV_NONE )
429 : 2004 : return;
430 : :
431 : : // the reference device should have only scalable fonts
432 : : // => clean up the original font lists before getting new ones
433 [ - + ]: 2004 : if ( mpFontEntry )
434 : : {
435 : 0 : mpFontCache->Release( mpFontEntry );
436 : 0 : mpFontEntry = NULL;
437 : : }
438 [ - + ]: 2004 : if ( mpGetDevFontList )
439 : : {
440 [ # # ]: 0 : delete mpGetDevFontList;
441 : 0 : mpGetDevFontList = NULL;
442 : : }
443 [ - + ]: 2004 : if ( mpGetDevSizeList )
444 : : {
445 [ # # ]: 0 : delete mpGetDevSizeList;
446 : 0 : mpGetDevSizeList = NULL;
447 : : }
448 : :
449 : : // preserve global font lists
450 : 2004 : ImplSVData* pSVData = ImplGetSVData();
451 [ - + ][ + - ]: 2004 : if( mpFontList && (mpFontList != pSVData->maGDIData.mpScreenFontList) )
452 [ # # ]: 0 : delete mpFontList;
453 [ + - ][ - + ]: 2004 : if( mpFontCache && (mpFontCache != pSVData->maGDIData.mpScreenFontCache) )
454 [ # # ]: 0 : delete mpFontCache;
455 : :
456 : : // get font list with scalable fonts only
457 : 2004 : ImplGetGraphics();
458 : 2004 : mpFontList = pSVData->maGDIData.mpScreenFontList->Clone( true, false );
459 : :
460 : : // prepare to use new font lists
461 [ + - ]: 2004 : mpFontCache = new ImplFontCache( false );
462 : : }
463 : :
464 : : // -----------------------------------------------------------------------
465 : :
466 : 0 : void VirtualDevice::Compat_ZeroExtleadBug()
467 : : {
468 : 0 : meRefDevMode = (sal_uInt8)meRefDevMode | REFDEV_FORCE_ZERO_EXTLEAD;
469 : 0 : }
470 : :
471 : : // -----------------------------------------------------------------------
472 : :
473 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|