|
1 /* |
|
2 * Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: Graphics Extension Library source file |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "GfxFlatteningPathIterator.h" |
|
20 #include "GfxShape.h" |
|
21 #include "GfxAffineTransform.h" |
|
22 |
|
23 |
|
24 // --------------------------------------------------------------------------- |
|
25 // Constructors |
|
26 // --------------------------------------------------------------------------- |
|
27 CGfxFlatteningPathIterator::CGfxFlatteningPathIterator( TInt32 aLimit ) |
|
28 : iIdx( 0 ), |
|
29 iSegType( EGfxSegClose ), |
|
30 iIsDone( EFalse ), |
|
31 iLimit( aLimit ) |
|
32 { |
|
33 } |
|
34 |
|
35 |
|
36 // --------------------------------------------------------------------------- |
|
37 // Create a new instance. |
|
38 // --------------------------------------------------------------------------- |
|
39 // -------------------------------------------------------------------------- |
|
40 // CGfxFlatteningPathIterator* CGfxFlatteningPathIterator::NewL( MGfxShape* aSrc, |
|
41 // --------------------------------------------------------------------------- |
|
42 CGfxFlatteningPathIterator* CGfxFlatteningPathIterator::NewL( MGfxShape* aSrc, |
|
43 TGfxAffineTransform* aAt, |
|
44 TInt32 aLimit ) |
|
45 { |
|
46 CGfxFlatteningPathIterator* self = new ( ELeave ) |
|
47 CGfxFlatteningPathIterator( aLimit ); |
|
48 |
|
49 CleanupStack::PushL( self ); |
|
50 self->ConstructL( aSrc, aAt ); |
|
51 CleanupStack::Pop(); |
|
52 return self; |
|
53 } |
|
54 |
|
55 // --------------------------------------------------------------------------- |
|
56 // Second phase in constructing this object. |
|
57 // --------------------------------------------------------------------------- |
|
58 void CGfxFlatteningPathIterator::ConstructL( MGfxShape* aSrc, |
|
59 TGfxAffineTransform* aAt ) |
|
60 { |
|
61 aSrc->GetPathIteratorL( aAt, iSrc ); |
|
62 iCoords = new ( ELeave ) RArray<TFloatFixPt>( 10 ); |
|
63 iCoords->AppendL( NULL ); |
|
64 iCoords->Remove(0); |
|
65 NextL(); |
|
66 } |
|
67 |
|
68 // --------------------------------------------------------------------------- |
|
69 // Destructor. |
|
70 // --------------------------------------------------------------------------- |
|
71 // -------------------------------------------------------------------------- |
|
72 // CGfxFlatteningPathIterator::~CGfxFlatteningPathIterator() |
|
73 // --------------------------------------------------------------------------- |
|
74 CGfxFlatteningPathIterator::~CGfxFlatteningPathIterator() |
|
75 { |
|
76 if ( iSrc ) |
|
77 { |
|
78 delete iSrc; |
|
79 iSrc = NULL; |
|
80 } |
|
81 if ( iCoords ) |
|
82 { |
|
83 iCoords->Close(); |
|
84 delete iCoords; |
|
85 iCoords = NULL; |
|
86 } |
|
87 } |
|
88 |
|
89 |
|
90 // -------------------------------------------------------------------------- |
|
91 // TGfxSegType CGfxFlatteningPathIterator::CurrentSegment( TFloatFixPt* aCoords ) |
|
92 // --------------------------------------------------------------------------- |
|
93 TGfxSegType CGfxFlatteningPathIterator::CurrentSegment( TFloatFixPt* aCoords ) |
|
94 { |
|
95 if ( iCoords->Count() > 0 && iCoords->Count() > iIdx ) |
|
96 { |
|
97 aCoords[0] = ( *iCoords )[iIdx]; |
|
98 aCoords[1] = ( *iCoords )[iIdx + 1]; |
|
99 } |
|
100 |
|
101 return iSegType; |
|
102 } |
|
103 |
|
104 |
|
105 // -------------------------------------------------------------------------- |
|
106 // TBool CGfxFlatteningPathIterator::IsDone() |
|
107 // --------------------------------------------------------------------------- |
|
108 TBool CGfxFlatteningPathIterator::IsDone() |
|
109 { |
|
110 return iIsDone; |
|
111 } |
|
112 |
|
113 |
|
114 // -------------------------------------------------------------------------- |
|
115 // void CGfxFlatteningPathIterator::Next() |
|
116 // --------------------------------------------------------------------------- |
|
117 void CGfxFlatteningPathIterator::NextL() |
|
118 { |
|
119 iIdx += 2; |
|
120 |
|
121 if ( iCoords->Count() <= 0 || iCoords->Count() <= iIdx ) |
|
122 { |
|
123 TFloatFixPt tmpcoords[6]; |
|
124 TInt i; |
|
125 |
|
126 iCoords->Reset(); |
|
127 iIdx = 0; |
|
128 if ( iSrc->IsDone() ) |
|
129 { |
|
130 iIsDone = ETrue; |
|
131 } |
|
132 else |
|
133 { |
|
134 iSegType = iSrc->CurrentSegment( tmpcoords ); |
|
135 switch ( iSegType ) |
|
136 { |
|
137 case EGfxSegMoveTo: |
|
138 iLastX = tmpcoords[0]; |
|
139 iLastY = tmpcoords[1]; |
|
140 iCoords->AppendL( iLastX ); |
|
141 iCoords->AppendL( iLastY ); |
|
142 break; |
|
143 case EGfxSegLineTo: |
|
144 iLastX = tmpcoords[0]; |
|
145 iLastY = tmpcoords[1]; |
|
146 iCoords->AppendL( iLastX ); |
|
147 iCoords->AppendL( iLastY ); |
|
148 break; |
|
149 case EGfxSegQuadTo: |
|
150 iCoords->AppendL( iLastX ); |
|
151 iCoords->AppendL( iLastY ); |
|
152 iCoords->AppendL( tmpcoords[0] ); |
|
153 iCoords->AppendL( tmpcoords[1] ); |
|
154 iCoords->AppendL( tmpcoords[2] ); |
|
155 iCoords->AppendL( tmpcoords[3] ); |
|
156 |
|
157 for ( i = 0; i < iLimit; i++ ) |
|
158 CreateSubcurveQuadL( iCoords ); |
|
159 //CreateSubcurveQuad(iCoords); |
|
160 //CreateSubcurveQuad(iCoords); |
|
161 //CreateSubcurveQuad(iCoords); |
|
162 |
|
163 iIdx = 2; |
|
164 iLastX = tmpcoords[2]; |
|
165 iLastY = tmpcoords[3]; |
|
166 iSegType = EGfxSegLineTo; |
|
167 break; |
|
168 case EGfxSegCubicTo: |
|
169 iCoords->AppendL( iLastX ); |
|
170 iCoords->AppendL( iLastY ); |
|
171 iCoords->AppendL( tmpcoords[0] ); |
|
172 iCoords->AppendL( tmpcoords[1] ); |
|
173 iCoords->AppendL( tmpcoords[2] ); |
|
174 iCoords->AppendL( tmpcoords[3] ); |
|
175 iCoords->AppendL( tmpcoords[4] ); |
|
176 iCoords->AppendL( tmpcoords[5] ); |
|
177 |
|
178 for ( i = 0; i < iLimit; i++ ) |
|
179 CreateSubcurveCubicL( iCoords ); |
|
180 |
|
181 iIdx = 2; |
|
182 iLastX = tmpcoords[4]; |
|
183 iLastY = tmpcoords[5]; |
|
184 iSegType = EGfxSegLineTo; |
|
185 break; |
|
186 case EGfxSegClose: // (cdm) |
|
187 iLastX = tmpcoords[0]; |
|
188 iLastY = tmpcoords[1]; |
|
189 iCoords->AppendL( iLastX ); |
|
190 iCoords->AppendL( iLastY ); |
|
191 break; |
|
192 |
|
193 default: |
|
194 break; |
|
195 } |
|
196 iSrc->NextL(); |
|
197 } |
|
198 } |
|
199 } |
|
200 |
|
201 // -------------------------------------------------------------------------- |
|
202 // void CGfxFlatteningPathIterator::SetFlatness( TFloatFixPt& aFlatness ) |
|
203 // --------------------------------------------------------------------------- |
|
204 void CGfxFlatteningPathIterator::SetFlatness( TFloatFixPt& aFlatness ) |
|
205 { |
|
206 iFlatness = aFlatness; |
|
207 } |
|
208 |
|
209 // -------------------------------------------------------------------------- |
|
210 // void CGfxFlatteningPathIterator::SetRecursionLimit( TInt32 aLimit ) |
|
211 // --------------------------------------------------------------------------- |
|
212 void CGfxFlatteningPathIterator::SetRecursionLimit( TInt32 aLimit ) |
|
213 { |
|
214 iLimit = aLimit; |
|
215 } |
|
216 |
|
217 // -------------------------------------------------------------------------- |
|
218 // TFloatFixPt CGfxFlatteningPathIterator::Flatness() |
|
219 // --------------------------------------------------------------------------- |
|
220 TFloatFixPt CGfxFlatteningPathIterator::Flatness() |
|
221 { |
|
222 return iFlatness; |
|
223 } |
|
224 |
|
225 // -------------------------------------------------------------------------- |
|
226 // TInt32 CGfxFlatteningPathIterator::RecursionLimit() |
|
227 // --------------------------------------------------------------------------- |
|
228 TInt32 CGfxFlatteningPathIterator::RecursionLimit() |
|
229 { |
|
230 return iLimit; |
|
231 } |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 // -------------------------------------------------------------------------- |
|
237 // void CGfxFlatteningPathIterator::CreateSubcurveQuad( RArray<TFloatFixPt>* aCtrlPoints ) |
|
238 // --------------------------------------------------------------------------- |
|
239 void CGfxFlatteningPathIterator::CreateSubcurveQuadL( RArray<TFloatFixPt>* aCtrlPoints ) |
|
240 { |
|
241 TInt32 ix = 0; |
|
242 TFloatFixPt x0, y0, xm, ym, x1, y1; |
|
243 TInt32 lCount; |
|
244 |
|
245 while ( ix + 5 < aCtrlPoints->Count() ) |
|
246 { |
|
247 lCount = ix; |
|
248 x0 = ( *aCtrlPoints )[lCount++]; |
|
249 y0 = ( *aCtrlPoints )[lCount++]; |
|
250 xm = ( *aCtrlPoints )[lCount++]; |
|
251 ym = ( *aCtrlPoints )[lCount++]; |
|
252 x1 = ( *aCtrlPoints )[lCount++]; |
|
253 y1 = ( *aCtrlPoints )[lCount++]; |
|
254 #ifdef SVG_FLOAT_BUILD |
|
255 x0 = ( x0 + xm ) * .5f; |
|
256 y0 = ( y0 + ym ) * .5f; |
|
257 x1 = ( x1 + xm ) * .5f; |
|
258 y1 = ( y1 + ym ) * .5f; |
|
259 xm = ( x0 + x1 ) * .5f; |
|
260 ym = ( y0 + y1 ) * .5f; |
|
261 #else |
|
262 x0 = ( x0 + xm ) >> 1; |
|
263 y0 = ( y0 + ym ) >> 1; |
|
264 x1 = ( x1 + xm ) >> 1; |
|
265 y1 = ( y1 + ym ) >> 1; |
|
266 xm = ( x0 + x1 ) >> 1; |
|
267 ym = ( y0 + y1 ) >> 1; |
|
268 #endif |
|
269 lCount=ix + 2; |
|
270 ( *aCtrlPoints )[lCount] = xm; |
|
271 ( *aCtrlPoints )[lCount + 1] = ym; |
|
272 aCtrlPoints->InsertL( TFloatFixPt( x0 ), lCount++); |
|
273 aCtrlPoints->InsertL( TFloatFixPt( y0 ), lCount ); |
|
274 aCtrlPoints->InsertL( TFloatFixPt( x1 ), ix + 6 ); |
|
275 aCtrlPoints->InsertL( TFloatFixPt( y1 ), ix + 7 ); |
|
276 ix += 8; |
|
277 } |
|
278 } |
|
279 |
|
280 // -------------------------------------------------------------------------- |
|
281 // void CGfxFlatteningPathIterator::CreateSubcurveCubic( RArray<TFloatFixPt>* aCtrlPoints ) |
|
282 // --------------------------------------------------------------------------- |
|
283 void CGfxFlatteningPathIterator::CreateSubcurveCubicL( RArray<TFloatFixPt>* aCtrlPoints ) |
|
284 { |
|
285 TInt32 ix = 0; |
|
286 TFloatFixPt x0, y0, xm, ym, xm1, ym1, xm2, ym2, x1, y1; |
|
287 TInt32 lCount; |
|
288 while ( ix + 7 < aCtrlPoints->Count() ) |
|
289 { |
|
290 lCount = ix; |
|
291 x0 = ( *aCtrlPoints )[lCount++]; |
|
292 y0 = ( *aCtrlPoints )[lCount++]; |
|
293 xm1 = ( *aCtrlPoints )[lCount++]; |
|
294 ym1 = ( *aCtrlPoints )[lCount++]; |
|
295 xm2 = ( *aCtrlPoints )[lCount++]; |
|
296 ym2 = ( *aCtrlPoints )[lCount++]; |
|
297 x1 = ( *aCtrlPoints )[lCount++]; |
|
298 y1 = ( *aCtrlPoints )[lCount ]; |
|
299 |
|
300 #ifdef SVG_FLOAT_BUILD |
|
301 x0 = ( x0 + xm1 ) * .5f; |
|
302 y0 = ( y0 + ym1 ) * .5f; |
|
303 x1 = ( x1 + xm2 ) * .5f; |
|
304 y1 = ( y1 + ym2 ) * .5f; |
|
305 xm = ( xm1 + xm2 ) * .5f; |
|
306 ym = ( ym1 + ym2 ) * .5f; |
|
307 xm1 = ( x0 + xm ) * .5f; |
|
308 ym1 = ( y0 + ym ) * .5f; |
|
309 xm2 = ( x1 + xm ) * .5f; |
|
310 ym2 = ( y1 + ym ) * .5f; |
|
311 xm = ( xm1 + xm2 ) * .5f; |
|
312 ym = ( ym1 + ym2 ) * .5f; |
|
313 #else |
|
314 x0 = ( x0 + xm1 ) >> 1; |
|
315 y0 = ( y0 + ym1 ) >> 1; |
|
316 x1 = ( x1 + xm2 ) >> 1; |
|
317 y1 = ( y1 + ym2 ) >> 1; |
|
318 xm = ( xm1 + xm2 ) >> 1; |
|
319 ym = ( ym1 + ym2 ) >> 1; |
|
320 xm1 = ( x0 + xm ) >> 1; |
|
321 ym1 = ( y0 + ym ) >> 1; |
|
322 xm2 = ( x1 + xm ) >> 1; |
|
323 ym2 = ( y1 + ym ) >> 1; |
|
324 xm = ( xm1 + xm2 ) >> 1; |
|
325 ym = ( ym1 + ym2 ) >> 1; |
|
326 #endif |
|
327 lCount=ix + 2; |
|
328 ( *aCtrlPoints )[lCount++] = x0; |
|
329 ( *aCtrlPoints )[lCount++] = y0; |
|
330 ( *aCtrlPoints )[lCount++] = xm1; |
|
331 ( *aCtrlPoints )[lCount++] = ym1; |
|
332 |
|
333 aCtrlPoints->InsertL( TFloatFixPt( y1 ), lCount); |
|
334 aCtrlPoints->InsertL( TFloatFixPt( x1 ), lCount ); |
|
335 aCtrlPoints->InsertL( TFloatFixPt( ym2 ), lCount ); |
|
336 aCtrlPoints->InsertL( TFloatFixPt( xm2 ), lCount ); |
|
337 aCtrlPoints->InsertL( TFloatFixPt( ym ), lCount ); |
|
338 aCtrlPoints->InsertL( TFloatFixPt( xm ), lCount ); |
|
339 ix += 12; |
|
340 } |
|
341 } |
|
342 |
|
343 |
|
344 // -------------------------------------------------------------------------- |
|
345 // void CGfxFlatteningPathIterator::PolygonizeL( CGfxEdgeListP* /* aRenderer */, TInt /* aFlatness */ ) |
|
346 // --------------------------------------------------------------------------- |
|
347 void CGfxFlatteningPathIterator::PolygonizeL( CGfxEdgeListP* /* aRenderer */, TInt /* aFlatness */ ) |
|
348 { |
|
349 } |