LCOV - code coverage report
Current view: top level - vcl/source/gdi - outdev4.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 231 686 33.7 %
Date: 2012-08-25 Functions: 9 14 64.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 194 1128 17.2 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <tools/debug.hxx>
      31                 :            : #include <tools/line.hxx>
      32                 :            : #include <tools/poly.hxx>
      33                 :            : 
      34                 :            : #include <vcl/gradient.hxx>
      35                 :            : #include <vcl/metaact.hxx>
      36                 :            : #include <vcl/gdimtf.hxx>
      37                 :            : #include <vcl/salbtype.hxx>
      38                 :            : #include <vcl/hatch.hxx>
      39                 :            : #include <vcl/window.hxx>
      40                 :            : #include <vcl/virdev.hxx>
      41                 :            : #include <vcl/outdev.hxx>
      42                 :            : 
      43                 :            : #include "pdfwriter_impl.hxx"
      44                 :            : 
      45                 :            : #include "window.h"
      46                 :            : #include "salframe.hxx"
      47                 :            : #include "salgdi.hxx"
      48                 :            : #include "svdata.hxx"
      49                 :            : #include "outdata.hxx"
      50                 :            : 
      51                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      52                 :            : #include <basegfx/polygon/b2dpolypolygon.hxx>
      53                 :            : #include <basegfx/matrix/b2dhommatrix.hxx>
      54                 :            : 
      55                 :            : // -----------
      56                 :            : // - Defines -
      57                 :            : // -----------
      58                 :            : 
      59                 :            : #define HATCH_MAXPOINTS             1024
      60                 :            : #define GRADIENT_DEFAULT_STEPCOUNT  0
      61                 :            : 
      62                 :            : // ----------------
      63                 :            : // - Cmp-Function -
      64                 :            : // ----------------
      65                 :            : 
      66                 :      31724 : extern "C" int __LOADONCALLAPI ImplHatchCmpFnc( const void* p1, const void* p2 )
      67                 :            : {
      68                 :      31724 :     const long nX1 = ( (Point*) p1 )->X();
      69                 :      31724 :     const long nX2 = ( (Point*) p2 )->X();
      70                 :      31724 :     const long nY1 = ( (Point*) p1 )->Y();
      71                 :      31724 :     const long nY2 = ( (Point*) p2 )->Y();
      72                 :            : 
      73 [ #  # ][ #  # ]:      31724 :     return ( nX1 > nX2 ? 1 : nX1 == nX2 ? nY1 > nY2 ? 1: nY1 == nY2 ? 0 : -1 : -1 );
         [ #  # ][ -  + ]
      74                 :            : }
      75                 :            : 
      76                 :            : // =======================================================================
      77                 :            : 
      78                 :            : DBG_NAMEEX( OutputDevice )
      79                 :            : DBG_NAMEEX( Gradient )
      80                 :            : 
      81                 :            : // =======================================================================
      82                 :            : 
      83                 :    2321362 : void OutputDevice::ImplDrawPolygon( const Polygon& rPoly, const PolyPolygon* pClipPolyPoly )
      84                 :            : {
      85         [ -  + ]:    2321362 :     if( pClipPolyPoly )
      86         [ #  # ]:          0 :         ImplDrawPolyPolygon( rPoly, pClipPolyPoly );
      87                 :            :     else
      88                 :            :     {
      89                 :    2321362 :         sal_uInt16 nPoints = rPoly.GetSize();
      90                 :            : 
      91         [ -  + ]:    2321362 :         if ( nPoints < 2 )
      92                 :    2321362 :             return;
      93                 :            : 
      94                 :    2321362 :         const SalPoint* pPtAry = (const SalPoint*)rPoly.GetConstPointAry();
      95                 :    2321362 :         mpGraphics->DrawPolygon( nPoints, pPtAry, this );
      96                 :            :     }
      97                 :            : }
      98                 :            : 
      99                 :            : // -----------------------------------------------------------------------
     100                 :            : 
     101                 :          0 : void OutputDevice::ImplDrawPolyPolygon( const PolyPolygon& rPolyPoly, const PolyPolygon* pClipPolyPoly )
     102                 :            : {
     103                 :            :     PolyPolygon* pPolyPoly;
     104                 :            : 
     105         [ #  # ]:          0 :     if( pClipPolyPoly )
     106                 :            :     {
     107         [ #  # ]:          0 :         pPolyPoly = new PolyPolygon;
     108                 :          0 :         rPolyPoly.GetIntersection( *pClipPolyPoly, *pPolyPoly );
     109                 :            :     }
     110                 :            :     else
     111                 :          0 :         pPolyPoly = (PolyPolygon*) &rPolyPoly;
     112                 :            : 
     113         [ #  # ]:          0 :     if( pPolyPoly->Count() == 1 )
     114                 :            :     {
     115 [ #  # ][ #  # ]:          0 :         const Polygon   rPoly = pPolyPoly->GetObject( 0 );
     116         [ #  # ]:          0 :         sal_uInt16          nSize = rPoly.GetSize();
     117                 :            : 
     118         [ #  # ]:          0 :         if( nSize >= 2 )
     119                 :            :         {
     120         [ #  # ]:          0 :             const SalPoint* pPtAry = (const SalPoint*)rPoly.GetConstPointAry();
     121         [ #  # ]:          0 :             mpGraphics->DrawPolygon( nSize, pPtAry, this );
     122         [ #  # ]:          0 :         }
     123                 :            :     }
     124         [ #  # ]:          0 :     else if( pPolyPoly->Count() )
     125                 :            :     {
     126                 :          0 :         sal_uInt16              nCount = pPolyPoly->Count();
     127                 :          0 :         sal_uInt32*         pPointAry = new sal_uInt32[nCount];
     128                 :          0 :         PCONSTSALPOINT*     pPointAryAry = new PCONSTSALPOINT[nCount];
     129                 :          0 :         sal_uInt16              i = 0;
     130         [ #  # ]:          0 :         do
     131                 :            :         {
     132                 :          0 :             const Polygon&  rPoly = pPolyPoly->GetObject( i );
     133                 :          0 :             sal_uInt16          nSize = rPoly.GetSize();
     134         [ #  # ]:          0 :             if ( nSize )
     135                 :            :             {
     136                 :          0 :                 pPointAry[i]    = nSize;
     137                 :          0 :                 pPointAryAry[i] = (PCONSTSALPOINT)rPoly.GetConstPointAry();
     138                 :          0 :                 i++;
     139                 :            :             }
     140                 :            :             else
     141                 :          0 :                 nCount--;
     142                 :            :         }
     143                 :            :         while( i < nCount );
     144                 :            : 
     145         [ #  # ]:          0 :         if( nCount == 1 )
     146                 :          0 :             mpGraphics->DrawPolygon( *pPointAry, *pPointAryAry, this );
     147                 :            :         else
     148                 :          0 :             mpGraphics->DrawPolyPolygon( nCount, pPointAry, pPointAryAry, this );
     149                 :            : 
     150         [ #  # ]:          0 :         delete[] pPointAry;
     151         [ #  # ]:          0 :         delete[] pPointAryAry;
     152                 :            :     }
     153                 :            : 
     154         [ #  # ]:          0 :     if( pClipPolyPoly )
     155         [ #  # ]:          0 :         delete pPolyPoly;
     156                 :          0 : }
     157                 :            : 
     158                 :            : // -----------------------------------------------------------------------
     159                 :            : 
     160                 :    6922431 : inline sal_uInt8 ImplGetGradientColorValue( long nValue )
     161                 :            : {
     162         [ -  + ]:    6922431 :     if ( nValue < 0 )
     163                 :          0 :         return 0;
     164         [ -  + ]:    6922431 :     else if ( nValue > 0xFF )
     165                 :          0 :         return 0xFF;
     166                 :            :     else
     167                 :    6922431 :         return (sal_uInt8)nValue;
     168                 :            : }
     169                 :            : 
     170                 :            : // -----------------------------------------------------------------------
     171                 :            : 
     172                 :     112334 : void OutputDevice::ImplDrawLinearGradient( const Rectangle& rRect,
     173                 :            :                                            const Gradient& rGradient,
     174                 :            :                                            sal_Bool bMtf, const PolyPolygon* pClipPolyPoly )
     175                 :            : {
     176                 :            :     // rotiertes BoundRect ausrechnen
     177         [ +  - ]:     112334 :     Rectangle aRect;
     178                 :     112334 :     Point     aCenter;
     179                 :     112334 :     sal_uInt16    nAngle = rGradient.GetAngle() % 3600;
     180                 :            : 
     181         [ +  - ]:     112334 :     rGradient.GetBoundRect( rRect, aRect, aCenter );
     182                 :            : 
     183                 :            :     // Rand berechnen und Rechteck neu setzen
     184                 :     112334 :     Rectangle   aFullRect = aRect;
     185         [ +  - ]:     112334 :     long        nBorder = (long)rGradient.GetBorder() * aRect.GetHeight() / 100;
     186                 :            : 
     187                 :            :     // Rand berechnen und Rechteck neu setzen fuer linearen Farbverlauf
     188                 :     112334 :     bool bLinear = (rGradient.GetStyle() == GradientStyle_LINEAR);
     189         [ +  - ]:     112334 :     if ( bLinear )
     190                 :            :     {
     191                 :     112334 :         aRect.Top() += nBorder;
     192                 :            :     }
     193                 :            :     // Rand berechnen und Rechteck neu setzen fuer axiale Farbverlauf
     194                 :            :     else
     195                 :            :     {
     196                 :          0 :         nBorder >>= 1;
     197                 :            : 
     198                 :          0 :         aRect.Top()    += nBorder;
     199                 :          0 :         aRect.Bottom() -= nBorder;
     200                 :            :     }
     201                 :            : 
     202                 :            :     // Top darf nicht groesser als Bottom sein
     203                 :     112334 :     aRect.Top() = Min( aRect.Top(), (long)(aRect.Bottom() - 1) );
     204                 :            : 
     205         [ +  - ]:     112334 :     long nMinRect = aRect.GetHeight();
     206                 :            : 
     207                 :            :     // Intensitaeten von Start- und Endfarbe ggf. aendern und
     208                 :            :     // Farbschrittweiten berechnen
     209                 :            :     long            nFactor;
     210                 :     112334 :     Color           aStartCol   = rGradient.GetStartColor();
     211                 :     112334 :     Color           aEndCol     = rGradient.GetEndColor();
     212                 :     112334 :     long            nStartRed   = aStartCol.GetRed();
     213                 :     112334 :     long            nStartGreen = aStartCol.GetGreen();
     214                 :     112334 :     long            nStartBlue  = aStartCol.GetBlue();
     215                 :     112334 :     long            nEndRed     = aEndCol.GetRed();
     216                 :     112334 :     long            nEndGreen   = aEndCol.GetGreen();
     217                 :     112334 :     long            nEndBlue    = aEndCol.GetBlue();
     218                 :     112334 :                     nFactor     = rGradient.GetStartIntensity();
     219                 :     112334 :                     nStartRed   = (nStartRed   * nFactor) / 100;
     220                 :     112334 :                     nStartGreen = (nStartGreen * nFactor) / 100;
     221                 :     112334 :                     nStartBlue  = (nStartBlue  * nFactor) / 100;
     222                 :     112334 :                     nFactor     = rGradient.GetEndIntensity();
     223                 :     112334 :                     nEndRed     = (nEndRed   * nFactor) / 100;
     224                 :     112334 :                     nEndGreen   = (nEndGreen * nFactor) / 100;
     225                 :     112334 :                     nEndBlue    = (nEndBlue  * nFactor) / 100;
     226                 :     112334 :     long            nRedSteps   = nEndRed   - nStartRed;
     227                 :     112334 :     long            nGreenSteps = nEndGreen - nStartGreen;
     228                 :     112334 :     long            nBlueSteps  = nEndBlue  - nStartBlue;
     229                 :     112334 :     long            nStepCount = rGradient.GetSteps();
     230                 :            : 
     231                 :            :     // Bei nicht linearen Farbverlaeufen haben wir nur die halben Steps
     232                 :            :     // pro Farbe
     233         [ -  + ]:     112334 :     if ( !bLinear )
     234                 :            :     {
     235                 :          0 :         nRedSteps   <<= 1;
     236                 :          0 :         nGreenSteps <<= 1;
     237                 :          0 :         nBlueSteps  <<= 1;
     238                 :            :     }
     239                 :            : 
     240                 :            :     // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
     241         [ +  - ]:     112334 :     if ( !nStepCount )
     242                 :            :     {
     243                 :            :         long nInc;
     244                 :            : 
     245 [ +  - ][ +  - ]:     112334 :         if ( meOutDevType != OUTDEV_PRINTER && !bMtf )
     246                 :            :         {
     247         [ +  + ]:     112334 :             nInc = (nMinRect < 50) ? 2 : 4;
     248                 :            :         }
     249                 :            :         else
     250                 :            :         {
     251                 :            :             // #105998# Use display-equivalent step size calculation
     252         [ #  # ]:          0 :             nInc = (nMinRect < 800) ? 10 : 20;
     253                 :            :         }
     254                 :            : 
     255         [ -  + ]:     112334 :         if ( !nInc )
     256                 :          0 :             nInc = 1;
     257                 :            : 
     258                 :     112334 :         nStepCount = nMinRect / nInc;
     259                 :            :     }
     260                 :            :     // minimal drei Schritte und maximal die Anzahl der Farbunterschiede
     261                 :     112334 :     long nSteps = Max( nStepCount, 2L );
     262                 :     112334 :     long nCalcSteps  = Abs( nRedSteps );
     263                 :     112334 :     long nTempSteps = Abs( nGreenSteps );
     264         [ -  + ]:     112334 :     if ( nTempSteps > nCalcSteps )
     265                 :          0 :         nCalcSteps = nTempSteps;
     266                 :     112334 :     nTempSteps = Abs( nBlueSteps );
     267         [ -  + ]:     112334 :     if ( nTempSteps > nCalcSteps )
     268                 :          0 :         nCalcSteps = nTempSteps;
     269         [ +  + ]:     112334 :     if ( nCalcSteps < nSteps )
     270                 :       4501 :         nSteps = nCalcSteps;
     271         [ +  + ]:     112334 :     if ( !nSteps )
     272                 :         43 :         nSteps = 1;
     273                 :            : 
     274                 :            :     // Falls axialer Farbverlauf, muss die Schrittanzahl ungerade sein
     275 [ -  + ][ #  # ]:     112334 :     if ( !bLinear && !(nSteps & 1) )
     276                 :          0 :         nSteps++;
     277                 :            : 
     278                 :            :     // Berechnung ueber Double-Addition wegen Genauigkeit
     279                 :     112334 :     double fScanLine = aRect.Top();
     280         [ +  - ]:     112334 :     double fScanInc  = (double)aRect.GetHeight() / (double)nSteps;
     281                 :            : 
     282                 :            :     // Startfarbe berechnen und setzen
     283                 :            :     sal_uInt8   nRed;
     284                 :            :     sal_uInt8   nGreen;
     285                 :            :     sal_uInt8   nBlue;
     286                 :            :     long    nSteps2;
     287                 :     112334 :     long    nStepsHalf = 0;
     288         [ +  - ]:     112334 :     if ( bLinear )
     289                 :            :     {
     290                 :            :         // Um 1 erhoeht, um die Border innerhalb der Schleife
     291                 :            :         // zeichnen zu koennen
     292                 :     112334 :         nSteps2     = nSteps + 1;
     293                 :     112334 :         nRed        = (sal_uInt8)nStartRed;
     294                 :     112334 :         nGreen      = (sal_uInt8)nStartGreen;
     295                 :     112334 :         nBlue       = (sal_uInt8)nStartBlue;
     296                 :            :     }
     297                 :            :     else
     298                 :            :     {
     299                 :            :         // Um 2 erhoeht, um die Border innerhalb der Schleife
     300                 :            :         // zeichnen zu koennen
     301                 :          0 :         nSteps2     = nSteps + 2;
     302                 :          0 :         nRed        = (sal_uInt8)nEndRed;
     303                 :          0 :         nGreen      = (sal_uInt8)nEndGreen;
     304                 :          0 :         nBlue       = (sal_uInt8)nEndBlue;
     305                 :          0 :         nStepsHalf  = nSteps >> 1;
     306                 :            :     }
     307                 :            : 
     308         [ -  + ]:     112334 :     if ( bMtf )
     309 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), sal_True ) );
                 [ #  # ]
     310                 :            :     else
     311         [ +  - ]:     112334 :         mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
     312                 :            : 
     313                 :            :     // Startpolygon erzeugen (== Borderpolygon)
     314         [ +  - ]:     112334 :     Polygon     aPoly( 4 );
     315         [ +  - ]:     112334 :     Polygon     aTempPoly( 2 );
     316         [ +  - ]:     112334 :     Polygon     aTempPoly2( 2 );
     317                 :            :     /* n#710061 Use overlapping fills to avoid color
     318                 :            :      * leak via gaps in some pdf viewers
     319                 :            :      */
     320                 :     112334 :     Point       aOverLap( 0, fScanInc*.1 );
     321         [ +  - ]:     112334 :     aPoly[0] = aFullRect.TopLeft();
     322 [ +  - ][ +  - ]:     112334 :     aPoly[1] = aFullRect.TopRight();
     323 [ +  - ][ +  - ]:     112334 :     aPoly[2] = aRect.TopRight();
     324         [ +  - ]:     112334 :     aPoly[3] = aRect.TopLeft();
     325         [ +  - ]:     112334 :     aPoly.Rotate( aCenter, nAngle );
     326 [ +  - ][ +  - ]:     112334 :     aTempPoly[0] = aPoly[3];
     327 [ +  - ][ +  - ]:     112334 :     aTempPoly[1] = aPoly[2];
     328                 :            : 
     329                 :            : 
     330                 :            :     // Schleife, um rotierten Verlauf zu fuellen
     331         [ +  + ]:    2419811 :     for ( long i = 0; i < nSteps2; i++ )
     332                 :            :     {
     333                 :            :         // berechnetesPolygon ausgeben
     334         [ -  + ]:    2307477 :         if ( bMtf )
     335 [ #  # ][ #  # ]:          0 :             mpMetaFile->AddAction( new MetaPolygonAction( aPoly ) );
                 [ #  # ]
     336                 :            :         else
     337         [ +  - ]:    2307477 :             ImplDrawPolygon( aPoly, pClipPolyPoly );
     338                 :            : 
     339                 :            :         // neues Polygon berechnen
     340                 :    2307477 :         aRect.Top() = (long)(fScanLine += fScanInc);
     341                 :            : 
     342 [ +  - ][ +  - ]:    2307477 :         aPoly[0] = aTempPoly[0];
     343 [ +  - ][ +  - ]:    2307477 :         aPoly[1] = aTempPoly[1];
     344                 :            :         // unteren Rand komplett fuellen
     345         [ +  + ]:    2307477 :         if ( i == nSteps )
     346                 :            :         {
     347 [ +  - ][ +  - ]:     112334 :             aTempPoly[0] = aFullRect.BottomLeft();
     348 [ +  - ][ +  - ]:     112334 :             aTempPoly[1] = aFullRect.BottomRight();
     349         [ +  - ]:     112334 :             aTempPoly2   = aTempPoly;
     350                 :            :         }
     351                 :            :         else
     352                 :            :         {
     353         [ +  - ]:    2195143 :             aTempPoly[0] = aRect.TopLeft();
     354 [ +  - ][ +  - ]:    2195143 :             aTempPoly[1] = aRect.TopRight();
     355 [ +  - ][ +  - ]:    2195143 :             aTempPoly2[0]= aTempPoly[0] + aOverLap;
     356 [ +  - ][ +  - ]:    2195143 :             aTempPoly2[1]= aTempPoly[1] + aOverLap;
     357                 :            :         }
     358         [ +  - ]:    2307477 :         aTempPoly2.Rotate( aCenter, nAngle );
     359         [ +  - ]:    2307477 :         aTempPoly.Rotate( aCenter, nAngle );
     360                 :            : 
     361 [ +  - ][ +  - ]:    2307477 :         aPoly[2] = aTempPoly2[1];
     362 [ +  - ][ +  - ]:    2307477 :         aPoly[3] = aTempPoly2[0];
     363                 :            : 
     364                 :            :         // Farbintensitaeten aendern...
     365                 :            :         // fuer lineare FV
     366         [ +  - ]:    2307477 :         if ( bLinear )
     367                 :            :         {
     368                 :    2307477 :             nRed    = ImplGetGradientColorValue( nStartRed+((nRedSteps*i)/nSteps2) );
     369                 :    2307477 :             nGreen  = ImplGetGradientColorValue( nStartGreen+((nGreenSteps*i)/nSteps2) );
     370                 :    2307477 :             nBlue   = ImplGetGradientColorValue( nStartBlue+((nBlueSteps*i)/nSteps2) );
     371                 :            :         }
     372                 :            :         // fuer radiale FV
     373                 :            :         else
     374                 :            :         {
     375                 :            :             // fuer axiale FV muss die letzte Farbe der ersten
     376                 :            :             // Farbe entsprechen
     377                 :            :             // #107350# Setting end color one step earlier, as the
     378                 :            :             // last time we get here, we drop out of the loop later
     379                 :            :             // on.
     380         [ #  # ]:          0 :             if ( i >= nSteps )
     381                 :            :             {
     382                 :          0 :                 nRed    = (sal_uInt8)nEndRed;
     383                 :          0 :                 nGreen  = (sal_uInt8)nEndGreen;
     384                 :          0 :                 nBlue   = (sal_uInt8)nEndBlue;
     385                 :            :             }
     386                 :            :             else
     387                 :            :             {
     388         [ #  # ]:          0 :                 if ( i <= nStepsHalf )
     389                 :            :                 {
     390                 :          0 :                     nRed    = ImplGetGradientColorValue( nEndRed-((nRedSteps*i)/nSteps2) );
     391                 :          0 :                     nGreen  = ImplGetGradientColorValue( nEndGreen-((nGreenSteps*i)/nSteps2) );
     392                 :          0 :                     nBlue   = ImplGetGradientColorValue( nEndBlue-((nBlueSteps*i)/nSteps2) );
     393                 :            :                 }
     394                 :            :                 // genau die Mitte und hoeher
     395                 :            :                 else
     396                 :            :                 {
     397                 :          0 :                     long i2 = i - nStepsHalf;
     398                 :          0 :                     nRed    = ImplGetGradientColorValue( nStartRed+((nRedSteps*i2)/nSteps2) );
     399                 :          0 :                     nGreen  = ImplGetGradientColorValue( nStartGreen+((nGreenSteps*i2)/nSteps2) );
     400                 :          0 :                     nBlue   = ImplGetGradientColorValue( nStartBlue+((nBlueSteps*i2)/nSteps2) );
     401                 :            :                 }
     402                 :            :             }
     403                 :            :         }
     404                 :            : 
     405         [ -  + ]:    2307477 :         if ( bMtf )
     406 [ #  # ][ #  # ]:          0 :             mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), sal_True ) );
                 [ #  # ]
     407                 :            :         else
     408         [ +  - ]:    2307477 :             mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
     409 [ +  - ][ +  - ]:     112334 :     }
                 [ +  - ]
     410                 :     112334 : }
     411                 :            : 
     412                 :            : // -----------------------------------------------------------------------
     413                 :            : 
     414                 :          0 : void OutputDevice::ImplDrawComplexGradient( const Rectangle& rRect,
     415                 :            :                                             const Gradient& rGradient,
     416                 :            :                                             sal_Bool bMtf, const PolyPolygon* pClipPolyPoly )
     417                 :            : {
     418                 :            :     // Feststellen ob Ausgabe ueber Polygon oder PolyPolygon
     419                 :            :     // Bei Rasteroperationen ungleich Overpaint immer PolyPolygone,
     420                 :            :     // da es zu falschen Ergebnissen kommt, wenn man mehrfach uebereinander
     421                 :            :     // ausgibt
     422                 :            :     // Bei Druckern auch immer PolyPolygone, da nicht alle Drucker
     423                 :            :     // das Uebereinanderdrucken von Polygonen koennen
     424                 :            :     // Virtuelle Device werden auch ausgeklammert, da einige Treiber
     425                 :            :     // ansonsten zu langsam sind
     426                 :            :     PolyPolygon*    pPolyPoly;
     427         [ #  # ]:          0 :     Rectangle       aRect;
     428                 :          0 :     Point           aCenter;
     429                 :          0 :     Color           aStartCol( rGradient.GetStartColor() );
     430                 :          0 :     Color           aEndCol( rGradient.GetEndColor() );
     431                 :          0 :     long            nStartRed = ( (long) aStartCol.GetRed() * rGradient.GetStartIntensity() ) / 100;
     432                 :          0 :     long            nStartGreen = ( (long) aStartCol.GetGreen() * rGradient.GetStartIntensity() ) / 100;
     433                 :          0 :     long            nStartBlue = ( (long) aStartCol.GetBlue() * rGradient.GetStartIntensity() ) / 100;
     434                 :          0 :     long            nEndRed = ( (long) aEndCol.GetRed() * rGradient.GetEndIntensity() ) / 100;
     435                 :          0 :     long            nEndGreen = ( (long) aEndCol.GetGreen() * rGradient.GetEndIntensity() ) / 100;
     436                 :          0 :     long            nEndBlue = ( (long) aEndCol.GetBlue() * rGradient.GetEndIntensity() ) / 100;
     437                 :          0 :     long            nRedSteps = nEndRed - nStartRed;
     438                 :          0 :     long            nGreenSteps = nEndGreen - nStartGreen;
     439                 :          0 :     long            nBlueSteps = nEndBlue   - nStartBlue;
     440                 :          0 :     long            nStepCount = rGradient.GetSteps();
     441                 :          0 :     sal_uInt16          nAngle = rGradient.GetAngle() % 3600;
     442                 :            : 
     443         [ #  # ]:          0 :     rGradient.GetBoundRect( rRect, aRect, aCenter );
     444                 :            : 
     445 [ #  # ][ #  # ]:          0 :     if( (meRasterOp != ROP_OVERPAINT) || (meOutDevType != OUTDEV_WINDOW) || bMtf )
                 [ #  # ]
     446 [ #  # ][ #  # ]:          0 :         pPolyPoly = new PolyPolygon( 2 );
     447                 :            :     else
     448                 :          0 :         pPolyPoly = NULL;
     449                 :            : 
     450 [ #  # ][ #  # ]:          0 :     long nMinRect = Min( aRect.GetWidth(), aRect.GetHeight() );
     451                 :            : 
     452                 :            :     // Anzahl der Schritte berechnen, falls nichts uebergeben wurde
     453         [ #  # ]:          0 :     if( !nStepCount )
     454                 :            :     {
     455                 :            :         long nInc;
     456                 :            : 
     457 [ #  # ][ #  # ]:          0 :         if ( meOutDevType != OUTDEV_PRINTER && !bMtf )
     458                 :            :         {
     459         [ #  # ]:          0 :             nInc = ( nMinRect < 50 ) ? 2 : 4;
     460                 :            :         }
     461                 :            :         else
     462                 :            :         {
     463                 :            :             // #105998# Use display-equivalent step size calculation
     464         [ #  # ]:          0 :             nInc = (nMinRect < 800) ? 10 : 20;
     465                 :            :         }
     466                 :            : 
     467         [ #  # ]:          0 :         if( !nInc )
     468                 :          0 :             nInc = 1;
     469                 :            : 
     470                 :          0 :         nStepCount = nMinRect / nInc;
     471                 :            :     }
     472                 :            : 
     473                 :            :     // minimal drei Schritte und maximal die Anzahl der Farbunterschiede
     474                 :          0 :     long nSteps = Max( nStepCount, 2L );
     475                 :          0 :     long nCalcSteps  = Abs( nRedSteps );
     476                 :          0 :     long nTempSteps = Abs( nGreenSteps );
     477         [ #  # ]:          0 :     if ( nTempSteps > nCalcSteps )
     478                 :          0 :         nCalcSteps = nTempSteps;
     479                 :          0 :     nTempSteps = Abs( nBlueSteps );
     480         [ #  # ]:          0 :     if ( nTempSteps > nCalcSteps )
     481                 :          0 :         nCalcSteps = nTempSteps;
     482         [ #  # ]:          0 :     if ( nCalcSteps < nSteps )
     483                 :          0 :         nSteps = nCalcSteps;
     484         [ #  # ]:          0 :     if ( !nSteps )
     485                 :          0 :         nSteps = 1;
     486                 :            : 
     487                 :            :     // Ausgabebegrenzungen und Schrittweite fuer jede Richtung festlegen
     488         [ #  # ]:          0 :     Polygon aPoly;
     489                 :          0 :     double  fScanLeft = aRect.Left();
     490                 :          0 :     double  fScanTop = aRect.Top();
     491                 :          0 :     double  fScanRight = aRect.Right();
     492                 :          0 :     double  fScanBottom = aRect.Bottom();
     493                 :          0 :     double  fScanInc = (double) nMinRect / (double) nSteps * 0.5;
     494                 :          0 :     sal_uInt8   nRed = (sal_uInt8) nStartRed, nGreen = (sal_uInt8) nStartGreen, nBlue = (sal_uInt8) nStartBlue;
     495                 :          0 :     bool    bPaintLastPolygon( false ); // #107349# Paint last polygon only if loop has generated any output
     496                 :            : 
     497         [ #  # ]:          0 :     if( bMtf )
     498 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), sal_True ) );
                 [ #  # ]
     499                 :            :     else
     500         [ #  # ]:          0 :         mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
     501                 :            : 
     502         [ #  # ]:          0 :     if( pPolyPoly )
     503                 :            :     {
     504 [ #  # ][ #  # ]:          0 :         pPolyPoly->Insert( aPoly = rRect );
         [ #  # ][ #  # ]
     505         [ #  # ]:          0 :         pPolyPoly->Insert( aPoly );
     506                 :            :     }
     507                 :            :     else
     508                 :            :     {
     509                 :            :         // extend rect, to avoid missing bounding line
     510                 :          0 :         Rectangle aExtRect( rRect );
     511                 :            : 
     512                 :          0 :         aExtRect.Left() -= 1;
     513                 :          0 :         aExtRect.Top() -= 1;
     514                 :          0 :         aExtRect.Right() += 1;
     515                 :          0 :         aExtRect.Bottom() += 1;
     516                 :            : 
     517 [ #  # ][ #  # ]:          0 :         ImplDrawPolygon( aPoly = aExtRect, pClipPolyPoly );
         [ #  # ][ #  # ]
     518                 :            :     }
     519                 :            : 
     520                 :            :     // Schleife, um nacheinander die Polygone/PolyPolygone auszugeben
     521         [ #  # ]:          0 :     for( long i = 1; i < nSteps; i++ )
     522                 :            :     {
     523                 :            :         // neues Polygon berechnen
     524                 :          0 :         aRect.Left() = (long)( fScanLeft += fScanInc );
     525                 :          0 :         aRect.Top() = (long)( fScanTop += fScanInc );
     526                 :          0 :         aRect.Right() = (long)( fScanRight -= fScanInc );
     527                 :          0 :         aRect.Bottom() = (long)( fScanBottom -= fScanInc );
     528                 :            : 
     529 [ #  # ][ #  # ]:          0 :         if( ( aRect.GetWidth() < 2 ) || ( aRect.GetHeight() < 2 ) )
         [ #  # ][ #  # ]
                 [ #  # ]
     530                 :          0 :             break;
     531                 :            : 
     532 [ #  # ][ #  # ]:          0 :         if( rGradient.GetStyle() == GradientStyle_RADIAL || rGradient.GetStyle() == GradientStyle_ELLIPTICAL )
                 [ #  # ]
     533 [ #  # ][ #  # ]:          0 :             aPoly = Polygon( aRect.Center(), aRect.GetWidth() >> 1, aRect.GetHeight() >> 1 );
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     534                 :            :         else
     535 [ #  # ][ #  # ]:          0 :             aPoly = Polygon( aRect );
                 [ #  # ]
     536                 :            : 
     537         [ #  # ]:          0 :         aPoly.Rotate( aCenter, nAngle );
     538                 :            : 
     539                 :            :         // Farbe entsprechend anpassen
     540         [ #  # ]:          0 :         const long nStepIndex = ( ( pPolyPoly != NULL ) ? i : ( i + 1 ) );
     541                 :          0 :         nRed = ImplGetGradientColorValue( nStartRed + ( ( nRedSteps * nStepIndex ) / nSteps ) );
     542                 :          0 :         nGreen = ImplGetGradientColorValue( nStartGreen + ( ( nGreenSteps * nStepIndex ) / nSteps ) );
     543                 :          0 :         nBlue = ImplGetGradientColorValue( nStartBlue + ( ( nBlueSteps * nStepIndex ) / nSteps ) );
     544                 :            : 
     545                 :            :         // entweder langsame PolyPolygon-Ausgaben oder schnelles Polygon-Painting
     546         [ #  # ]:          0 :         if( pPolyPoly )
     547                 :            :         {
     548                 :          0 :             bPaintLastPolygon = true; // #107349# Paint last polygon only if loop has generated any output
     549                 :            : 
     550 [ #  # ][ #  # ]:          0 :             pPolyPoly->Replace( pPolyPoly->GetObject( 1 ), 0 );
     551         [ #  # ]:          0 :             pPolyPoly->Replace( aPoly, 1 );
     552                 :            : 
     553         [ #  # ]:          0 :             if( bMtf )
     554 [ #  # ][ #  # ]:          0 :                 mpMetaFile->AddAction( new MetaPolyPolygonAction( *pPolyPoly ) );
                 [ #  # ]
     555                 :            :             else
     556         [ #  # ]:          0 :                 ImplDrawPolyPolygon( *pPolyPoly, pClipPolyPoly );
     557                 :            : 
     558                 :            :             // #107349# Set fill color _after_ geometry painting:
     559                 :            :             // pPolyPoly's geometry is the band from last iteration's
     560                 :            :             // aPoly to current iteration's aPoly. The window outdev
     561                 :            :             // path (see else below), on the other hand, paints the
     562                 :            :             // full aPoly. Thus, here, we're painting the band before
     563                 :            :             // the one painted in the window outdev path below. To get
     564                 :            :             // matching colors, have to delay color setting here.
     565         [ #  # ]:          0 :             if( bMtf )
     566 [ #  # ][ #  # ]:          0 :                 mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), sal_True ) );
                 [ #  # ]
     567                 :            :             else
     568         [ #  # ]:          0 :                 mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
     569                 :            :         }
     570                 :            :         else
     571                 :            :         {
     572                 :            :             // #107349# Set fill color _before_ geometry painting
     573         [ #  # ]:          0 :             if( bMtf )
     574 [ #  # ][ #  # ]:          0 :                 mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), sal_True ) );
                 [ #  # ]
     575                 :            :             else
     576         [ #  # ]:          0 :                 mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
     577                 :            : 
     578         [ #  # ]:          0 :             ImplDrawPolygon( aPoly, pClipPolyPoly );
     579                 :            :         }
     580                 :            :     }
     581                 :            : 
     582                 :            :     // Falls PolyPolygon-Ausgabe, muessen wir noch ein letztes inneres Polygon zeichnen
     583         [ #  # ]:          0 :     if( pPolyPoly )
     584                 :            :     {
     585         [ #  # ]:          0 :         const Polygon& rPoly = pPolyPoly->GetObject( 1 );
     586                 :            : 
     587 [ #  # ][ #  # ]:          0 :         if( !rPoly.GetBoundRect().IsEmpty() )
                 [ #  # ]
     588                 :            :         {
     589                 :            :             // #107349# Paint last polygon with end color only if loop
     590                 :            :             // has generated output. Otherwise, the current
     591                 :            :             // (i.e. start) color is taken, to generate _any_ output.
     592         [ #  # ]:          0 :             if( bPaintLastPolygon )
     593                 :            :             {
     594                 :          0 :                 nRed = ImplGetGradientColorValue( nEndRed );
     595                 :          0 :                 nGreen = ImplGetGradientColorValue( nEndGreen );
     596                 :          0 :                 nBlue = ImplGetGradientColorValue( nEndBlue );
     597                 :            :             }
     598                 :            : 
     599         [ #  # ]:          0 :             if( bMtf )
     600                 :            :             {
     601 [ #  # ][ #  # ]:          0 :                 mpMetaFile->AddAction( new MetaFillColorAction( Color( nRed, nGreen, nBlue ), sal_True ) );
                 [ #  # ]
     602 [ #  # ][ #  # ]:          0 :                 mpMetaFile->AddAction( new MetaPolygonAction( rPoly ) );
                 [ #  # ]
     603                 :            :             }
     604                 :            :             else
     605                 :            :             {
     606         [ #  # ]:          0 :                 mpGraphics->SetFillColor( MAKE_SALCOLOR( nRed, nGreen, nBlue ) );
     607         [ #  # ]:          0 :                    ImplDrawPolygon( rPoly, pClipPolyPoly );
     608                 :            :             }
     609                 :            :         }
     610                 :            : 
     611 [ #  # ][ #  # ]:          0 :         delete pPolyPoly;
     612         [ #  # ]:          0 :     }
     613                 :          0 : }
     614                 :            : 
     615                 :            : // -----------------------------------------------------------------------
     616                 :            : 
     617                 :     255807 : void OutputDevice::DrawGradient( const Rectangle& rRect,
     618                 :            :                                  const Gradient& rGradient )
     619                 :            : {
     620                 :            :     OSL_TRACE( "OutputDevice::DrawGradient()" );
     621                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     622                 :            :     DBG_CHKOBJ( &rGradient, Gradient, NULL );
     623                 :            : 
     624         [ +  - ]:     255807 :     if ( mnDrawMode & DRAWMODE_NOGRADIENT )
     625                 :            :         return;
     626         [ -  + ]:     255807 :     else if ( mnDrawMode & ( DRAWMODE_BLACKGRADIENT | DRAWMODE_WHITEGRADIENT | DRAWMODE_SETTINGSGRADIENT) )
     627                 :            :     {
     628                 :          0 :         Color aColor;
     629                 :            : 
     630         [ #  # ]:          0 :         if ( mnDrawMode & DRAWMODE_BLACKGRADIENT )
     631                 :          0 :             aColor = Color( COL_BLACK );
     632         [ #  # ]:          0 :         else if ( mnDrawMode & DRAWMODE_WHITEGRADIENT )
     633                 :          0 :             aColor = Color( COL_WHITE );
     634         [ #  # ]:          0 :         else if ( mnDrawMode & DRAWMODE_SETTINGSGRADIENT )
     635                 :          0 :             aColor = GetSettings().GetStyleSettings().GetWindowColor();
     636                 :            : 
     637         [ #  # ]:          0 :         if ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT )
     638                 :            :         {
     639                 :          0 :             aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
     640                 :          0 :                             ( aColor.GetGreen() >> 1 ) | 0x80,
     641                 :          0 :                             ( aColor.GetBlue() >> 1 ) | 0x80 );
     642                 :            :         }
     643                 :            : 
     644         [ #  # ]:          0 :         Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
     645         [ #  # ]:          0 :         SetLineColor( aColor );
     646         [ #  # ]:          0 :         SetFillColor( aColor );
     647         [ #  # ]:          0 :         DrawRect( rRect );
     648         [ #  # ]:          0 :         Pop();
     649                 :            :         return;
     650                 :            :     }
     651                 :            : 
     652         [ +  - ]:     255807 :     Gradient aGradient( rGradient );
     653                 :            : 
     654         [ -  + ]:     255807 :     if ( mnDrawMode & ( DRAWMODE_GRAYGRADIENT | DRAWMODE_GHOSTEDGRADIENT ) )
     655                 :            :     {
     656                 :          0 :         Color aStartCol( aGradient.GetStartColor() );
     657                 :          0 :         Color aEndCol( aGradient.GetEndColor() );
     658                 :            : 
     659         [ #  # ]:          0 :         if ( mnDrawMode & DRAWMODE_GRAYGRADIENT )
     660                 :            :         {
     661 [ #  # ][ #  # ]:          0 :             sal_uInt8 cStartLum = aStartCol.GetLuminance(), cEndLum = aEndCol.GetLuminance();
     662                 :          0 :             aStartCol = Color( cStartLum, cStartLum, cStartLum );
     663                 :          0 :             aEndCol = Color( cEndLum, cEndLum, cEndLum );
     664                 :            :         }
     665                 :            : 
     666         [ #  # ]:          0 :         if ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT )
     667                 :            :         {
     668                 :          0 :             aStartCol = Color( ( aStartCol.GetRed() >> 1 ) | 0x80,
     669                 :          0 :                                ( aStartCol.GetGreen() >> 1 ) | 0x80,
     670                 :          0 :                                ( aStartCol.GetBlue() >> 1 ) | 0x80 );
     671                 :            : 
     672                 :          0 :             aEndCol = Color( ( aEndCol.GetRed() >> 1 ) | 0x80,
     673                 :          0 :                              ( aEndCol.GetGreen() >> 1 ) | 0x80,
     674                 :          0 :                              ( aEndCol.GetBlue() >> 1 ) | 0x80 );
     675                 :            :         }
     676                 :            : 
     677         [ #  # ]:          0 :         aGradient.SetStartColor( aStartCol );
     678         [ #  # ]:          0 :         aGradient.SetEndColor( aEndCol );
     679                 :            :     }
     680                 :            : 
     681         [ -  + ]:     255807 :     if( mpMetaFile )
     682 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaGradientAction( rRect, aGradient ) );
                 [ #  # ]
     683                 :            : 
     684 [ +  - ][ +  - ]:     255807 :     if( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
         [ -  + ][ -  + ]
     685                 :            :         return;
     686                 :            : 
     687                 :            :     // Rechteck in Pixel umrechnen
     688         [ +  - ]:     255807 :     Rectangle aRect( ImplLogicToDevicePixel( rRect ) );
     689         [ +  - ]:     255807 :     aRect.Justify();
     690                 :            : 
     691                 :            :     // Wenn Rechteck leer ist, brauchen wir nichts machen
     692 [ +  - ][ +  - ]:     255807 :     if ( !aRect.IsEmpty() )
     693                 :            :     {
     694                 :            :         // Clip Region sichern
     695         [ +  - ]:     255807 :         Push( PUSH_CLIPREGION );
     696         [ +  - ]:     255807 :         IntersectClipRegion( rRect );
     697                 :            : 
     698                 :            :         // because we draw with no border line, we have to expand gradient
     699                 :            :         // rect to avoid missing lines on the right and bottom edge
     700                 :     255807 :         aRect.Left()--;
     701                 :     255807 :         aRect.Top()--;
     702                 :     255807 :         aRect.Right()++;
     703                 :     255807 :         aRect.Bottom()++;
     704                 :            : 
     705                 :            :         // we need a graphics
     706         [ -  + ]:     255807 :         if ( !mpGraphics )
     707                 :            :         {
     708 [ #  # ][ #  # ]:          0 :             if ( !ImplGetGraphics() )
     709                 :            :                 return;
     710                 :            :         }
     711                 :            : 
     712         [ +  - ]:     255807 :         if ( mbInitClipRegion )
     713         [ +  - ]:     255807 :             ImplInitClipRegion();
     714                 :            : 
     715         [ +  + ]:     255807 :         if ( !mbOutputClipped )
     716                 :            :         {
     717                 :            :             // Gradienten werden ohne Umrandung gezeichnet
     718 [ +  + ][ +  + ]:     112334 :             if ( mbLineColor || mbInitLineColor )
     719                 :            :             {
     720         [ +  - ]:     112307 :                 mpGraphics->SetLineColor();
     721                 :     112307 :                 mbInitLineColor = sal_True;
     722                 :            :             }
     723                 :            : 
     724                 :     112334 :             mbInitFillColor = sal_True;
     725                 :            : 
     726                 :            :             // calculate step count if neccessary
     727         [ +  - ]:     112334 :             if ( !aGradient.GetSteps() )
     728         [ +  - ]:     112334 :                 aGradient.SetSteps( GRADIENT_DEFAULT_STEPCOUNT );
     729                 :            : 
     730 [ -  + ][ #  # ]:     112334 :             if( aGradient.GetStyle() == GradientStyle_LINEAR || aGradient.GetStyle() == GradientStyle_AXIAL )
                 [ +  - ]
     731         [ +  - ]:     112334 :                 ImplDrawLinearGradient( aRect, aGradient, sal_False, NULL );
     732                 :            :             else
     733         [ #  # ]:          0 :                 ImplDrawComplexGradient( aRect, aGradient, sal_False, NULL );
     734                 :            :         }
     735                 :            : 
     736         [ +  - ]:     255807 :         Pop();
     737                 :            :     }
     738                 :            : 
     739         [ -  + ]:     255807 :     if( mpAlphaVDev )
     740                 :            :     {
     741                 :            :         // #i32109#: Make gradient area opaque
     742         [ #  # ]:     255807 :         mpAlphaVDev->ImplFillOpaqueRectangle( rRect );
     743 [ +  - ][ +  - ]:     255807 :     }
     744                 :            : }
     745                 :            : 
     746                 :            : // -----------------------------------------------------------------------
     747                 :            : 
     748                 :          0 : void OutputDevice::DrawGradient( const PolyPolygon& rPolyPoly,
     749                 :            :                                  const Gradient& rGradient )
     750                 :            : {
     751                 :            :     OSL_TRACE( "OutputDevice::DrawGradient()" );
     752                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     753                 :            :     DBG_CHKOBJ( &rGradient, Gradient, NULL );
     754                 :            : 
     755         [ #  # ]:          0 :     if( mbInitClipRegion )
     756                 :          0 :         ImplInitClipRegion();
     757                 :            : 
     758         [ #  # ]:          0 :     if( mbOutputClipped )
     759                 :          0 :         return;
     760                 :            : 
     761         [ #  # ]:          0 :     if( !mpGraphics )
     762         [ #  # ]:          0 :         if( !ImplGetGraphics() )
     763                 :          0 :             return;
     764                 :            : 
     765 [ #  # ][ #  # ]:          0 :     if( rPolyPoly.Count() && rPolyPoly[ 0 ].GetSize() && !( mnDrawMode & DRAWMODE_NOGRADIENT ) )
         [ #  # ][ #  # ]
     766                 :            :     {
     767         [ #  # ]:          0 :         if ( mnDrawMode & ( DRAWMODE_BLACKGRADIENT | DRAWMODE_WHITEGRADIENT | DRAWMODE_SETTINGSGRADIENT) )
     768                 :            :         {
     769                 :          0 :             Color aColor;
     770                 :            : 
     771         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_BLACKGRADIENT )
     772                 :          0 :                 aColor = Color( COL_BLACK );
     773         [ #  # ]:          0 :             else if ( mnDrawMode & DRAWMODE_WHITEGRADIENT )
     774                 :          0 :                 aColor = Color( COL_WHITE );
     775         [ #  # ]:          0 :             else if ( mnDrawMode & DRAWMODE_SETTINGSGRADIENT )
     776                 :          0 :                 aColor = GetSettings().GetStyleSettings().GetWindowColor();
     777                 :            : 
     778         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT )
     779                 :            :             {
     780                 :          0 :                 aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
     781                 :          0 :                                 ( aColor.GetGreen() >> 1 ) | 0x80,
     782                 :          0 :                                 ( aColor.GetBlue() >> 1 ) | 0x80 );
     783                 :            :             }
     784                 :            : 
     785         [ #  # ]:          0 :             Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
     786         [ #  # ]:          0 :             SetLineColor( aColor );
     787         [ #  # ]:          0 :             SetFillColor( aColor );
     788         [ #  # ]:          0 :             DrawPolyPolygon( rPolyPoly );
     789         [ #  # ]:          0 :             Pop();
     790                 :            :             return;
     791                 :            :         }
     792                 :            : 
     793         [ #  # ]:          0 :         if( mpMetaFile )
     794                 :            :         {
     795         [ #  # ]:          0 :             const Rectangle aRect( rPolyPoly.GetBoundRect() );
     796                 :            : 
     797 [ #  # ][ #  # ]:          0 :             mpMetaFile->AddAction( new MetaCommentAction( "XGRAD_SEQ_BEGIN" ) );
                 [ #  # ]
     798 [ #  # ][ #  # ]:          0 :             mpMetaFile->AddAction( new MetaGradientExAction( rPolyPoly, rGradient ) );
                 [ #  # ]
     799                 :            : 
     800         [ #  # ]:          0 :             if( OUTDEV_PRINTER == meOutDevType )
     801                 :            :             {
     802         [ #  # ]:          0 :                 Push( PUSH_CLIPREGION );
     803 [ #  # ][ #  # ]:          0 :                 IntersectClipRegion( rPolyPoly );
                 [ #  # ]
     804         [ #  # ]:          0 :                 DrawGradient( aRect, rGradient );
     805         [ #  # ]:          0 :                 Pop();
     806                 :            :             }
     807                 :            :             else
     808                 :            :             {
     809                 :          0 :                 const sal_Bool  bOldOutput = IsOutputEnabled();
     810                 :            : 
     811         [ #  # ]:          0 :                 EnableOutput( sal_False );
     812         [ #  # ]:          0 :                 Push( PUSH_RASTEROP );
     813         [ #  # ]:          0 :                 SetRasterOp( ROP_XOR );
     814         [ #  # ]:          0 :                 DrawGradient( aRect, rGradient );
     815         [ #  # ]:          0 :                 SetFillColor( COL_BLACK );
     816         [ #  # ]:          0 :                 SetRasterOp( ROP_0 );
     817         [ #  # ]:          0 :                 DrawPolyPolygon( rPolyPoly );
     818         [ #  # ]:          0 :                 SetRasterOp( ROP_XOR );
     819         [ #  # ]:          0 :                 DrawGradient( aRect, rGradient );
     820         [ #  # ]:          0 :                 Pop();
     821         [ #  # ]:          0 :                 EnableOutput( bOldOutput );
     822                 :            :             }
     823                 :            : 
     824 [ #  # ][ #  # ]:          0 :             mpMetaFile->AddAction( new MetaCommentAction( "XGRAD_SEQ_END" ) );
                 [ #  # ]
     825                 :            :         }
     826                 :            : 
     827 [ #  # ][ #  # ]:          0 :         if( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
         [ #  # ][ #  # ]
     828                 :            :             return;
     829                 :            : 
     830         [ #  # ]:          0 :         Gradient aGradient( rGradient );
     831                 :            : 
     832         [ #  # ]:          0 :         if ( mnDrawMode & ( DRAWMODE_GRAYGRADIENT | DRAWMODE_GHOSTEDGRADIENT ) )
     833                 :            :         {
     834                 :          0 :             Color aStartCol( aGradient.GetStartColor() );
     835                 :          0 :             Color aEndCol( aGradient.GetEndColor() );
     836                 :            : 
     837         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_GRAYGRADIENT )
     838                 :            :             {
     839 [ #  # ][ #  # ]:          0 :                 sal_uInt8 cStartLum = aStartCol.GetLuminance(), cEndLum = aEndCol.GetLuminance();
     840                 :          0 :                 aStartCol = Color( cStartLum, cStartLum, cStartLum );
     841                 :          0 :                 aEndCol = Color( cEndLum, cEndLum, cEndLum );
     842                 :            :             }
     843                 :            : 
     844         [ #  # ]:          0 :             if ( mnDrawMode & DRAWMODE_GHOSTEDGRADIENT )
     845                 :            :             {
     846                 :          0 :                 aStartCol = Color( ( aStartCol.GetRed() >> 1 ) | 0x80,
     847                 :          0 :                                    ( aStartCol.GetGreen() >> 1 ) | 0x80,
     848                 :          0 :                                    ( aStartCol.GetBlue() >> 1 ) | 0x80 );
     849                 :            : 
     850                 :          0 :                 aEndCol = Color( ( aEndCol.GetRed() >> 1 ) | 0x80,
     851                 :          0 :                                  ( aEndCol.GetGreen() >> 1 ) | 0x80,
     852                 :          0 :                                  ( aEndCol.GetBlue() >> 1 ) | 0x80 );
     853                 :            :             }
     854                 :            : 
     855         [ #  # ]:          0 :             aGradient.SetStartColor( aStartCol );
     856         [ #  # ]:          0 :             aGradient.SetEndColor( aEndCol );
     857                 :            :         }
     858                 :            : 
     859 [ #  # ][ #  # ]:          0 :         if( OUTDEV_PRINTER == meOutDevType || ImplGetSVData()->maGDIData.mbNoXORClipping )
         [ #  # ][ #  # ]
     860                 :            :         {
     861         [ #  # ]:          0 :             const Rectangle aBoundRect( rPolyPoly.GetBoundRect() );
     862                 :            : 
     863 [ #  # ][ #  # ]:          0 :             if( !Rectangle( PixelToLogic( Point() ), GetOutputSize() ).IsEmpty() )
         [ #  # ][ #  # ]
                 [ #  # ]
     864                 :            :             {
     865                 :            :                 // Rechteck in Pixel umrechnen
     866         [ #  # ]:          0 :                 Rectangle aRect( ImplLogicToDevicePixel( aBoundRect ) );
     867         [ #  # ]:          0 :                 aRect.Justify();
     868                 :            : 
     869                 :            :                 // Wenn Rechteck leer ist, brauchen wir nichts machen
     870 [ #  # ][ #  # ]:          0 :                 if ( !aRect.IsEmpty() )
     871                 :            :                 {
     872 [ #  # ][ #  # ]:          0 :                     if( !mpGraphics && !ImplGetGraphics() )
         [ #  # ][ #  # ]
     873                 :            :                         return;
     874                 :            : 
     875         [ #  # ]:          0 :                     if( mbInitClipRegion )
     876         [ #  # ]:          0 :                         ImplInitClipRegion();
     877                 :            : 
     878         [ #  # ]:          0 :                     if( !mbOutputClipped )
     879                 :            :                     {
     880         [ #  # ]:          0 :                         PolyPolygon aClipPolyPoly( ImplLogicToDevicePixel( rPolyPoly ) );
     881                 :            : 
     882                 :            :                         // Gradienten werden ohne Umrandung gezeichnet
     883 [ #  # ][ #  # ]:          0 :                         if( mbLineColor || mbInitLineColor )
     884                 :            :                         {
     885         [ #  # ]:          0 :                             mpGraphics->SetLineColor();
     886                 :          0 :                             mbInitLineColor = sal_True;
     887                 :            :                         }
     888                 :            : 
     889                 :          0 :                         mbInitFillColor = sal_True;
     890                 :            : 
     891                 :            :                         // calculate step count if neccessary
     892         [ #  # ]:          0 :                         if ( !aGradient.GetSteps() )
     893         [ #  # ]:          0 :                             aGradient.SetSteps( GRADIENT_DEFAULT_STEPCOUNT );
     894                 :            : 
     895 [ #  # ][ #  # ]:          0 :                         if( aGradient.GetStyle() == GradientStyle_LINEAR || aGradient.GetStyle() == GradientStyle_AXIAL )
                 [ #  # ]
     896         [ #  # ]:          0 :                             ImplDrawLinearGradient( aRect, aGradient, sal_False, &aClipPolyPoly );
     897                 :            :                         else
     898 [ #  # ][ #  # ]:          0 :                             ImplDrawComplexGradient( aRect, aGradient, sal_False, &aClipPolyPoly );
     899                 :            :                     }
     900                 :            :                 }
     901                 :            :             }
     902                 :            :         }
     903                 :            :         else
     904                 :            :         {
     905         [ #  # ]:          0 :             const PolyPolygon   aPolyPoly( LogicToPixel( rPolyPoly ) );
     906         [ #  # ]:          0 :             const Rectangle     aBoundRect( aPolyPoly.GetBoundRect() );
     907                 :          0 :             Point aPoint;
     908         [ #  # ]:          0 :             Rectangle           aDstRect( aPoint, GetOutputSizePixel() );
     909                 :            : 
     910         [ #  # ]:          0 :             aDstRect.Intersection( aBoundRect );
     911                 :            : 
     912         [ #  # ]:          0 :             if( OUTDEV_WINDOW == meOutDevType )
     913                 :            :             {
     914         [ #  # ]:          0 :                 const Region aPaintRgn( ( (Window*) this )->GetPaintRegion() );
     915                 :            : 
     916 [ #  # ][ #  # ]:          0 :                 if( !aPaintRgn.IsNull() )
     917 [ #  # ][ #  # ]:          0 :                     aDstRect.Intersection( LogicToPixel( aPaintRgn ).GetBoundRect() );
         [ #  # ][ #  # ]
                 [ #  # ]
     918                 :            :             }
     919                 :            : 
     920 [ #  # ][ #  # ]:          0 :             if( !aDstRect.IsEmpty() )
     921                 :            :             {
     922                 :            :                 VirtualDevice*  pVDev;
     923         [ #  # ]:          0 :                 const Size      aDstSize( aDstRect.GetSize() );
     924                 :            : 
     925 [ #  # ][ #  # ]:          0 :                 if( HasAlpha() )
     926                 :            :                 {
     927                 :            :                     // #110958# Pay attention to alpha VDevs here, otherwise,
     928                 :            :                     // background will be wrong: Temp VDev has to have alpha, too.
     929 [ #  # ][ #  # ]:          0 :                     pVDev = new VirtualDevice( *this, 0, GetAlphaBitCount() > 1 ? 0 : 1 );
                 [ #  # ]
     930                 :            :                 }
     931                 :            :                 else
     932                 :            :                 {
     933                 :            :                     // nothing special here. Plain VDev
     934 [ #  # ][ #  # ]:          0 :                     pVDev = new VirtualDevice();
     935                 :            :                 }
     936                 :            : 
     937 [ #  # ][ #  # ]:          0 :                 if( pVDev->SetOutputSizePixel( aDstSize) )
     938                 :            :                 {
     939         [ #  # ]:          0 :                     MapMode         aVDevMap;
     940                 :          0 :                     const sal_Bool      bOldMap = mbMap;
     941                 :            : 
     942         [ #  # ]:          0 :                     EnableMapMode( sal_False );
     943                 :            : 
     944         [ #  # ]:          0 :                     pVDev->DrawOutDev( Point(), aDstSize, aDstRect.TopLeft(), aDstSize, *this );
     945         [ #  # ]:          0 :                     pVDev->SetRasterOp( ROP_XOR );
     946         [ #  # ]:          0 :                     aVDevMap.SetOrigin( Point( -aDstRect.Left(), -aDstRect.Top() ) );
     947         [ #  # ]:          0 :                     pVDev->SetMapMode( aVDevMap );
     948         [ #  # ]:          0 :                     pVDev->DrawGradient( aBoundRect, aGradient );
     949         [ #  # ]:          0 :                     pVDev->SetFillColor( COL_BLACK );
     950         [ #  # ]:          0 :                     pVDev->SetRasterOp( ROP_0 );
     951         [ #  # ]:          0 :                     pVDev->DrawPolyPolygon( aPolyPoly );
     952         [ #  # ]:          0 :                     pVDev->SetRasterOp( ROP_XOR );
     953         [ #  # ]:          0 :                     pVDev->DrawGradient( aBoundRect, aGradient );
     954         [ #  # ]:          0 :                     aVDevMap.SetOrigin( Point() );
     955         [ #  # ]:          0 :                     pVDev->SetMapMode( aVDevMap );
     956         [ #  # ]:          0 :                     DrawOutDev( aDstRect.TopLeft(), aDstSize, Point(), aDstSize, *pVDev );
     957                 :            : 
     958 [ #  # ][ #  # ]:          0 :                     EnableMapMode( bOldMap );
     959                 :            :                 }
     960                 :            : 
     961 [ #  # ][ #  # ]:          0 :                 delete pVDev;
     962         [ #  # ]:          0 :             }
     963 [ #  # ][ #  # ]:          0 :         }
     964                 :            :     }
     965                 :            : 
     966         [ #  # ]:          0 :     if( mpAlphaVDev )
     967                 :          0 :         mpAlphaVDev->DrawPolyPolygon( rPolyPoly );
     968                 :            : }
     969                 :            : 
     970                 :            : // -----------------------------------------------------------------------
     971                 :            : 
     972                 :          0 : void OutputDevice::AddGradientActions( const Rectangle& rRect, const Gradient& rGradient,
     973                 :            :                                        GDIMetaFile& rMtf )
     974                 :            : {
     975                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
     976                 :            :     DBG_CHKOBJ( &rGradient, Gradient, NULL );
     977                 :            : 
     978                 :          0 :     Rectangle aRect( rRect );
     979                 :            : 
     980         [ #  # ]:          0 :     aRect.Justify();
     981                 :            : 
     982                 :            :     // Wenn Rechteck leer ist, brauchen wir nichts machen
     983 [ #  # ][ #  # ]:          0 :     if ( !aRect.IsEmpty() )
     984                 :            :     {
     985         [ #  # ]:          0 :         Gradient        aGradient( rGradient );
     986                 :          0 :         GDIMetaFile*    pOldMtf = mpMetaFile;
     987                 :            : 
     988                 :          0 :         mpMetaFile = &rMtf;
     989 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaPushAction( PUSH_ALL ) );
                 [ #  # ]
     990 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaISectRectClipRegionAction( aRect ) );
                 [ #  # ]
     991 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaLineColorAction( Color(), sal_False ) );
                 [ #  # ]
     992                 :            : 
     993                 :            :         // because we draw with no border line, we have to expand gradient
     994                 :            :         // rect to avoid missing lines on the right and bottom edge
     995                 :          0 :         aRect.Left()--;
     996                 :          0 :         aRect.Top()--;
     997                 :          0 :         aRect.Right()++;
     998                 :          0 :         aRect.Bottom()++;
     999                 :            : 
    1000                 :            :         // calculate step count if neccessary
    1001         [ #  # ]:          0 :         if ( !aGradient.GetSteps() )
    1002         [ #  # ]:          0 :             aGradient.SetSteps( GRADIENT_DEFAULT_STEPCOUNT );
    1003                 :            : 
    1004 [ #  # ][ #  # ]:          0 :         if( aGradient.GetStyle() == GradientStyle_LINEAR || aGradient.GetStyle() == GradientStyle_AXIAL )
                 [ #  # ]
    1005         [ #  # ]:          0 :             ImplDrawLinearGradient( aRect, aGradient, sal_True, NULL );
    1006                 :            :         else
    1007         [ #  # ]:          0 :             ImplDrawComplexGradient( aRect, aGradient, sal_True, NULL );
    1008                 :            : 
    1009 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaPopAction() );
                 [ #  # ]
    1010         [ #  # ]:          0 :         mpMetaFile = pOldMtf;
    1011                 :            :     }
    1012                 :          0 : }
    1013                 :            : 
    1014                 :            : // -----------------------------------------------------------------------
    1015                 :            : 
    1016                 :        616 : void OutputDevice::DrawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHatch )
    1017                 :            : {
    1018                 :            :     OSL_TRACE( "OutputDevice::DrawHatch()" );
    1019                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1020                 :            : 
    1021         [ +  - ]:        616 :     Hatch aHatch( rHatch );
    1022                 :            : 
    1023         [ -  + ]:        616 :     if ( mnDrawMode & ( DRAWMODE_BLACKLINE | DRAWMODE_WHITELINE |
    1024                 :            :                         DRAWMODE_GRAYLINE | DRAWMODE_GHOSTEDLINE |
    1025                 :            :                         DRAWMODE_SETTINGSLINE ) )
    1026                 :            :     {
    1027                 :          0 :         Color aColor( rHatch.GetColor() );
    1028                 :            : 
    1029         [ #  # ]:          0 :         if ( mnDrawMode & DRAWMODE_BLACKLINE )
    1030                 :          0 :             aColor = Color( COL_BLACK );
    1031         [ #  # ]:          0 :         else if ( mnDrawMode & DRAWMODE_WHITELINE )
    1032                 :          0 :             aColor = Color( COL_WHITE );
    1033         [ #  # ]:          0 :         else if ( mnDrawMode & DRAWMODE_GRAYLINE )
    1034                 :            :         {
    1035         [ #  # ]:          0 :             const sal_uInt8 cLum = aColor.GetLuminance();
    1036                 :          0 :             aColor = Color( cLum, cLum, cLum );
    1037                 :            :         }
    1038         [ #  # ]:          0 :         else if( mnDrawMode & DRAWMODE_SETTINGSLINE )
    1039                 :            :         {
    1040                 :          0 :             aColor = GetSettings().GetStyleSettings().GetFontColor();
    1041                 :            :         }
    1042                 :            : 
    1043         [ #  # ]:          0 :         if ( mnDrawMode & DRAWMODE_GHOSTEDLINE )
    1044                 :            :         {
    1045                 :          0 :             aColor = Color( ( aColor.GetRed() >> 1 ) | 0x80,
    1046                 :          0 :                             ( aColor.GetGreen() >> 1 ) | 0x80,
    1047                 :          0 :                             ( aColor.GetBlue() >> 1 ) | 0x80);
    1048                 :            :         }
    1049                 :            : 
    1050         [ #  # ]:          0 :         aHatch.SetColor( aColor );
    1051                 :            :     }
    1052                 :            : 
    1053         [ -  + ]:        616 :     if( mpMetaFile )
    1054 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaHatchAction( rPolyPoly, aHatch ) );
                 [ #  # ]
    1055                 :            : 
    1056 [ +  - ][ +  - ]:        616 :     if( !IsDeviceOutputNecessary() || ImplIsRecordLayout() )
         [ -  + ][ -  + ]
    1057                 :            :         return;
    1058                 :            : 
    1059 [ -  + ][ #  # ]:        616 :     if( !mpGraphics && !ImplGetGraphics() )
         [ #  # ][ -  + ]
    1060                 :            :         return;
    1061                 :            : 
    1062         [ -  + ]:        616 :     if( mbInitClipRegion )
    1063         [ #  # ]:          0 :         ImplInitClipRegion();
    1064                 :            : 
    1065         [ -  + ]:        616 :     if( mbOutputClipped )
    1066                 :            :         return;
    1067                 :            : 
    1068 [ +  - ][ +  - ]:        616 :     if( rPolyPoly.Count() )
    1069                 :            :     {
    1070         [ +  - ]:        616 :         PolyPolygon     aPolyPoly( LogicToPixel( rPolyPoly ) );
    1071                 :        616 :         GDIMetaFile*    pOldMetaFile = mpMetaFile;
    1072                 :        616 :         sal_Bool            bOldMap = mbMap;
    1073                 :            : 
    1074         [ +  - ]:        616 :         aPolyPoly.Optimize( POLY_OPTIMIZE_NO_SAME );
    1075 [ +  - ][ +  - ]:        616 :         aHatch.SetDistance( ImplLogicWidthToDevicePixel( aHatch.GetDistance() ) );
    1076                 :            : 
    1077                 :        616 :         mpMetaFile = NULL;
    1078         [ +  - ]:        616 :         EnableMapMode( sal_False );
    1079         [ +  - ]:        616 :         Push( PUSH_LINECOLOR );
    1080         [ +  - ]:        616 :         SetLineColor( aHatch.GetColor() );
    1081         [ +  - ]:        616 :         ImplInitLineColor();
    1082         [ +  - ]:        616 :         ImplDrawHatch( aPolyPoly, aHatch, sal_False );
    1083         [ +  - ]:        616 :         Pop();
    1084         [ +  - ]:        616 :         EnableMapMode( bOldMap );
    1085         [ +  - ]:        616 :         mpMetaFile = pOldMetaFile;
    1086                 :            :     }
    1087                 :            : 
    1088         [ -  + ]:        616 :     if( mpAlphaVDev )
    1089 [ #  # ][ +  - ]:        616 :         mpAlphaVDev->DrawHatch( rPolyPoly, rHatch );
                 [ +  - ]
    1090                 :            : }
    1091                 :            : 
    1092                 :            : // -----------------------------------------------------------------------
    1093                 :            : 
    1094                 :          0 : void OutputDevice::AddHatchActions( const PolyPolygon& rPolyPoly, const Hatch& rHatch,
    1095                 :            :                                     GDIMetaFile& rMtf )
    1096                 :            : {
    1097                 :            :     DBG_CHKTHIS( OutputDevice, ImplDbgCheckOutputDevice );
    1098                 :            : 
    1099         [ #  # ]:          0 :     PolyPolygon aPolyPoly( rPolyPoly );
    1100         [ #  # ]:          0 :     aPolyPoly.Optimize( POLY_OPTIMIZE_NO_SAME | POLY_OPTIMIZE_CLOSE );
    1101                 :            : 
    1102 [ #  # ][ #  # ]:          0 :     if( aPolyPoly.Count() )
    1103                 :            :     {
    1104                 :          0 :         GDIMetaFile* pOldMtf = mpMetaFile;
    1105                 :            : 
    1106                 :          0 :         mpMetaFile = &rMtf;
    1107 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaPushAction( PUSH_ALL ) );
                 [ #  # ]
    1108 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaLineColorAction( rHatch.GetColor(), sal_True ) );
                 [ #  # ]
    1109         [ #  # ]:          0 :         ImplDrawHatch( aPolyPoly, rHatch, sal_True );
    1110 [ #  # ][ #  # ]:          0 :         mpMetaFile->AddAction( new MetaPopAction() );
                 [ #  # ]
    1111                 :          0 :         mpMetaFile = pOldMtf;
    1112         [ #  # ]:          0 :     }
    1113                 :          0 : }
    1114                 :            : 
    1115                 :            : // -----------------------------------------------------------------------
    1116                 :            : 
    1117                 :        616 : void OutputDevice::ImplDrawHatch( const PolyPolygon& rPolyPoly, const Hatch& rHatch, sal_Bool bMtf )
    1118                 :            : {
    1119         [ +  - ]:        616 :     Rectangle   aRect( rPolyPoly.GetBoundRect() );
    1120         [ +  - ]:        616 :     const long  nLogPixelWidth = ImplDevicePixelToLogicWidth( 1 );
    1121 [ +  - ][ +  - ]:        616 :     const long  nWidth = ImplDevicePixelToLogicWidth( Max( ImplLogicWidthToDevicePixel( rHatch.GetDistance() ), 3L ) );
    1122 [ +  - ][ +  + ]:     631400 :     Point*      pPtBuffer = new Point[ HATCH_MAXPOINTS ];
    1123                 :        616 :     Point       aPt1, aPt2, aEndPt1;
    1124                 :        616 :     Size        aInc;
    1125                 :            : 
    1126                 :            :     // Single hatch
    1127                 :        616 :     aRect.Left() -= nLogPixelWidth; aRect.Top() -= nLogPixelWidth; aRect.Right() += nLogPixelWidth; aRect.Bottom() += nLogPixelWidth;
    1128         [ +  - ]:        616 :     ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle(), aPt1, aPt2, aInc, aEndPt1 );
    1129         [ +  + ]:      64680 :     do
           [ +  -  +  + ]
    1130                 :            :     {
    1131         [ +  - ]:      32340 :         ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf );
    1132                 :      32340 :         aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height();
    1133                 :      32340 :         aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height();
    1134                 :            :     }
    1135                 :      64680 :     while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
    1136                 :            : 
    1137 [ +  - ][ -  + ]:        616 :     if( ( rHatch.GetStyle() == HATCH_DOUBLE ) || ( rHatch.GetStyle() == HATCH_TRIPLE ) )
                 [ -  + ]
    1138                 :            :     {
    1139                 :            :         // Double hatch
    1140         [ #  # ]:          0 :         ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 900, aPt1, aPt2, aInc, aEndPt1 );
    1141         [ #  # ]:          0 :         do
           [ #  #  #  # ]
    1142                 :            :         {
    1143         [ #  # ]:          0 :             ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf );
    1144                 :          0 :             aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height();
    1145                 :          0 :             aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height();
    1146                 :            :         }
    1147                 :          0 :         while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
    1148                 :            : 
    1149         [ #  # ]:          0 :         if( rHatch.GetStyle() == HATCH_TRIPLE )
    1150                 :            :         {
    1151                 :            :             // Triple hatch
    1152         [ #  # ]:          0 :             ImplCalcHatchValues( aRect, nWidth, rHatch.GetAngle() + 450, aPt1, aPt2, aInc, aEndPt1 );
    1153         [ #  # ]:          0 :             do
           [ #  #  #  # ]
    1154                 :            :             {
    1155         [ #  # ]:          0 :                 ImplDrawHatchLine( Line( aPt1, aPt2 ), rPolyPoly, pPtBuffer, bMtf );
    1156                 :          0 :                 aPt1.X() += aInc.Width(); aPt1.Y() += aInc.Height();
    1157                 :          0 :                 aPt2.X() += aInc.Width(); aPt2.Y() += aInc.Height();
    1158                 :            :             }
    1159                 :          0 :             while( ( aPt1.X() <= aEndPt1.X() ) && ( aPt1.Y() <= aEndPt1.Y() ) );
    1160                 :            :         }
    1161                 :            :     }
    1162                 :            : 
    1163         [ +  - ]:        616 :     delete[] pPtBuffer;
    1164                 :        616 : }
    1165                 :            : 
    1166                 :            : // -----------------------------------------------------------------------
    1167                 :            : 
    1168                 :        616 : void OutputDevice::ImplCalcHatchValues( const Rectangle& rRect, long nDist, sal_uInt16 nAngle10,
    1169                 :            :                                         Point& rPt1, Point& rPt2, Size& rInc, Point& rEndPt1 )
    1170                 :            : {
    1171                 :        616 :     Point   aRef;
    1172                 :        616 :     long    nAngle = nAngle10 % 1800;
    1173                 :        616 :     long    nOffset = 0;
    1174                 :            : 
    1175         [ -  + ]:        616 :     if( nAngle > 900 )
    1176                 :          0 :         nAngle -= 1800;
    1177                 :            : 
    1178         [ +  - ]:        616 :     aRef = ( !IsRefPoint() ? rRect.TopLeft() : GetRefPoint() );
    1179                 :            : 
    1180         [ +  - ]:        616 :     if( 0 == nAngle )
    1181                 :            :     {
    1182                 :        616 :         rInc = Size( 0, nDist );
    1183                 :        616 :         rPt1 = rRect.TopLeft();
    1184         [ +  - ]:        616 :         rPt2 = rRect.TopRight();
    1185         [ +  - ]:        616 :         rEndPt1 = rRect.BottomLeft();
    1186                 :            : 
    1187         [ +  - ]:        616 :         if( aRef.Y() <= rRect.Top() )
    1188                 :        616 :             nOffset = ( ( rRect.Top() - aRef.Y() ) % nDist );
    1189                 :            :         else
    1190                 :          0 :             nOffset = ( nDist - ( ( aRef.Y() - rRect.Top() ) % nDist ) );
    1191                 :            : 
    1192                 :        616 :         rPt1.Y() -= nOffset;
    1193                 :        616 :         rPt2.Y() -= nOffset;
    1194                 :            :     }
    1195         [ #  # ]:          0 :     else if( 900 == nAngle )
    1196                 :            :     {
    1197                 :          0 :         rInc = Size( nDist, 0 );
    1198                 :          0 :         rPt1 = rRect.TopLeft();
    1199         [ #  # ]:          0 :         rPt2 = rRect.BottomLeft();
    1200         [ #  # ]:          0 :         rEndPt1 = rRect.TopRight();
    1201                 :            : 
    1202         [ #  # ]:          0 :         if( aRef.X() <= rRect.Left() )
    1203                 :          0 :             nOffset = ( rRect.Left() - aRef.X() ) % nDist;
    1204                 :            :         else
    1205                 :          0 :             nOffset = nDist - ( ( aRef.X() - rRect.Left() ) % nDist );
    1206                 :            : 
    1207                 :          0 :         rPt1.X() -= nOffset;
    1208                 :          0 :         rPt2.X() -= nOffset;
    1209                 :            :     }
    1210 [ #  # ][ #  # ]:          0 :     else if( nAngle >= -450 && nAngle <= 450 )
    1211                 :            :     {
    1212                 :          0 :         const double    fAngle = F_PI1800 * labs( nAngle );
    1213                 :          0 :         const double    fTan = tan( fAngle );
    1214                 :          0 :         const long      nYOff = FRound( ( rRect.Right() - rRect.Left() ) * fTan );
    1215                 :            :         long            nPY;
    1216                 :            : 
    1217                 :          0 :         rInc = Size( 0, nDist = FRound( nDist / cos( fAngle ) ) );
    1218                 :            : 
    1219         [ #  # ]:          0 :         if( nAngle > 0 )
    1220                 :            :         {
    1221                 :          0 :             rPt1 = rRect.TopLeft();
    1222                 :          0 :             rPt2 = Point( rRect.Right(), rRect.Top() - nYOff );
    1223                 :          0 :             rEndPt1 = Point( rRect.Left(), rRect.Bottom() + nYOff );
    1224                 :          0 :             nPY = FRound( aRef.Y() - ( ( rPt1.X() - aRef.X() ) * fTan ) );
    1225                 :            :         }
    1226                 :            :         else
    1227                 :            :         {
    1228         [ #  # ]:          0 :             rPt1 = rRect.TopRight();
    1229                 :          0 :             rPt2 = Point( rRect.Left(), rRect.Top() - nYOff );
    1230                 :          0 :             rEndPt1 = Point( rRect.Right(), rRect.Bottom() + nYOff );
    1231                 :          0 :             nPY = FRound( aRef.Y() + ( ( rPt1.X() - aRef.X() ) * fTan ) );
    1232                 :            :         }
    1233                 :            : 
    1234         [ #  # ]:          0 :         if( nPY <= rPt1.Y() )
    1235                 :          0 :             nOffset = ( rPt1.Y() - nPY ) % nDist;
    1236                 :            :         else
    1237                 :          0 :             nOffset = nDist - ( ( nPY - rPt1.Y() ) % nDist );
    1238                 :            : 
    1239                 :          0 :         rPt1.Y() -= nOffset;
    1240                 :          0 :         rPt2.Y() -= nOffset;
    1241                 :            :     }
    1242                 :            :     else
    1243                 :            :     {
    1244                 :          0 :         const double fAngle = F_PI1800 * labs( nAngle );
    1245                 :          0 :         const double fTan = tan( fAngle );
    1246                 :          0 :         const long   nXOff = FRound( ( rRect.Bottom() - rRect.Top() ) / fTan );
    1247                 :            :         long         nPX;
    1248                 :            : 
    1249                 :          0 :         rInc = Size( nDist = FRound( nDist / sin( fAngle ) ), 0 );
    1250                 :            : 
    1251         [ #  # ]:          0 :         if( nAngle > 0 )
    1252                 :            :         {
    1253                 :          0 :             rPt1 = rRect.TopLeft();
    1254                 :          0 :             rPt2 = Point( rRect.Left() - nXOff, rRect.Bottom() );
    1255                 :          0 :             rEndPt1 = Point( rRect.Right() + nXOff, rRect.Top() );
    1256                 :          0 :             nPX = FRound( aRef.X() - ( ( rPt1.Y() - aRef.Y() ) / fTan ) );
    1257                 :            :         }
    1258                 :            :         else
    1259                 :            :         {
    1260         [ #  # ]:          0 :             rPt1 = rRect.BottomLeft();
    1261                 :          0 :             rPt2 = Point( rRect.Left() - nXOff, rRect.Top() );
    1262                 :          0 :             rEndPt1 = Point( rRect.Right() + nXOff, rRect.Bottom() );
    1263                 :          0 :             nPX = FRound( aRef.X() + ( ( rPt1.Y() - aRef.Y() ) / fTan ) );
    1264                 :            :         }
    1265                 :            : 
    1266         [ #  # ]:          0 :         if( nPX <= rPt1.X() )
    1267                 :          0 :             nOffset = ( rPt1.X() - nPX ) % nDist;
    1268                 :            :         else
    1269                 :          0 :             nOffset = nDist - ( ( nPX - rPt1.X() ) % nDist );
    1270                 :            : 
    1271                 :          0 :         rPt1.X() -= nOffset;
    1272                 :          0 :         rPt2.X() -= nOffset;
    1273                 :            :     }
    1274                 :        616 : }
    1275                 :            : 
    1276                 :            : // ------------------------------------------------------------------------
    1277                 :            : 
    1278                 :      32340 : void OutputDevice::ImplDrawHatchLine( const Line& rLine, const PolyPolygon& rPolyPoly,
    1279                 :            :                                       Point* pPtBuffer, sal_Bool bMtf )
    1280                 :            : {
    1281                 :            :     double  fX, fY;
    1282                 :      32340 :     long    nAdd, nPCounter = 0;
    1283                 :            : 
    1284 [ +  - ][ +  + ]:      64680 :     for( long nPoly = 0, nPolyCount = rPolyPoly.Count(); nPoly < nPolyCount; nPoly++ )
    1285                 :            :     {
    1286         [ +  - ]:      32340 :         const Polygon& rPoly = rPolyPoly[ (sal_uInt16) nPoly ];
    1287                 :            : 
    1288 [ +  - ][ +  - ]:      32340 :         if( rPoly.GetSize() > 1 )
    1289                 :            :         {
    1290         [ +  - ]:      32340 :             Line    aCurSegment( rPoly[ 0 ], Point() );
    1291                 :            : 
    1292 [ +  + ][ +  - ]:     161700 :             for( long i = 1, nCount = rPoly.GetSize(); i <= nCount; i++ )
    1293                 :            :             {
    1294         [ +  - ]:     129360 :                 aCurSegment.SetEnd( rPoly[ (sal_uInt16)( i % nCount ) ] );
    1295                 :     129360 :                 nAdd = 0;
    1296                 :            : 
    1297 [ +  + ][ +  - ]:     129360 :                 if( rLine.Intersection( aCurSegment, fX, fY ) )
    1298                 :            :                 {
    1299   [ +  -  -  + ]:     126896 :                     if( ( fabs( fX - aCurSegment.GetStart().X() ) <= 0.0000001 ) &&
                 [ -  + ]
    1300                 :      63448 :                         ( fabs( fY - aCurSegment.GetStart().Y() ) <= 0.0000001 ) )
    1301                 :            :                     {
    1302 [ #  # ][ #  # ]:          0 :                         const Line      aPrevSegment( rPoly[ (sal_uInt16)( ( i > 1 ) ? ( i - 2 ) : ( nCount - 1 ) ) ], aCurSegment.GetStart() );
    1303         [ #  # ]:          0 :                         const double    fPrevDistance = rLine.GetDistance( aPrevSegment.GetStart() );
    1304         [ #  # ]:          0 :                         const double    fCurDistance = rLine.GetDistance( aCurSegment.GetEnd() );
    1305                 :            : 
    1306 [ #  # ][ #  # ]:          0 :                         if( ( fPrevDistance <= 0.0 && fCurDistance > 0.0 ) ||
         [ #  # ][ #  # ]
    1307                 :            :                             ( fPrevDistance > 0.0 && fCurDistance < 0.0 ) )
    1308                 :            :                         {
    1309                 :          0 :                             nAdd = 1;
    1310                 :            :                         }
    1311                 :            :                     }
    1312   [ +  -  -  + ]:     126896 :                     else if( ( fabs( fX - aCurSegment.GetEnd().X() ) <= 0.0000001 ) &&
                 [ -  + ]
    1313                 :      63448 :                              ( fabs( fY - aCurSegment.GetEnd().Y() ) <= 0.0000001 ) )
    1314                 :            :                     {
    1315         [ #  # ]:          0 :                         const Line aNextSegment( aCurSegment.GetEnd(), rPoly[ (sal_uInt16)( ( i + 1 ) % nCount ) ] );
    1316                 :            : 
    1317 [ #  # ][ #  # ]:          0 :                         if( ( fabs( rLine.GetDistance( aNextSegment.GetEnd() ) ) <= 0.0000001 ) &&
         [ #  # ][ #  # ]
    1318         [ #  # ]:          0 :                             ( rLine.GetDistance( aCurSegment.GetStart() ) > 0.0 ) )
    1319                 :            :                         {
    1320                 :          0 :                             nAdd = 1;
    1321                 :            :                         }
    1322                 :            :                     }
    1323                 :            :                     else
    1324                 :      63448 :                         nAdd = 1;
    1325                 :            : 
    1326         [ +  - ]:      63448 :                     if( nAdd )
    1327                 :      63448 :                         pPtBuffer[ nPCounter++ ] = Point( FRound( fX ), FRound( fY ) );
    1328                 :            :                 }
    1329                 :            : 
    1330                 :     129360 :                 aCurSegment.SetStart( aCurSegment.GetEnd() );
    1331                 :            :             }
    1332                 :            :         }
    1333                 :            :     }
    1334                 :            : 
    1335         [ +  + ]:      32340 :     if( nPCounter > 1 )
    1336                 :            :     {
    1337         [ +  - ]:      31724 :         qsort( pPtBuffer, nPCounter, sizeof( Point ), ImplHatchCmpFnc );
    1338                 :            : 
    1339         [ -  + ]:      31724 :         if( nPCounter & 1 )
    1340                 :          0 :             nPCounter--;
    1341                 :            : 
    1342         [ -  + ]:      31724 :         if( bMtf )
    1343                 :            :         {
    1344         [ #  # ]:          0 :             for( long i = 0; i < nPCounter; i += 2 )
    1345 [ #  # ][ #  # ]:          0 :                 mpMetaFile->AddAction( new MetaLineAction( pPtBuffer[ i ], pPtBuffer[ i + 1 ] ) );
                 [ #  # ]
    1346                 :            :         }
    1347                 :            :         else
    1348                 :            :         {
    1349         [ +  + ]:      63448 :             for( long i = 0; i < nPCounter; i += 2 )
    1350                 :            :             {
    1351         [ -  + ]:      31724 :                 if( mpPDFWriter )
    1352                 :            :                 {
    1353         [ #  # ]:          0 :                     mpPDFWriter->drawLine( pPtBuffer[ i ], pPtBuffer[ i+1 ] );
    1354                 :            :                 }
    1355                 :            :                 else
    1356                 :            :                 {
    1357         [ +  - ]:      31724 :                     const Point aPt1( ImplLogicToDevicePixel( pPtBuffer[ i ] ) );
    1358         [ +  - ]:      31724 :                     const Point aPt2( ImplLogicToDevicePixel( pPtBuffer[ i + 1 ] ) );
    1359         [ +  - ]:      31724 :                     mpGraphics->DrawLine( aPt1.X(), aPt1.Y(), aPt2.X(), aPt2.Y(), this );
    1360                 :            :                 }
    1361                 :            :             }
    1362                 :            :         }
    1363                 :            :     }
    1364                 :      32340 : }
    1365                 :            : 
    1366                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10