Changeset View
Changeset View
Standalone View
Standalone View
pixmapfx/kpPixmapFX_Transforms.cpp
Show First 20 Lines • Show All 46 Lines • ▼ Show 20 Line(s) | |||||
47 | //--------------------------------------------------------------------- | 47 | //--------------------------------------------------------------------- | ||
48 | 48 | | |||
49 | // public static | 49 | // public static | ||
50 | void kpPixmapFX::resize (QImage *destPtr, int w, int h, | 50 | void kpPixmapFX::resize (QImage *destPtr, int w, int h, | ||
51 | const kpColor &backgroundColor) | 51 | const kpColor &backgroundColor) | ||
52 | { | 52 | { | ||
53 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::resize()"; | 53 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::resize()"; | ||
54 | 54 | | |||
55 | if (!destPtr) | 55 | if (!destPtr) { | ||
56 | return; | 56 | return; | ||
57 | } | ||||
57 | 58 | | |||
58 | const int oldWidth = destPtr->width (); | 59 | const int oldWidth = destPtr->width (); | ||
59 | const int oldHeight = destPtr->height (); | 60 | const int oldHeight = destPtr->height (); | ||
60 | 61 | | |||
61 | if (w == oldWidth && h == oldHeight) | 62 | if (w == oldWidth && h == oldHeight) { | ||
62 | return; | 63 | return; | ||
64 | } | ||||
63 | 65 | | |||
64 | QImage newImage (w, h, QImage::Format_ARGB32_Premultiplied); | 66 | QImage newImage (w, h, QImage::Format_ARGB32_Premultiplied); | ||
65 | 67 | | |||
66 | // Would have new undefined areas? | 68 | // Would have new undefined areas? | ||
67 | if (w > oldWidth || h > oldHeight) | 69 | if (w > oldWidth || h > oldHeight) { | ||
68 | newImage.fill (backgroundColor.toQRgb ()); | 70 | newImage.fill (backgroundColor.toQRgb ()); | ||
71 | } | ||||
69 | 72 | | |||
70 | // Copy over old pixmap. | 73 | // Copy over old pixmap. | ||
71 | QPainter painter(&newImage); | 74 | QPainter painter(&newImage); | ||
72 | painter.setCompositionMode(QPainter::CompositionMode_Source); | 75 | painter.setCompositionMode(QPainter::CompositionMode_Source); | ||
73 | painter.drawImage(0, 0, *destPtr); | 76 | painter.drawImage(0, 0, *destPtr); | ||
74 | painter.end(); | 77 | painter.end(); | ||
75 | 78 | | |||
76 | // Replace pixmap with new one. | 79 | // Replace pixmap with new one. | ||
Show All 11 Lines | 88 | { | |||
88 | return ret; | 91 | return ret; | ||
89 | } | 92 | } | ||
90 | 93 | | |||
91 | //--------------------------------------------------------------------- | 94 | //--------------------------------------------------------------------- | ||
92 | 95 | | |||
93 | // public static | 96 | // public static | ||
94 | void kpPixmapFX::scale (QImage *destPtr, int w, int h, bool pretty) | 97 | void kpPixmapFX::scale (QImage *destPtr, int w, int h, bool pretty) | ||
95 | { | 98 | { | ||
96 | if (!destPtr) | 99 | if (!destPtr) { | ||
97 | return; | 100 | return; | ||
101 | } | ||||
98 | 102 | | |||
99 | *destPtr = kpPixmapFX::scale (*destPtr, w, h, pretty); | 103 | *destPtr = kpPixmapFX::scale (*destPtr, w, h, pretty); | ||
100 | } | 104 | } | ||
101 | 105 | | |||
102 | //--------------------------------------------------------------------- | 106 | //--------------------------------------------------------------------- | ||
103 | 107 | | |||
104 | // public static | 108 | // public static | ||
105 | QImage kpPixmapFX::scale (const QImage &image, int w, int h, bool pretty) | 109 | QImage kpPixmapFX::scale (const QImage &image, int w, int h, bool pretty) | ||
106 | { | 110 | { | ||
107 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::scale(oldRect=" << image.rect () | 111 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::scale(oldRect=" << image.rect () | ||
108 | << ",w=" << w | 112 | << ",w=" << w | ||
109 | << ",h=" << h | 113 | << ",h=" << h | ||
110 | << ",pretty=" << pretty | 114 | << ",pretty=" << pretty | ||
111 | << ")" | 115 | << ")"; | ||
112 | << endl; | | |||
113 | 116 | | |||
114 | if (w == image.width () && h == image.height ()) | 117 | if (w == image.width () && h == image.height ()) { | ||
115 | return image; | 118 | return image; | ||
119 | } | ||||
116 | 120 | | |||
117 | return image.scaled(w, h, Qt::IgnoreAspectRatio, | 121 | return image.scaled(w, h, Qt::IgnoreAspectRatio, | ||
118 | pretty ? Qt::SmoothTransformation : Qt::FastTransformation); | 122 | pretty ? Qt::SmoothTransformation : Qt::FastTransformation); | ||
119 | } | 123 | } | ||
120 | 124 | | |||
121 | //--------------------------------------------------------------------- | 125 | //--------------------------------------------------------------------- | ||
122 | 126 | | |||
123 | // public static | 127 | // public static | ||
124 | const double kpPixmapFX::AngleInDegreesEpsilon = | 128 | const double kpPixmapFX::AngleInDegreesEpsilon = | ||
125 | qRadiansToDegrees (std::tan (1.0 / 10000.0)) | 129 | qRadiansToDegrees (std::tan (1.0 / 10000.0)) | ||
126 | / (2.0/*max error allowed*/ * 2.0/*for good measure*/); | 130 | / (2.0/*max error allowed*/ * 2.0/*for good measure*/); | ||
127 | 131 | | |||
128 | 132 | | |||
129 | static void MatrixDebug (const QString matrixName, const QTransform &matrix, | 133 | static void MatrixDebug (const QString& matrixName, const QTransform &matrix, | ||
130 | int srcPixmapWidth = -1, int srcPixmapHeight = -1) | 134 | int srcPixmapWidth = -1, int srcPixmapHeight = -1) | ||
131 | { | 135 | { | ||
132 | const int w = srcPixmapWidth, h = srcPixmapHeight; | 136 | const int w = srcPixmapWidth, h = srcPixmapHeight; | ||
133 | 137 | | |||
134 | qCDebug(kpLogPixmapfx) << matrixName << "=" << matrix; | 138 | qCDebug(kpLogPixmapfx) << matrixName << "=" << matrix; | ||
135 | // Sometimes this precision lets us see unexpected rounding errors. | 139 | // Sometimes this precision lets us see unexpected rounding errors. | ||
136 | fprintf (stderr, "m11=%.24f m12=%.24f m21=%.24f m22=%.24f dx=%.24f dy=%.24f\n", | 140 | fprintf (stderr, "m11=%.24f m12=%.24f m21=%.24f m22=%.24f dx=%.24f dy=%.24f\n", | ||
137 | matrix.m11 (), matrix.m12 (), | 141 | matrix.m11 (), matrix.m12 (), | ||
▲ Show 20 Lines • Show All 60 Lines • ▼ Show 20 Line(s) | |||||
198 | // using a QPixmap painter, prior to the 2007-10-09 change -- did not test after | 202 | // using a QPixmap painter, prior to the 2007-10-09 change -- did not test after | ||
199 | // the change). | 203 | // the change). | ||
200 | // Unfortunately, this does not work enough to stop the rendering errors | 204 | // Unfortunately, this does not work enough to stop the rendering errors | ||
201 | // that follow. But it was worth a try and might still help us given the | 205 | // that follow. But it was worth a try and might still help us given the | ||
202 | // sometimes excessive aliasing QPainter::draw{Pixmap,Image}() gives us, when | 206 | // sometimes excessive aliasing QPainter::draw{Pixmap,Image}() gives us, when | ||
203 | // QPainter::SmoothPixmapTransform is disabled. | 207 | // QPainter::SmoothPixmapTransform is disabled. | ||
204 | static double TrueMatrixFixInts (double x) | 208 | static double TrueMatrixFixInts (double x) | ||
205 | { | 209 | { | ||
206 | if (std::fabs (x - qRound (x)) < TrueMatrixEpsilon) | 210 | if (std::fabs (x - qRound (x)) < TrueMatrixEpsilon) { | ||
207 | return qRound (x); | 211 | return qRound (x); | ||
208 | else | 212 | } | ||
213 | | ||||
209 | return x; | 214 | return x; | ||
210 | } | 215 | } | ||
211 | 216 | | |||
212 | //--------------------------------------------------------------------- | 217 | //--------------------------------------------------------------------- | ||
213 | 218 | | |||
214 | static QTransform TrueMatrix (const QTransform &matrix, int srcPixmapWidth, int srcPixmapHeight) | 219 | static QTransform TrueMatrix (const QTransform &matrix, int srcPixmapWidth, int srcPixmapHeight) | ||
215 | { | 220 | { | ||
216 | ::MatrixDebug ("TrueMatrix(): org", matrix); | 221 | ::MatrixDebug ("TrueMatrix(): org", matrix); | ||
Show All 30 Lines | 251 | static QImage TransformPixmap (const QImage &pm, const QTransform &transformMatrix_, | |||
247 | const kpColor &backgroundColor, | 252 | const kpColor &backgroundColor, | ||
248 | int targetWidth, int targetHeight) | 253 | int targetWidth, int targetHeight) | ||
249 | { | 254 | { | ||
250 | QTransform transformMatrix = transformMatrix_; | 255 | QTransform transformMatrix = transformMatrix_; | ||
251 | 256 | | |||
252 | qCDebug(kpLogPixmapfx) << "kppixmapfx.cpp: TransformPixmap(pm.size=" << pm.size () | 257 | qCDebug(kpLogPixmapfx) << "kppixmapfx.cpp: TransformPixmap(pm.size=" << pm.size () | ||
253 | << ",targetWidth=" << targetWidth | 258 | << ",targetWidth=" << targetWidth | ||
254 | << ",targetHeight=" << targetHeight | 259 | << ",targetHeight=" << targetHeight | ||
255 | << ")" | 260 | << ")"; | ||
256 | << endl; | | |||
257 | 261 | | |||
258 | QRect newRect = transformMatrix.mapRect (pm.rect ()); | 262 | QRect newRect = transformMatrix.mapRect (pm.rect ()); | ||
259 | qCDebug(kpLogPixmapfx) << "\tmappedRect=" << newRect; | 263 | qCDebug(kpLogPixmapfx) << "\tmappedRect=" << newRect; | ||
260 | 264 | | |||
261 | 265 | | |||
262 | QTransform scaleMatrix; | 266 | QTransform scaleMatrix; | ||
263 | if (targetWidth > 0 && targetWidth != newRect.width ()) | 267 | if (targetWidth > 0 && targetWidth != newRect.width ()) | ||
264 | { | 268 | { | ||
265 | qCDebug(kpLogPixmapfx) << "\tadjusting for targetWidth"; | 269 | qCDebug(kpLogPixmapfx) << "\tadjusting for targetWidth"; | ||
266 | scaleMatrix.scale (double (targetWidth) / double (newRect.width ()), 1); | 270 | scaleMatrix.scale (double (targetWidth) / double (newRect.width ()), 1); | ||
267 | } | 271 | } | ||
268 | 272 | | |||
269 | if (targetHeight > 0 && targetHeight != newRect.height ()) | 273 | if (targetHeight > 0 && targetHeight != newRect.height ()) | ||
270 | { | 274 | { | ||
271 | qCDebug(kpLogPixmapfx) << "\tadjusting for targetHeight"; | 275 | qCDebug(kpLogPixmapfx) << "\tadjusting for targetHeight"; | ||
272 | scaleMatrix.scale (1, double (targetHeight) / double (newRect.height ())); | 276 | scaleMatrix.scale (1, double (targetHeight) / double (newRect.height ())); | ||
273 | } | 277 | } | ||
274 | 278 | | |||
275 | if (!scaleMatrix.isIdentity ()) | 279 | if (!scaleMatrix.isIdentity ()) | ||
276 | { | 280 | { | ||
277 | // TODO: What is going on here??? Why isn't matrix * working properly? | 281 | // TODO: What is going on here??? Why isn't matrix * working properly? | ||
278 | QTransform wrongMatrix = transformMatrix * scaleMatrix; | 282 | QTransform wrongMatrix = transformMatrix * scaleMatrix; | ||
279 | QTransform oldHat = transformMatrix; | 283 | QTransform oldHat = transformMatrix; | ||
280 | if (targetWidth > 0 && targetWidth != newRect.width ()) | 284 | | ||
285 | if (targetWidth > 0 && targetWidth != newRect.width ()) { | ||||
281 | oldHat.scale (double (targetWidth) / double (newRect.width ()), 1); | 286 | oldHat.scale (double (targetWidth) / double (newRect.width ()), 1); | ||
282 | if (targetHeight > 0 && targetHeight != newRect.height ()) | 287 | } | ||
288 | if (targetHeight > 0 && targetHeight != newRect.height ()) { | ||||
283 | oldHat.scale (1, double (targetHeight) / double (newRect.height ())); | 289 | oldHat.scale (1, double (targetHeight) / double (newRect.height ())); | ||
290 | } | ||||
291 | | ||||
284 | QTransform altHat = transformMatrix; | 292 | QTransform altHat = transformMatrix; | ||
293 | | ||||
285 | altHat.scale ((targetWidth > 0 && targetWidth != newRect.width ()) ? double (targetWidth) / double (newRect.width ()) : 1, | 294 | altHat.scale ((targetWidth > 0 && targetWidth != newRect.width ()) ? double (targetWidth) / double (newRect.width ()) : 1, | ||
286 | (targetHeight > 0 && targetHeight != newRect.height ()) ? double (targetHeight) / double (newRect.height ()) : 1); | 295 | (targetHeight > 0 && targetHeight != newRect.height ()) ? double (targetHeight) / double (newRect.height ()) : 1); | ||
287 | QTransform correctMatrix = scaleMatrix * transformMatrix; | 296 | QTransform correctMatrix = scaleMatrix * transformMatrix; | ||
288 | 297 | | |||
289 | qCDebug(kpLogPixmapfx) << "\tsupposedlyWrongMatrix: m11=" << wrongMatrix.m11 () // <<<---- this is the correct matrix??? | 298 | qCDebug(kpLogPixmapfx) << "\tsupposedlyWrongMatrix: m11=" << wrongMatrix.m11 () // <<<---- this is the correct matrix??? | ||
290 | << " m12=" << wrongMatrix.m12 () | 299 | << " m12=" << wrongMatrix.m12 () | ||
291 | << " m21=" << wrongMatrix.m21 () | 300 | << " m21=" << wrongMatrix.m21 () | ||
292 | << " m22=" << wrongMatrix.m22 () | 301 | << " m22=" << wrongMatrix.m22 () | ||
293 | << " dx=" << wrongMatrix.dx () | 302 | << " dx=" << wrongMatrix.dx () | ||
294 | << " dy=" << wrongMatrix.dy () | 303 | << " dy=" << wrongMatrix.dy () | ||
295 | << " rect=" << wrongMatrix.mapRect (pm.rect ()) | 304 | << " rect=" << wrongMatrix.mapRect (pm.rect ()) | ||
296 | << endl | 305 | << "\n" | ||
297 | << "\ti_used_to_use_thisMatrix: m11=" << oldHat.m11 () | 306 | << "\ti_used_to_use_thisMatrix: m11=" << oldHat.m11 () | ||
298 | << " m12=" << oldHat.m12 () | 307 | << " m12=" << oldHat.m12 () | ||
299 | << " m21=" << oldHat.m21 () | 308 | << " m21=" << oldHat.m21 () | ||
300 | << " m22=" << oldHat.m22 () | 309 | << " m22=" << oldHat.m22 () | ||
301 | << " dx=" << oldHat.dx () | 310 | << " dx=" << oldHat.dx () | ||
302 | << " dy=" << oldHat.dy () | 311 | << " dy=" << oldHat.dy () | ||
303 | << " rect=" << oldHat.mapRect (pm.rect ()) | 312 | << " rect=" << oldHat.mapRect (pm.rect ()) | ||
304 | << endl | 313 | << "\n" | ||
305 | << "\tabove but scaled at the same time: m11=" << altHat.m11 () | 314 | << "\tabove but scaled at the same time: m11=" << altHat.m11 () | ||
306 | << " m12=" << altHat.m12 () | 315 | << " m12=" << altHat.m12 () | ||
307 | << " m21=" << altHat.m21 () | 316 | << " m21=" << altHat.m21 () | ||
308 | << " m22=" << altHat.m22 () | 317 | << " m22=" << altHat.m22 () | ||
309 | << " dx=" << altHat.dx () | 318 | << " dx=" << altHat.dx () | ||
310 | << " dy=" << altHat.dy () | 319 | << " dy=" << altHat.dy () | ||
311 | << " rect=" << altHat.mapRect (pm.rect ()) | 320 | << " rect=" << altHat.mapRect (pm.rect ()) | ||
312 | << endl | 321 | << "\n" | ||
313 | << "\tsupposedlyCorrectMatrix: m11=" << correctMatrix.m11 () | 322 | << "\tsupposedlyCorrectMatrix: m11=" << correctMatrix.m11 () | ||
314 | << " m12=" << correctMatrix.m12 () | 323 | << " m12=" << correctMatrix.m12 () | ||
315 | << " m21=" << correctMatrix.m21 () | 324 | << " m21=" << correctMatrix.m21 () | ||
316 | << " m22=" << correctMatrix.m22 () | 325 | << " m22=" << correctMatrix.m22 () | ||
317 | << " dx=" << correctMatrix.dx () | 326 | << " dx=" << correctMatrix.dx () | ||
318 | << " dy=" << correctMatrix.dy () | 327 | << " dy=" << correctMatrix.dy () | ||
319 | << " rect=" << correctMatrix.mapRect (pm.rect ()) | 328 | << " rect=" << correctMatrix.mapRect (pm.rect ()); | ||
320 | << endl; | | |||
321 | 329 | | |||
322 | transformMatrix = transformMatrix * scaleMatrix; | 330 | transformMatrix = transformMatrix * scaleMatrix; | ||
323 | 331 | | |||
324 | newRect = transformMatrix.mapRect (pm.rect ()); | 332 | newRect = transformMatrix.mapRect (pm.rect ()); | ||
325 | qCDebug(kpLogPixmapfx) << "\tnewRect after targetWidth,targetHeight adjust=" << newRect; | 333 | qCDebug(kpLogPixmapfx) << "\tnewRect after targetWidth,targetHeight adjust=" << newRect; | ||
326 | } | 334 | } | ||
327 | 335 | | |||
328 | 336 | | |||
Show All 34 Lines | |||||
363 | 371 | | |||
364 | if ((targetWidth > 0 && targetWidth != newRect.width ()) || | 372 | if ((targetWidth > 0 && targetWidth != newRect.width ()) || | ||
365 | (targetHeight > 0 && targetHeight != newRect.height ())) | 373 | (targetHeight > 0 && targetHeight != newRect.height ())) | ||
366 | { | 374 | { | ||
367 | qCDebug(kpLogPixmapfx) << "kppixmapfx.cpp: TransformPixmap(pm.size=" << pm.size () | 375 | qCDebug(kpLogPixmapfx) << "kppixmapfx.cpp: TransformPixmap(pm.size=" << pm.size () | ||
368 | << ",targetWidth=" << targetWidth | 376 | << ",targetWidth=" << targetWidth | ||
369 | << ",targetHeight=" << targetHeight | 377 | << ",targetHeight=" << targetHeight | ||
370 | << ") newRect=" << newRect | 378 | << ") newRect=" << newRect | ||
371 | << " (you are a victim of rounding error)" | 379 | << " (you are a victim of rounding error)"; | ||
372 | << endl; | | |||
373 | } | 380 | } | ||
374 | 381 | | |||
375 | // Note: Do _not_ use "p.setRenderHints (QPainter::SmoothPixmapTransform);" | 382 | // Note: Do _not_ use "p.setRenderHints (QPainter::SmoothPixmapTransform);" | ||
376 | // as the user does not want their image to get blurier every | 383 | // as the user does not want their image to get blurier every | ||
377 | // time they e.g. rotate it (especially important for multiples | 384 | // time they e.g. rotate it (especially important for multiples | ||
378 | // of 90 degrees but also true for every other angle). Being a | 385 | // of 90 degrees but also true for every other angle). Being a | ||
379 | // pixel-based program, we generally like to preserve RGB values | 386 | // pixel-based program, we generally like to preserve RGB values | ||
380 | // and avoid unnecessary blurs -- in the worst case, we'd rather | 387 | // and avoid unnecessary blurs -- in the worst case, we'd rather | ||
Show All 9 Lines | 396 | { | |||
390 | p.fillRect (newQImage.rect (), backgroundColor.toQColor ()); | 397 | p.fillRect (newQImage.rect (), backgroundColor.toQColor ()); | ||
391 | } | 398 | } | ||
392 | 399 | | |||
393 | p.setWorldTransform (transformMatrix); | 400 | p.setWorldTransform (transformMatrix); | ||
394 | p.drawImage (QPoint (0, 0), pm); | 401 | p.drawImage (QPoint (0, 0), pm); | ||
395 | } | 402 | } | ||
396 | p.end (); | 403 | p.end (); | ||
397 | 404 | | |||
398 | qCDebug(kpLogPixmapfx) << "Done" << endl << endl; | 405 | qCDebug(kpLogPixmapfx) << "Done"; | ||
399 | 406 | | |||
400 | return newQImage; | 407 | return newQImage; | ||
401 | } | 408 | } | ||
402 | 409 | | |||
403 | //--------------------------------------------------------------------- | 410 | //--------------------------------------------------------------------- | ||
404 | 411 | | |||
405 | // public static | 412 | // public static | ||
406 | QTransform kpPixmapFX::skewMatrix (int width, int height, double hangle, double vangle) | 413 | QTransform kpPixmapFX::skewMatrix (int width, int height, double hangle, double vangle) | ||
407 | { | 414 | { | ||
408 | if (std::fabs (hangle - 0) < kpPixmapFX::AngleInDegreesEpsilon && | 415 | if (std::fabs (hangle - 0) < kpPixmapFX::AngleInDegreesEpsilon && | ||
409 | std::fabs (vangle - 0) < kpPixmapFX::AngleInDegreesEpsilon) | 416 | std::fabs (vangle - 0) < kpPixmapFX::AngleInDegreesEpsilon) | ||
410 | { | 417 | { | ||
411 | return QTransform (); | 418 | return {}; | ||
412 | } | 419 | } | ||
413 | 420 | | |||
414 | 421 | | |||
415 | /* Diagram for completeness :) | 422 | /* Diagram for completeness :) | ||
416 | * | 423 | * | ||
417 | * |---------- w ----------| | 424 | * |---------- w ----------| | ||
418 | * (0,0) | 425 | * (0,0) | ||
419 | * _ _______________________ (w,0) | 426 | * _ _______________________ (w,0) | ||
Show All 40 Lines | |||||
460 | //--------------------------------------------------------------------- | 467 | //--------------------------------------------------------------------- | ||
461 | 468 | | |||
462 | 469 | | |||
463 | // public static | 470 | // public static | ||
464 | void kpPixmapFX::skew (QImage *destPtr, double hangle, double vangle, | 471 | void kpPixmapFX::skew (QImage *destPtr, double hangle, double vangle, | ||
465 | const kpColor &backgroundColor, | 472 | const kpColor &backgroundColor, | ||
466 | int targetWidth, int targetHeight) | 473 | int targetWidth, int targetHeight) | ||
467 | { | 474 | { | ||
468 | if (!destPtr) | 475 | if (!destPtr) { | ||
469 | return; | 476 | return; | ||
477 | } | ||||
470 | 478 | | |||
471 | *destPtr = kpPixmapFX::skew (*destPtr, hangle, vangle, | 479 | *destPtr = kpPixmapFX::skew (*destPtr, hangle, vangle, | ||
472 | backgroundColor, | 480 | backgroundColor, | ||
473 | targetWidth, targetHeight); | 481 | targetWidth, targetHeight); | ||
474 | } | 482 | } | ||
475 | 483 | | |||
476 | //--------------------------------------------------------------------- | 484 | //--------------------------------------------------------------------- | ||
477 | 485 | | |||
478 | // public static | 486 | // public static | ||
479 | QImage kpPixmapFX::skew (const QImage &pm, double hangle, double vangle, | 487 | QImage kpPixmapFX::skew (const QImage &pm, double hangle, double vangle, | ||
480 | const kpColor &backgroundColor, | 488 | const kpColor &backgroundColor, | ||
481 | int targetWidth, int targetHeight) | 489 | int targetWidth, int targetHeight) | ||
482 | { | 490 | { | ||
483 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::skew() pm.width=" << pm.width () | 491 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::skew() pm.width=" << pm.width () | ||
484 | << " pm.height=" << pm.height () | 492 | << " pm.height=" << pm.height () | ||
485 | << " hangle=" << hangle | 493 | << " hangle=" << hangle | ||
486 | << " vangle=" << vangle | 494 | << " vangle=" << vangle | ||
487 | << " targetWidth=" << targetWidth | 495 | << " targetWidth=" << targetWidth | ||
488 | << " targetHeight=" << targetHeight | 496 | << " targetHeight=" << targetHeight; | ||
489 | << endl; | | |||
490 | 497 | | |||
491 | if (std::fabs (hangle - 0) < kpPixmapFX::AngleInDegreesEpsilon && | 498 | if (std::fabs (hangle - 0) < kpPixmapFX::AngleInDegreesEpsilon && | ||
492 | std::fabs (vangle - 0) < kpPixmapFX::AngleInDegreesEpsilon && | 499 | std::fabs (vangle - 0) < kpPixmapFX::AngleInDegreesEpsilon && | ||
493 | (targetWidth <= 0 && targetHeight <= 0)/*don't want to scale?*/) | 500 | (targetWidth <= 0 && targetHeight <= 0)/*don't want to scale?*/) | ||
494 | { | 501 | { | ||
495 | return pm; | 502 | return pm; | ||
496 | } | 503 | } | ||
497 | 504 | | |||
498 | if (std::fabs (hangle) > 90 - kpPixmapFX::AngleInDegreesEpsilon || | 505 | if (std::fabs (hangle) > 90 - kpPixmapFX::AngleInDegreesEpsilon || | ||
499 | std::fabs (vangle) > 90 - kpPixmapFX::AngleInDegreesEpsilon) | 506 | std::fabs (vangle) > 90 - kpPixmapFX::AngleInDegreesEpsilon) | ||
500 | { | 507 | { | ||
501 | qCCritical(kpLogPixmapfx) << "kpPixmapFX::skew() passed hangle and/or vangle out of range (-90 < x < 90)" << endl; | 508 | qCCritical(kpLogPixmapfx) << "kpPixmapFX::skew() passed hangle and/or vangle out of range (-90 < x < 90)"; | ||
502 | return pm; | 509 | return pm; | ||
503 | } | 510 | } | ||
504 | 511 | | |||
505 | 512 | | |||
506 | QTransform matrix = skewMatrix (pm, hangle, vangle); | 513 | QTransform matrix = skewMatrix (pm, hangle, vangle); | ||
507 | 514 | | |||
508 | return ::TransformPixmap (pm, matrix, backgroundColor, targetWidth, targetHeight); | 515 | return ::TransformPixmap (pm, matrix, backgroundColor, targetWidth, targetHeight); | ||
509 | } | 516 | } | ||
510 | 517 | | |||
511 | //--------------------------------------------------------------------- | 518 | //--------------------------------------------------------------------- | ||
512 | 519 | | |||
513 | 520 | | |||
514 | // public static | 521 | // public static | ||
515 | QTransform kpPixmapFX::rotateMatrix (int width, int height, double angle) | 522 | QTransform kpPixmapFX::rotateMatrix (int width, int height, double angle) | ||
516 | { | 523 | { | ||
517 | if (std::fabs (angle - 0) < kpPixmapFX::AngleInDegreesEpsilon) | 524 | if (std::fabs (angle - 0) < kpPixmapFX::AngleInDegreesEpsilon) | ||
518 | { | 525 | { | ||
519 | return QTransform (); | 526 | return {}; | ||
520 | } | 527 | } | ||
521 | 528 | | |||
522 | QTransform matrix; | 529 | QTransform matrix; | ||
523 | matrix.translate (width / 2, height / 2); | 530 | matrix.translate (width / 2, height / 2); | ||
524 | matrix.rotate (angle); | 531 | matrix.rotate (angle); | ||
525 | 532 | | |||
526 | return ::MatrixWithZeroOrigin (matrix, width, height); | 533 | return ::MatrixWithZeroOrigin (matrix, width, height); | ||
527 | } | 534 | } | ||
Show All 10 Lines | |||||
538 | 545 | | |||
539 | 546 | | |||
540 | // public static | 547 | // public static | ||
541 | bool kpPixmapFX::isLosslessRotation (double angle) | 548 | bool kpPixmapFX::isLosslessRotation (double angle) | ||
542 | { | 549 | { | ||
543 | const double angleIn = angle; | 550 | const double angleIn = angle; | ||
544 | 551 | | |||
545 | // Reflect angle into positive if negative | 552 | // Reflect angle into positive if negative | ||
546 | if (angle < 0) | 553 | if (angle < 0) { | ||
547 | angle = -angle; | 554 | angle = -angle; | ||
555 | } | ||||
548 | 556 | | |||
549 | // Remove multiples of 90 to make sure 0 <= angle <= 90 | 557 | // Remove multiples of 90 to make sure 0 <= angle <= 90 | ||
550 | angle -= (static_cast<int> (angle)) / 90 * 90; | 558 | angle -= (static_cast<int> (angle)) / 90 * 90; | ||
551 | 559 | | |||
552 | // "Impossible" situation? | 560 | // "Impossible" situation? | ||
553 | if (angle < 0 || angle > 90) | 561 | if (angle < 0 || angle > 90) | ||
554 | { | 562 | { | ||
555 | qCCritical(kpLogPixmapfx) << "kpPixmapFX::isLosslessRotation(" << angleIn | 563 | qCCritical(kpLogPixmapfx) << "kpPixmapFX::isLosslessRotation(" << angleIn | ||
556 | << ") result=" << angle | 564 | << ") result=" << angle; | ||
557 | << endl; | | |||
558 | return false; // better safe than sorry | 565 | return false; // better safe than sorry | ||
559 | } | 566 | } | ||
560 | 567 | | |||
561 | const bool ret = (angle < kpPixmapFX::AngleInDegreesEpsilon || | 568 | const bool ret = (angle < kpPixmapFX::AngleInDegreesEpsilon || | ||
562 | 90 - angle < kpPixmapFX::AngleInDegreesEpsilon); | 569 | 90 - angle < kpPixmapFX::AngleInDegreesEpsilon); | ||
563 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::isLosslessRotation(" << angleIn << ")" | 570 | qCDebug(kpLogPixmapfx) << "kpPixmapFX::isLosslessRotation(" << angleIn << ")" | ||
564 | << " residual angle=" << angle | 571 | << " residual angle=" << angle | ||
565 | << " returning " << ret | 572 | << " returning " << ret; | ||
566 | << endl; | | |||
567 | return ret; | 573 | return ret; | ||
568 | } | 574 | } | ||
569 | 575 | | |||
570 | //--------------------------------------------------------------------- | 576 | //--------------------------------------------------------------------- | ||
571 | 577 | | |||
572 | 578 | | |||
573 | // public static | 579 | // public static | ||
574 | void kpPixmapFX::rotate (QImage *destPtr, double angle, | 580 | void kpPixmapFX::rotate (QImage *destPtr, double angle, | ||
575 | const kpColor &backgroundColor, | 581 | const kpColor &backgroundColor, | ||
576 | int targetWidth, int targetHeight) | 582 | int targetWidth, int targetHeight) | ||
577 | { | 583 | { | ||
578 | if (!destPtr) | 584 | if (!destPtr) { | ||
579 | return; | 585 | return; | ||
586 | } | ||||
580 | 587 | | |||
581 | *destPtr = kpPixmapFX::rotate (*destPtr, angle, | 588 | *destPtr = kpPixmapFX::rotate (*destPtr, angle, | ||
582 | backgroundColor, | 589 | backgroundColor, | ||
583 | targetWidth, targetHeight); | 590 | targetWidth, targetHeight); | ||
584 | } | 591 | } | ||
585 | 592 | | |||
586 | //--------------------------------------------------------------------- | 593 | //--------------------------------------------------------------------- | ||
587 | 594 | | |||
Show All 18 Lines |