Update ooo320-m1
[ooovba.git] / vcl / source / gdi / virdev.cxx
blob1dc1df636a2e1d8566b01d1b0e2ebb8c1b71b60f
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: virdev.cxx,v $
10 * $Revision: 1.33 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_vcl.hxx"
34 #ifndef _SV_SVSYS_HXX
35 #include <svsys.h>
36 #endif
37 #include <vcl/salinst.hxx>
38 #include <vcl/salgdi.hxx>
39 #include <vcl/salframe.hxx>
40 #include <vcl/salvd.hxx>
41 #include <tools/debug.hxx>
42 #include <vcl/svdata.hxx>
43 #include <vcl/settings.hxx>
44 #include <vcl/svapp.hxx>
45 #include <vcl/wrkwin.hxx>
46 #include <vcl/outdev.h>
47 #include <vcl/virdev.hxx>
49 using namespace ::com::sun::star::uno;
51 // =======================================================================
53 void VirtualDevice::ImplInitVirDev( const OutputDevice* pOutDev,
54 long nDX, long nDY, USHORT nBitCount, const SystemGraphicsData *pData )
56 DBG_ASSERT( nBitCount <= 1,
57 "VirtualDevice::VirtualDevice(): Only 0 or 1 is for BitCount allowed" );
59 if ( nDX < 1 )
60 nDX = 1;
62 if ( nDY < 1 )
63 nDY = 1;
65 ImplSVData* pSVData = ImplGetSVData();
67 if ( !pOutDev )
68 pOutDev = ImplGetDefaultWindow();
69 if( !pOutDev )
70 return;
72 SalGraphics* pGraphics;
73 if ( !pOutDev->mpGraphics )
74 ((OutputDevice*)pOutDev)->ImplGetGraphics();
75 pGraphics = pOutDev->mpGraphics;
76 if ( pGraphics )
77 mpVirDev = pSVData->mpDefInst->CreateVirtualDevice( pGraphics, nDX, nDY, nBitCount, pData );
78 else
79 mpVirDev = NULL;
80 if ( !mpVirDev )
82 // do not abort but throw an exception, may be the current thread terminates anyway (plugin-scenario)
83 throw ::com::sun::star::uno::RuntimeException(
84 OUString( RTL_CONSTASCII_USTRINGPARAM( "Could not create system bitmap!" ) ),
85 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >() );
86 //GetpApp()->Exception( EXC_SYSOBJNOTCREATED );
89 mnBitCount = ( nBitCount ? nBitCount : pOutDev->GetBitCount() );
90 mnOutWidth = nDX;
91 mnOutHeight = nDY;
92 mbScreenComp = TRUE;
93 mnAlphaDepth = -1;
95 // #i59315# init vdev size from system object, when passed a
96 // SystemGraphicsData. Otherwise, output size will always
97 // incorrectly stay at (1,1)
98 if( pData && mpVirDev )
99 mpVirDev->GetSize(mnOutWidth,mnOutHeight);
101 if( mnBitCount < 8 )
102 SetAntialiasing( ANTIALIASING_DISABLE_TEXT );
104 if ( pOutDev->GetOutDevType() == OUTDEV_PRINTER )
105 mbScreenComp = FALSE;
106 else if ( pOutDev->GetOutDevType() == OUTDEV_VIRDEV )
107 mbScreenComp = ((VirtualDevice*)pOutDev)->mbScreenComp;
109 meOutDevType = OUTDEV_VIRDEV;
110 mbDevOutput = TRUE;
111 mpFontList = pSVData->maGDIData.mpScreenFontList;
112 mpFontCache = pSVData->maGDIData.mpScreenFontCache;
113 mnDPIX = pOutDev->mnDPIX;
114 mnDPIY = pOutDev->mnDPIY;
115 maFont = pOutDev->maFont;
117 if( maTextColor != pOutDev->maTextColor )
119 maTextColor = pOutDev->maTextColor;
120 mbInitTextColor = true;
123 // Virtuelle Devices haben defaultmaessig einen weissen Hintergrund
124 SetBackground( Wallpaper( Color( COL_WHITE ) ) );
126 // #i59283# don't erase user-provided surface
127 if( !pData )
128 Erase();
130 // VirDev in Liste eintragen
131 mpNext = pSVData->maGDIData.mpFirstVirDev;
132 mpPrev = NULL;
133 if ( mpNext )
134 mpNext->mpPrev = this;
135 else
136 pSVData->maGDIData.mpLastVirDev = this;
137 pSVData->maGDIData.mpFirstVirDev = this;
140 // -----------------------------------------------------------------------
142 VirtualDevice::VirtualDevice( USHORT nBitCount )
143 : mpVirDev( NULL ),
144 meRefDevMode( REFDEV_NONE )
146 DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
148 ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount );
151 // -----------------------------------------------------------------------
153 VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, USHORT nBitCount )
154 : mpVirDev( NULL ),
155 meRefDevMode( REFDEV_NONE )
157 DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
159 ImplInitVirDev( &rCompDev, 1, 1, nBitCount );
162 // -----------------------------------------------------------------------
164 VirtualDevice::VirtualDevice( const OutputDevice& rCompDev, USHORT nBitCount, USHORT nAlphaBitCount )
165 : mpVirDev( NULL ),
166 meRefDevMode( REFDEV_NONE )
168 DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
170 ImplInitVirDev( &rCompDev, 1, 1, nBitCount );
172 // #110958# Enable alpha channel
173 mnAlphaDepth = sal::static_int_cast<sal_Int8>(nAlphaBitCount);
176 // -----------------------------------------------------------------------
178 VirtualDevice::VirtualDevice( const SystemGraphicsData *pData, USHORT nBitCount )
179 : mpVirDev( NULL ),
180 meRefDevMode( REFDEV_NONE )
182 DBG_TRACE1( "VirtualDevice::VirtualDevice( %hu )", nBitCount );
184 ImplInitVirDev( Application::GetDefaultDevice(), 1, 1, nBitCount, pData );
187 // -----------------------------------------------------------------------
189 VirtualDevice::~VirtualDevice()
191 DBG_TRACE( "VirtualDevice::~VirtualDevice()" );
193 ImplSVData* pSVData = ImplGetSVData();
195 ImplReleaseGraphics();
197 if ( mpVirDev )
198 pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
200 // remove this VirtualDevice from the double-linked global list
201 if( mpPrev )
202 mpPrev->mpNext = mpNext;
203 else
204 pSVData->maGDIData.mpFirstVirDev = mpNext;
206 if( mpNext )
207 mpNext->mpPrev = mpPrev;
208 else
209 pSVData->maGDIData.mpLastVirDev = mpPrev;
212 // -----------------------------------------------------------------------
214 BOOL VirtualDevice::ImplSetOutputSizePixel( const Size& rNewSize, BOOL bErase )
216 DBG_TRACE3( "VirtualDevice::ImplSetOutputSizePixel( %ld, %ld, %d )", rNewSize.Width(), rNewSize.Height(), (int)bErase );
218 if ( !mpVirDev )
219 return FALSE;
220 else if ( rNewSize == GetOutputSizePixel() )
222 if ( bErase )
223 Erase();
224 return TRUE;
227 BOOL bRet;
228 long nNewWidth = rNewSize.Width(), nNewHeight = rNewSize.Height();
230 if ( nNewWidth < 1 )
231 nNewWidth = 1;
233 if ( nNewHeight < 1 )
234 nNewHeight = 1;
236 if ( bErase )
238 bRet = mpVirDev->SetSize( nNewWidth, nNewHeight );
240 if ( bRet )
242 mnOutWidth = rNewSize.Width();
243 mnOutHeight = rNewSize.Height();
244 Erase();
247 else
249 SalVirtualDevice* pNewVirDev;
250 ImplSVData* pSVData = ImplGetSVData();
252 // we need a graphics
253 if ( !mpGraphics )
255 if ( !ImplGetGraphics() )
256 return FALSE;
259 pNewVirDev = pSVData->mpDefInst->CreateVirtualDevice( mpGraphics, nNewWidth, nNewHeight, mnBitCount );
260 if ( pNewVirDev )
262 SalGraphics* pGraphics = pNewVirDev->GetGraphics();
263 if ( pGraphics )
265 SalTwoRect aPosAry;
266 long nWidth;
267 long nHeight;
268 if ( mnOutWidth < nNewWidth )
269 nWidth = mnOutWidth;
270 else
271 nWidth = nNewWidth;
272 if ( mnOutHeight < nNewHeight )
273 nHeight = mnOutHeight;
274 else
275 nHeight = nNewHeight;
276 aPosAry.mnSrcX = 0;
277 aPosAry.mnSrcY = 0;
278 aPosAry.mnSrcWidth = nWidth;
279 aPosAry.mnSrcHeight = nHeight;
280 aPosAry.mnDestX = 0;
281 aPosAry.mnDestY = 0;
282 aPosAry.mnDestWidth = nWidth;
283 aPosAry.mnDestHeight = nHeight;
285 pGraphics->CopyBits( &aPosAry, mpGraphics, this, this );
286 pNewVirDev->ReleaseGraphics( pGraphics );
287 ImplReleaseGraphics();
288 pSVData->mpDefInst->DestroyVirtualDevice( mpVirDev );
289 mpVirDev = pNewVirDev;
290 mnOutWidth = rNewSize.Width();
291 mnOutHeight = rNewSize.Height();
292 bRet = TRUE;
294 else
296 bRet = FALSE;
297 pSVData->mpDefInst->DestroyVirtualDevice( pNewVirDev );
300 else
301 bRet = FALSE;
304 return bRet;
307 // -----------------------------------------------------------------------
309 // #i32109#: Fill opaque areas correctly (without relying on
310 // fill/linecolor state)
311 void VirtualDevice::ImplFillOpaqueRectangle( const Rectangle& rRect )
313 // Set line and fill color to black (->opaque),
314 // fill rect with that (linecolor, too, because of
315 // those pesky missing pixel problems)
316 Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
317 SetLineColor( COL_BLACK );
318 SetFillColor( COL_BLACK );
319 DrawRect( rRect );
320 Pop();
323 // -----------------------------------------------------------------------
325 BOOL VirtualDevice::SetOutputSizePixel( const Size& rNewSize, BOOL bErase )
327 if( ImplSetOutputSizePixel(rNewSize, bErase) )
329 if( mnAlphaDepth != -1 )
331 // #110958# Setup alpha bitmap
332 if(mpAlphaVDev && mpAlphaVDev->GetOutputSizePixel() != rNewSize)
334 delete mpAlphaVDev;
335 mpAlphaVDev = 0L;
338 if( !mpAlphaVDev )
340 mpAlphaVDev = new VirtualDevice( *this, mnAlphaDepth );
341 mpAlphaVDev->ImplSetOutputSizePixel(rNewSize, bErase);
344 // TODO: copy full outdev state to new one, here. Also needed in outdev2.cxx:DrawOutDev
345 if( GetLineColor() != Color( COL_TRANSPARENT ) )
346 mpAlphaVDev->SetLineColor( COL_BLACK );
348 if( GetFillColor() != Color( COL_TRANSPARENT ) )
349 mpAlphaVDev->SetFillColor( COL_BLACK );
351 mpAlphaVDev->SetMapMode( GetMapMode() );
354 return TRUE;
357 return FALSE;
360 // -----------------------------------------------------------------------
362 void VirtualDevice::SetReferenceDevice( RefDevMode eRefDevMode )
364 switch( eRefDevMode )
366 case REFDEV_NONE:
367 default:
368 DBG_ASSERT( FALSE, "VDev::SetRefDev illegal argument!" );
369 // fall through
370 case REFDEV_MODE06:
371 mnDPIX = mnDPIY = 600;
372 break;
373 case REFDEV_MODE48:
374 mnDPIX = mnDPIY = 4800;
375 break;
376 case REFDEV_MODE_MSO1:
377 mnDPIX = mnDPIY = 6*1440;
378 break;
379 case REFDEV_MODE_PDF1:
380 mnDPIX = mnDPIY = 720;
381 break;
384 EnableOutput( FALSE ); // prevent output on reference device
385 mbScreenComp = FALSE;
387 // invalidate currently selected fonts
388 mbInitFont = TRUE;
389 mbNewFont = TRUE;
391 // avoid adjusting font lists when already in refdev mode
392 BYTE nOldRefDevMode = meRefDevMode;
393 BYTE nOldCompatFlag = (BYTE)meRefDevMode & REFDEV_FORCE_ZERO_EXTLEAD;
394 meRefDevMode = (BYTE)(eRefDevMode | nOldCompatFlag);
395 if( (nOldRefDevMode ^ nOldCompatFlag) != REFDEV_NONE )
396 return;
398 // the reference device should have only scalable fonts
399 // => clean up the original font lists before getting new ones
400 if ( mpFontEntry )
402 mpFontCache->Release( mpFontEntry );
403 mpFontEntry = NULL;
405 if ( mpGetDevFontList )
407 delete mpGetDevFontList;
408 mpGetDevFontList = NULL;
410 if ( mpGetDevSizeList )
412 delete mpGetDevSizeList;
413 mpGetDevSizeList = NULL;
416 // preserve global font lists
417 ImplSVData* pSVData = ImplGetSVData();
418 if( mpFontList && (mpFontList != pSVData->maGDIData.mpScreenFontList) )
419 delete mpFontList;
420 if( mpFontCache && (mpFontCache != pSVData->maGDIData.mpScreenFontCache) )
421 delete mpFontCache;
423 // get font list with scalable fonts only
424 ImplGetGraphics();
425 mpFontList = pSVData->maGDIData.mpScreenFontList->Clone( true, false );
427 // prepare to use new font lists
428 mpFontCache = new ImplFontCache( false );
431 // -----------------------------------------------------------------------
433 void VirtualDevice::Compat_ZeroExtleadBug()
435 meRefDevMode = (BYTE)meRefDevMode | REFDEV_FORCE_ZERO_EXTLEAD;
438 // -----------------------------------------------------------------------