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