LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/vcl/source/gdi - impvect.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 90 512 17.6 %
Date: 2013-07-09 Functions: 14 37 37.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <stdlib.h>
      22             : #include <vcl/bmpacc.hxx>
      23             : #include <tools/poly.hxx>
      24             : #include <vcl/gdimtf.hxx>
      25             : #include <vcl/metaact.hxx>
      26             : #include <vcl/svapp.hxx>
      27             : #include <vcl/wrkwin.hxx>
      28             : #include <vcl/virdev.hxx>
      29             : #include <impvect.hxx>
      30             : 
      31             : #define VECT_POLY_MAX 8192
      32             : 
      33             : #define VECT_FREE_INDEX 0
      34             : #define VECT_CONT_INDEX 1
      35             : #define VECT_DONE_INDEX 2
      36             : 
      37             : #define VECT_POLY_INLINE_INNER  1UL
      38             : #define VECT_POLY_INLINE_OUTER  2UL
      39             : #define VECT_POLY_OUTLINE_INNER 4UL
      40             : #define VECT_POLY_OUTLINE_OUTER 8UL
      41             : 
      42             : #define VECT_MAP( _def_pIn, _def_pOut, _def_nVal )  _def_pOut[_def_nVal]=(_def_pIn[_def_nVal]=((_def_nVal)*4L)+1L)+5L;
      43             : #define BACK_MAP( _def_nVal )                       ((((_def_nVal)+2)>>2)-1)
      44             : #define VECT_PROGRESS( _def_pProgress, _def_nVal )  if(_def_pProgress&&_def_pProgress->IsSet())(_def_pProgress->Call((void*)(sal_IntPtr)_def_nVal));
      45             : 
      46             : struct ChainMove { long nDX; long nDY; };
      47             : 
      48             : static ChainMove aImplMove[ 8 ] =   {
      49             :                                         { 1L, 0L },
      50             :                                         { 0L, -1L },
      51             :                                         { -1L, 0L },
      52             :                                         { 0L, 1L },
      53             :                                         { 1L, -1L },
      54             :                                         { -1, -1L },
      55             :                                         { -1L, 1L },
      56             :                                         { 1L, 1L }
      57             :                                     };
      58             : 
      59             : static ChainMove aImplMoveInner[ 8 ] =  {
      60             :                                             { 0L, 1L },
      61             :                                             { 1L, 0L },
      62             :                                             { 0L, -1L },
      63             :                                             { -1L, 0L },
      64             :                                             { 0L, 1L },
      65             :                                             { 1L, 0L },
      66             :                                             { 0L, -1L },
      67             :                                             { -1L, 0L }
      68             :                                         };
      69             : 
      70             : static ChainMove aImplMoveOuter[ 8 ] =  {
      71             :                                             { 0L, -1L },
      72             :                                             { -1L, 0L },
      73             :                                             { 0L, 1L },
      74             :                                             { 1L, 0L },
      75             :                                             { -1L, 0L },
      76             :                                             { 0L, 1L },
      77             :                                             { 1L, 0L },
      78             :                                             { 0L, -1L }
      79             :                                         };
      80             : 
      81             : struct ImplColorSet
      82             : {
      83             :     BitmapColor maColor;
      84             :     sal_uInt16      mnIndex;
      85             :     sal_Bool        mbSet;
      86             : 
      87             :     sal_Bool        operator<( const ImplColorSet& rSet ) const;
      88             :     sal_Bool        operator>( const ImplColorSet& rSet ) const;
      89             : };
      90             : 
      91             : inline sal_Bool ImplColorSet::operator<( const ImplColorSet& rSet ) const
      92             : {
      93             :     return( mbSet && ( !rSet.mbSet || ( maColor.GetLuminance() > rSet.maColor.GetLuminance() ) ) );
      94             : }
      95             : 
      96             : inline sal_Bool ImplColorSet::operator>( const ImplColorSet& rSet ) const
      97             : {
      98             :     return( !mbSet || ( rSet.mbSet && maColor.GetLuminance() < rSet.maColor.GetLuminance() ) );
      99             : }
     100             : 
     101           0 : extern "C" int SAL_CALL ImplColorSetCmpFnc( const void* p1, const void* p2 )
     102             : {
     103           0 :     ImplColorSet*   pSet1 = (ImplColorSet*) p1;
     104           0 :     ImplColorSet*   pSet2 = (ImplColorSet*) p2;
     105             :     int             nRet;
     106             : 
     107           0 :     if( pSet1->mbSet && pSet2->mbSet )
     108             :     {
     109           0 :         const sal_uInt8 cLum1 = pSet1->maColor.GetLuminance();
     110           0 :         const sal_uInt8 cLum2 = pSet2->maColor.GetLuminance();
     111           0 :         nRet = ( ( cLum1 > cLum2 ) ? -1 : ( ( cLum1 == cLum2 ) ? 0 : 1 ) );
     112             :     }
     113           0 :     else if( pSet1->mbSet )
     114           0 :         nRet = -1;
     115           0 :     else if( pSet2->mbSet )
     116           0 :         nRet = 1;
     117             :     else
     118           0 :         nRet = 0;
     119             : 
     120           0 :     return nRet;
     121             : }
     122             : 
     123             : class ImplPointArray
     124             : {
     125             :     Point*              mpArray;
     126             :     sal_uLong               mnSize;
     127             :     sal_uLong               mnRealSize;
     128             : 
     129             : public:
     130             : 
     131             :                         ImplPointArray();
     132             :                         ~ImplPointArray();
     133             : 
     134             :     void                ImplSetSize( sal_uLong nSize );
     135             : 
     136           0 :     sal_uLong               ImplGetRealSize() const { return mnRealSize; }
     137           0 :     void                ImplSetRealSize( sal_uLong nRealSize ) { mnRealSize = nRealSize; }
     138             : 
     139             :     inline Point&       operator[]( sal_uLong nPos );
     140             :     inline const Point& operator[]( sal_uLong nPos ) const;
     141             : 
     142             :     void                ImplCreatePoly( Polygon& rPoly ) const;
     143             : };
     144             : 
     145           0 : ImplPointArray::ImplPointArray() :
     146             :     mpArray     ( NULL ),
     147             :     mnSize      ( 0UL ),
     148           0 :     mnRealSize  ( 0UL )
     149             : 
     150             : {
     151           0 : }
     152             : 
     153           0 : ImplPointArray::~ImplPointArray()
     154             : {
     155           0 :     if( mpArray )
     156           0 :         rtl_freeMemory( mpArray );
     157           0 : }
     158             : 
     159           0 : void ImplPointArray::ImplSetSize( sal_uLong nSize )
     160             : {
     161           0 :     const sal_uLong nTotal = nSize * sizeof( Point );
     162             : 
     163           0 :     mnSize = nSize;
     164           0 :     mnRealSize = 0UL;
     165             : 
     166           0 :     if( mpArray )
     167           0 :         rtl_freeMemory( mpArray );
     168             : 
     169           0 :     mpArray = (Point*) rtl_allocateMemory( nTotal );
     170           0 :     memset( (HPBYTE) mpArray, 0, nTotal );
     171           0 : }
     172             : 
     173           0 : inline Point& ImplPointArray::operator[]( sal_uLong nPos )
     174             : {
     175             :     DBG_ASSERT( nPos < mnSize, "ImplPointArray::operator[]: nPos out of range!" );
     176           0 :     return mpArray[ nPos ];
     177             : }
     178             : 
     179           0 : inline const Point& ImplPointArray::operator[]( sal_uLong nPos ) const
     180             : {
     181             :     DBG_ASSERT( nPos < mnSize, "ImplPointArray::operator[]: nPos out of range!" );
     182           0 :     return mpArray[ nPos ];
     183             : }
     184             : 
     185           0 : void ImplPointArray::ImplCreatePoly( Polygon& rPoly ) const
     186             : {
     187           0 :     rPoly = Polygon( sal::static_int_cast<sal_uInt16>(mnRealSize), mpArray );
     188           0 : }
     189             : 
     190             : class ImplVectMap
     191             : {
     192             : private:
     193             : 
     194             :     Scanline        mpBuf;
     195             :     Scanline*       mpScan;
     196             :     long            mnWidth;
     197             :     long            mnHeight;
     198             : 
     199             :                     ImplVectMap() {};
     200             : 
     201             : public:
     202             : 
     203             :                     ImplVectMap( long nWidth, long nHeight );
     204             :                     ~ImplVectMap();
     205             : 
     206           2 :     inline long     Width() const { return mnWidth; }
     207           2 :     inline long     Height() const { return mnHeight; }
     208             : 
     209             :     inline void     Set( long nY, long nX, sal_uInt8 cVal );
     210             :     inline sal_uInt8        Get( long nY, long nX ) const;
     211             : 
     212             :     inline bool     IsFree( long nY, long nX ) const;
     213             :     inline bool     IsCont( long nY, long nX ) const;
     214             :     inline bool     IsDone( long nY, long nX ) const;
     215             : 
     216             : };
     217             : 
     218           2 : ImplVectMap::ImplVectMap( long nWidth, long nHeight ) :
     219             :     mnWidth ( nWidth ),
     220           2 :     mnHeight( nHeight )
     221             : {
     222           2 :     const long  nWidthAl = ( nWidth >> 2L ) + 1L;
     223           2 :     const long  nSize = nWidthAl * nHeight;
     224           2 :     Scanline    pTmp = mpBuf = (Scanline) rtl_allocateMemory( nSize );
     225             : 
     226           2 :     memset( mpBuf, 0, nSize );
     227           2 :     mpScan = (Scanline*) rtl_allocateMemory( nHeight * sizeof( Scanline ) );
     228             : 
     229        1334 :     for( long nY = 0L; nY < nHeight; pTmp += nWidthAl )
     230        1332 :         mpScan[ nY++ ] = pTmp;
     231           2 : }
     232             : 
     233           2 : ImplVectMap::~ImplVectMap()
     234             : {
     235           2 :     rtl_freeMemory( mpBuf );
     236           2 :     rtl_freeMemory( mpScan );
     237           2 : }
     238             : 
     239           0 : inline void ImplVectMap::Set( long nY, long nX, sal_uInt8 cVal )
     240             : {
     241           0 :     const sal_uInt8 cShift = sal::static_int_cast<sal_uInt8>(6 - ( ( nX & 3 ) << 1 ));
     242           0 :     ( ( mpScan[ nY ][ nX >> 2 ] ) &= ~( 3 << cShift ) ) |= ( cVal << cShift );
     243           0 : }
     244             : 
     245      806112 : inline sal_uInt8    ImplVectMap::Get( long nY, long nX ) const
     246             : {
     247      806112 :     return sal::static_int_cast<sal_uInt8>( ( ( mpScan[ nY ][ nX >> 2 ] ) >> ( 6 - ( ( nX & 3 ) << 1 ) ) ) & 3 );
     248             : }
     249             : 
     250      806112 : inline bool ImplVectMap::IsFree( long nY, long nX ) const
     251             : {
     252      806112 :     return( VECT_FREE_INDEX == Get( nY, nX ) );
     253             : }
     254             : 
     255           0 : inline bool ImplVectMap::IsCont( long nY, long nX ) const
     256             : {
     257           0 :     return( VECT_CONT_INDEX == Get( nY, nX ) );
     258             : }
     259             : 
     260           0 : inline bool ImplVectMap::IsDone( long nY, long nX ) const
     261             : {
     262           0 :     return( VECT_DONE_INDEX == Get( nY, nX ) );
     263             : }
     264             : 
     265             : class ImplChain
     266             : {
     267             : private:
     268             : 
     269             :     Polygon         maPoly;
     270             :     Point           maStartPt;
     271             :     sal_uLong           mnArraySize;
     272             :     sal_uLong           mnCount;
     273             :     long            mnResize;
     274             :     sal_uInt8*          mpCodes;
     275             : 
     276             :     void            ImplGetSpace();
     277             : 
     278             :     void            ImplCreate();
     279             :     void            ImplCreateInner();
     280             :     void            ImplCreateOuter();
     281             :     void            ImplPostProcess( const ImplPointArray& rArr );
     282             : 
     283             : public:
     284             : 
     285             :                     ImplChain( sal_uLong nInitCount = 1024UL, long nResize = -1L );
     286             :                     ~ImplChain();
     287             : 
     288             :     void            ImplBeginAdd( const Point& rStartPt );
     289             :     inline void     ImplAdd( sal_uInt8 nCode );
     290             :     void            ImplEndAdd( sal_uLong nTypeFlag );
     291             : 
     292           0 :     const Polygon&  ImplGetPoly() const { return maPoly; }
     293             : };
     294             : 
     295           0 : ImplChain::ImplChain( sal_uLong nInitCount, long nResize ) :
     296             :     mnArraySize ( nInitCount ),
     297             :     mnCount     ( 0UL ),
     298           0 :     mnResize    ( nResize )
     299             : {
     300             :     DBG_ASSERT( nInitCount && nResize, "ImplChain::ImplChain(): invalid parameters!" );
     301           0 :     mpCodes = new sal_uInt8[ mnArraySize ];
     302           0 : }
     303             : 
     304           0 : ImplChain::~ImplChain()
     305             : {
     306           0 :     delete[] mpCodes;
     307           0 : }
     308             : 
     309           0 : void ImplChain::ImplGetSpace()
     310             : {
     311           0 :     const sal_uLong nOldArraySize = mnArraySize;
     312             :     sal_uInt8*      pNewCodes;
     313             : 
     314           0 :     mnArraySize = ( mnResize < 0L ) ? ( mnArraySize << 1UL ) : ( mnArraySize + (sal_uLong) mnResize );
     315           0 :     pNewCodes = new sal_uInt8[ mnArraySize ];
     316           0 :     memcpy( pNewCodes, mpCodes, nOldArraySize );
     317           0 :     delete[] mpCodes;
     318           0 :     mpCodes = pNewCodes;
     319           0 : }
     320             : 
     321           0 : void ImplChain::ImplBeginAdd( const Point& rStartPt )
     322             : {
     323           0 :     maPoly = Polygon();
     324           0 :     maStartPt = rStartPt;
     325           0 :     mnCount = 0UL;
     326           0 : }
     327             : 
     328           0 : inline void ImplChain::ImplAdd( sal_uInt8 nCode )
     329             : {
     330           0 :     if( mnCount == mnArraySize )
     331           0 :         ImplGetSpace();
     332             : 
     333           0 :     mpCodes[ mnCount++ ] = nCode;
     334           0 : }
     335             : 
     336           0 : void ImplChain::ImplEndAdd( sal_uLong nFlag )
     337             : {
     338           0 :     if( mnCount )
     339             :     {
     340           0 :         ImplPointArray aArr;
     341             : 
     342           0 :         if( nFlag & VECT_POLY_INLINE_INNER )
     343             :         {
     344             :             long nFirstX, nFirstY;
     345             :             long nLastX, nLastY;
     346             : 
     347           0 :             nFirstX = nLastX = maStartPt.X();
     348           0 :             nFirstY = nLastY = maStartPt.Y();
     349           0 :             aArr.ImplSetSize( mnCount << 1 );
     350             : 
     351             :             sal_uInt16 i, nPolyPos;
     352           0 :             for( i = 0, nPolyPos = 0; i < ( mnCount - 1 ); i++ )
     353             :             {
     354           0 :                 const sal_uInt8             cMove = mpCodes[ i ];
     355           0 :                 const sal_uInt8             cNextMove = mpCodes[ i + 1 ];
     356           0 :                 const ChainMove&        rMove = aImplMove[ cMove ];
     357           0 :                 const ChainMove&        rMoveInner = aImplMoveInner[ cMove ];
     358             : //              Point&                  rPt = aArr[ nPolyPos ];
     359           0 :                 bool                    bDone = true;
     360             : 
     361           0 :                 nLastX += rMove.nDX;
     362           0 :                 nLastY += rMove.nDY;
     363             : 
     364           0 :                 if( cMove < 4 )
     365             :                 {
     366           0 :                     if( ( cMove == 0 && cNextMove == 3 ) ||
     367           0 :                         ( cMove == 3 && cNextMove == 2 ) ||
     368           0 :                         ( cMove == 2 && cNextMove == 1 ) ||
     369           0 :                         ( cMove == 1 && cNextMove == 0 ) )
     370             :                     {
     371             :                     }
     372           0 :                     else if( cMove == 2 && cNextMove == 3 )
     373             :                     {
     374           0 :                         aArr[ nPolyPos ].X() = nLastX;
     375           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     376             : 
     377           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     378           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     379             : 
     380           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     381           0 :                         aArr[ nPolyPos++ ].Y() = nLastY;
     382             :                     }
     383           0 :                     else if( cMove == 3 && cNextMove == 0 )
     384             :                     {
     385           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     386           0 :                         aArr[ nPolyPos++ ].Y() = nLastY;
     387             : 
     388           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     389           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     390             : 
     391           0 :                         aArr[ nPolyPos ].X() = nLastX;
     392           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     393             :                     }
     394           0 :                     else if( cMove == 0 && cNextMove == 1 )
     395             :                     {
     396           0 :                         aArr[ nPolyPos ].X() = nLastX;
     397           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     398             : 
     399           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     400           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     401             : 
     402           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     403           0 :                         aArr[ nPolyPos++ ].Y() = nLastY;
     404             :                     }
     405           0 :                     else if( cMove == 1 && cNextMove == 2 )
     406             :                     {
     407           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     408           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     409             : 
     410           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     411           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     412             : 
     413           0 :                         aArr[ nPolyPos ].X() = nLastX;
     414           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     415             :                     }
     416             :                     else
     417           0 :                         bDone = false;
     418             :                 }
     419           0 :                 else if( cMove == 7 && cNextMove == 0 )
     420             :                 {
     421           0 :                     aArr[ nPolyPos ].X() = nLastX - 1;
     422           0 :                     aArr[ nPolyPos++ ].Y() = nLastY;
     423             : 
     424           0 :                     aArr[ nPolyPos ].X() = nLastX;
     425           0 :                     aArr[ nPolyPos++ ].Y() = nLastY + 1;
     426             :                 }
     427           0 :                 else if( cMove == 4 && cNextMove == 1 )
     428             :                 {
     429           0 :                     aArr[ nPolyPos ].X() = nLastX;
     430           0 :                     aArr[ nPolyPos++ ].Y() = nLastY + 1;
     431             : 
     432           0 :                     aArr[ nPolyPos ].X() = nLastX + 1;
     433           0 :                     aArr[ nPolyPos++ ].Y() = nLastY;
     434             :                 }
     435             :                 else
     436           0 :                     bDone = false;
     437             : 
     438           0 :                 if( !bDone )
     439             :                 {
     440           0 :                     aArr[ nPolyPos ].X() = nLastX + rMoveInner.nDX;
     441           0 :                     aArr[ nPolyPos++ ].Y() = nLastY + rMoveInner.nDY;
     442             :                 }
     443             :             }
     444             : 
     445           0 :             aArr[ nPolyPos ].X() = nFirstX + 1L;
     446           0 :             aArr[ nPolyPos++ ].Y() = nFirstY + 1L;
     447           0 :             aArr.ImplSetRealSize( nPolyPos );
     448             :         }
     449           0 :         else if( nFlag & VECT_POLY_INLINE_OUTER )
     450             :         {
     451             :             long nFirstX, nFirstY;
     452             :             long nLastX, nLastY;
     453             : 
     454           0 :             nFirstX = nLastX = maStartPt.X();
     455           0 :             nFirstY = nLastY = maStartPt.Y();
     456           0 :             aArr.ImplSetSize( mnCount << 1 );
     457             : 
     458             :             sal_uInt16 i, nPolyPos;
     459           0 :             for( i = 0, nPolyPos = 0; i < ( mnCount - 1 ); i++ )
     460             :             {
     461           0 :                 const sal_uInt8             cMove = mpCodes[ i ];
     462           0 :                 const sal_uInt8             cNextMove = mpCodes[ i + 1 ];
     463           0 :                 const ChainMove&        rMove = aImplMove[ cMove ];
     464           0 :                 const ChainMove&        rMoveOuter = aImplMoveOuter[ cMove ];
     465             : //              Point&                  rPt = aArr[ nPolyPos ];
     466           0 :                 bool                    bDone = true;
     467             : 
     468           0 :                 nLastX += rMove.nDX;
     469           0 :                 nLastY += rMove.nDY;
     470             : 
     471           0 :                 if( cMove < 4 )
     472             :                 {
     473           0 :                     if( ( cMove == 0 && cNextMove == 1 ) ||
     474           0 :                         ( cMove == 1 && cNextMove == 2 ) ||
     475           0 :                         ( cMove == 2 && cNextMove == 3 ) ||
     476           0 :                         ( cMove == 3 && cNextMove == 0 ) )
     477             :                     {
     478             :                     }
     479           0 :                     else if( cMove == 0 && cNextMove == 3 )
     480             :                     {
     481           0 :                         aArr[ nPolyPos ].X() = nLastX;
     482           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     483             : 
     484           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     485           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     486             : 
     487           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     488           0 :                         aArr[ nPolyPos++ ].Y() = nLastY;
     489             :                     }
     490           0 :                     else if( cMove == 3 && cNextMove == 2 )
     491             :                     {
     492           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     493           0 :                         aArr[ nPolyPos++ ].Y() = nLastY;
     494             : 
     495           0 :                         aArr[ nPolyPos ].X() = nLastX + 1;
     496           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     497             : 
     498           0 :                         aArr[ nPolyPos ].X() = nLastX;
     499           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     500             :                     }
     501           0 :                     else if( cMove == 2 && cNextMove == 1 )
     502             :                     {
     503           0 :                         aArr[ nPolyPos ].X() = nLastX;
     504           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     505             : 
     506           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     507           0 :                         aArr[ nPolyPos++ ].Y() = nLastY + 1;
     508             : 
     509           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     510           0 :                         aArr[ nPolyPos++ ].Y() = nLastY;
     511             :                     }
     512           0 :                     else if( cMove == 1 && cNextMove == 0 )
     513             :                     {
     514           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     515           0 :                         aArr[ nPolyPos++ ].Y() = nLastY;
     516             : 
     517           0 :                         aArr[ nPolyPos ].X() = nLastX - 1;
     518           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     519             : 
     520           0 :                         aArr[ nPolyPos ].X() = nLastX;
     521           0 :                         aArr[ nPolyPos++ ].Y() = nLastY - 1;
     522             :                     }
     523             :                     else
     524           0 :                         bDone = false;
     525             :                 }
     526           0 :                 else if( cMove == 7 && cNextMove == 3 )
     527             :                 {
     528           0 :                     aArr[ nPolyPos ].X() = nLastX;
     529           0 :                     aArr[ nPolyPos++ ].Y() = nLastY - 1;
     530             : 
     531           0 :                     aArr[ nPolyPos ].X() = nLastX + 1;
     532           0 :                     aArr[ nPolyPos++ ].Y() = nLastY;
     533             :                 }
     534           0 :                 else if( cMove == 6 && cNextMove == 2 )
     535             :                 {
     536           0 :                     aArr[ nPolyPos ].X() = nLastX + 1;
     537           0 :                     aArr[ nPolyPos++ ].Y() = nLastY;
     538             : 
     539           0 :                     aArr[ nPolyPos ].X() = nLastX;
     540           0 :                     aArr[ nPolyPos++ ].Y() = nLastY + 1;
     541             :                 }
     542             :                 else
     543           0 :                     bDone = false;
     544             : 
     545           0 :                 if( !bDone )
     546             :                 {
     547           0 :                     aArr[ nPolyPos ].X() = nLastX + rMoveOuter.nDX;
     548           0 :                     aArr[ nPolyPos++ ].Y() = nLastY + rMoveOuter.nDY;
     549             :                 }
     550             :             }
     551             : 
     552           0 :             aArr[ nPolyPos ].X() = nFirstX - 1L;
     553           0 :             aArr[ nPolyPos++ ].Y() = nFirstY - 1L;
     554           0 :             aArr.ImplSetRealSize( nPolyPos );
     555             :         }
     556             :         else
     557             :         {
     558           0 :             long nLastX = maStartPt.X(), nLastY = maStartPt.Y();
     559             : 
     560           0 :             aArr.ImplSetSize( mnCount + 1 );
     561           0 :             aArr[ 0 ] = Point( nLastX, nLastY );
     562             : 
     563           0 :             for( sal_uLong i = 0; i < mnCount; )
     564             :             {
     565           0 :                 const ChainMove& rMove = aImplMove[ mpCodes[ i ] ];
     566           0 :                 aArr[ ++i ] = Point( nLastX += rMove.nDX, nLastY += rMove.nDY );
     567             :             }
     568             : 
     569           0 :             aArr.ImplSetRealSize( mnCount + 1 );
     570             :         }
     571             : 
     572           0 :         ImplPostProcess( aArr );
     573             :     }
     574             :     else
     575           0 :         maPoly.SetSize( 0 );
     576           0 : }
     577             : 
     578           0 : void ImplChain::ImplPostProcess( const ImplPointArray& rArr )
     579             : {
     580           0 :     ImplPointArray  aNewArr1;
     581           0 :     ImplPointArray  aNewArr2;
     582             :     Point*          pLast;
     583             :     Point*          pLeast;
     584             :     sal_uLong           nNewPos;
     585           0 :     sal_uLong           nCount = rArr.ImplGetRealSize();
     586             :     sal_uLong           n;
     587             : 
     588             :     // pass 1
     589           0 :     aNewArr1.ImplSetSize( nCount );
     590           0 :     pLast = &( aNewArr1[ 0 ] );
     591           0 :     pLast->X() = BACK_MAP( rArr[ 0 ].X() );
     592           0 :     pLast->Y() = BACK_MAP( rArr[ 0 ].Y() );
     593             : 
     594           0 :     for( n = nNewPos = 1; n < nCount; )
     595             :     {
     596           0 :         const Point& rPt = rArr[ n++ ];
     597           0 :         const long   nX = BACK_MAP( rPt.X() );
     598           0 :         const long   nY = BACK_MAP( rPt.Y() );
     599             : 
     600           0 :         if( nX != pLast->X() || nY != pLast->Y() )
     601             :         {
     602           0 :             pLast = pLeast = &( aNewArr1[ nNewPos++ ] );
     603           0 :             pLeast->X() = nX;
     604           0 :             pLeast->Y() = nY;
     605             :         }
     606             :     }
     607             : 
     608           0 :     aNewArr1.ImplSetRealSize( nCount = nNewPos );
     609             : 
     610             :     // pass 2
     611           0 :     aNewArr2.ImplSetSize( nCount );
     612           0 :     pLast = &( aNewArr2[ 0 ] );
     613           0 :     *pLast = aNewArr1[ 0 ];
     614             : 
     615           0 :     for( n = nNewPos = 1; n < nCount; )
     616             :     {
     617           0 :         pLeast = &( aNewArr1[ n++ ] );
     618             : 
     619           0 :         if( pLeast->X() == pLast->X() )
     620             :         {
     621           0 :             while( n < nCount && aNewArr1[ n ].X() == pLast->X() )
     622           0 :                 pLeast = &( aNewArr1[ n++ ] );
     623             :         }
     624           0 :         else if( pLeast->Y() == pLast->Y() )
     625             :         {
     626           0 :             while( n < nCount && aNewArr1[ n ].Y() == pLast->Y() )
     627           0 :                 pLeast = &( aNewArr1[ n++ ] );
     628             :         }
     629             : 
     630           0 :         aNewArr2[ nNewPos++ ] = *( pLast = pLeast );
     631             :     }
     632             : 
     633           0 :     aNewArr2.ImplSetRealSize( nNewPos );
     634           0 :     aNewArr2.ImplCreatePoly( maPoly );
     635           0 : }
     636             : 
     637           2 : ImplVectorizer::ImplVectorizer()
     638             : {
     639           2 : }
     640             : 
     641           2 : ImplVectorizer::~ImplVectorizer()
     642             : {
     643           2 : }
     644             : 
     645           0 : sal_Bool ImplVectorizer::ImplVectorize( const Bitmap& rColorBmp, GDIMetaFile& rMtf,
     646             :                                     sal_uInt8 cReduce, sal_uLong nFlags, const Link* pProgress )
     647             : {
     648           0 :     sal_Bool bRet = sal_False;
     649             : 
     650           0 :     VECT_PROGRESS( pProgress, 0 );
     651             : 
     652           0 :     Bitmap*             pBmp = new Bitmap( rColorBmp );
     653           0 :     BitmapReadAccess*   pRAcc = pBmp->AcquireReadAccess();
     654             : 
     655           0 :     if( pRAcc )
     656             :     {
     657           0 :         PolyPolygon         aPolyPoly;
     658           0 :         double              fPercent = 0.0;
     659           0 :         double              fPercentStep_2 = 0.0;
     660           0 :         const long          nWidth = pRAcc->Width();
     661           0 :         const long          nHeight = pRAcc->Height();
     662           0 :         const sal_uInt16        nColorCount = pRAcc->GetPaletteEntryCount();
     663             :         sal_uInt16              n;
     664           0 :         ImplColorSet*       pColorSet = (ImplColorSet*) new sal_uInt8[ 256 * sizeof( ImplColorSet ) ];
     665             : 
     666           0 :         memset( pColorSet, 0, 256 * sizeof( ImplColorSet ) );
     667           0 :         rMtf.Clear();
     668             : 
     669             :         // get used palette colors and sort them from light to dark colors
     670           0 :         for( n = 0; n < nColorCount; n++ )
     671             :         {
     672           0 :             pColorSet[ n ].mnIndex = n;
     673           0 :             pColorSet[ n ].maColor = pRAcc->GetPaletteColor( n );
     674             :         }
     675             : 
     676           0 :         for( long nY = 0L; nY < nHeight; nY++ )
     677           0 :             for( long nX = 0L; nX < nWidth; nX++ )
     678           0 :                 pColorSet[ pRAcc->GetPixel( nY, nX ).GetIndex() ].mbSet = 1;
     679             : 
     680           0 :         qsort( pColorSet, 256, sizeof( ImplColorSet ), ImplColorSetCmpFnc );
     681             : 
     682           0 :         for( n = 0; n < 256; n++ )
     683           0 :             if( !pColorSet[ n ].mbSet )
     684           0 :                 break;
     685             : 
     686           0 :         if( n )
     687           0 :             fPercentStep_2 = 45.0 / n;
     688             : 
     689           0 :         VECT_PROGRESS( pProgress, FRound( fPercent += 10.0 ) );
     690             : 
     691           0 :         for( sal_uInt16 i = 0; i < n; i++ )
     692             :         {
     693           0 :             const BitmapColor   aBmpCol( pRAcc->GetPaletteColor( pColorSet[ i ].mnIndex ) );
     694           0 :             const Color         aFindColor( aBmpCol.GetRed(), aBmpCol.GetGreen(), aBmpCol.GetBlue() );
     695             : //          const sal_uInt8         cLum = aFindColor.GetLuminance();
     696           0 :             ImplVectMap*        pMap = ImplExpand( pRAcc, aFindColor );
     697             : 
     698           0 :             VECT_PROGRESS( pProgress, FRound( fPercent += fPercentStep_2 ) );
     699             : 
     700           0 :             if( pMap )
     701             :             {
     702           0 :                 aPolyPoly.Clear();
     703           0 :                 ImplCalculate( pMap, aPolyPoly, cReduce, nFlags );
     704           0 :                 delete pMap;
     705             : 
     706           0 :                 if( aPolyPoly.Count() )
     707             :                 {
     708           0 :                     ImplLimitPolyPoly( aPolyPoly );
     709             : 
     710           0 :                     if( nFlags & BMP_VECTORIZE_REDUCE_EDGES )
     711           0 :                         aPolyPoly.Optimize( POLY_OPTIMIZE_EDGES );
     712             : 
     713           0 :                     if( aPolyPoly.Count() )
     714             :                     {
     715           0 :                         rMtf.AddAction( new MetaLineColorAction( aFindColor, sal_True ) );
     716           0 :                         rMtf.AddAction( new MetaFillColorAction( aFindColor, sal_True ) );
     717           0 :                         rMtf.AddAction( new MetaPolyPolygonAction( aPolyPoly ) );
     718             :                     }
     719             :                 }
     720             :             }
     721             : 
     722           0 :             VECT_PROGRESS( pProgress, FRound( fPercent += fPercentStep_2 ) );
     723           0 :         }
     724             : 
     725           0 :         delete[] (sal_uInt8*) pColorSet;
     726             : 
     727           0 :         if( rMtf.GetActionSize() )
     728             :         {
     729           0 :             MapMode         aMap( MAP_100TH_MM );
     730           0 :             VirtualDevice   aVDev;
     731           0 :             const Size      aLogSize1( aVDev.PixelToLogic( Size( 1, 1 ), aMap ) );
     732             : 
     733           0 :             rMtf.SetPrefMapMode( aMap );
     734           0 :             rMtf.SetPrefSize( Size( nWidth + 2, nHeight + 2 ) );
     735           0 :             rMtf.Move( 1, 1 );
     736           0 :             rMtf.Scale( aLogSize1.Width(), aLogSize1.Height() );
     737           0 :             bRet = sal_True;
     738           0 :         }
     739             :     }
     740             : 
     741           0 :     pBmp->ReleaseAccess( pRAcc );
     742           0 :     delete pBmp;
     743           0 :     VECT_PROGRESS( pProgress, 100 );
     744             : 
     745           0 :     return bRet;
     746             : }
     747             : 
     748           2 : sal_Bool ImplVectorizer::ImplVectorize( const Bitmap& rMonoBmp,
     749             :                                     PolyPolygon& rPolyPoly,
     750             :                                     sal_uLong nFlags, const Link* pProgress )
     751             : {
     752           2 :     Bitmap*             pBmp = new Bitmap( rMonoBmp );
     753             :     BitmapReadAccess*   pRAcc;
     754             :     ImplVectMap*        pMap;
     755           2 :     sal_Bool                bRet = sal_False;
     756             : 
     757           2 :     VECT_PROGRESS( pProgress, 10 );
     758             : 
     759           2 :     if( pBmp->GetBitCount() > 1 )
     760           0 :         pBmp->Convert( BMP_CONVERSION_1BIT_THRESHOLD );
     761             : 
     762           2 :     VECT_PROGRESS( pProgress, 30 );
     763             : 
     764           2 :     pRAcc = pBmp->AcquireReadAccess();
     765           2 :     pMap = ImplExpand( pRAcc, COL_BLACK );
     766           2 :     pBmp->ReleaseAccess( pRAcc );
     767           2 :     delete pBmp;
     768             : 
     769           2 :     VECT_PROGRESS( pProgress, 60 );
     770             : 
     771           2 :     if( pMap )
     772             :     {
     773           2 :         rPolyPoly.Clear();
     774           2 :         ImplCalculate( pMap, rPolyPoly, 0, nFlags );
     775           2 :         delete pMap;
     776           2 :         ImplLimitPolyPoly( rPolyPoly );
     777             : 
     778           2 :         if( nFlags & BMP_VECTORIZE_REDUCE_EDGES )
     779           2 :             rPolyPoly.Optimize( POLY_OPTIMIZE_EDGES );
     780             : 
     781             :         // #i14895#:setting the correct direction for polygons
     782             :         // that represent holes and non-holes; non-hole polygons
     783             :         // need to have a right orientation, holes need to have a
     784             :         // left orientation in order to be treated correctly by
     785             :         // several external tools like Flash viewers
     786           2 :         sal_Int32   nFirstPoly = -1;
     787           2 :         sal_uInt16  nCurPoly( 0 ), nCount( rPolyPoly.Count() );
     788             : 
     789           2 :         for( ; nCurPoly < nCount; ++nCurPoly )
     790             :         {
     791           0 :             const Polygon&      rPoly = rPolyPoly.GetObject( nCurPoly );
     792           0 :             const sal_uInt16    nSize( rPoly.GetSize() );
     793           0 :             sal_uInt16          nDepth( 0 ), i( 0 );
     794           0 :             const bool          bRight( rPoly.IsRightOrientated() );
     795             : 
     796           0 :             for( ; i < nCount; ++i )
     797           0 :                 if( ( i != nCurPoly ) && rPolyPoly.GetObject( i ).IsInside( rPoly[ 0 ] ) )
     798           0 :                     ++nDepth;
     799             : 
     800           0 :             const bool bHole( ( nDepth & 0x0001 ) == 1 );
     801             : 
     802           0 :             if( nSize && ( ( !bRight && !bHole ) || ( bRight && bHole ) ) )
     803             :             {
     804           0 :                 Polygon     aNewPoly( nSize );
     805           0 :                 sal_uInt16  nPrim( 0 ), nSec( nSize - 1 );
     806             : 
     807           0 :                 if( rPoly.HasFlags() )
     808             :                 {
     809           0 :                     while( nPrim < nSize )
     810             :                     {
     811           0 :                         aNewPoly.SetPoint( rPoly.GetPoint( nSec ), nPrim );
     812           0 :                         aNewPoly.SetFlags( nPrim++, rPoly.GetFlags( nSec-- ) );
     813             :                     }
     814             :                 }
     815             :                 else
     816           0 :                     while( nPrim < nSize )
     817           0 :                         aNewPoly.SetPoint( rPoly.GetPoint( nSec-- ), nPrim++ );
     818             : 
     819           0 :                 rPolyPoly.Replace( aNewPoly, nCurPoly );
     820             :             }
     821             : 
     822           0 :             if( ( 0 == nDepth ) && ( -1 == nFirstPoly ) )
     823           0 :                 nFirstPoly = nCurPoly;
     824             :         }
     825             : 
     826             :         // put outmost polygon to the front
     827           2 :         if( nFirstPoly > 0 )
     828             :         {
     829           0 :             const Polygon aFirst( rPolyPoly.GetObject( static_cast< sal_uInt16 >( nFirstPoly ) ) );
     830             : 
     831           0 :             rPolyPoly.Remove( static_cast< sal_uInt16 >( nFirstPoly ) );
     832           0 :             rPolyPoly.Insert( aFirst, 0 );
     833             :         }
     834             : 
     835           2 :         bRet = sal_True;
     836             :     }
     837             : 
     838           2 :     VECT_PROGRESS( pProgress, 100 );
     839             : 
     840           2 :     return bRet;
     841             : }
     842             : 
     843           2 : void ImplVectorizer::ImplLimitPolyPoly( PolyPolygon& rPolyPoly )
     844             : {
     845           2 :     if( rPolyPoly.Count() > VECT_POLY_MAX )
     846             :     {
     847           0 :         PolyPolygon aNewPolyPoly;
     848           0 :         long        nReduce = 0;
     849             :         sal_uInt16      nNewCount;
     850             : 
     851           0 :         do
     852             :         {
     853           0 :             aNewPolyPoly.Clear();
     854           0 :             nReduce++;
     855             : 
     856           0 :             for( sal_uInt16 i = 0, nCount = rPolyPoly.Count(); i < nCount; i++ )
     857             :             {
     858           0 :                 const Rectangle aBound( rPolyPoly[ i ].GetBoundRect() );
     859             : 
     860           0 :                 if( aBound.GetWidth() > nReduce && aBound.GetHeight() > nReduce )
     861             :                 {
     862           0 :                     if( rPolyPoly[ i ].GetSize() )
     863           0 :                         aNewPolyPoly.Insert( rPolyPoly[ i ] );
     864             :                 }
     865             :             }
     866             : 
     867           0 :             nNewCount = aNewPolyPoly.Count();
     868             :         }
     869             :         while( nNewCount > VECT_POLY_MAX );
     870             : 
     871           0 :         rPolyPoly = aNewPolyPoly;
     872             :     }
     873           2 : }
     874             : 
     875           2 : ImplVectMap* ImplVectorizer::ImplExpand( BitmapReadAccess* pRAcc, const Color& rColor )
     876             : {
     877           2 :     ImplVectMap* pMap = NULL;
     878             : 
     879           2 :        if( pRAcc && pRAcc->Width() && pRAcc->Height() )
     880             :     {
     881           2 :         const long          nOldWidth = pRAcc->Width();
     882           2 :         const long          nOldHeight = pRAcc->Height();
     883           2 :         const long          nNewWidth = ( nOldWidth << 2L ) + 4L;
     884           2 :         const long          nNewHeight = ( nOldHeight << 2L ) + 4L;
     885           2 :         const BitmapColor   aTest( pRAcc->GetBestMatchingColor( rColor ) );
     886           2 :         long*               pMapIn = new long[ std::max( nOldWidth, nOldHeight ) ];
     887           2 :         long*               pMapOut = new long[ std::max( nOldWidth, nOldHeight ) ];
     888             :         long                nX, nY, nTmpX, nTmpY;
     889             : 
     890           2 :         pMap = new ImplVectMap( nNewWidth, nNewHeight );
     891             : 
     892         308 :         for( nX = 0L; nX < nOldWidth; nX++ )
     893         306 :             VECT_MAP( pMapIn, pMapOut, nX );
     894             : 
     895         333 :         for( nY = 0L, nTmpY = 5L; nY < nOldHeight; nY++, nTmpY += 4L )
     896             :         {
     897       50405 :             for( nX = 0L; nX < nOldWidth; )
     898             :             {
     899       49743 :                 if( pRAcc->GetPixel( nY, nX ) == aTest )
     900             :                 {
     901           0 :                     nTmpX = pMapIn[ nX++ ];
     902           0 :                     nTmpY -= 3L;
     903             : 
     904           0 :                     pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
     905           0 :                     pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
     906           0 :                     pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
     907           0 :                     pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
     908             : 
     909           0 :                     while( nX < nOldWidth && pRAcc->GetPixel( nY, nX ) == aTest )
     910           0 :                          nX++;
     911             : 
     912           0 :                     nTmpX = pMapOut[ nX - 1L ];
     913           0 :                     nTmpY -= 3L;
     914             : 
     915           0 :                     pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
     916           0 :                     pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
     917           0 :                     pMap->Set( nTmpY++, nTmpX, VECT_CONT_INDEX );
     918           0 :                     pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
     919             :                 }
     920             :                 else
     921       49743 :                     nX++;
     922             :             }
     923             :         }
     924             : 
     925         333 :         for( nY = 0L; nY < nOldHeight; nY++ )
     926         331 :             VECT_MAP( pMapIn, pMapOut, nY );
     927             : 
     928         308 :         for( nX = 0L, nTmpX = 5L; nX < nOldWidth; nX++, nTmpX += 4L )
     929             :         {
     930       50355 :             for( nY = 0L; nY < nOldHeight; )
     931             :             {
     932       49743 :                 if( pRAcc->GetPixel( nY, nX ) == aTest )
     933             :                 {
     934           0 :                     nTmpX -= 3L;
     935           0 :                     nTmpY = pMapIn[ nY++ ];
     936             : 
     937           0 :                     pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
     938           0 :                     pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
     939           0 :                     pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
     940           0 :                     pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
     941             : 
     942           0 :                     while( nY < nOldHeight && pRAcc->GetPixel( nY, nX ) == aTest )
     943           0 :                         nY++;
     944             : 
     945           0 :                     nTmpX -= 3L;
     946           0 :                     nTmpY = pMapOut[ nY - 1L ];
     947             : 
     948           0 :                     pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
     949           0 :                     pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
     950           0 :                     pMap->Set( nTmpY, nTmpX++, VECT_CONT_INDEX );
     951           0 :                     pMap->Set( nTmpY, nTmpX, VECT_CONT_INDEX );
     952             :                 }
     953             :                 else
     954       49743 :                     nY++;
     955             :             }
     956             :         }
     957             : 
     958             :         // cleanup
     959           2 :         delete[] pMapIn;
     960           2 :         delete[] pMapOut;
     961             :     }
     962             : 
     963           2 :     return pMap;
     964             : }
     965             : 
     966           2 : void ImplVectorizer::ImplCalculate( ImplVectMap* pMap, PolyPolygon& rPolyPoly, sal_uInt8 cReduce, sal_uLong nFlags )
     967             : {
     968           2 :     const long nWidth = pMap->Width(), nHeight= pMap->Height();
     969             : 
     970        1334 :     for( long nY = 0L; nY < nHeight; nY++ )
     971             :     {
     972        1332 :         long    nX = 0L;
     973        1332 :         bool    bInner = true;
     974             : 
     975        2664 :         while( nX < nWidth )
     976             :         {
     977             :             // skip free
     978      808776 :             while( ( nX < nWidth ) && pMap->IsFree( nY, nX ) )
     979      806112 :                 nX++;
     980             : 
     981        1332 :             if( nX == nWidth )
     982        1332 :                 break;
     983             : 
     984           0 :             if( pMap->IsCont( nY, nX ) )
     985             :             {
     986             :                 // new contour
     987           0 :                 ImplChain   aChain;
     988           0 :                 const Point aStartPt( nX++, nY );
     989             : 
     990             :                 // get chain code
     991           0 :                 aChain.ImplBeginAdd( aStartPt );
     992           0 :                 ImplGetChain( pMap, aStartPt, aChain );
     993             : 
     994           0 :                 if( nFlags & BMP_VECTORIZE_INNER )
     995           0 :                     aChain.ImplEndAdd( bInner ? VECT_POLY_INLINE_INNER : VECT_POLY_INLINE_OUTER );
     996             :                 else
     997           0 :                     aChain.ImplEndAdd( bInner ? VECT_POLY_OUTLINE_INNER : VECT_POLY_OUTLINE_OUTER );
     998             : 
     999           0 :                 const Polygon& rPoly = aChain.ImplGetPoly();
    1000             : 
    1001           0 :                 if( rPoly.GetSize() > 2 )
    1002             :                 {
    1003           0 :                     if( cReduce )
    1004             :                     {
    1005           0 :                         const Rectangle aBound( rPoly.GetBoundRect() );
    1006             : 
    1007           0 :                         if( aBound.GetWidth() > cReduce && aBound.GetHeight() > cReduce )
    1008           0 :                             rPolyPoly.Insert( rPoly );
    1009             :                     }
    1010             :                     else
    1011           0 :                         rPolyPoly.Insert( rPoly  );
    1012             :                 }
    1013             : 
    1014             :                 // skip rest of detected contour
    1015           0 :                 while( pMap->IsCont( nY, nX ) )
    1016           0 :                     nX++;
    1017             :             }
    1018             :             else
    1019             :             {
    1020             :                 // process done segment
    1021           0 :                 const long nStartSegX = nX++;
    1022             : 
    1023           0 :                 while( pMap->IsDone( nY, nX ) )
    1024           0 :                     nX++;
    1025             : 
    1026           0 :                 if( ( ( nX - nStartSegX ) == 1L ) || ( ImplIsUp( pMap, nY, nStartSegX ) != ImplIsUp( pMap, nY, nX - 1L ) ) )
    1027           0 :                     bInner = !bInner;
    1028             :             }
    1029             :         }
    1030             :     }
    1031           2 : }
    1032             : 
    1033           0 : sal_Bool ImplVectorizer::ImplGetChain(  ImplVectMap* pMap, const Point& rStartPt, ImplChain& rChain )
    1034             : {
    1035           0 :     long                nActX = rStartPt.X();
    1036           0 :     long                nActY = rStartPt.Y();
    1037             :     long                nTryX;
    1038             :     long                nTryY;
    1039             :     sal_uLong               nFound;
    1040           0 :     sal_uLong               nLastDir = 0UL;
    1041             :     sal_uLong               nDir;
    1042             : 
    1043           0 :     do
    1044             :     {
    1045           0 :         nFound = 0UL;
    1046             : 
    1047             :         // first try last direction
    1048           0 :         nTryX = nActX + aImplMove[ nLastDir ].nDX;
    1049           0 :         nTryY = nActY + aImplMove[ nLastDir ].nDY;
    1050             : 
    1051           0 :         if( pMap->IsCont( nTryY, nTryX ) )
    1052             :         {
    1053           0 :             rChain.ImplAdd( (sal_uInt8) nLastDir );
    1054           0 :             pMap->Set( nActY = nTryY, nActX = nTryX, VECT_DONE_INDEX );
    1055           0 :             nFound = 1UL;
    1056             :         }
    1057             :         else
    1058             :         {
    1059             :             // try other directions
    1060           0 :             for( nDir = 0UL; nDir < 8UL; nDir++ )
    1061             :             {
    1062             :                 // we already tried nLastDir
    1063           0 :                 if( nDir != nLastDir )
    1064             :                 {
    1065           0 :                     nTryX = nActX + aImplMove[ nDir ].nDX;
    1066           0 :                     nTryY = nActY + aImplMove[ nDir ].nDY;
    1067             : 
    1068           0 :                     if( pMap->IsCont( nTryY, nTryX ) )
    1069             :                     {
    1070           0 :                         rChain.ImplAdd( (sal_uInt8) nDir );
    1071           0 :                         pMap->Set( nActY = nTryY, nActX = nTryX, VECT_DONE_INDEX );
    1072           0 :                         nFound = 1UL;
    1073           0 :                         nLastDir = nDir;
    1074           0 :                         break;
    1075             :                     }
    1076             :                 }
    1077             :             }
    1078             :         }
    1079             :     }
    1080             :     while( nFound );
    1081             : 
    1082           0 :     return sal_True;
    1083             : }
    1084             : 
    1085           0 : sal_Bool ImplVectorizer::ImplIsUp( ImplVectMap* pMap, long nY, long nX ) const
    1086             : {
    1087           0 :     if( pMap->IsDone( nY - 1L, nX ) )
    1088           0 :         return sal_True;
    1089           0 :     else if( pMap->IsDone( nY + 1L, nX ) )
    1090           0 :         return sal_False;
    1091           0 :     else if( pMap->IsDone( nY - 1L, nX - 1L ) || pMap->IsDone( nY - 1L, nX + 1L ) )
    1092           0 :         return sal_True;
    1093             :     else
    1094           0 :         return sal_False;
    1095         465 : }
    1096             : 
    1097             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10