LCOV - code coverage report
Current view: top level - vcl/headless - svpgdi.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 301 346 87.0 %
Date: 2015-06-13 12:38:46 Functions: 45 57 78.9 %
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 "headless/svpgdi.hxx"
      21             : #include "headless/svpbmp.hxx"
      22             : #ifndef IOS
      23             : #include "headless/svptextrender.hxx"
      24             : #endif
      25             : #include "saldatabasic.hxx"
      26             : 
      27             : #include <vcl/sysdata.hxx>
      28             : #include <basegfx/range/b2drange.hxx>
      29             : #include <basegfx/range/b2ibox.hxx>
      30             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      31             : #include <basegfx/polygon/b2dpolygon.hxx>
      32             : #include <basegfx/polygon/b2dpolygontools.hxx>
      33             : #include <basebmp/scanlineformats.hxx>
      34             : 
      35             : #if OSL_DEBUG_LEVEL > 2
      36             : #include <basebmp/debug.hxx>
      37             : #include <fstream>
      38             : #include <rtl/strbuf.hxx>
      39             : #include <sys/stat.h>
      40             : #endif
      41             : 
      42     5812404 : inline void dbgOut( const basebmp::BitmapDeviceSharedPtr&
      43             : #if OSL_DEBUG_LEVEL > 2
      44             : rDevice
      45             : #endif
      46             : )
      47             : {
      48             :     #if OSL_DEBUG_LEVEL > 2
      49             :     static int dbgStreamNum = 0;
      50             :     OStringBuffer aBuf( 256 );
      51             :     aBuf.append( "debug" );
      52             :     mkdir( aBuf.getStr(), 0777 );
      53             :     aBuf.append( "/" );
      54             :     aBuf.append( sal_Int64(reinterpret_cast<sal_IntPtr>(rDevice.get())), 16 );
      55             :     mkdir( aBuf.getStr(), 0777 );
      56             :     aBuf.append( "/bmp" );
      57             :     aBuf.append( sal_Int32(dbgStreamNum++) );
      58             :     std::fstream bmpstream( aBuf.getStr(), std::ios::out );
      59             :     debugDump( rDevice, bmpstream );
      60             :     #endif
      61     5812404 : }
      62             : 
      63             : #ifndef IOS
      64             : 
      65           0 : bool SvpSalGraphics::blendBitmap( const SalTwoRect&, const SalBitmap& /*rBitmap*/ )
      66             : {
      67           0 :     return false;
      68             : }
      69             : 
      70         286 : bool SvpSalGraphics::blendAlphaBitmap( const SalTwoRect&, const SalBitmap&, const SalBitmap&, const SalBitmap& )
      71             : {
      72         286 :     return false;
      73             : }
      74             : 
      75      143863 : bool SvpSalGraphics::drawAlphaBitmap( const SalTwoRect&, const SalBitmap& /*rSourceBitmap*/, const SalBitmap& /*rAlphaBitmap*/ )
      76             : {
      77             :     // TODO(P3) implement alpha blending
      78      143863 :     return false;
      79             : }
      80             : 
      81          34 : bool SvpSalGraphics::drawTransformedBitmap(
      82             :     const basegfx::B2DPoint& rNull,
      83             :     const basegfx::B2DPoint& rX,
      84             :     const basegfx::B2DPoint& rY,
      85             :     const SalBitmap& rSourceBitmap,
      86             :     const SalBitmap* pAlphaBitmap)
      87             : {
      88             :     // here direct support for transformed bitmaps can be implemented
      89             :     (void)rNull; (void)rX; (void)rY; (void)rSourceBitmap; (void)pAlphaBitmap;
      90          34 :     return false;
      91             : }
      92             : 
      93          18 : bool SvpSalGraphics::drawAlphaRect( long /*nX*/, long /*nY*/, long /*nWidth*/, long /*nHeight*/, sal_uInt8 /*nTransparency*/ )
      94             : {
      95             :     // TODO(P3) implement alpha blending
      96          18 :     return false;
      97             : }
      98             : 
      99      415558 : SvpSalGraphics::SvpSalGraphics() :
     100             :     m_bUseLineColor( true ),
     101             :     m_aLineColor( COL_BLACK ),
     102             :     m_bUseFillColor( false ),
     103             :     m_aFillColor( COL_WHITE ),
     104             :     m_aDrawMode( basebmp::DrawMode::Paint ),
     105      415558 :     m_bClipSetup( false )
     106             : {
     107      415558 :     m_xTextRenderImpl.reset(new SvpTextRender(*this));
     108      415558 : }
     109             : 
     110      825284 : SvpSalGraphics::~SvpSalGraphics()
     111             : {
     112      825284 : }
     113             : 
     114      515902 : void SvpSalGraphics::setDevice( basebmp::BitmapDeviceSharedPtr& rDevice )
     115             : {
     116      515902 :     m_aOrigDevice = rDevice;
     117      515902 :     ResetClipRegion();
     118      515902 :     m_xTextRenderImpl->setDevice(rDevice);
     119      515902 : }
     120             : 
     121             : #endif
     122             : 
     123        3630 : void SvpSalGraphics::GetResolution( sal_Int32& rDPIX, sal_Int32& rDPIY )
     124             : {
     125        3630 :     rDPIX = rDPIY = 96;
     126        3630 : }
     127             : 
     128             : #ifndef IOS
     129             : 
     130      228845 : sal_uInt16 SvpSalGraphics::GetBitCount() const
     131             : {
     132      228845 :     return SvpSalBitmap::getBitCountFromScanlineFormat( m_aDevice->getScanlineFormat() );
     133             : }
     134             : 
     135       27549 : long SvpSalGraphics::GetGraphicsWidth() const
     136             : {
     137       27549 :     if( m_aDevice.get() )
     138             :     {
     139       27549 :         basegfx::B2IVector aSize = m_aOrigDevice->getSize();
     140       27549 :         return aSize.getX();
     141             :     }
     142           0 :     return 0;
     143             : }
     144             : 
     145      523232 : void SvpSalGraphics::ResetClipRegion()
     146             : {
     147      523232 :     m_aDevice = m_aOrigDevice;
     148      523232 :     m_aClipMap.reset();
     149      523232 :     m_bClipSetup = true;
     150      523232 :     m_aClipRegion.SetNull();
     151      523232 : }
     152             : 
     153             : // verify clip for the whole area is setup
     154     5471675 : void SvpSalGraphics::ensureClip()
     155             : {
     156     5471675 :     if (m_bClipSetup)
     157    10927119 :         return;
     158             : 
     159       16231 :     m_aDevice = m_aOrigDevice;
     160       16231 :     basegfx::B2IVector aSize = m_aDevice->getSize();
     161       16231 :     m_aClipMap = basebmp::createClipDevice( aSize );
     162             : 
     163       32462 :     RectangleVector aRectangles;
     164       16231 :     m_aClipRegion.GetRegionRectangles(aRectangles);
     165             : 
     166       76703 :     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     167             :     {
     168       60472 :         const long nW(aRectIter->GetWidth());
     169       60472 :         if(nW)
     170             :         {
     171       60472 :             const long nH(aRectIter->GetHeight());
     172             : 
     173       60472 :             if(nH)
     174             :             {
     175       60472 :                 basegfx::B2DPolyPolygon aFull;
     176             : 
     177             :                 aFull.append(
     178             :                     basegfx::tools::createPolygonFromRect(
     179             :                         basegfx::B2DRectangle(
     180       60472 :                             aRectIter->Left(),
     181       60472 :                             aRectIter->Top(),
     182       60472 :                             aRectIter->Left() + nW,
     183      241888 :                             aRectIter->Top() + nH)));
     184       60472 :                 m_aClipMap->fillPolyPolygon(aFull, basebmp::Color(0), basebmp::DrawMode::Paint);
     185             :             }
     186             :         }
     187             :     }
     188       32462 :     m_bClipSetup = true;
     189             : }
     190             : 
     191     3607834 : SvpSalGraphics::ClipUndoHandle::~ClipUndoHandle()
     192             : {
     193     1803917 :     if( m_aDevice.get() )
     194         412 :         m_rGfx.m_aDevice = m_aDevice;
     195     1803917 : }
     196             : 
     197             : // setup a clip rectangle -only- iff we have to; if aRange
     198             : // is entirely contained inside an existing clip frame, we
     199             : // will avoid setting up the clip bitmap. Similarly if the
     200             : // range doesn't appear at all we return true to avoid
     201             : // rendering
     202     1803917 : bool SvpSalGraphics::isClippedSetup( const basegfx::B2IBox &aRange, SvpSalGraphics::ClipUndoHandle &rUndo )
     203             : {
     204     1803917 :     if( m_bClipSetup )
     205     1795109 :         return false;
     206             : 
     207        8808 :     if( m_aClipRegion.IsEmpty() ) // no clipping
     208           0 :         return false;
     209             : 
     210             :     // fprintf( stderr, "ensureClipFor: %d, %d %dx%d\n",
     211             :     //         aRange.getMinX(), aRange.getMinY(),
     212             :     //         (int)aRange.getWidth(), (int)aRange.getHeight() );
     213             : 
     214             :     // first see if aRange is purely internal to one of the clip regions
     215       17616 :     Rectangle aRect( Point( aRange.getMinX(), aRange.getMinY() ),
     216       26424 :                      Size( aRange.getWidth(), aRange.getHeight() ) );
     217             : 
     218             :     // then see if we are overlapping with just one
     219        8808 :     int nHit = 0;
     220        8808 :     Rectangle aHitRect;
     221        8808 :     RectangleVector aRectangles;
     222        8808 :     m_aClipRegion.GetRegionRectangles(aRectangles);
     223       45830 :     for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter)
     224             :     {
     225       37022 :         if( aRectIter->IsOver( aRect ) )
     226             :         {
     227        5593 :             aHitRect = *aRectIter;
     228        5593 :             nHit++;
     229             :         }
     230             :     }
     231             : 
     232        8808 :     if( nHit == 0 ) // rendering outside any clipping region
     233             :     {
     234             :         SAL_WARN("vcl.headless", "SvpSalGraphics::isClippedSetup: denegerate case detected ...\n");
     235        3557 :         return true;
     236             :     }
     237        5251 :     else if( nHit == 1 ) // common path: rendering against just one clipping region
     238             :     {
     239        5057 :         if( aHitRect.IsInside( aRect ) )
     240             :         {
     241             :             //The region to be painted (aRect) is equal to or inside the
     242             :             //current clipping region
     243             :             SAL_WARN("vcl.headless", "SvpSalGraphics::isClippedSetup: is inside ! avoid deeper clip ...\n");
     244        4645 :             return false;
     245             :         }
     246             :         SAL_WARN("vcl.headless", "SvpSalGraphics::isClippedSetup: operation only overlaps with a single clip zone\n");
     247         412 :         rUndo.m_aDevice = m_aDevice;
     248        2060 :         m_aDevice = basebmp::subsetBitmapDevice( m_aOrigDevice,
     249         412 :                                                  basegfx::B2IBox (aHitRect.Left(),
     250         412 :                                                                   aHitRect.Top(),
     251         412 :                                                                   aHitRect.Right() + 1,
     252         824 :                                                                   aHitRect.Bottom() + 1) );
     253         412 :         return false;
     254             :     }
     255             :     SAL_INFO("vcl.headless", "SvpSalGraphics::isClippedSetup: URK: complex & slow clipping case\n");
     256             :     // horribly slow & complicated case ...
     257             : 
     258         194 :     ensureClip();
     259         194 :     return false;
     260             : }
     261             : 
     262             : // Clipping by creating unconditional mask bitmaps is horribly
     263             : // slow so defer it, as much as possible. It is common to get
     264             : // 3 rectangles pushed, and have to create a vast off-screen
     265             : // mask only to destroy it shortly afterwards. That is
     266             : // particularly galling if we render only to a small,
     267             : // well defined rectangular area inside one of these clip
     268             : // rectangles.
     269             : 
     270             : // ensureClipFor() or ensureClip() need to be called before
     271             : // real rendering. FIXME: we should prolly push this down to
     272             : // bitmapdevice instead.
     273      513437 : bool SvpSalGraphics::setClipRegion( const vcl::Region& i_rClip )
     274             : {
     275      513437 :     m_aClipRegion = i_rClip;
     276      513437 :     m_aClipMap.reset();
     277      513437 :     if( i_rClip.IsEmpty() )
     278             :     {
     279           0 :         m_aDevice = m_aOrigDevice;
     280           0 :         m_bClipSetup = true;
     281           0 :         return true;
     282             :     }
     283             : 
     284      513437 :     RectangleVector aRectangles;
     285      513437 :     i_rClip.GetRegionRectangles(aRectangles);
     286             : 
     287      513437 :     if (1 == aRectangles.size())
     288             :     {
     289             :         //simplest case, subset the device to clip bounds
     290      489899 :         m_aClipMap.reset();
     291             : 
     292      489899 :         const Rectangle& aBoundRect = aRectangles[0];
     293     2449495 :         m_aDevice = basebmp::subsetBitmapDevice(
     294             :             m_aOrigDevice,
     295     2449495 :             basegfx::B2IBox(aBoundRect.Left(),aBoundRect.Top(),aBoundRect.Right() + 1,aBoundRect.Bottom() + 1) );
     296             : 
     297      489899 :         m_bClipSetup = true;
     298             :     }
     299             :     else
     300             :     {
     301             :         //more complex, either setup and tear down temporary
     302             :         //subsets of the original device around render calls
     303             :         //or generate m_aClipMap and pass that to basebmp
     304             :         //calls
     305       23538 :         m_aDevice = m_aOrigDevice;
     306       23538 :         m_bClipSetup = false;
     307             :     }
     308             : 
     309      513437 :     return true;
     310             : }
     311             : 
     312      622593 : void SvpSalGraphics::SetLineColor()
     313             : {
     314      622593 :     m_bUseLineColor = false;
     315      622593 : }
     316             : 
     317      578346 : void SvpSalGraphics::SetLineColor( SalColor nSalColor )
     318             : {
     319      578346 :     m_bUseLineColor = true;
     320      578346 :     m_aLineColor = basebmp::Color( nSalColor );
     321      578346 : }
     322             : 
     323        4729 : void SvpSalGraphics::SetFillColor()
     324             : {
     325        4729 :     m_bUseFillColor = false;
     326        4729 : }
     327             : 
     328     2220292 : void SvpSalGraphics::SetFillColor( SalColor nSalColor )
     329             : {
     330     2220292 :     m_bUseFillColor = true;
     331     2220292 :     m_aFillColor = basebmp::Color( nSalColor );
     332     2220292 : }
     333             : 
     334      420065 : void SvpSalGraphics::SetXORMode( bool bSet, bool )
     335             : {
     336      420065 :     m_aDrawMode = bSet ? basebmp::DrawMode::XOR : basebmp::DrawMode::Paint;
     337      420065 : }
     338             : 
     339           0 : void SvpSalGraphics::SetROPLineColor( SalROPColor nROPColor )
     340             : {
     341           0 :     m_bUseLineColor = true;
     342           0 :     switch( nROPColor )
     343             :     {
     344             :         case SAL_ROP_0:
     345           0 :             m_aLineColor = basebmp::Color( 0 );
     346           0 :             break;
     347             :         case SAL_ROP_1:
     348           0 :             m_aLineColor = basebmp::Color( 0xffffff );
     349           0 :             break;
     350             :         case SAL_ROP_INVERT:
     351           0 :             m_aLineColor = basebmp::Color( 0xffffff );
     352           0 :             break;
     353             :     }
     354           0 : }
     355             : 
     356           0 : void SvpSalGraphics::SetROPFillColor( SalROPColor nROPColor )
     357             : {
     358           0 :     m_bUseFillColor = true;
     359           0 :     switch( nROPColor )
     360             :     {
     361             :         case SAL_ROP_0:
     362           0 :             m_aFillColor = basebmp::Color( 0 );
     363           0 :             break;
     364             :         case SAL_ROP_1:
     365           0 :             m_aFillColor = basebmp::Color( 0xffffff );
     366           0 :             break;
     367             :         case SAL_ROP_INVERT:
     368           0 :             m_aFillColor = basebmp::Color( 0xffffff );
     369           0 :             break;
     370             :     }
     371           0 : }
     372             : 
     373      348844 : void SvpSalGraphics::drawPixel( long nX, long nY )
     374             : {
     375      348844 :     if( m_bUseLineColor )
     376             :     {
     377      348844 :         ensureClip();
     378             :         m_aDevice->setPixel( basegfx::B2IPoint( nX, nY ),
     379             :                              m_aLineColor,
     380             :                              m_aDrawMode,
     381             :                              m_aClipMap
     382      348844 :                              );
     383             :     }
     384      348844 :     dbgOut( m_aDevice );
     385      348844 : }
     386             : 
     387      402957 : void SvpSalGraphics::drawPixel( long nX, long nY, SalColor nSalColor )
     388             : {
     389      402957 :     basebmp::Color aColor( nSalColor );
     390      402957 :     ensureClip();
     391             :     m_aDevice->setPixel( basegfx::B2IPoint( nX, nY ),
     392             :                          aColor,
     393             :                          m_aDrawMode,
     394             :                          m_aClipMap
     395      402957 :                          );
     396      402957 :     dbgOut( m_aDevice );
     397      402957 : }
     398             : 
     399     1113448 : void SvpSalGraphics::drawLine( long nX1, long nY1, long nX2, long nY2 )
     400             : {
     401     1113448 :     if( m_bUseLineColor )
     402             :     {
     403     1113448 :         ensureClip(); // FIXME: for ...
     404             :         m_aDevice->drawLine( basegfx::B2IPoint( nX1, nY1 ),
     405             :                              basegfx::B2IPoint( nX2, nY2 ),
     406             :                              m_aLineColor,
     407             :                              m_aDrawMode,
     408     1113448 :                              m_aClipMap );
     409             :     }
     410     1113448 :     dbgOut( m_aDevice );
     411     1113448 : }
     412             : 
     413     1684108 : void SvpSalGraphics::drawRect( long nX, long nY, long nWidth, long nHeight )
     414             : {
     415     1684108 :     if ((m_bUseLineColor || m_bUseFillColor) && m_aDevice)
     416             :     {
     417     1684108 :         ensureClip(); // FIXME: for ...
     418     1684108 :         if( m_bUseFillColor )
     419             :         {
     420     1681355 :             basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
     421     3362710 :             basegfx::B2DPolyPolygon aPolyPoly( aRect );
     422     3362710 :             m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
     423             :         }
     424     1684108 :         if( m_bUseLineColor )
     425             :         {
     426             :             // need same -1 hack as X11SalGraphicsImpl::drawRect
     427      758278 :             basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth-1, nY+nHeight-1 ) );
     428      758278 :             m_aDevice->drawPolygon( aRect, m_aLineColor, m_aDrawMode, m_aClipMap );
     429             :         }
     430             :     }
     431     1684108 :     dbgOut( m_aDevice );
     432     1684108 : }
     433             : 
     434      158086 : void SvpSalGraphics::drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry )
     435             : {
     436      158086 :     if (m_bUseLineColor && nPoints && m_aDevice)
     437             :     {
     438      158086 :         basegfx::B2DPolygon aPoly;
     439      158086 :         aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
     440      882416 :         for( sal_uLong i = 1; i < nPoints; i++ )
     441      724330 :             aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
     442      158086 :         aPoly.setClosed( false );
     443      158086 :         ensureClip(); // FIXME: for ...
     444      158086 :         m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
     445             :     }
     446      158086 :     dbgOut( m_aDevice );
     447      158086 : }
     448             : 
     449     1760630 : void SvpSalGraphics::drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry )
     450             : {
     451     1760630 :     if ((m_bUseLineColor || m_bUseFillColor) && nPoints && m_aDevice)
     452             :     {
     453     1760630 :         basegfx::B2DPolygon aPoly;
     454     1760630 :         aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
     455     8584363 :         for( sal_uLong i = 1; i < nPoints; i++ )
     456     6823733 :             aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
     457     1760630 :         ensureClip(); // FIXME: for ...
     458     1760630 :         if( m_bUseFillColor )
     459             :         {
     460     1759567 :             aPoly.setClosed( true );
     461     1759567 :             m_aDevice->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly), m_aFillColor, m_aDrawMode, m_aClipMap );
     462             :         }
     463     1760630 :         if( m_bUseLineColor )
     464             :         {
     465       10827 :             aPoly.setClosed( false );
     466       10827 :             m_aDevice->drawPolygon( aPoly, m_aLineColor, m_aDrawMode, m_aClipMap );
     467     1760630 :         }
     468             :     }
     469     1760630 :     dbgOut( m_aDevice );
     470     1760630 : }
     471             : 
     472        3390 : void SvpSalGraphics::drawPolyPolygon( sal_uInt32 nPoly,
     473             :                                       const sal_uInt32* pPointCounts,
     474             :                                       PCONSTSALPOINT*   pPtAry )
     475             : {
     476        3390 :     if ((m_bUseLineColor || m_bUseFillColor) && nPoly && m_aDevice)
     477             :     {
     478        3390 :         basegfx::B2DPolyPolygon aPolyPoly;
     479       19727 :         for( sal_uInt32 nPolygon = 0; nPolygon < nPoly; nPolygon++ )
     480             :         {
     481       16337 :             sal_uInt32 nPoints = pPointCounts[nPolygon];
     482       16337 :             if( nPoints )
     483             :             {
     484       16337 :                 PCONSTSALPOINT pPoints = pPtAry[nPolygon];
     485       16337 :                 basegfx::B2DPolygon aPoly;
     486       16337 :                 aPoly.append( basegfx::B2DPoint( pPoints->mnX, pPoints->mnY ), nPoints );
     487      205671 :                 for( sal_uInt32 i = 1; i < nPoints; i++ )
     488      189334 :                     aPoly.setB2DPoint( i, basegfx::B2DPoint( pPoints[i].mnX, pPoints[i].mnY ) );
     489             : 
     490       16337 :                 aPolyPoly.append( aPoly );
     491             :             }
     492             :         }
     493        3390 :         ensureClip(); // FIXME: for ...
     494        3390 :         if( m_bUseFillColor )
     495             :         {
     496        3390 :             aPolyPoly.setClosed( true );
     497        3390 :             m_aDevice->fillPolyPolygon( aPolyPoly, m_aFillColor, m_aDrawMode, m_aClipMap );
     498             :         }
     499        3390 :         if( m_bUseLineColor )
     500             :         {
     501          87 :             aPolyPoly.setClosed( false );
     502          87 :             nPoly = aPolyPoly.count();
     503        1875 :             for( sal_uInt32 i = 0; i < nPoly; i++ )
     504        1788 :                 m_aDevice->drawPolygon( aPolyPoly.getB2DPolygon(i), m_aLineColor, m_aDrawMode, m_aClipMap );
     505        3390 :         }
     506             :     }
     507        3390 :     dbgOut( m_aDevice );
     508        3390 : }
     509             : 
     510           0 : bool SvpSalGraphics::drawPolyLine(
     511             :     const ::basegfx::B2DPolygon&,
     512             :     double /*fTransparency*/,
     513             :     const ::basegfx::B2DVector& /*rLineWidths*/,
     514             :     basegfx::B2DLineJoin /*eJoin*/,
     515             :     com::sun::star::drawing::LineCap /*eLineCap*/)
     516             : {
     517             :     // TODO: implement and advertise OutDevSupport_B2DDraw support
     518           0 :     return false;
     519             : }
     520             : 
     521           0 : bool SvpSalGraphics::drawPolyLineBezier( sal_uInt32,
     522             :                                          const SalPoint*,
     523             :                                          const sal_uInt8* )
     524             : {
     525           0 :     return false;
     526             : }
     527             : 
     528        9540 : bool SvpSalGraphics::drawPolygonBezier( sal_uInt32,
     529             :                                         const SalPoint*,
     530             :                                         const sal_uInt8* )
     531             : {
     532        9540 :     return false;
     533             : }
     534             : 
     535        2852 : bool SvpSalGraphics::drawPolyPolygonBezier( sal_uInt32,
     536             :                                             const sal_uInt32*,
     537             :                                             const SalPoint* const*,
     538             :                                             const sal_uInt8* const* )
     539             : {
     540        2852 :     return false;
     541             : }
     542             : 
     543           0 : bool SvpSalGraphics::drawPolyPolygon( const basegfx::B2DPolyPolygon&, double /*fTransparency*/ )
     544             : {
     545             :     // TODO: maybe BaseBmp can draw B2DPolyPolygons directly
     546           0 :     return false;
     547             : }
     548             : 
     549         311 : void SvpSalGraphics::copyArea( long nDestX,
     550             :                                       long nDestY,
     551             :                                       long nSrcX,
     552             :                                       long nSrcY,
     553             :                                       long nSrcWidth,
     554             :                                       long nSrcHeight,
     555             :                                       sal_uInt16 /*nFlags*/ )
     556             : {
     557         311 :     basegfx::B2IBox aSrcRect( nSrcX, nSrcY, nSrcX+nSrcWidth, nSrcY+nSrcHeight );
     558         311 :     basegfx::B2IBox aDestRect( nDestX, nDestY, nDestX+nSrcWidth, nDestY+nSrcHeight );
     559             :     // fprintf( stderr, "copyArea %ld pixels - clip region %d\n",
     560             :     //         (long)(nSrcWidth * nSrcHeight), m_aClipMap.get() != NULL );
     561         311 :     SvpSalGraphics::ClipUndoHandle aUndo( this );
     562         311 :     if( !isClippedSetup( aDestRect, aUndo ) )
     563         311 :         m_aDevice->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode::Paint, m_aClipMap );
     564         311 :     dbgOut( m_aDevice );
     565         311 : }
     566             : 
     567       96244 : void SvpSalGraphics::copyBits( const SalTwoRect& rPosAry,
     568             :                                SalGraphics*      pSrcGraphics )
     569             : {
     570       96244 :     if( !m_aDevice.get() )
     571       96244 :         return;
     572             : 
     573             :     SvpSalGraphics* pSrc = pSrcGraphics ?
     574       96244 :         static_cast<SvpSalGraphics*>(pSrcGraphics) : this;
     575             :     basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
     576             :                      rPosAry.mnSrcX+rPosAry.mnSrcWidth,
     577       96244 :                      rPosAry.mnSrcY+rPosAry.mnSrcHeight );
     578             :     basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
     579             :                       rPosAry.mnDestX+rPosAry.mnDestWidth,
     580       96244 :                       rPosAry.mnDestY+rPosAry.mnDestHeight );
     581             : 
     582       96244 :     SvpSalGraphics::ClipUndoHandle aUndo( this );
     583       96244 :     if( !isClippedSetup( aDestRect, aUndo ) )
     584       96242 :         m_aDevice->drawBitmap( pSrc->m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode::Paint, m_aClipMap );
     585       96244 :     dbgOut( m_aDevice );
     586             : }
     587             : 
     588      169665 : void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
     589             :                                  const SalBitmap& rSalBitmap )
     590             : {
     591      169665 :     if( !m_aDevice.get() )
     592      169665 :         return;
     593             : 
     594      169665 :     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
     595             :     basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
     596             :                      rPosAry.mnSrcX+rPosAry.mnSrcWidth,
     597      169665 :                      rPosAry.mnSrcY+rPosAry.mnSrcHeight );
     598             :     basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
     599             :                       rPosAry.mnDestX+rPosAry.mnDestWidth,
     600      169665 :                       rPosAry.mnDestY+rPosAry.mnDestHeight );
     601             : 
     602      169665 :     SvpSalGraphics::ClipUndoHandle aUndo( this );
     603      169665 :     if( !isClippedSetup( aDestRect, aUndo ) )
     604      166110 :         m_aDevice->drawBitmap( rSrc.getBitmap(), aSrcRect, aDestRect, basebmp::DrawMode::Paint, m_aClipMap );
     605      169665 :     dbgOut( m_aDevice );
     606             : }
     607             : 
     608           0 : void SvpSalGraphics::drawBitmap( const SalTwoRect&,
     609             :                                  const SalBitmap&,
     610             :                                  SalColor )
     611             : {
     612             :     // SNI, as in X11 plugin
     613           0 : }
     614             : 
     615       12349 : void SvpSalGraphics::drawBitmap( const SalTwoRect& rPosAry,
     616             :                                  const SalBitmap& rSalBitmap,
     617             :                                  const SalBitmap& rTransparentBitmap )
     618             : {
     619       12349 :     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
     620       12349 :     const SvpSalBitmap& rSrcTrans = static_cast<const SvpSalBitmap&>(rTransparentBitmap);
     621             :     basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
     622             :                      rPosAry.mnSrcX+rPosAry.mnSrcWidth,
     623       12349 :                      rPosAry.mnSrcY+rPosAry.mnSrcHeight );
     624             :     basegfx::B2IBox aDestRect( rPosAry.mnDestX, rPosAry.mnDestY,
     625             :                       rPosAry.mnDestX+rPosAry.mnDestWidth,
     626       12349 :                       rPosAry.mnDestY+rPosAry.mnDestHeight );
     627       12349 :     SvpSalGraphics::ClipUndoHandle aUndo( this );
     628       12349 :     if (!isClippedSetup(aDestRect, aUndo) && m_aDevice)
     629       12349 :         m_aDevice->drawMaskedBitmap( rSrc.getBitmap(), rSrcTrans.getBitmap(),
     630       24698 :                                      aSrcRect, aDestRect, basebmp::DrawMode::Paint, m_aClipMap );
     631       12349 :     dbgOut( m_aDevice );
     632       12349 : }
     633             : 
     634           9 : void SvpSalGraphics::drawMask( const SalTwoRect& rPosAry,
     635             :                                const SalBitmap& rSalBitmap,
     636             :                                SalColor nMaskColor )
     637             : {
     638           9 :     const SvpSalBitmap& rSrc = static_cast<const SvpSalBitmap&>(rSalBitmap);
     639             :     basegfx::B2IBox aSrcRect( rPosAry.mnSrcX, rPosAry.mnSrcY,
     640             :                      rPosAry.mnSrcX+rPosAry.mnSrcWidth,
     641           9 :                      rPosAry.mnSrcY+rPosAry.mnSrcHeight );
     642           9 :     basegfx::B2IPoint aDestPoint( rPosAry.mnDestX, rPosAry.mnDestY );
     643             : 
     644             :     // BitmapDevice::drawMaskedColor works with 0==transparent,
     645             :     // 255==opaque. drawMask() semantic is the other way
     646             :     // around. Therefore, invert mask.
     647             :     basebmp::BitmapDeviceSharedPtr aCopy =
     648             :         cloneBitmapDevice( basegfx::B2IVector( rPosAry.mnSrcWidth, rPosAry.mnSrcHeight ),
     649          18 :                            rSrc.getBitmap() );
     650           9 :     basebmp::Color aBgColor( COL_WHITE );
     651           9 :     aCopy->clear(aBgColor);
     652           9 :     basebmp::Color aFgColor( COL_BLACK );
     653           9 :     aCopy->drawMaskedColor( aFgColor, rSrc.getBitmap(), aSrcRect, basegfx::B2IPoint() );
     654             : 
     655           9 :     basebmp::Color aColor( nMaskColor );
     656           9 :     basegfx::B2IBox aSrcRect2( 0, 0, rPosAry.mnSrcWidth, rPosAry.mnSrcHeight );
     657           9 :     const basegfx::B2IBox aClipRect( aDestPoint, basegfx::B2ITuple( aSrcRect.getWidth(), aSrcRect.getHeight() ) );
     658             : 
     659          18 :     SvpSalGraphics::ClipUndoHandle aUndo( this );
     660           9 :     if( !isClippedSetup( aClipRect, aUndo ) )
     661           9 :         m_aDevice->drawMaskedColor( aColor, aCopy, aSrcRect, aDestPoint, m_aClipMap );
     662          18 :     dbgOut( m_aDevice );
     663           9 : }
     664             : 
     665      176031 : SalBitmap* SvpSalGraphics::getBitmap( long nX, long nY, long nWidth, long nHeight )
     666             : {
     667      176031 :     SvpSalBitmap* pBitmap = new SvpSalBitmap();
     668             : 
     669      176031 :     if (m_aDevice)
     670             :     {
     671      176031 :         basebmp::BitmapDeviceSharedPtr aCopy;
     672      352062 :         aCopy = cloneBitmapDevice(basegfx::B2IVector(nWidth, nHeight),
     673      176031 :                                    m_aDevice);
     674      176031 :         basegfx::B2IBox aSrcRect( nX, nY, nX+nWidth, nY+nHeight );
     675      176031 :         basegfx::B2IBox aDestRect( 0, 0, nWidth, nHeight );
     676             : 
     677      176031 :         aCopy->drawBitmap( m_aOrigDevice, aSrcRect, aDestRect, basebmp::DrawMode::Paint );
     678             : 
     679      176031 :         pBitmap->setBitmap( aCopy );
     680             :     }
     681             : 
     682      176031 :     return pBitmap;
     683             : }
     684             : 
     685           4 : SalColor SvpSalGraphics::getPixel( long nX, long nY )
     686             : {
     687           4 :     basebmp::Color aColor( m_aOrigDevice->getPixel( basegfx::B2IPoint( nX, nY ) ) );
     688           4 :     return aColor.toInt32();
     689             : }
     690             : 
     691       62345 : void SvpSalGraphics::invert( long nX, long nY, long nWidth, long nHeight, SalInvert /*nFlags*/ )
     692             : {
     693             :     // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
     694       62345 :     basegfx::B2DPolygon aRect = basegfx::tools::createPolygonFromRect( basegfx::B2DRectangle( nX, nY, nX+nWidth, nY+nHeight ) );
     695      124690 :     basegfx::B2DPolyPolygon aPolyPoly( aRect );
     696       62345 :     basegfx::B2IBox aDestRange( nX, nY, nX + nWidth, nY + nHeight );
     697             : 
     698      124690 :     SvpSalGraphics::ClipUndoHandle aUndo( this );
     699       62345 :     if( !isClippedSetup( aDestRange, aUndo ) )
     700       62345 :         m_aDevice->fillPolyPolygon( aPolyPoly, basebmp::Color( 0xffffff ), basebmp::DrawMode::XOR, m_aClipMap );
     701      124690 :     dbgOut( m_aDevice );
     702       62345 : }
     703             : 
     704          18 : void SvpSalGraphics::invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert /*nFlags*/ )
     705             : {
     706             :     // FIXME: handle SAL_INVERT_50 and SAL_INVERT_TRACKFRAME
     707          18 :     basegfx::B2DPolygon aPoly;
     708          18 :     aPoly.append( basegfx::B2DPoint( pPtAry->mnX, pPtAry->mnY ), nPoints );
     709         126 :     for( sal_uLong i = 1; i < nPoints; i++ )
     710         108 :         aPoly.setB2DPoint( i, basegfx::B2DPoint( pPtAry[i].mnX, pPtAry[i].mnY ) );
     711          18 :     aPoly.setClosed( true );
     712          18 :     ensureClip(); // FIXME for ...
     713          18 :     m_aDevice->fillPolyPolygon( basegfx::B2DPolyPolygon(aPoly), basebmp::Color( 0xffffff ), basebmp::DrawMode::XOR, m_aClipMap );
     714          18 :     dbgOut( m_aDevice );
     715          18 : }
     716             : 
     717             : #endif
     718             : 
     719           0 : bool SvpSalGraphics::drawEPS( long, long, long, long, void*, sal_uLong )
     720             : {
     721           0 :     return false;
     722             : }
     723             : 
     724             : #ifndef IOS
     725             : 
     726          85 : SystemGraphicsData SvpSalGraphics::GetGraphicsData() const
     727             : {
     728          85 :     return SystemGraphicsData();
     729             : }
     730             : 
     731       22890 : bool SvpSalGraphics::supportsOperation( OutDevSupportType ) const
     732             : {
     733       22890 :     return false;
     734             : }
     735             : 
     736             : #endif
     737             : 
     738           1 : bool SvpSalGraphics::SupportsCairo() const
     739             : {
     740           1 :     return false;
     741             : }
     742             : 
     743           0 : cairo::SurfaceSharedPtr SvpSalGraphics::CreateSurface(const cairo::CairoSurfaceSharedPtr& /*rSurface*/) const
     744             : {
     745           0 :     return cairo::SurfaceSharedPtr();
     746             : }
     747             : 
     748           0 : cairo::SurfaceSharedPtr SvpSalGraphics::CreateSurface(const OutputDevice& /*rRefDevice*/, int /*x*/, int /*y*/, int /*width*/, int /*height*/) const
     749             : {
     750           0 :     return cairo::SurfaceSharedPtr();
     751             : }
     752             : 
     753           0 : cairo::SurfaceSharedPtr SvpSalGraphics::CreateBitmapSurface(const OutputDevice& /*rRefDevice*/, const BitmapSystemData& /*rData*/, const Size& /*rSize*/) const
     754             : {
     755           0 :     return cairo::SurfaceSharedPtr();
     756             : }
     757             : 
     758           0 : css::uno::Any SvpSalGraphics::GetNativeSurfaceHandle(cairo::SurfaceSharedPtr& /*rSurface*/, const basegfx::B2ISize& /*rSize*/) const
     759             : {
     760           0 :     return css::uno::Any();
     761         801 : }
     762             : 
     763             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11