LCOV - code coverage report
Current view: top level - vcl/source/gdi - impvect.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 511 0.2 %
Date: 2014-11-03 Functions: 2 37 5.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10