23 ** |
23 ** |
24 ****************************************************************************/ |
24 ****************************************************************************/ |
25 |
25 |
26 #include "hbnvgfittoviewbox_p.h" |
26 #include "hbnvgfittoviewbox_p.h" |
27 |
27 |
28 const qreal Zero = 0.0f ; |
28 const qreal zero = 0.0f ; |
29 const qreal One = 1.0f ; |
29 const qreal one = 1.0f ; |
30 |
30 |
31 HbNvgFitToViewBoxImpl::HbNvgFitToViewBoxImpl() |
31 HbNvgFitToViewBoxImpl::HbNvgFitToViewBoxImpl() |
32 : mM00(One), |
32 : mM00(one), |
33 mM01(Zero), |
33 mM01(zero), |
34 mM02(Zero), |
34 mM02(zero), |
35 mM10(Zero), |
35 mM10(zero), |
36 mM11(One), |
36 mM11(one), |
37 mM12(Zero), |
37 mM12(zero), |
38 mViewBoxDefined(false), |
38 mViewBoxDefined(false), |
39 mAlign(HbNvgEngine::NvgPreserveAspectRatioXmidYmid), |
39 mAlign(HbNvgEngine::NvgPreserveAspectRatioXmidYmid), |
40 mMeetSlice(HbNvgEngine::NvgMeet) |
40 mMeetSlice(HbNvgEngine::NvgMeet) |
41 { |
41 { |
42 mVbX = 0.0; |
42 mVbX = 0.0; |
52 |
52 |
53 void HbNvgFitToViewBoxImpl::setWindowViewportTrans(const QRect &viewPort, const QSize &size) |
53 void HbNvgFitToViewBoxImpl::setWindowViewportTrans(const QRect &viewPort, const QSize &size) |
54 { |
54 { |
55 |
55 |
56 //VIEWPORT NUMBERS |
56 //VIEWPORT NUMBERS |
57 qreal lViewPortX = viewPort.left(); |
57 qreal viewPortX = viewPort.left(); |
58 qreal lViewPortY = viewPort.top(); |
58 qreal viewPortY = viewPort.top(); |
59 qreal lViewPortWidth = viewPort.width(); |
59 qreal viewPortWidth = viewPort.width(); |
60 qreal lViewPortHeight = viewPort.height(); |
60 qreal viewPortHeight = viewPort.height(); |
61 |
61 |
62 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); |
62 vgSeti(VG_MATRIX_MODE, VG_MATRIX_PATH_USER_TO_SURFACE); |
63 vgTranslate(lViewPortX, lViewPortY); |
63 vgTranslate(viewPortX, viewPortY); |
64 |
64 |
65 qreal lViewBoxXmin; |
65 qreal viewBoxXmin; |
66 qreal lViewBoxYmin; |
66 qreal viewBoxYmin; |
67 qreal lViewBoxWidth; |
67 qreal viewBoxWidth; |
68 qreal lViewBoxHeight; |
68 qreal viewBoxHeight; |
69 |
69 |
70 if (mViewBoxDefined) { |
70 if (mViewBoxDefined) { |
71 lViewBoxXmin = mVbX; |
71 viewBoxXmin = mVbX; |
72 lViewBoxYmin = mVbY; |
72 viewBoxYmin = mVbY; |
73 lViewBoxWidth = mVbW; |
73 viewBoxWidth = mVbW; |
74 lViewBoxHeight = mVbH; |
74 viewBoxHeight = mVbH; |
75 } else { |
75 } else { |
76 //this will default viewBox to <svg> element width and height |
76 //this will default viewBox to <svg> element width and height |
77 lViewBoxXmin = 0; |
77 viewBoxXmin = 0; |
78 lViewBoxYmin = 0; |
78 viewBoxYmin = 0; |
79 lViewBoxWidth = size.width(); |
79 viewBoxWidth = size.width(); |
80 lViewBoxHeight = size.height(); |
80 viewBoxHeight = size.height(); |
81 } |
81 } |
82 |
82 |
83 if (lViewBoxWidth == 0.0f || lViewBoxHeight == 0.0f) { |
83 if (viewBoxWidth == 0.0f || viewBoxHeight == 0.0f) { |
84 return; |
84 return; |
85 } |
85 } |
86 |
86 |
87 qreal sx = lViewPortWidth / lViewBoxWidth; |
87 qreal sx = viewPortWidth / viewBoxWidth; |
88 qreal sy = lViewPortHeight / lViewBoxHeight; |
88 qreal sy = viewPortHeight / viewBoxHeight; |
89 |
89 |
90 if (sx == 0.0f || sy == 0.0f) { |
90 if (sx == 0.0f || sy == 0.0f) { |
91 return; |
91 return; |
92 } |
92 } |
93 |
93 |
94 qreal xtrans = qreal(-1.0f) * lViewBoxXmin; |
94 qreal xtrans = qreal(-1.0f) * viewBoxXmin; |
95 qreal ytrans = qreal(-1.0f) * lViewBoxYmin; |
95 qreal ytrans = qreal(-1.0f) * viewBoxYmin; |
96 |
96 |
97 switch (mAlign) { |
97 switch (mAlign) { |
98 case HbNvgEngine::NvgPreserveAspectRatioNone: |
98 case HbNvgEngine::NvgPreserveAspectRatioNone: |
99 /* Non uniform scaling */ |
99 /* Non uniform scaling */ |
100 //none - Do not force uniform scaling. |
100 //none - Do not force uniform scaling. |
129 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
129 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
130 |
130 |
131 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
131 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
132 if (sx > sy) { |
132 if (sx > sy) { |
133 sx = sy; |
133 sx = sy; |
134 xtrans = ((lViewPortWidth - ((lViewBoxWidth / lViewBoxHeight) * lViewPortHeight)) * (.5f)) / sx - lViewBoxXmin; |
134 xtrans = ((viewPortWidth - ((viewBoxWidth / viewBoxHeight) * viewPortHeight)) * (.5f)) / sx - viewBoxXmin; |
135 } else { |
135 } else { |
136 sy = sx; |
136 sy = sx; |
137 //no change for ytrans...default above |
137 //no change for ytrans...default above |
138 } |
138 } |
139 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
139 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
140 if (sx > sy) { |
140 if (sx > sy) { |
141 sy = sx; |
141 sy = sx; |
142 } else { |
142 } else { |
143 sx = sy; |
143 sx = sy; |
144 xtrans = lViewPortWidth - sx * lViewBoxWidth; |
144 xtrans = viewPortWidth - sx * viewBoxWidth; |
145 xtrans = xtrans / sx; |
145 xtrans = xtrans / sx; |
146 xtrans = xtrans / qreal(2) - lViewBoxXmin; |
146 xtrans = xtrans / qreal(2) - viewBoxXmin; |
147 } |
147 } |
148 } |
148 } |
149 break; |
149 break; |
150 case HbNvgEngine::NvgPreserveAspectRatioXmaxYmin: |
150 case HbNvgEngine::NvgPreserveAspectRatioXmaxYmin: |
151 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
151 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
152 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
152 //Align the <min-y> of the element's viewBox with the smallest Y value of the viewport. |
153 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
153 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
154 if (sx > sy) { |
154 if (sx > sy) { |
155 sx = sy; |
155 sx = sy; |
156 xtrans = ((lViewPortWidth - ((lViewBoxWidth / lViewBoxHeight) * lViewPortHeight))) / sx - lViewBoxXmin; |
156 xtrans = ((viewPortWidth - ((viewBoxWidth / viewBoxHeight) * viewPortHeight))) / sx - viewBoxXmin; |
157 } else { |
157 } else { |
158 sy = sx; |
158 sy = sx; |
159 //no change for ytrans...default above |
159 //no change for ytrans...default above |
160 } |
160 } |
161 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
161 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
162 if (sx > sy) { |
162 if (sx > sy) { |
163 sy = sx; |
163 sy = sx; |
164 //no change for ytrans...default above |
164 //no change for ytrans...default above |
165 } else { |
165 } else { |
166 sx = sy; |
166 sx = sy; |
167 xtrans = lViewPortWidth - sx * lViewBoxWidth; |
167 xtrans = viewPortWidth - sx * viewBoxWidth; |
168 xtrans = xtrans / sx - lViewBoxXmin; |
168 xtrans = xtrans / sx - viewBoxXmin; |
169 } |
169 } |
170 } |
170 } |
171 break; |
171 break; |
172 case HbNvgEngine::NvgPreserveAspectRatioXminYmid: |
172 case HbNvgEngine::NvgPreserveAspectRatioXminYmid: |
173 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
173 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
174 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
174 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
175 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
175 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
176 if (sx > sy) { |
176 if (sx > sy) { |
177 sx = sy; |
177 sx = sy; |
178 //no change for xtrans...default above |
178 //no change for xtrans...default above |
179 } else { |
179 } else { |
180 sy = sx; |
180 sy = sx; |
181 ytrans = ((qreal) |
181 ytrans = ((qreal) |
182 (lViewPortHeight - ((qreal)(lViewBoxHeight / lViewBoxWidth) * lViewPortWidth)) * qreal(.5f)) / sy - lViewBoxYmin; |
182 (viewPortHeight - ((qreal)(viewBoxHeight / viewBoxWidth) * viewPortWidth)) * qreal(.5f)) / sy - viewBoxYmin; |
183 } |
183 } |
184 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
184 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
185 if (sx > sy) { |
185 if (sx > sy) { |
186 sy = sx; |
186 sy = sx; |
187 ytrans = lViewPortHeight - sx * lViewBoxHeight; |
187 ytrans = viewPortHeight - sx * viewBoxHeight; |
188 ytrans = ytrans / sx; |
188 ytrans = ytrans / sx; |
189 ytrans = ytrans / qreal(2) - lViewBoxYmin; |
189 ytrans = ytrans / qreal(2) - viewBoxYmin; |
190 } else { |
190 } else { |
191 sx = sy; |
191 sx = sy; |
192 } |
192 } |
193 } |
193 } |
194 break; |
194 break; |
195 case HbNvgEngine::NvgPreserveAspectRatioXmidYmid: |
195 case HbNvgEngine::NvgPreserveAspectRatioXmidYmid: |
197 //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport. |
197 //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport. |
198 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
198 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
199 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
199 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
200 if (sx > sy) { |
200 if (sx > sy) { |
201 sx = sy; |
201 sx = sy; |
202 xtrans = ((lViewPortWidth - ((lViewBoxWidth / lViewBoxHeight) * lViewPortHeight)) * (.5f)) / sx - lViewBoxXmin; |
202 xtrans = ((viewPortWidth - ((viewBoxWidth / viewBoxHeight) * viewPortHeight)) * (.5f)) / sx - viewBoxXmin; |
203 |
203 |
204 } else if (sx < sy) { |
204 } else if (sx < sy) { |
205 sy = sx; |
205 sy = sx; |
206 ytrans = ((lViewPortHeight - ((lViewBoxHeight / lViewBoxWidth) * lViewPortWidth)) * (.5f)) / sy - lViewBoxYmin; |
206 ytrans = ((viewPortHeight - ((viewBoxHeight / viewBoxWidth) * viewPortWidth)) * (.5f)) / sy - viewBoxYmin; |
207 } |
207 } |
208 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
208 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
209 if (sx > sy) { |
209 if (sx > sy) { |
210 sy = sx; |
210 sy = sx; |
211 ytrans = lViewPortHeight - sx * lViewBoxHeight; |
211 ytrans = viewPortHeight - sx * viewBoxHeight; |
212 ytrans = ytrans / sx; |
212 ytrans = ytrans / sx; |
213 ytrans = ytrans / qreal(2) - lViewBoxYmin; |
213 ytrans = ytrans / qreal(2) - viewBoxYmin; |
214 } else { |
214 } else { |
215 sx = sy; |
215 sx = sy; |
216 xtrans = lViewPortWidth - sx * lViewBoxWidth; |
216 xtrans = viewPortWidth - sx * viewBoxWidth; |
217 xtrans = xtrans / sx; |
217 xtrans = xtrans / sx; |
218 xtrans = xtrans / qreal(2) - lViewBoxXmin; |
218 xtrans = xtrans / qreal(2) - viewBoxXmin; |
219 } |
219 } |
220 } |
220 } |
221 break; |
221 break; |
222 case HbNvgEngine::NvgPreserveAspectRatioXmaxYmid: |
222 case HbNvgEngine::NvgPreserveAspectRatioXmaxYmid: |
223 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
223 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
224 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
224 //Align the midpoint Y value of the element's viewBox with the midpoint Y value of the viewport. |
225 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
225 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
226 if (sx > sy) { |
226 if (sx > sy) { |
227 sx = sy; |
227 sx = sy; |
228 xtrans = ((lViewPortWidth - ((lViewBoxWidth / lViewBoxHeight) * lViewPortHeight))) / sx - lViewBoxXmin; |
228 xtrans = ((viewPortWidth - ((viewBoxWidth / viewBoxHeight) * viewPortHeight))) / sx - viewBoxXmin; |
229 } else { |
229 } else { |
230 sy = sx; |
230 sy = sx; |
231 ytrans = ((lViewPortHeight - ((lViewBoxHeight / lViewBoxWidth) * lViewPortWidth)) * (.5f)) / sy - lViewBoxYmin; |
231 ytrans = ((viewPortHeight - ((viewBoxHeight / viewBoxWidth) * viewPortWidth)) * (.5f)) / sy - viewBoxYmin; |
232 } |
232 } |
233 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
233 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
234 if (sx > sy) { |
234 if (sx > sy) { |
235 sy = sx; |
235 sy = sx; |
236 ytrans = lViewPortHeight - sx * lViewBoxHeight; |
236 ytrans = viewPortHeight - sx * viewBoxHeight; |
237 ytrans = ytrans / sx; |
237 ytrans = ytrans / sx; |
238 ytrans = ytrans / qreal(2) - lViewBoxYmin; |
238 ytrans = ytrans / qreal(2) - viewBoxYmin; |
239 } else { |
239 } else { |
240 sx = sy; |
240 sx = sy; |
241 xtrans = lViewPortWidth - sx * lViewBoxWidth; |
241 xtrans = viewPortWidth - sx * viewBoxWidth; |
242 xtrans = xtrans / sx - lViewBoxXmin; |
242 xtrans = xtrans / sx - viewBoxXmin; |
243 } |
243 } |
244 } |
244 } |
245 break; |
245 break; |
246 case HbNvgEngine::NvgPreserveAspectRatioXminYmax: |
246 case HbNvgEngine::NvgPreserveAspectRatioXminYmax: |
247 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
247 //Align the <min-x> of the element's viewBox with the smallest X value of the viewport. |
248 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
248 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
249 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
249 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
250 if (sx > sy) { |
250 if (sx > sy) { |
251 sx = sy; |
251 sx = sy; |
252 //no change for xtrans...default above |
252 //no change for xtrans...default above |
253 } else { |
253 } else { |
254 sy = sx; |
254 sy = sx; |
255 |
255 |
256 ytrans = ((lViewPortHeight - ((lViewBoxHeight / lViewBoxWidth) * lViewPortWidth))) / sy - lViewBoxYmin; |
256 ytrans = ((viewPortHeight - ((viewBoxHeight / viewBoxWidth) * viewPortWidth))) / sy - viewBoxYmin; |
257 } |
257 } |
258 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
258 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
259 if (sx > sy) { |
259 if (sx > sy) { |
260 sy = sx; |
260 sy = sx; |
261 ytrans = lViewPortHeight - sx * lViewBoxHeight; |
261 ytrans = viewPortHeight - sx * viewBoxHeight; |
262 ytrans = ytrans / sx - lViewBoxYmin; |
262 ytrans = ytrans / sx - viewBoxYmin; |
263 } else { |
263 } else { |
264 sx = sy; |
264 sx = sy; |
265 } |
265 } |
266 } |
266 } |
267 break; |
267 break; |
269 //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport. |
269 //Align the midpoint X value of the element's viewBox with the midpoint X value of the viewport. |
270 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
270 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
271 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
271 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
272 if (sx > sy) { |
272 if (sx > sy) { |
273 sx = sy; |
273 sx = sy; |
274 xtrans = ((lViewPortWidth - ((lViewBoxWidth / lViewBoxHeight) * lViewPortHeight)) * qreal(.5f)) / sx - lViewBoxXmin; |
274 xtrans = ((viewPortWidth - ((viewBoxWidth / viewBoxHeight) * viewPortHeight)) * qreal(.5f)) / sx - viewBoxXmin; |
275 } else { |
275 } else { |
276 sy = sx; |
276 sy = sx; |
277 ytrans = ((lViewPortHeight - ((lViewBoxHeight / lViewBoxWidth) * lViewPortWidth))) / sy - lViewBoxYmin; |
277 ytrans = ((viewPortHeight - ((viewBoxHeight / viewBoxWidth) * viewPortWidth))) / sy - viewBoxYmin; |
278 } |
278 } |
279 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
279 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
280 if (sx > sy) { |
280 if (sx > sy) { |
281 sy = sx; |
281 sy = sx; |
282 ytrans = lViewPortHeight - sx * lViewBoxHeight; |
282 ytrans = viewPortHeight - sx * viewBoxHeight; |
283 ytrans = ytrans / sx - lViewBoxYmin; |
283 ytrans = ytrans / sx - viewBoxYmin; |
284 } else { |
284 } else { |
285 sx = sy; |
285 sx = sy; |
286 xtrans = lViewPortWidth - sx * lViewBoxWidth; |
286 xtrans = viewPortWidth - sx * viewBoxWidth; |
287 xtrans = xtrans / sx; |
287 xtrans = xtrans / sx; |
288 xtrans = xtrans / qreal(2) - lViewBoxXmin; |
288 xtrans = xtrans / qreal(2) - viewBoxXmin; |
289 } |
289 } |
290 } |
290 } |
291 break; |
291 break; |
292 case HbNvgEngine::NvgPreserveAspectRatioXmaxYmax: |
292 case HbNvgEngine::NvgPreserveAspectRatioXmaxYmax: |
293 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
293 //Align the <min-x>+<width> of the element's viewBox with the maximum X value of the viewport. |
294 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
294 //Align the <min-y>+<height> of the element's viewBox with the maximum Y value of the viewport. |
295 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
295 if (mMeetSlice == HbNvgEngine::NvgMeet) { |
296 if (sx > sy) { |
296 if (sx > sy) { |
297 sx = sy; |
297 sx = sy; |
298 xtrans = ((lViewPortWidth - ((lViewBoxWidth / lViewBoxHeight) * lViewPortHeight))) / sx - lViewBoxXmin; |
298 xtrans = ((viewPortWidth - ((viewBoxWidth / viewBoxHeight) * viewPortHeight))) / sx - viewBoxXmin; |
299 } else { |
299 } else { |
300 sy = sx; |
300 sy = sx; |
301 ytrans = ((lViewPortHeight - ((lViewBoxHeight / lViewBoxWidth) * lViewPortWidth))) / sy - lViewBoxYmin; |
301 ytrans = ((viewPortHeight - ((viewBoxHeight / viewBoxWidth) * viewPortWidth))) / sy - viewBoxYmin; |
302 } |
302 } |
303 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
303 } else if (mMeetSlice == HbNvgEngine::NvgSlice) { |
304 if (sx > sy) { |
304 if (sx > sy) { |
305 sy = sx; |
305 sy = sx; |
306 ytrans = lViewPortHeight - sx * lViewBoxHeight; |
306 ytrans = viewPortHeight - sx * viewBoxHeight; |
307 ytrans = ytrans / sx - lViewBoxYmin; |
307 ytrans = ytrans / sx - viewBoxYmin; |
308 } else { |
308 } else { |
309 sx = sy; |
309 sx = sy; |
310 xtrans = lViewPortWidth - sx * lViewBoxWidth; |
310 xtrans = viewPortWidth - sx * viewBoxWidth; |
311 xtrans = xtrans / sx - lViewBoxXmin; |
311 xtrans = xtrans / sx - viewBoxXmin; |
312 } |
312 } |
313 } |
313 } |
314 break; |
314 break; |
315 default: |
315 default: |
316 break; |
316 break; |