xref: /AOO41X/main/vcl/source/gdi/impvect.cxx (revision 9f62ea84a806e17e6f2bbff75724a7257a0eb5d9)
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