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