LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/gdi - virdev.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 161 213 75.6 %
Date: 2013-07-09 Functions: 13 18 72.2 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10