bool imagePrepare(SwImage* image, const Matrix* transform, const SwBBox& clipRegion, SwBBox& renderRegion, SwMpool* mpool, unsigned tid, bool outline)
{
- if (outline || mathRotated(transform)) {
+ if (outline || !mathRightAngle(transform)) {
if (!_genOutline(image, transform, mpool, tid)) return false;
return mathUpdateOutlineBBox(image->outline, clipRegion, renderRegion, false);
//Fast Track, don't need outlines.
} else {
- renderRegion.min.x = static_cast<SwCoord>(round(transform->e13));
- renderRegion.max.x = renderRegion.min.x + static_cast<SwCoord>(image->w);
- renderRegion.min.y = static_cast<SwCoord>(round(transform->e23));
- renderRegion.max.y= renderRegion.min.y + static_cast<SwCoord>(image->h);
+ auto w = static_cast<float>(image->w);
+ auto h = static_cast<float>(image->h);
+
+ Point pt[4] = {{0 ,0}, {w, 0}, {w, h}, {0, h}};
+ for (int i = 0; i < 4; i++) mathMultiply(&pt[i], transform);
+
+ auto xMin = pt[0].x;
+ auto xMax = pt[0].x;
+ auto yMin = pt[0].y;
+ auto yMax = pt[0].y;
+
+ for (uint32_t i = 1; i < 4; ++i) {
+ if (xMin > pt[i].x) xMin = pt[i].x;
+ if (xMax < pt[i].x) xMax = pt[i].x;
+ if (yMin > pt[i].y) yMin = pt[i].y;
+ if (yMax < pt[i].y) yMax = pt[i].y;
+ }
+
+ renderRegion.min.x = static_cast<SwCoord>(xMin);
+ renderRegion.max.x = static_cast<SwCoord>(round(xMax));
+ renderRegion.min.y = static_cast<SwCoord>(yMin);
+ renderRegion.max.y = static_cast<SwCoord>(round(yMax));
+
return mathClipBBox(clipRegion, renderRegion);
}
}
#include <math.h>
#include "tvgCommon.h"
-static inline bool mathRotated(const Matrix* m)
+static inline bool mathRightAngle(const Matrix* m)
{
- if (fabs(m->e12) > FLT_EPSILON || fabs(m->e21 > FLT_EPSILON) || (m->e11 < -FLT_EPSILON) || (m->e22 < -FLT_EPSILON)) return true;
-
- else return false;
+ auto radian = fabsf(atan2(m->e21, m->e11));
+ if (radian < FLT_EPSILON || fabsf(radian - float(M_PI_2)) < FLT_EPSILON || fabsf(radian - float(M_PI)) < FLT_EPSILON) return true;
+ return false;
}
if (rTransform) rTransform->update();
//No Rotation?
- if (pTransform && (fabs(pTransform->m.e12) > FLT_EPSILON || fabs(pTransform->m.e21 > FLT_EPSILON))) return false;
- if (rTransform && (fabs(rTransform->m.e12) > FLT_EPSILON || fabs(rTransform->m.e21 > FLT_EPSILON))) return false;
+ if (pTransform && !mathRightAngle(&pTransform->m)) return false;
+ if (rTransform && !mathRightAngle(&rTransform->m)) return false;
- //Axis-Aligned Rectangle?
+ //Perpendicular Rectangle?
auto pt1 = pts + 0;
auto pt2 = pts + 1;
auto pt3 = pts + 2;