LCOV - code coverage report
Current view: top level - vcl/source/outdev - outdev.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 277 411 67.4 %
Date: 2015-06-13 12:38:46 Functions: 33 41 80.5 %
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             : #include <tools/debug.hxx>
      21             : #include <tools/poly.hxx>
      22             : 
      23             : #include <vcl/svapp.hxx>
      24             : #include <vcl/ctrl.hxx>
      25             : #include <vcl/region.hxx>
      26             : #include <vcl/virdev.hxx>
      27             : #include <vcl/window.hxx>
      28             : #include <vcl/metaact.hxx>
      29             : #include <vcl/gdimtf.hxx>
      30             : #include <vcl/print.hxx>
      31             : #include <vcl/outdev.hxx>
      32             : #include <vcl/unowrap.hxx>
      33             : #include <vcl/settings.hxx>
      34             : #include <vcl/sysdata.hxx>
      35             : 
      36             : #include <vcl/outdevstate.hxx>
      37             : 
      38             : #include <salgdi.hxx>
      39             : #include <sallayout.hxx>
      40             : #include <salframe.hxx>
      41             : #include <salvd.hxx>
      42             : #include <salprn.hxx>
      43             : #include <svdata.hxx>
      44             : #include <window.h>
      45             : #include <outdev.h>
      46             : #include <outdata.hxx>
      47             : #include <outdevstatestack.hxx>
      48             : 
      49             : #include "PhysicalFontCollection.hxx"
      50             : 
      51             : #include <basegfx/point/b2dpoint.hxx>
      52             : #include <basegfx/vector/b2dvector.hxx>
      53             : #include <basegfx/polygon/b2dpolygon.hxx>
      54             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      55             : #include <basegfx/matrix/b2dhommatrix.hxx>
      56             : #include <basegfx/polygon/b2dpolygontools.hxx>
      57             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      58             : #include <basegfx/polygon/b2dlinegeometry.hxx>
      59             : 
      60             : #include <com/sun/star/awt/XGraphics.hpp>
      61             : #include <com/sun/star/uno/Sequence.hxx>
      62             : #include <com/sun/star/rendering/XCanvas.hpp>
      63             : #include <com/sun/star/rendering/CanvasFactory.hpp>
      64             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      65             : #include <comphelper/processfactory.hxx>
      66             : 
      67             : #include <config_cairo_canvas.h>
      68             : 
      69             : #include <numeric>
      70             : #include <stack>
      71             : 
      72             : #ifdef DISABLE_DYNLOADING
      73             : // Linking all needed LO code into one .so/executable, these already
      74             : // exist in the tools library, so put them in the anonymous namespace
      75             : // here to avoid clash...
      76             : namespace {
      77             : #endif
      78             : #ifdef DISABLE_DYNLOADING
      79             : }
      80             : #endif
      81             : 
      82             : // Begin initializer and accessor public functions
      83             : 
      84      422350 : OutputDevice::OutputDevice() :
      85             :     mnRefCnt(1), // cf. VclPtrInstance and README.lifecycle
      86             :     maRegion(true),
      87             :     maFillColor( COL_WHITE ),
      88             :     maTextLineColor( COL_TRANSPARENT ),
      89      422350 :     mxSettings( new AllSettings(Application::GetSettings()) )
      90             : {
      91      422350 :     mpGraphics                      = NULL;
      92      422350 :     mpUnoGraphicsList               = NULL;
      93      422350 :     mpPrevGraphics                  = NULL;
      94      422350 :     mpNextGraphics                  = NULL;
      95      422350 :     mpMetaFile                      = NULL;
      96      422350 :     mpFontEntry                     = NULL;
      97      422350 :     mpFontCache                     = NULL;
      98      422350 :     mpFontCollection                = NULL;
      99      422350 :     mpGetDevFontList                = NULL;
     100      422350 :     mpGetDevSizeList                = NULL;
     101      422350 :     mpOutDevStateStack              = new OutDevStateStack;
     102      422350 :     mpPDFWriter                     = NULL;
     103      422350 :     mpAlphaVDev                     = NULL;
     104      422350 :     mpExtOutDevData                 = NULL;
     105      422350 :     mnOutOffX                       = 0;
     106      422350 :     mnOutOffY                       = 0;
     107      422350 :     mnOutWidth                      = 0;
     108      422350 :     mnOutHeight                     = 0;
     109      422350 :     mnDPIX                          = 0;
     110      422350 :     mnDPIY                          = 0;
     111      422350 :     mnDPIScaleFactor                = 1;
     112      422350 :     mnTextOffX                      = 0;
     113      422350 :     mnTextOffY                      = 0;
     114      422350 :     mnOutOffOrigX                   = 0;
     115      422350 :     mnOutOffLogicX                  = 0;
     116      422350 :     mnOutOffOrigY                   = 0;
     117      422350 :     mnOutOffLogicY                  = 0;
     118      422350 :     mnEmphasisAscent                = 0;
     119      422350 :     mnEmphasisDescent               = 0;
     120      422350 :     mnDrawMode                      = DrawModeFlags::Default;
     121      422350 :     mnTextLayoutMode                = TEXT_LAYOUT_DEFAULT;
     122             : 
     123      422350 :     if( AllSettings::GetLayoutRTL() ) //#i84553# tip BiDi preference to RTL
     124           0 :         mnTextLayoutMode            = TEXT_LAYOUT_BIDI_RTL | TEXT_LAYOUT_TEXTORIGIN_LEFT;
     125             : 
     126      422350 :     meOutDevType                    = OUTDEV_DONTKNOW;
     127      422350 :     meOutDevViewType                = OUTDEV_VIEWTYPE_DONTKNOW;
     128      422350 :     mbMap                           = false;
     129      422350 :     mbMapIsDefault                  = true;
     130      422350 :     mbClipRegion                    = false;
     131      422350 :     mbBackground                    = false;
     132      422350 :     mbOutput                        = true;
     133      422350 :     mbDevOutput                     = false;
     134      422350 :     mbOutputClipped                 = false;
     135      422350 :     maTextColor                     = Color( COL_BLACK );
     136      422350 :     maOverlineColor                 = Color( COL_TRANSPARENT );
     137      422350 :     meTextAlign                     = maFont.GetAlign();
     138      422350 :     meRasterOp                      = ROP_OVERPAINT;
     139      422350 :     mnAntialiasing                  = AntialiasingFlags::NONE;
     140      422350 :     meTextLanguage                  = 0;  // TODO: get default from configuration?
     141      422350 :     mbLineColor                     = true;
     142      422350 :     mbFillColor                     = true;
     143      422350 :     mbInitLineColor                 = true;
     144      422350 :     mbInitFillColor                 = true;
     145      422350 :     mbInitFont                      = true;
     146      422350 :     mbInitTextColor                 = true;
     147      422350 :     mbInitClipRegion                = true;
     148      422350 :     mbClipRegionSet                 = false;
     149      422350 :     mbKerning                       = false;
     150      422350 :     mbNewFont                       = true;
     151      422350 :     mbTextLines                     = false;
     152      422350 :     mbTextBackground                = false;
     153      422350 :     mbTextSpecial                   = false;
     154      422350 :     mbRefPoint                      = false;
     155      422350 :     mbEnableRTL                     = false;    // mirroring must be explicitly allowed (typically for windows only)
     156             : 
     157             :     // struct ImplMapRes
     158      422350 :     maMapRes.mnMapOfsX              = 0;
     159      422350 :     maMapRes.mnMapOfsY              = 0;
     160      422350 :     maMapRes.mnMapScNumX            = 1;
     161      422350 :     maMapRes.mnMapScNumY            = 1;
     162      422350 :     maMapRes.mnMapScDenomX          = 1;
     163      422350 :     maMapRes.mnMapScDenomY          = 1;
     164      422350 :     maMapRes.mfOffsetX              = 0.0;
     165      422350 :     maMapRes.mfOffsetY              = 0.0;
     166      422350 :     maMapRes.mfScaleX               = 1.0;
     167      422350 :     maMapRes.mfScaleY               = 1.0;
     168             :     // struct ImplThresholdRes
     169      422350 :     maThresRes.mnThresLogToPixX     = 0;
     170      422350 :     maThresRes.mnThresLogToPixY     = 0;
     171      422350 :     maThresRes.mnThresPixToLogX     = 0;
     172      422350 :     maThresRes.mnThresPixToLogY     = 0;
     173             : 
     174             :     // struct ImplOutDevData- see #i82615#
     175      422350 :     mpOutDevData                    = new ImplOutDevData;
     176      422350 :     mpOutDevData->mpRotateDev       = NULL;
     177      422350 :     mpOutDevData->mpRecordLayout    = NULL;
     178             : 
     179             :     // #i75163#
     180      422350 :     mpOutDevData->mpViewTransform   = NULL;
     181      422350 :     mpOutDevData->mpInverseViewTransform = NULL;
     182             : 
     183      422350 :     mbDisposed = false;
     184      422350 : }
     185             : 
     186      820512 : OutputDevice::~OutputDevice()
     187             : {
     188      410256 :     disposeOnce();
     189      410256 : }
     190             : 
     191     1688146 : void OutputDevice::disposeOnce()
     192             : {
     193     1688146 :     if ( mbDisposed )
     194     2956939 :         return;
     195      419353 :     mbDisposed = true;
     196             : 
     197             :     // catch badness where our OutputDevice sub-class was not
     198             :     // wrapped safely in a VclPtr cosily.
     199             :     // FIXME: as/when we make our destructors all protected,
     200             :     // we should introduce this assert:
     201             :     //    assert( mnRefCnt > 0 );
     202             : 
     203      419353 :     dispose();
     204             : }
     205             : 
     206      419353 : void OutputDevice::dispose()
     207             : {
     208      419353 :     if ( GetUnoGraphicsList() )
     209             :     {
     210         760 :         UnoWrapperBase* pWrapper = Application::GetUnoWrapper( false );
     211         760 :         if ( pWrapper )
     212         760 :             pWrapper->ReleaseAllGraphics( this );
     213         760 :         delete mpUnoGraphicsList;
     214         760 :         mpUnoGraphicsList = NULL;
     215             :     }
     216             : 
     217      419353 :     mpOutDevData->mpRotateDev.disposeAndClear();
     218             : 
     219             :     // #i75163#
     220      419353 :     ImplInvalidateViewTransform();
     221             : 
     222      419353 :     delete mpOutDevData;
     223      419353 :     mpOutDevData = NULL;
     224             : 
     225             :     // for some reason, we haven't removed state from the stack properly
     226      419353 :     if ( !mpOutDevStateStack->empty() )
     227             :     {
     228             :         SAL_WARN( "vcl.gdi", "OutputDevice::~OutputDevice(): OutputDevice::Push() calls != OutputDevice::Pop() calls" );
     229           0 :         while ( !mpOutDevStateStack->empty() )
     230             :         {
     231           0 :             mpOutDevStateStack->pop_back();
     232             :         }
     233             :     }
     234      419353 :     delete mpOutDevStateStack;
     235      419353 :     mpOutDevStateStack = NULL;
     236             : 
     237             :     // release the active font instance
     238      419353 :     if( mpFontEntry )
     239          55 :         mpFontCache->Release( mpFontEntry );
     240             : 
     241             :     // remove cached results of GetDevFontList/GetDevSizeList
     242             :     // TODO: use smart pointers for them
     243      419353 :     delete mpGetDevFontList;
     244      419353 :     mpGetDevFontList = NULL;
     245             : 
     246      419353 :     delete mpGetDevSizeList;
     247      419353 :     mpGetDevSizeList = NULL;
     248             : 
     249             :     // release ImplFontCache specific to this OutputDevice
     250             :     // TODO: refcount ImplFontCache
     251      419353 :     if( mpFontCache
     252      418926 :     && (mpFontCache != ImplGetSVData()->maGDIData.mpScreenFontCache)
     253      422955 :     && (ImplGetSVData()->maGDIData.mpScreenFontCache != NULL) )
     254             :     {
     255        3602 :         delete mpFontCache;
     256        3602 :         mpFontCache = NULL;
     257             :     }
     258             : 
     259             :     // release ImplFontList specific to this OutputDevice
     260             :     // TODO: refcount ImplFontList
     261      419353 :     if( mpFontCollection
     262      419350 :     && (mpFontCollection != ImplGetSVData()->maGDIData.mpScreenFontList)
     263      423379 :     && (ImplGetSVData()->maGDIData.mpScreenFontList != NULL) )
     264             :     {
     265        4026 :         mpFontCollection->Clear();
     266        4026 :         delete mpFontCollection;
     267        4026 :         mpFontCollection = NULL;
     268             :     }
     269             : 
     270      419353 :     mpAlphaVDev.disposeAndClear();
     271      419353 : }
     272             : 
     273         213 : SalGraphics* OutputDevice::GetGraphics()
     274             : {
     275             :     DBG_TESTSOLARMUTEX();
     276             : 
     277         213 :     if ( !mpGraphics )
     278             :     {
     279         213 :         if ( !AcquireGraphics() )
     280             :         {
     281             :             SAL_WARN("vcl", "No mpGraphics set");
     282             :         }
     283             :     }
     284             : 
     285         213 :     return mpGraphics;
     286             : }
     287             : 
     288           0 : SalGraphics const *OutputDevice::GetGraphics() const
     289             : {
     290             :     DBG_TESTSOLARMUTEX();
     291             : 
     292           0 :     if ( !mpGraphics )
     293             :     {
     294           0 :         if ( !AcquireGraphics() )
     295             :         {
     296             :             SAL_WARN("vcl", "No mpGraphics set");
     297             :         }
     298             :     }
     299             : 
     300           0 :     return mpGraphics;
     301             : }
     302             : 
     303       46410 : void OutputDevice::SetConnectMetaFile( GDIMetaFile* pMtf )
     304             : {
     305       46410 :     mpMetaFile = pMtf;
     306       46410 : }
     307             : 
     308      346718 : void OutputDevice::SetSettings( const AllSettings& rSettings )
     309             : {
     310      346718 :     *mxSettings = rSettings;
     311             : 
     312      346718 :     if( mpAlphaVDev )
     313          10 :         mpAlphaVDev->SetSettings( rSettings );
     314      346718 : }
     315             : 
     316          87 : SystemGraphicsData OutputDevice::GetSystemGfxData() const
     317             : {
     318          87 :     if ( !mpGraphics )
     319             :     {
     320           1 :         if ( !AcquireGraphics() )
     321           0 :             return SystemGraphicsData();
     322             :     }
     323             : 
     324          87 :     return mpGraphics->GetGraphicsData();
     325             : }
     326             : 
     327           3 : bool OutputDevice::SupportsCairo() const
     328             : {
     329             : #if ENABLE_CAIRO_CANVAS
     330           3 :     if (!mpGraphics)
     331             :     {
     332           0 :         if (!AcquireGraphics())
     333           0 :             return false;
     334             :     }
     335             : 
     336           3 :     return mpGraphics->SupportsCairo();
     337             : #else
     338             :     (void) this; // loplugin:staticmethods
     339             :     return false;
     340             : #endif
     341             : }
     342             : 
     343           2 : cairo::SurfaceSharedPtr OutputDevice::CreateSurface(const cairo::CairoSurfaceSharedPtr& rSurface) const
     344             : {
     345           2 :     if (!mpGraphics)
     346             :     {
     347           0 :         if (!AcquireGraphics())
     348           0 :             return cairo::SurfaceSharedPtr();
     349             :     }
     350           2 :     return mpGraphics->CreateSurface(rSurface);
     351             : }
     352             : 
     353           2 : cairo::SurfaceSharedPtr OutputDevice::CreateSurface(int x, int y, int width, int height) const
     354             : {
     355           2 :     if (!mpGraphics)
     356             :     {
     357           0 :         if (!AcquireGraphics())
     358           0 :             return cairo::SurfaceSharedPtr();
     359             :     }
     360           2 :     return mpGraphics->CreateSurface(*this, x, y, width, height);
     361             : }
     362             : 
     363           0 : cairo::SurfaceSharedPtr OutputDevice::CreateBitmapSurface(const BitmapSystemData& rData, const Size& rSize) const
     364             : {
     365           0 :     if (!mpGraphics)
     366             :     {
     367           0 :         if (!AcquireGraphics())
     368           0 :             return cairo::SurfaceSharedPtr();
     369             :     }
     370           0 :     return mpGraphics->CreateBitmapSurface(*this, rData, rSize);
     371             : }
     372             : 
     373           0 : css::uno::Any OutputDevice::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& rSurface, const ::basegfx::B2ISize& rSize) const
     374             : {
     375           0 :     if (!mpGraphics)
     376             :     {
     377           0 :         if (!AcquireGraphics())
     378           0 :             return css::uno::Any();
     379             :     }
     380           0 :     return mpGraphics->GetNativeSurfaceHandle(rSurface, rSize);
     381             : }
     382             : 
     383          87 : css::uno::Any OutputDevice::GetSystemGfxDataAny() const
     384             : {
     385          87 :     const SystemGraphicsData aSysData = GetSystemGfxData();
     386             :     css::uno::Sequence< sal_Int8 > aSeq( reinterpret_cast<sal_Int8 const *>(&aSysData),
     387          87 :                                                       aSysData.nSize );
     388             : 
     389          87 :     return css::uno::makeAny(aSeq);
     390             : }
     391             : 
     392      128234 : void OutputDevice::SetRefPoint()
     393             : {
     394             : 
     395      128234 :     if ( mpMetaFile )
     396       12783 :         mpMetaFile->AddAction( new MetaRefPointAction( Point(), false ) );
     397             : 
     398      128234 :     mbRefPoint = false;
     399      128234 :     maRefPoint.X() = maRefPoint.Y() = 0L;
     400             : 
     401      128234 :     if( mpAlphaVDev )
     402       25670 :         mpAlphaVDev->SetRefPoint();
     403      128234 : }
     404             : 
     405          27 : void OutputDevice::SetRefPoint( const Point& rRefPoint )
     406             : {
     407             : 
     408          27 :     if ( mpMetaFile )
     409           9 :         mpMetaFile->AddAction( new MetaRefPointAction( rRefPoint, true ) );
     410             : 
     411          27 :     mbRefPoint = true;
     412          27 :     maRefPoint = rRefPoint;
     413             : 
     414          27 :     if( mpAlphaVDev )
     415           0 :         mpAlphaVDev->SetRefPoint( rRefPoint );
     416          27 : }
     417             : 
     418      229019 : sal_uInt16 OutputDevice::GetBitCount() const
     419             : {
     420             :     // we need a graphics instance
     421      229019 :     if ( !mpGraphics )
     422             :     {
     423           7 :         if ( !AcquireGraphics() )
     424           0 :             return 0;
     425             :     }
     426             : 
     427      229019 :     return (sal_uInt16)mpGraphics->GetBitCount();
     428             : }
     429             : 
     430         305 : sal_uLong OutputDevice::GetColorCount() const
     431             : {
     432             : 
     433         305 :     const sal_uInt16 nBitCount = GetBitCount();
     434         305 :     return( ( nBitCount > 31 ) ? ULONG_MAX : ( ( (sal_uLong) 1 ) << nBitCount) );
     435             : }
     436             : 
     437           0 : css::uno::Reference< css::rendering::XCanvas > OutputDevice::GetCanvas() const
     438             : {
     439           0 :     css::uno::Sequence< css::uno::Any > aArg(6);
     440             : 
     441           0 :     aArg[ 0 ] = css::uno::makeAny( reinterpret_cast<sal_Int64>(this) );
     442           0 :     aArg[ 2 ] = css::uno::makeAny( css::awt::Rectangle( mnOutOffX, mnOutOffY, mnOutWidth, mnOutHeight ) );
     443           0 :     aArg[ 3 ] = css::uno::makeAny( sal_False );
     444           0 :     aArg[ 5 ] = GetSystemGfxDataAny();
     445             : 
     446           0 :     css::uno::Reference<css::uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
     447             : 
     448             :     // Create canvas instance with window handle
     449           0 :     static css::uno::Reference<css::lang::XMultiComponentFactory > xCanvasFactory( css::rendering::CanvasFactory::create( xContext ) );
     450             : 
     451           0 :     css::uno::Reference<css::rendering::XCanvas> xCanvas;
     452             :     xCanvas.set(
     453           0 :         xCanvasFactory->createInstanceWithArgumentsAndContext(
     454           0 :             "com.sun.star.rendering.Canvas", aArg, xContext ),
     455           0 :         css::uno::UNO_QUERY );
     456             : 
     457           0 :     return xCanvas;
     458             : }
     459             : 
     460       28505 : css::uno::Reference< css::awt::XGraphics > OutputDevice::CreateUnoGraphics()
     461             : {
     462       28505 :     UnoWrapperBase* pWrapper = Application::GetUnoWrapper();
     463       28505 :     return pWrapper ? pWrapper->CreateGraphics( this ) : css::uno::Reference< css::awt::XGraphics >();
     464             : }
     465             : 
     466         760 : std::vector< VCLXGraphics* > *OutputDevice::CreateUnoGraphicsList()
     467             : {
     468         760 :     mpUnoGraphicsList = new std::vector< VCLXGraphics* >();
     469         760 :     return mpUnoGraphicsList;
     470             : }
     471             : 
     472             : // Helper public function
     473             : 
     474       14542 : bool OutputDevice::SupportsOperation( OutDevSupportType eType ) const
     475             : {
     476       14542 :     if( !mpGraphics )
     477           0 :         if( !AcquireGraphics() )
     478           0 :             return false;
     479       14542 :     const bool bHasSupport = mpGraphics->supportsOperation( eType );
     480       14542 :     return bHasSupport;
     481             : }
     482             : 
     483             : // Direct OutputDevice drawing public functions
     484             : 
     485         367 : void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
     486             :                                const Point& rSrcPt,  const Size& rSrcSize )
     487             : {
     488         367 :     if( ImplIsRecordLayout() )
     489           0 :         return;
     490             : 
     491         367 :     if ( ROP_INVERT == meRasterOp )
     492             :     {
     493           0 :         DrawRect( Rectangle( rDestPt, rDestSize ) );
     494           0 :         return;
     495             :     }
     496             : 
     497         367 :     if ( mpMetaFile )
     498             :     {
     499           0 :         const Bitmap aBmp( GetBitmap( rSrcPt, rSrcSize ) );
     500           0 :         mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
     501             :     }
     502             : 
     503         367 :     if ( !IsDeviceOutputNecessary() )
     504           0 :         return;
     505             : 
     506         367 :     if ( !mpGraphics )
     507          24 :         if ( !AcquireGraphics() )
     508           0 :             return;
     509             : 
     510         367 :     if ( mbInitClipRegion )
     511          24 :         InitClipRegion();
     512             : 
     513         367 :     if ( mbOutputClipped )
     514           0 :         return;
     515             : 
     516         367 :     long nSrcWidth   = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
     517         367 :     long nSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
     518         367 :     long nDestWidth  = ImplLogicWidthToDevicePixel( rDestSize.Width() );
     519         367 :     long nDestHeight = ImplLogicHeightToDevicePixel( rDestSize.Height() );
     520             : 
     521         367 :     if (nSrcWidth && nSrcHeight && nDestWidth && nDestHeight)
     522             :     {
     523             :         SalTwoRect aPosAry(ImplLogicXToDevicePixel(rSrcPt.X()), ImplLogicYToDevicePixel(rSrcPt.Y()),
     524             :                            nSrcWidth, nSrcHeight,
     525             :                            ImplLogicXToDevicePixel(rDestPt.X()), ImplLogicYToDevicePixel(rDestPt.Y()),
     526         366 :                            nDestWidth, nDestHeight);
     527             : 
     528             :         const Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
     529         366 :                                      Size( mnOutWidth, mnOutHeight ) );
     530             : 
     531         366 :         AdjustTwoRect( aPosAry, aSrcOutRect );
     532             : 
     533         366 :         if ( aPosAry.mnSrcWidth && aPosAry.mnSrcHeight && aPosAry.mnDestWidth && aPosAry.mnDestHeight )
     534         366 :             mpGraphics->CopyBits( aPosAry, NULL, this, NULL );
     535             :     }
     536             : 
     537         367 :     if( mpAlphaVDev )
     538           0 :         mpAlphaVDev->DrawOutDev( rDestPt, rDestSize, rSrcPt, rSrcSize );
     539             : }
     540             : 
     541       93579 : void OutputDevice::DrawOutDev( const Point& rDestPt, const Size& rDestSize,
     542             :                                const Point& rSrcPt,  const Size& rSrcSize,
     543             :                                const OutputDevice& rOutDev )
     544             : {
     545       93579 :     if ( ImplIsRecordLayout() )
     546         503 :         return;
     547             : 
     548       93579 :     if ( ROP_INVERT == meRasterOp )
     549             :     {
     550           0 :         DrawRect( Rectangle( rDestPt, rDestSize ) );
     551           0 :         return;
     552             :     }
     553             : 
     554       93579 :     if ( mpMetaFile )
     555             :     {
     556           0 :         const Bitmap aBmp( rOutDev.GetBitmap( rSrcPt, rSrcSize ) );
     557           0 :         mpMetaFile->AddAction( new MetaBmpScaleAction( rDestPt, rDestSize, aBmp ) );
     558             :     }
     559             : 
     560       93579 :     if ( !IsDeviceOutputNecessary() )
     561         495 :         return;
     562             : 
     563       93084 :     if ( !mpGraphics )
     564        2431 :         if ( !AcquireGraphics() )
     565           0 :             return;
     566             : 
     567       93084 :     if ( mbInitClipRegion )
     568       15969 :         InitClipRegion();
     569             : 
     570       93084 :     if ( mbOutputClipped )
     571           8 :         return;
     572             : 
     573             :     SalTwoRect aPosAry(rOutDev.ImplLogicXToDevicePixel(rSrcPt.X()),
     574             :                        rOutDev.ImplLogicYToDevicePixel(rSrcPt.Y()),
     575             :                        rOutDev.ImplLogicWidthToDevicePixel(rSrcSize.Width()),
     576             :                        rOutDev.ImplLogicHeightToDevicePixel(rSrcSize.Height()),
     577             :                        ImplLogicXToDevicePixel(rDestPt.X()),
     578             :                        ImplLogicYToDevicePixel(rDestPt.Y()),
     579             :                        ImplLogicWidthToDevicePixel(rDestSize.Width()),
     580       93076 :                        ImplLogicHeightToDevicePixel(rDestSize.Height()));
     581             : 
     582       93076 :     if( mpAlphaVDev )
     583             :     {
     584           0 :         if( rOutDev.mpAlphaVDev )
     585             :         {
     586             :             // alpha-blend source over destination
     587           0 :             DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );
     588             :         }
     589             :         else
     590             :         {
     591           0 :             drawOutDevDirect( &rOutDev, aPosAry );
     592             : 
     593             :             // #i32109#: make destination rectangle opaque - source has no alpha
     594           0 :             mpAlphaVDev->ImplFillOpaqueRectangle( Rectangle(rDestPt, rDestSize) );
     595             :         }
     596             :     }
     597             :     else
     598             :     {
     599       93076 :         if( rOutDev.mpAlphaVDev )
     600             :         {
     601             :             // alpha-blend source over destination
     602           0 :             DrawBitmapEx( rDestPt, rDestSize, rOutDev.GetBitmapEx(rSrcPt, rSrcSize) );
     603             :         }
     604             :         else
     605             :         {
     606             :             // no alpha at all, neither in source nor destination device
     607       93076 :             drawOutDevDirect( &rOutDev, aPosAry );
     608             :         }
     609             :     }
     610             : }
     611             : 
     612           0 : void OutputDevice::CopyArea( const Point& rDestPt,
     613             :                              const Point& rSrcPt,  const Size& rSrcSize,
     614             :                              bool bWindowInvalidate )
     615             : {
     616           0 :     if ( ImplIsRecordLayout() )
     617           0 :         return;
     618             : 
     619           0 :     RasterOp eOldRop = GetRasterOp();
     620           0 :     SetRasterOp( ROP_OVERPAINT );
     621             : 
     622           0 :     if ( !IsDeviceOutputNecessary() )
     623           0 :         return;
     624             : 
     625           0 :     if ( !mpGraphics )
     626           0 :         if ( !AcquireGraphics() )
     627           0 :             return;
     628             : 
     629           0 :     if ( mbInitClipRegion )
     630           0 :         InitClipRegion();
     631             : 
     632           0 :     if ( mbOutputClipped )
     633           0 :         return;
     634             : 
     635           0 :     long nSrcWidth   = ImplLogicWidthToDevicePixel( rSrcSize.Width() );
     636           0 :     long nSrcHeight  = ImplLogicHeightToDevicePixel( rSrcSize.Height() );
     637           0 :     if (nSrcWidth && nSrcHeight)
     638             :     {
     639             :         SalTwoRect aPosAry(ImplLogicXToDevicePixel(rSrcPt.X()), ImplLogicYToDevicePixel(rSrcPt.Y()),
     640             :                            nSrcWidth, nSrcHeight,
     641             :                            ImplLogicXToDevicePixel(rDestPt.X()), ImplLogicYToDevicePixel(rDestPt.Y()),
     642           0 :                            nSrcWidth, nSrcHeight);
     643             : 
     644             :         const Rectangle aSrcOutRect( Point( mnOutOffX, mnOutOffY ),
     645           0 :                                      Size( mnOutWidth, mnOutHeight ) );
     646             : 
     647           0 :         AdjustTwoRect( aPosAry, aSrcOutRect );
     648             : 
     649           0 :         CopyDeviceArea( aPosAry, bWindowInvalidate );
     650             :     }
     651             : 
     652           0 :     SetRasterOp( eOldRop );
     653             : 
     654           0 :     if( mpAlphaVDev )
     655           0 :         mpAlphaVDev->CopyArea( rDestPt, rSrcPt, rSrcSize, bWindowInvalidate );
     656             : }
     657             : 
     658             : // Direct OutputDevice drawing protected function
     659             : 
     660           0 : void OutputDevice::CopyDeviceArea( SalTwoRect& aPosAry, bool /*bWindowInvalidate*/)
     661             : {
     662           0 :     if (aPosAry.mnSrcWidth == 0 || aPosAry.mnSrcHeight == 0 || aPosAry.mnDestWidth == 0 || aPosAry.mnDestHeight == 0)
     663           0 :         return;
     664             : 
     665           0 :     aPosAry.mnDestWidth  = aPosAry.mnSrcWidth;
     666           0 :     aPosAry.mnDestHeight = aPosAry.mnSrcHeight;
     667           0 :     mpGraphics->CopyBits(aPosAry, NULL, this, NULL);
     668             : }
     669             : 
     670             : // Direct OutputDevice drawing private function
     671             : 
     672       93076 : void OutputDevice::drawOutDevDirect( const OutputDevice* pSrcDev, SalTwoRect& rPosAry )
     673             : {
     674             :     SalGraphics* pSrcGraphics;
     675             : 
     676       93076 :     if ( this == pSrcDev )
     677           0 :         pSrcGraphics = NULL;
     678             :     else
     679             :     {
     680      115217 :         if ( (GetOutDevType() != pSrcDev->GetOutDevType()) ||
     681       22141 :              (GetOutDevType() != OUTDEV_WINDOW) )
     682             :         {
     683       93076 :             if ( !pSrcDev->mpGraphics )
     684             :             {
     685           0 :                 if ( !pSrcDev->AcquireGraphics() )
     686           0 :                     return;
     687             :             }
     688       93076 :             pSrcGraphics = pSrcDev->mpGraphics;
     689             :         }
     690             :         else
     691             :         {
     692           0 :             if ( static_cast<vcl::Window*>(this)->mpWindowImpl->mpFrameWindow == static_cast<const vcl::Window*>(pSrcDev)->mpWindowImpl->mpFrameWindow )
     693           0 :                 pSrcGraphics = NULL;
     694             :             else
     695             :             {
     696           0 :                 if ( !pSrcDev->mpGraphics )
     697             :                 {
     698           0 :                     if ( !pSrcDev->AcquireGraphics() )
     699           0 :                         return;
     700             :                 }
     701           0 :                 pSrcGraphics = pSrcDev->mpGraphics;
     702             : 
     703           0 :                 if ( !mpGraphics )
     704             :                 {
     705           0 :                     if ( !AcquireGraphics() )
     706           0 :                         return;
     707             :                 }
     708             :                 DBG_ASSERT( mpGraphics && pSrcDev->mpGraphics,
     709             :                             "OutputDevice::DrawOutDev(): We need more than one Graphics" );
     710             :             }
     711             :         }
     712             :     }
     713             : 
     714             :     // #102532# Offset only has to be pseudo window offset
     715             :     const Rectangle aSrcOutRect( Point( pSrcDev->mnOutOffX, pSrcDev->mnOutOffY ),
     716       93076 :                                  Size( pSrcDev->mnOutWidth, pSrcDev->mnOutHeight ) );
     717             : 
     718       93076 :     AdjustTwoRect( rPosAry, aSrcOutRect );
     719             : 
     720       93076 :     if ( rPosAry.mnSrcWidth && rPosAry.mnSrcHeight && rPosAry.mnDestWidth && rPosAry.mnDestHeight )
     721             :     {
     722             :         // --- RTL --- if this is no window, but pSrcDev is a window
     723             :         // mirroring may be required
     724             :         // because only windows have a SalGraphicsLayout
     725             :         // mirroring is performed here
     726       92978 :         if( (GetOutDevType() != OUTDEV_WINDOW) && pSrcGraphics && (pSrcGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) )
     727             :         {
     728           0 :             SalTwoRect aPosAry2 = rPosAry;
     729           0 :             pSrcGraphics->mirror( aPosAry2.mnSrcX, aPosAry2.mnSrcWidth, pSrcDev );
     730           0 :             mpGraphics->CopyBits( aPosAry2, pSrcGraphics, this, pSrcDev );
     731             :         }
     732             :         else
     733       92978 :             mpGraphics->CopyBits( rPosAry, pSrcGraphics, this, pSrcDev );
     734             :     }
     735             : }
     736             : 
     737             : // Layout public functions
     738             : 
     739      114119 : void OutputDevice::EnableRTL( bool bEnable )
     740             : {
     741      114119 :     mbEnableRTL = bEnable;
     742             : 
     743      114119 :     if( mpAlphaVDev )
     744       12799 :         mpAlphaVDev->EnableRTL( bEnable );
     745      114119 : }
     746             : 
     747      875100 : bool OutputDevice::ImplIsAntiparallel() const
     748             : {
     749      875100 :     bool bRet = false;
     750      875100 :     if( AcquireGraphics() )
     751             :     {
     752     3503551 :         if( ( (mpGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) && ! IsRTLEnabled() ) ||
     753     3473490 :             ( ! (mpGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) && IsRTLEnabled() ) )
     754             :         {
     755        3151 :             bRet = true;
     756             :         }
     757             :     }
     758      875100 :     return bRet;
     759             : }
     760             : 
     761             : // note: the coordinates to be remirrored are in frame coordiantes !
     762             : 
     763          42 : void    OutputDevice::ReMirror( Point &rPoint ) const
     764             : {
     765          42 :     rPoint.X() = mnOutOffX + mnOutWidth - 1 - rPoint.X() + mnOutOffX;
     766          42 : }
     767          90 : void    OutputDevice::ReMirror( Rectangle &rRect ) const
     768             : {
     769          90 :     long nWidth = rRect.Right() - rRect.Left();
     770             : 
     771             :     //long lc_x = rRect.nLeft - mnOutOffX;    // normalize
     772             :     //lc_x = mnOutWidth - nWidth - 1 - lc_x;  // mirror
     773             :     //rRect.nLeft = lc_x + mnOutOffX;         // re-normalize
     774             : 
     775          90 :     rRect.Left() = mnOutOffX + mnOutWidth - nWidth - 1 - rRect.Left() + mnOutOffX;
     776          90 :     rRect.Right() = rRect.Left() + nWidth;
     777          90 : }
     778             : 
     779        1450 : void OutputDevice::ReMirror( vcl::Region &rRegion ) const
     780             : {
     781        1450 :     RectangleVector aRectangles;
     782        1450 :     rRegion.GetRegionRectangles(aRectangles);
     783        2900 :     vcl::Region aMirroredRegion;
     784             : 
     785        1495 :     for(RectangleVector::iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     786             :     {
     787          45 :         ReMirror(*aRectIter);
     788          45 :         aMirroredRegion.Union(*aRectIter);
     789             :     }
     790             : 
     791        2900 :     rRegion = aMirroredRegion;
     792             : 
     793        1450 : }
     794             : 
     795      997479 : bool OutputDevice::HasMirroredGraphics() const
     796             : {
     797      997479 :    return ( AcquireGraphics() && (mpGraphics->GetLayout() & SalLayoutFlags::BiDiRtl) );
     798             : }
     799             : 
     800     5183766 : bool OutputDevice::ImplIsRecordLayout() const
     801             : {
     802     5183766 :     return mpOutDevData->mpRecordLayout;
     803             : }
     804             : 
     805             : // EPS public function
     806             : 
     807           0 : bool OutputDevice::DrawEPS( const Point& rPoint, const Size& rSize,
     808             :                             const GfxLink& rGfxLink, GDIMetaFile* pSubst )
     809             : {
     810           0 :     bool bDrawn(true);
     811             : 
     812           0 :     if ( mpMetaFile )
     813             :     {
     814           0 :         GDIMetaFile aSubst;
     815             : 
     816           0 :         if( pSubst )
     817           0 :             aSubst = *pSubst;
     818             : 
     819           0 :         mpMetaFile->AddAction( new MetaEPSAction( rPoint, rSize, rGfxLink, aSubst ) );
     820             :     }
     821             : 
     822           0 :     if ( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
     823           0 :         return bDrawn;
     824             : 
     825           0 :     if( mbOutputClipped )
     826           0 :         return bDrawn;
     827             : 
     828           0 :     Rectangle aRect( ImplLogicToDevicePixel( Rectangle( rPoint, rSize ) ) );
     829             : 
     830           0 :     if( !aRect.IsEmpty() )
     831             :     {
     832             :         // draw the real EPS graphics
     833           0 :         if( rGfxLink.GetData() && rGfxLink.GetDataSize() )
     834             :         {
     835           0 :             if( !mpGraphics && !AcquireGraphics() )
     836           0 :                 return bDrawn;
     837             : 
     838           0 :             if( mbInitClipRegion )
     839           0 :                 InitClipRegion();
     840             : 
     841           0 :             aRect.Justify();
     842           0 :             bDrawn = mpGraphics->DrawEPS( aRect.Left(), aRect.Top(), aRect.GetWidth(), aRect.GetHeight(),
     843           0 :                          const_cast<sal_uInt8*>(rGfxLink.GetData()), rGfxLink.GetDataSize(), this );
     844             :         }
     845             : 
     846             :         // else draw the substitution graphics
     847           0 :         if( !bDrawn && pSubst )
     848             :         {
     849           0 :             GDIMetaFile* pOldMetaFile = mpMetaFile;
     850             : 
     851           0 :             mpMetaFile = NULL;
     852           0 :             Graphic( *pSubst ).Draw( this, rPoint, rSize );
     853           0 :             mpMetaFile = pOldMetaFile;
     854             :         }
     855             :     }
     856             : 
     857           0 :     if( mpAlphaVDev )
     858           0 :         mpAlphaVDev->DrawEPS( rPoint, rSize, rGfxLink, pSubst );
     859             : 
     860           0 :     return bDrawn;
     861             : }
     862             : 
     863      162136 : void OutputDevice::BeginPaint()
     864             : {
     865      162136 :     if( mpGraphics || AcquireGraphics() )
     866      162136 :         mpGraphics->BeginPaint();
     867      162136 : }
     868             : 
     869      162136 : void OutputDevice::EndPaint()
     870             : {
     871      162136 :     if( mpGraphics || AcquireGraphics() )
     872      162136 :         mpGraphics->EndPaint();
     873      162937 : }
     874             : 
     875             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11