xref: /trunk/main/vcl/source/gdi/impvect.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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 
operator <(const ImplColorSet & rSet) const119cdf0e10cSrcweir inline sal_Bool ImplColorSet::operator<( const ImplColorSet& rSet ) const
120cdf0e10cSrcweir {
121cdf0e10cSrcweir     return( mbSet && ( !rSet.mbSet || ( maColor.GetLuminance() > rSet.maColor.GetLuminance() ) ) );
122cdf0e10cSrcweir }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir // ----------------------------------------------------------------------------
125cdf0e10cSrcweir 
operator >(const ImplColorSet & rSet) const126cdf0e10cSrcweir inline sal_Bool ImplColorSet::operator>( const ImplColorSet& rSet ) const
127cdf0e10cSrcweir {
128cdf0e10cSrcweir     return( !mbSet || ( rSet.mbSet && maColor.GetLuminance() < rSet.maColor.GetLuminance() ) );
129cdf0e10cSrcweir }
130cdf0e10cSrcweir 
131cdf0e10cSrcweir // ----------------------------------------------------------------------------
132cdf0e10cSrcweir 
ImplColorSetCmpFnc(const void * p1,const void * p2)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 
ImplGetRealSize() const172cdf0e10cSrcweir     sal_uLong               ImplGetRealSize() const { return mnRealSize; }
ImplSetRealSize(sal_uLong nRealSize)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 
ImplPointArray()183cdf0e10cSrcweir ImplPointArray::ImplPointArray() :
184cdf0e10cSrcweir     mpArray     ( NULL ),
185cdf0e10cSrcweir     mnSize      ( 0UL ),
186cdf0e10cSrcweir     mnRealSize  ( 0UL )
187cdf0e10cSrcweir 
188cdf0e10cSrcweir {
189cdf0e10cSrcweir }
190cdf0e10cSrcweir 
191cdf0e10cSrcweir // -----------------------------------------------------------------------------
192cdf0e10cSrcweir 
~ImplPointArray()193cdf0e10cSrcweir ImplPointArray::~ImplPointArray()
194cdf0e10cSrcweir {
195cdf0e10cSrcweir     if( mpArray )
196cdf0e10cSrcweir         rtl_freeMemory( mpArray );
197cdf0e10cSrcweir }
198cdf0e10cSrcweir 
199cdf0e10cSrcweir // -----------------------------------------------------------------------------
200cdf0e10cSrcweir 
ImplSetSize(sal_uLong nSize)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 
operator [](sal_uLong nPos)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 
operator [](sal_uLong nPos) const225cdf0e10cSrcweir 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 
ImplCreatePoly(Polygon & rPoly) const233cdf0e10cSrcweir 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 
ImplVectMap()251cdf0e10cSrcweir                     ImplVectMap() {};
252cdf0e10cSrcweir 
253cdf0e10cSrcweir public:
254cdf0e10cSrcweir 
255cdf0e10cSrcweir                     ImplVectMap( long nWidth, long nHeight );
256cdf0e10cSrcweir                     ~ImplVectMap();
257cdf0e10cSrcweir 
Width() const258cdf0e10cSrcweir     inline long     Width() const { return mnWidth; }
Height() const259cdf0e10cSrcweir     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 
ImplVectMap(long nWidth,long nHeight)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 
~ImplVectMap()290cdf0e10cSrcweir ImplVectMap::~ImplVectMap()
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     rtl_freeMemory( mpBuf );
293cdf0e10cSrcweir     rtl_freeMemory( mpScan );
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir // -----------------------------------------------------------------------------
297cdf0e10cSrcweir 
Set(long nY,long nX,sal_uInt8 cVal)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 
Get(long nY,long nX) const306cdf0e10cSrcweir 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 
IsFree(long nY,long nX) const313cdf0e10cSrcweir inline sal_Bool ImplVectMap::IsFree( long nY, long nX ) const
314cdf0e10cSrcweir {
315cdf0e10cSrcweir     return( VECT_FREE_INDEX == Get( nY, nX ) );
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir // -----------------------------------------------------------------------------
319cdf0e10cSrcweir 
IsCont(long nY,long nX) const320cdf0e10cSrcweir inline sal_Bool ImplVectMap::IsCont( long nY, long nX ) const
321cdf0e10cSrcweir {
322cdf0e10cSrcweir     return( VECT_CONT_INDEX == Get( nY, nX ) );
323cdf0e10cSrcweir }
324cdf0e10cSrcweir 
325cdf0e10cSrcweir // -----------------------------------------------------------------------------
326cdf0e10cSrcweir 
IsDone(long nY,long nX) const327cdf0e10cSrcweir 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 
ImplGetPoly()363cdf0e10cSrcweir     const Polygon&  ImplGetPoly() { return maPoly; }
364cdf0e10cSrcweir };
365cdf0e10cSrcweir 
366cdf0e10cSrcweir // -----------------------------------------------------------------------------
367cdf0e10cSrcweir 
ImplChain(sal_uLong nInitCount,long nResize)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 
~ImplChain()379cdf0e10cSrcweir ImplChain::~ImplChain()
380cdf0e10cSrcweir {
381cdf0e10cSrcweir     delete[] mpCodes;
382cdf0e10cSrcweir }
383cdf0e10cSrcweir 
384cdf0e10cSrcweir // -----------------------------------------------------------------------------
385cdf0e10cSrcweir 
ImplGetSpace()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 
ImplBeginAdd(const Point & rStartPt)400cdf0e10cSrcweir void ImplChain::ImplBeginAdd( const Point& rStartPt )
401cdf0e10cSrcweir {
402cdf0e10cSrcweir     maPoly = Polygon();
403cdf0e10cSrcweir     maStartPt = rStartPt;
404cdf0e10cSrcweir     mnCount = 0UL;
405cdf0e10cSrcweir }
406cdf0e10cSrcweir 
407cdf0e10cSrcweir // -----------------------------------------------------------------------------
408cdf0e10cSrcweir 
ImplAdd(sal_uInt8 nCode)409cdf0e10cSrcweir inline void ImplChain::ImplAdd( sal_uInt8 nCode )
410cdf0e10cSrcweir {
411cdf0e10cSrcweir     if( mnCount == mnArraySize )
412cdf0e10cSrcweir         ImplGetSpace();
413cdf0e10cSrcweir 
414cdf0e10cSrcweir     mpCodes[ mnCount++ ] = nCode;
415cdf0e10cSrcweir }
416cdf0e10cSrcweir 
417cdf0e10cSrcweir // -----------------------------------------------------------------------------
418cdf0e10cSrcweir 
ImplEndAdd(sal_uLong nFlag)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 
ImplPostProcess(const ImplPointArray & rArr)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 
ImplVectorizer()726cdf0e10cSrcweir ImplVectorizer::ImplVectorizer()
727cdf0e10cSrcweir {
728cdf0e10cSrcweir }
729cdf0e10cSrcweir 
730cdf0e10cSrcweir // -----------------------------------------------------------------------------
731cdf0e10cSrcweir 
~ImplVectorizer()732cdf0e10cSrcweir ImplVectorizer::~ImplVectorizer()
733cdf0e10cSrcweir {
734cdf0e10cSrcweir }
735cdf0e10cSrcweir 
736cdf0e10cSrcweir // -----------------------------------------------------------------------------
737cdf0e10cSrcweir 
ImplVectorize(const Bitmap & rColorBmp,GDIMetaFile & rMtf,sal_uInt8 cReduce,sal_uLong nFlags,const Link * pProgress)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 
ImplVectorize(const Bitmap & rMonoBmp,PolyPolygon & rPolyPoly,sal_uLong nFlags,const Link * pProgress)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 
ImplLimitPolyPoly(PolyPolygon & rPolyPoly)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 
ImplExpand(BitmapReadAccess * pRAcc,const Color & rColor)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 
ImplCalculate(ImplVectMap * pMap,PolyPolygon & rPolyPoly,sal_uInt8 cReduce,sal_uLong nFlags)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 
ImplGetChain(ImplVectMap * pMap,const Point & rStartPt,ImplChain & rChain)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 
ImplIsUp(ImplVectMap * pMap,long nY,long nX) const1190cdf0e10cSrcweir 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