|
1 /* |
|
2 * Copyright (c) 2008 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: NVG Decoder source file |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include "nvgfittoviewbox.h" |
|
20 |
|
21 const TReal KZero = 0.0; |
|
22 const TReal KOne = 1.0; |
|
23 |
|
24 |
|
25 // --------------------------------------------------------------------------- |
|
26 // 2 Phase Constructor |
|
27 // --------------------------------------------------------------------------- |
|
28 CNvgFitToViewBoxImpl* CNvgFitToViewBoxImpl::NewL() |
|
29 { |
|
30 CNvgFitToViewBoxImpl* self = new ( ELeave ) CNvgFitToViewBoxImpl(); |
|
31 CleanupStack::PushL( self ); |
|
32 self->ConstructL(); |
|
33 CleanupStack::Pop(self); |
|
34 |
|
35 return self; |
|
36 } |
|
37 |
|
38 |
|
39 |
|
40 // --------------------------------------------------------------------------- |
|
41 // 2 Phase Constructor |
|
42 // --------------------------------------------------------------------------- |
|
43 CNvgFitToViewBoxImpl* CNvgFitToViewBoxImpl::NewLC() |
|
44 { |
|
45 CNvgFitToViewBoxImpl* self = new ( ELeave ) CNvgFitToViewBoxImpl(); |
|
46 CleanupStack::PushL( self ); |
|
47 self->ConstructL(); |
|
48 |
|
49 return self; |
|
50 } |
|
51 |
|
52 |
|
53 |
|
54 // --------------------------------------------------------------------------- |
|
55 // Constuctor |
|
56 // --------------------------------------------------------------------------- |
|
57 CNvgFitToViewBoxImpl::CNvgFitToViewBoxImpl(): iM00(KOne), |
|
58 iM01(KZero), |
|
59 iM02(KZero), |
|
60 iM10(KZero), |
|
61 iM11(KOne), |
|
62 iM12(KZero), |
|
63 iViewBoxDefined(EFalse), |
|
64 iAlign(ENvgPreserveAspectRatio_XmidYmid), |
|
65 iMeetSlice(ENvgMeet) |
|
66 { |
|
67 ivbX = 0.0; |
|
68 ivbY = 0.0; |
|
69 ivbW = 0.0; |
|
70 ivbH = 0.0; |
|
71 |
|
72 } |
|
73 |
|
74 // --------------------------------------------------------------------------- |
|
75 // |
|
76 // --------------------------------------------------------------------------- |
|
77 void CNvgFitToViewBoxImpl::ConstructL() |
|
78 { |
|
79 |
|
80 } |
|
81 |
|
82 |
|
83 |
|
84 // --------------------------------------------------------------------------- |
|
85 // Destructor |
|
86 // --------------------------------------------------------------------------- |
|
87 CNvgFitToViewBoxImpl::~CNvgFitToViewBoxImpl() |
|
88 { |
|
89 |
|
90 } |
|
91 |
|
92 |
|
93 |
|
94 // --------------------------------------------------------------------------- |
|
95 // Computation of the viewport to viewbox transformation matrix |
|
96 // --------------------------------------------------------------------------- |
|
97 void CNvgFitToViewBoxImpl::SetWindowViewportTrans(TRect aViewPort, TSize aSize) |
|
98 { |
|
99 |
|
100 //VIEWPORT NUMBERS |
|
101 TReal lViewPortX = aViewPort.iTl.iX; |
|
102 TReal lViewPortY = aViewPort.iTl.iY; |
|
103 TReal lViewPortWidth = aViewPort.Width(); |
|
104 TReal lViewPortHeight = aViewPort.Height(); |
|
105 |
|
106 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); |
|
107 vgTranslate(lViewPortX, lViewPortY ); |
|
108 |
|
109 /* 2. Scale */ |
|
110 |
|
111 TReal lViewBoxXmin; |
|
112 TReal lViewBoxYmin; |
|
113 TReal lViewBoxWidth; |
|
114 TReal lViewBoxHeight; |
|
115 |
|
116 if ( iViewBoxDefined ) |
|
117 { |
|
118 lViewBoxXmin = ivbX; |
|
119 lViewBoxYmin = ivbY; |
|
120 lViewBoxWidth = ivbW; |
|
121 lViewBoxHeight = ivbH; |
|
122 } |
|
123 else |
|
124 { |
|
125 //this will default viewBox to <svg> element width and height |
|
126 lViewBoxXmin = 0; |
|
127 lViewBoxYmin = 0; |
|
128 lViewBoxWidth = aSize.iWidth; |
|
129 lViewBoxHeight = aSize.iHeight; |
|
130 } |
|
131 |
|
132 |
|
133 if ( lViewBoxWidth == 0.0f || lViewBoxHeight == 0.0f ) |
|
134 { |
|
135 return; |
|
136 } |
|
137 |
|
138 |
|
139 TReal sx = lViewPortWidth / lViewBoxWidth; |
|
140 TReal sy = lViewPortHeight / lViewBoxHeight; |
|
141 |
|
142 if ( sx == 0.0f || sy == 0.0f ) |
|
143 { |
|
144 return; |
|
145 } |
|
146 |
|
147 |
|
148 |
|
149 TReal xtrans = TReal( -1.0f ) * lViewBoxXmin; |
|
150 TReal ytrans = TReal( -1.0f ) * lViewBoxYmin; |
|
151 |
|
152 switch ( iAlign ) |
|
153 { |
|
154 case ENvgPreserveAspectRatio_None: |
|
155 /* Non uniform scaling */ |
|
156 //none - Do not force uniform scaling. |
|
157 //Scale the graphic content of the given element |
|
158 //non-uniformly if necessary such that the element's |
|
159 //bounding box exactly matches the viewport rectangle. |
|
160 |
|
161 //(Note: if <align> is none, then the optional <meetOrSlice> value is ignored.) |
|
162 break; |
|
163 |
|
164 case ENvgPreserveAspectRatio_XminYmin: |
|
165 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
|
166 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
|
167 |
|
168 if (iMeetSlice == ENvgMeet) |
|
169 { |
|
170 if ( sx > sy ) |
|
171 { |
|
172 sx = sy; |
|
173 //no change for xtrans...default above |
|
174 } |
|
175 else // ( sx < sy ) |
|
176 { |
|
177 sy = sx; |
|
178 //no change for ytrans...default above |
|
179 } |
|
180 } |
|
181 else if (iMeetSlice == ENvgSlice) |
|
182 { |
|
183 if (sx > sy) |
|
184 { |
|
185 sy = sx; |
|
186 } |
|
187 else // ( sx < sy ) |
|
188 { |
|
189 sx = sy; |
|
190 } |
|
191 } |
|
192 break; |
|
193 |
|
194 case ENvgPreserveAspectRatio_XmidYmin: |
|
195 //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport. |
|
196 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
|
197 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
|
198 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
|
199 |
|
200 if (iMeetSlice == ENvgMeet) |
|
201 { |
|
202 if ( sx > sy ) |
|
203 { |
|
204 sx = sy; |
|
205 xtrans = ( ( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) )\ |
|
206 * 0.5 ) / sx - lViewBoxXmin; |
|
207 } |
|
208 else // ( sx < sy ) |
|
209 { |
|
210 sy = sx; |
|
211 //no change for ytrans...default above |
|
212 } |
|
213 } |
|
214 else if (iMeetSlice == ENvgSlice) |
|
215 { |
|
216 if ( sx > sy ) |
|
217 { |
|
218 sy = sx; |
|
219 } |
|
220 else //( sx < sy ) |
|
221 { |
|
222 sx = sy; |
|
223 xtrans = lViewPortWidth - sx*lViewBoxWidth; |
|
224 xtrans = xtrans/sx; |
|
225 xtrans = xtrans/2.0 - lViewBoxXmin; |
|
226 } |
|
227 } |
|
228 break; |
|
229 |
|
230 case ENvgPreserveAspectRatio_XmaxYmin: |
|
231 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
|
232 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
|
233 if (iMeetSlice == ENvgMeet) |
|
234 { |
|
235 if ( sx > sy ) |
|
236 { |
|
237 sx = sy; |
|
238 |
|
239 xtrans = (( lViewPortWidth - ( ( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx\ |
|
240 - lViewBoxXmin; |
|
241 } |
|
242 else // ( sx < sy ) |
|
243 { |
|
244 sy = sx; |
|
245 //no change for ytrans...default above |
|
246 } |
|
247 } |
|
248 else if (iMeetSlice == ENvgSlice) |
|
249 { |
|
250 if ( sx > sy ) |
|
251 { |
|
252 sy = sx; |
|
253 //no change for ytrans...default above |
|
254 } |
|
255 else // ( sx < sy ) |
|
256 { |
|
257 sx = sy; |
|
258 xtrans = lViewPortWidth - sx*lViewBoxWidth; |
|
259 xtrans = xtrans/sx - lViewBoxXmin; |
|
260 } |
|
261 } |
|
262 break; |
|
263 |
|
264 case ENvgPreserveAspectRatio_XminYmid: |
|
265 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
|
266 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
|
267 if (iMeetSlice == ENvgMeet) |
|
268 { |
|
269 if ( sx > sy ) |
|
270 { |
|
271 sx = sy; |
|
272 //no change for xtrans...default above |
|
273 } |
|
274 else // ( sx < sy ) |
|
275 { |
|
276 sy = sx; |
|
277 ytrans = ( ( TReal ) |
|
278 ( lViewPortHeight - ( ( TReal ) ( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) )\ |
|
279 * TReal(.5) ) /sy - lViewBoxYmin; |
|
280 } |
|
281 } |
|
282 else if (iMeetSlice == ENvgSlice) |
|
283 { |
|
284 if ( sx > sy ) |
|
285 { |
|
286 sy = sx; |
|
287 ytrans = lViewPortHeight - sx*lViewBoxHeight; |
|
288 ytrans = ytrans/sx; |
|
289 ytrans = ytrans/2.0 - lViewBoxYmin; |
|
290 } |
|
291 else |
|
292 { |
|
293 sx = sy; |
|
294 } |
|
295 } |
|
296 break; |
|
297 |
|
298 case ENvgPreserveAspectRatio_XmidYmid: |
|
299 //(default) case |
|
300 //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport. |
|
301 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
|
302 if (iMeetSlice == ENvgMeet) |
|
303 { |
|
304 if ( sx > sy ) |
|
305 { |
|
306 sx = sy; |
|
307 xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) * \ |
|
308 0.5 ) / sx - lViewBoxXmin; |
|
309 |
|
310 } |
|
311 else if ( sx < sy ) |
|
312 { |
|
313 sy = sx; |
|
314 |
|
315 ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) * \ |
|
316 0.5 ) /sy - lViewBoxYmin; |
|
317 } |
|
318 } |
|
319 else if (iMeetSlice == ENvgSlice) |
|
320 { |
|
321 if ( sx > sy ) |
|
322 { |
|
323 sy = sx; |
|
324 ytrans = lViewPortHeight - sx*lViewBoxHeight; |
|
325 ytrans = ytrans/sx; |
|
326 ytrans = ytrans/2.0 - lViewBoxYmin; |
|
327 } |
|
328 else // ( sx < sy ) |
|
329 { |
|
330 sx = sy; |
|
331 xtrans = lViewPortWidth - sx*lViewBoxWidth; |
|
332 xtrans = xtrans/sx; |
|
333 xtrans = xtrans/2.0 - lViewBoxXmin; |
|
334 } |
|
335 } |
|
336 break; |
|
337 |
|
338 case ENvgPreserveAspectRatio_XmaxYmid: |
|
339 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
|
340 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
|
341 if (iMeetSlice == ENvgMeet) |
|
342 { |
|
343 if ( sx > sy ) |
|
344 { |
|
345 sx = sy; |
|
346 xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx \ |
|
347 - lViewBoxXmin; |
|
348 } |
|
349 else //( sx < sy ) |
|
350 { |
|
351 sy = sx; |
|
352 |
|
353 ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) \ |
|
354 * 0.5 ) /sy - lViewBoxYmin; |
|
355 } |
|
356 } |
|
357 else if (iMeetSlice == ENvgSlice) |
|
358 { |
|
359 if ( sx > sy ) |
|
360 { |
|
361 sy = sx; |
|
362 ytrans = lViewPortHeight - sx*lViewBoxHeight; |
|
363 ytrans = ytrans/sx; |
|
364 ytrans = ytrans/2.0 - lViewBoxYmin; |
|
365 } |
|
366 else //( sx < sy ) |
|
367 { |
|
368 sx = sy; |
|
369 xtrans = lViewPortWidth - sx*lViewBoxWidth; |
|
370 xtrans = xtrans/sx - lViewBoxXmin; |
|
371 } |
|
372 } |
|
373 break; |
|
374 |
|
375 case ENvgPreserveAspectRatio_XminYmax: |
|
376 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
|
377 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
|
378 if (iMeetSlice == ENvgMeet) |
|
379 { |
|
380 if ( sx > sy ) |
|
381 { |
|
382 sx = sy; |
|
383 //no change for xtrans...default above |
|
384 } |
|
385 else //( sx < sy ) |
|
386 { |
|
387 sy = sx; |
|
388 |
|
389 ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \ |
|
390 - lViewBoxYmin; |
|
391 } |
|
392 } |
|
393 else if (iMeetSlice == ENvgSlice) |
|
394 { |
|
395 if ( sx > sy ) |
|
396 { |
|
397 sy = sx; |
|
398 ytrans = lViewPortHeight - sx*lViewBoxHeight; |
|
399 ytrans = ytrans/sx - lViewBoxYmin; |
|
400 } |
|
401 else //( sx < sy ) |
|
402 { |
|
403 sx = sy; |
|
404 } |
|
405 } |
|
406 break; |
|
407 |
|
408 case ENvgPreserveAspectRatio_XmidYmax: |
|
409 //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport. |
|
410 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
|
411 if (iMeetSlice == ENvgMeet) |
|
412 { |
|
413 if ( sx > sy ) |
|
414 { |
|
415 sx = sy; |
|
416 |
|
417 xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) \ |
|
418 * 0.5 ) / sx - lViewBoxXmin; |
|
419 } |
|
420 else //( sx < sy ) |
|
421 { |
|
422 sy = sx; |
|
423 |
|
424 ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \ |
|
425 - lViewBoxYmin; |
|
426 } |
|
427 } |
|
428 else if (iMeetSlice == ENvgSlice) |
|
429 { |
|
430 if ( sx > sy ) |
|
431 { |
|
432 sy = sx; |
|
433 ytrans = lViewPortHeight - sx*lViewBoxHeight; |
|
434 ytrans = ytrans/sx - lViewBoxYmin; |
|
435 } |
|
436 else //( sx < sy ) |
|
437 { |
|
438 sx = sy; |
|
439 xtrans = lViewPortWidth - sx*lViewBoxWidth; |
|
440 xtrans = xtrans/sx; |
|
441 xtrans = xtrans/2.0 - lViewBoxXmin; |
|
442 } |
|
443 } |
|
444 break; |
|
445 |
|
446 case ENvgPreserveAspectRatio_XmaxYmax: |
|
447 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
|
448 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
|
449 if (iMeetSlice == ENvgMeet) |
|
450 { |
|
451 if ( sx > sy ) |
|
452 { |
|
453 sx = sy; |
|
454 |
|
455 xtrans = (( lViewPortWidth - (( lViewBoxWidth / lViewBoxHeight ) * lViewPortHeight ) ) ) / sx\ |
|
456 - lViewBoxXmin; |
|
457 } |
|
458 else //( sx < sy ) |
|
459 { |
|
460 sy = sx; |
|
461 |
|
462 ytrans = (( lViewPortHeight - (( lViewBoxHeight / lViewBoxWidth ) * lViewPortWidth ) ) ) /sy \ |
|
463 - lViewBoxYmin; |
|
464 } |
|
465 } |
|
466 else if (iMeetSlice == ENvgSlice) |
|
467 { |
|
468 if ( sx > sy ) |
|
469 { |
|
470 sy = sx; |
|
471 ytrans = lViewPortHeight - sx*lViewBoxHeight; |
|
472 ytrans = ytrans/sx - lViewBoxYmin; |
|
473 } |
|
474 else //( sx < sy ) |
|
475 { |
|
476 sx = sy; |
|
477 xtrans = lViewPortWidth - sx*lViewBoxWidth; |
|
478 xtrans = xtrans/sx - lViewBoxXmin; |
|
479 } |
|
480 } |
|
481 break; |
|
482 |
|
483 default: |
|
484 break; |
|
485 } |
|
486 vgScale( sx, sy); |
|
487 |
|
488 vgTranslate( xtrans, ytrans ); |
|
489 |
|
490 } |
|
491 |
|
492 void CNvgFitToViewBoxImpl::Concatenate( TReal aM00, TReal aM01, TReal aM02, TReal aM10, TReal aM11, TReal aM12 ) |
|
493 { |
|
494 TReal m0, m1; |
|
495 m0 = iM00; |
|
496 m1 = iM01; |
|
497 iM00 = aM00 * m0 + aM10 * m1; |
|
498 iM01 = aM01 * m0 + aM11 * m1; |
|
499 iM02 += aM02 * m0 + aM12 * m1; |
|
500 m0 = iM10; |
|
501 m1 = iM11; |
|
502 iM11 = aM01 * m0 + aM11 * m1; |
|
503 iM10 = aM00 * m0 + aM10 * m1; |
|
504 iM12 += aM02 * m0 + aM12 * m1; |
|
505 } |
|
506 //--------------------------------EndOfFile------------------------------------ |