Index: core/src/fxcrt/fx_basic_coords.cpp |
diff --git a/core/src/fxcrt/fx_basic_coords.cpp b/core/src/fxcrt/fx_basic_coords.cpp |
index 2e830809b8351d21c6ff49d291cf8405850c689a..4b570c6436588ea7b42e6c63227caeda1a7ddb12 100644 |
--- a/core/src/fxcrt/fx_basic_coords.cpp |
+++ b/core/src/fxcrt/fx_basic_coords.cpp |
@@ -9,561 +9,531 @@ |
#include "../../include/fxcrt/fx_coordinates.h" |
#include "../../include/fxcrt/fx_ext.h" |
-void FX_RECT::Normalize() |
-{ |
- if (left > right) { |
- int temp = left; |
- left = right; |
- right = temp; |
- } |
- if (top > bottom) { |
- int temp = top; |
- top = bottom; |
- bottom = temp; |
- } |
-} |
-void FX_RECT::Intersect(const FX_RECT& src) |
-{ |
- FX_RECT src_n = src; |
- src_n.Normalize(); |
- Normalize(); |
- left = left > src_n.left ? left : src_n.left; |
- top = top > src_n.top ? top : src_n.top; |
- right = right < src_n.right ? right : src_n.right; |
- bottom = bottom < src_n.bottom ? bottom : src_n.bottom; |
- if (left > right || top > bottom) { |
- left = top = right = bottom = 0; |
- } |
-} |
-void FX_RECT::Union(const FX_RECT& other_rect) |
-{ |
- Normalize(); |
- FX_RECT other = other_rect; |
- other.Normalize(); |
- left = left < other.left ? left : other.left; |
- right = right > other.right ? right : other.right; |
- bottom = bottom > other.bottom ? bottom : other.bottom; |
- top = top < other.top ? top : other.top; |
-} |
-FX_BOOL GetIntersection(FX_FLOAT low1, FX_FLOAT high1, FX_FLOAT low2, FX_FLOAT high2, |
- FX_FLOAT& interlow, FX_FLOAT& interhigh) |
-{ |
- if (low1 >= high2 || low2 >= high1) { |
- return FALSE; |
- } |
- interlow = low1 > low2 ? low1 : low2; |
- interhigh = high1 > high2 ? high2 : high1; |
- return TRUE; |
-} |
-extern "C" int FXSYS_round(FX_FLOAT d) |
-{ |
- if (d < (FX_FLOAT)INT_MIN) { |
- return INT_MIN; |
- } |
- if (d > (FX_FLOAT)INT_MAX) { |
- return INT_MAX; |
- } |
- |
- return (int)round(d); |
-} |
-CFX_FloatRect::CFX_FloatRect(const FX_RECT& rect) |
-{ |
- left = (FX_FLOAT)(rect.left); |
- right = (FX_FLOAT)(rect.right); |
- bottom = (FX_FLOAT)(rect.top); |
- top = (FX_FLOAT)(rect.bottom); |
-} |
-void CFX_FloatRect::Normalize() |
-{ |
- FX_FLOAT temp; |
- if (left > right) { |
- temp = left; |
- left = right; |
- right = temp; |
- } |
- if (bottom > top) { |
- temp = top; |
- top = bottom; |
- bottom = temp; |
- } |
-} |
-void CFX_FloatRect::Intersect(const CFX_FloatRect& other_rect) |
-{ |
- Normalize(); |
- CFX_FloatRect other = other_rect; |
- other.Normalize(); |
- left = left > other.left ? left : other.left; |
- right = right < other.right ? right : other.right; |
- bottom = bottom > other.bottom ? bottom : other.bottom; |
- top = top < other.top ? top : other.top; |
- if (left > right || bottom > top) { |
- left = right = bottom = top = 0; |
- } |
-} |
-void CFX_FloatRect::Union(const CFX_FloatRect& other_rect) |
-{ |
- Normalize(); |
- CFX_FloatRect other = other_rect; |
- other.Normalize(); |
- left = left < other.left ? left : other.left; |
- right = right > other.right ? right : other.right; |
- bottom = bottom < other.bottom ? bottom : other.bottom; |
- top = top > other.top ? top : other.top; |
-} |
-void CFX_FloatRect::Transform(const CFX_Matrix* pMatrix) |
-{ |
- pMatrix->TransformRect(left, right, top, bottom); |
-} |
-int CFX_FloatRect::Substract4(CFX_FloatRect& s, CFX_FloatRect* pRects) |
-{ |
- Normalize(); |
- s.Normalize(); |
- int nRects = 0; |
- CFX_FloatRect rects[4]; |
- if (left < s.left) { |
- rects[nRects].left = left; |
- rects[nRects].right = s.left; |
- rects[nRects].bottom = bottom; |
- rects[nRects].top = top; |
- nRects ++; |
- } |
- if (s.left < right && s.top < top) { |
- rects[nRects].left = s.left; |
- rects[nRects].right = right; |
- rects[nRects].bottom = s.top; |
- rects[nRects].top = top; |
- nRects ++; |
- } |
- if (s.top > bottom && s.right < right) { |
- rects[nRects].left = s.right; |
- rects[nRects].right = right; |
- rects[nRects].bottom = bottom; |
- rects[nRects].top = s.top; |
- nRects ++; |
- } |
- if (s.bottom > bottom) { |
- rects[nRects].left = s.left; |
- rects[nRects].right = s.right; |
- rects[nRects].bottom = bottom; |
- rects[nRects].top = s.bottom; |
- nRects ++; |
- } |
- if (nRects == 0) { |
- return 0; |
- } |
- for (int i = 0; i < nRects; i ++) { |
- pRects[i] = rects[i]; |
- pRects[i].Intersect(*this); |
- } |
- return nRects; |
-} |
-FX_RECT CFX_FloatRect::GetOutterRect() const |
-{ |
- CFX_FloatRect rect1 = *this; |
- FX_RECT rect; |
- rect.left = (int)FXSYS_floor(rect1.left); |
- rect.right = (int)FXSYS_ceil(rect1.right); |
- rect.top = (int)FXSYS_floor(rect1.bottom); |
- rect.bottom = (int)FXSYS_ceil(rect1.top); |
- rect.Normalize(); |
- return rect; |
-} |
-FX_RECT CFX_FloatRect::GetInnerRect() const |
-{ |
- CFX_FloatRect rect1 = *this; |
- FX_RECT rect; |
- rect.left = (int)FXSYS_ceil(rect1.left); |
- rect.right = (int)FXSYS_floor(rect1.right); |
- rect.top = (int)FXSYS_ceil(rect1.bottom); |
- rect.bottom = (int)FXSYS_floor(rect1.top); |
- rect.Normalize(); |
- return rect; |
-} |
-static void _MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int& i1, int& i2) |
-{ |
- int length = (int)FXSYS_ceil(f2 - f1); |
- int i1_1 = (int)FXSYS_floor(f1); |
- int i1_2 = (int)FXSYS_ceil(f1); |
- FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length); |
- FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length); |
- i1 = (error1 > error2) ? i1_2 : i1_1; |
- i2 = i1 + length; |
-} |
-FX_RECT CFX_FloatRect::GetClosestRect() const |
-{ |
- CFX_FloatRect rect1 = *this; |
- FX_RECT rect; |
- _MatchFloatRange(rect1.left, rect1.right, rect.left, rect.right); |
- _MatchFloatRange(rect1.bottom, rect1.top, rect.top, rect.bottom); |
- rect.Normalize(); |
- return rect; |
-} |
-FX_BOOL CFX_FloatRect::Contains(const CFX_FloatRect& other_rect) const |
-{ |
- CFX_FloatRect n1 = *this; |
- n1.Normalize(); |
- CFX_FloatRect n2 = other_rect; |
- n2.Normalize(); |
- if (n2.left >= n1.left && n2.right <= n1.right && n2.bottom >= n1.bottom && n2.top <= n1.top) { |
- return TRUE; |
- } |
+void FX_RECT::Normalize() { |
+ if (left > right) { |
+ int temp = left; |
+ left = right; |
+ right = temp; |
+ } |
+ if (top > bottom) { |
+ int temp = top; |
+ top = bottom; |
+ bottom = temp; |
+ } |
+} |
+void FX_RECT::Intersect(const FX_RECT& src) { |
+ FX_RECT src_n = src; |
+ src_n.Normalize(); |
+ Normalize(); |
+ left = left > src_n.left ? left : src_n.left; |
+ top = top > src_n.top ? top : src_n.top; |
+ right = right < src_n.right ? right : src_n.right; |
+ bottom = bottom < src_n.bottom ? bottom : src_n.bottom; |
+ if (left > right || top > bottom) { |
+ left = top = right = bottom = 0; |
+ } |
+} |
+void FX_RECT::Union(const FX_RECT& other_rect) { |
+ Normalize(); |
+ FX_RECT other = other_rect; |
+ other.Normalize(); |
+ left = left < other.left ? left : other.left; |
+ right = right > other.right ? right : other.right; |
+ bottom = bottom > other.bottom ? bottom : other.bottom; |
+ top = top < other.top ? top : other.top; |
+} |
+FX_BOOL GetIntersection(FX_FLOAT low1, |
+ FX_FLOAT high1, |
+ FX_FLOAT low2, |
+ FX_FLOAT high2, |
+ FX_FLOAT& interlow, |
+ FX_FLOAT& interhigh) { |
+ if (low1 >= high2 || low2 >= high1) { |
return FALSE; |
-} |
-FX_BOOL CFX_FloatRect::Contains(FX_FLOAT x, FX_FLOAT y) const |
-{ |
- CFX_FloatRect n1 = *this; |
- n1.Normalize(); |
- return x <= n1.right && x >= n1.left && y <= n1.top && y >= n1.bottom; |
-} |
-void CFX_FloatRect::UpdateRect(FX_FLOAT x, FX_FLOAT y) |
-{ |
- if (left > x) { |
- left = x; |
- } |
- if (right < x) { |
- right = x; |
- } |
- if (bottom > y) { |
- bottom = y; |
- } |
- if (top < y) { |
- top = y; |
- } |
-} |
-CFX_FloatRect CFX_FloatRect::GetBBox(const CFX_FloatPoint* pPoints, int nPoints) |
-{ |
- if (nPoints == 0) { |
- return CFX_FloatRect(); |
- } |
- FX_FLOAT min_x = pPoints->x, max_x = pPoints->x, min_y = pPoints->y, max_y = pPoints->y; |
- for (int i = 1; i < nPoints; i ++) { |
- if (min_x > pPoints[i].x) { |
- min_x = pPoints[i].x; |
- } |
- if (max_x < pPoints[i].x) { |
- max_x = pPoints[i].x; |
- } |
- if (min_y > pPoints[i].y) { |
- min_y = pPoints[i].y; |
- } |
- if (max_y < pPoints[i].y) { |
- max_y = pPoints[i].y; |
- } |
- } |
- return CFX_FloatRect(min_x, min_y, max_x, max_y); |
+ } |
+ interlow = low1 > low2 ? low1 : low2; |
+ interhigh = high1 > high2 ? high2 : high1; |
+ return TRUE; |
+} |
+extern "C" int FXSYS_round(FX_FLOAT d) { |
+ if (d < (FX_FLOAT)INT_MIN) { |
+ return INT_MIN; |
+ } |
+ if (d > (FX_FLOAT)INT_MAX) { |
+ return INT_MAX; |
+ } |
+ |
+ return (int)round(d); |
+} |
+CFX_FloatRect::CFX_FloatRect(const FX_RECT& rect) { |
+ left = (FX_FLOAT)(rect.left); |
+ right = (FX_FLOAT)(rect.right); |
+ bottom = (FX_FLOAT)(rect.top); |
+ top = (FX_FLOAT)(rect.bottom); |
+} |
+void CFX_FloatRect::Normalize() { |
+ FX_FLOAT temp; |
+ if (left > right) { |
+ temp = left; |
+ left = right; |
+ right = temp; |
+ } |
+ if (bottom > top) { |
+ temp = top; |
+ top = bottom; |
+ bottom = temp; |
+ } |
+} |
+void CFX_FloatRect::Intersect(const CFX_FloatRect& other_rect) { |
+ Normalize(); |
+ CFX_FloatRect other = other_rect; |
+ other.Normalize(); |
+ left = left > other.left ? left : other.left; |
+ right = right < other.right ? right : other.right; |
+ bottom = bottom > other.bottom ? bottom : other.bottom; |
+ top = top < other.top ? top : other.top; |
+ if (left > right || bottom > top) { |
+ left = right = bottom = top = 0; |
+ } |
+} |
+void CFX_FloatRect::Union(const CFX_FloatRect& other_rect) { |
+ Normalize(); |
+ CFX_FloatRect other = other_rect; |
+ other.Normalize(); |
+ left = left < other.left ? left : other.left; |
+ right = right > other.right ? right : other.right; |
+ bottom = bottom < other.bottom ? bottom : other.bottom; |
+ top = top > other.top ? top : other.top; |
+} |
+void CFX_FloatRect::Transform(const CFX_Matrix* pMatrix) { |
+ pMatrix->TransformRect(left, right, top, bottom); |
+} |
+int CFX_FloatRect::Substract4(CFX_FloatRect& s, CFX_FloatRect* pRects) { |
+ Normalize(); |
+ s.Normalize(); |
+ int nRects = 0; |
+ CFX_FloatRect rects[4]; |
+ if (left < s.left) { |
+ rects[nRects].left = left; |
+ rects[nRects].right = s.left; |
+ rects[nRects].bottom = bottom; |
+ rects[nRects].top = top; |
+ nRects++; |
+ } |
+ if (s.left < right && s.top < top) { |
+ rects[nRects].left = s.left; |
+ rects[nRects].right = right; |
+ rects[nRects].bottom = s.top; |
+ rects[nRects].top = top; |
+ nRects++; |
+ } |
+ if (s.top > bottom && s.right < right) { |
+ rects[nRects].left = s.right; |
+ rects[nRects].right = right; |
+ rects[nRects].bottom = bottom; |
+ rects[nRects].top = s.top; |
+ nRects++; |
+ } |
+ if (s.bottom > bottom) { |
+ rects[nRects].left = s.left; |
+ rects[nRects].right = s.right; |
+ rects[nRects].bottom = bottom; |
+ rects[nRects].top = s.bottom; |
+ nRects++; |
+ } |
+ if (nRects == 0) { |
+ return 0; |
+ } |
+ for (int i = 0; i < nRects; i++) { |
+ pRects[i] = rects[i]; |
+ pRects[i].Intersect(*this); |
+ } |
+ return nRects; |
+} |
+FX_RECT CFX_FloatRect::GetOutterRect() const { |
+ CFX_FloatRect rect1 = *this; |
+ FX_RECT rect; |
+ rect.left = (int)FXSYS_floor(rect1.left); |
+ rect.right = (int)FXSYS_ceil(rect1.right); |
+ rect.top = (int)FXSYS_floor(rect1.bottom); |
+ rect.bottom = (int)FXSYS_ceil(rect1.top); |
+ rect.Normalize(); |
+ return rect; |
+} |
+FX_RECT CFX_FloatRect::GetInnerRect() const { |
+ CFX_FloatRect rect1 = *this; |
+ FX_RECT rect; |
+ rect.left = (int)FXSYS_ceil(rect1.left); |
+ rect.right = (int)FXSYS_floor(rect1.right); |
+ rect.top = (int)FXSYS_ceil(rect1.bottom); |
+ rect.bottom = (int)FXSYS_floor(rect1.top); |
+ rect.Normalize(); |
+ return rect; |
+} |
+static void _MatchFloatRange(FX_FLOAT f1, FX_FLOAT f2, int& i1, int& i2) { |
+ int length = (int)FXSYS_ceil(f2 - f1); |
+ int i1_1 = (int)FXSYS_floor(f1); |
+ int i1_2 = (int)FXSYS_ceil(f1); |
+ FX_FLOAT error1 = f1 - i1_1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_1 - length); |
+ FX_FLOAT error2 = i1_2 - f1 + (FX_FLOAT)FXSYS_fabs(f2 - i1_2 - length); |
+ i1 = (error1 > error2) ? i1_2 : i1_1; |
+ i2 = i1 + length; |
+} |
+FX_RECT CFX_FloatRect::GetClosestRect() const { |
+ CFX_FloatRect rect1 = *this; |
+ FX_RECT rect; |
+ _MatchFloatRange(rect1.left, rect1.right, rect.left, rect.right); |
+ _MatchFloatRange(rect1.bottom, rect1.top, rect.top, rect.bottom); |
+ rect.Normalize(); |
+ return rect; |
+} |
+FX_BOOL CFX_FloatRect::Contains(const CFX_FloatRect& other_rect) const { |
+ CFX_FloatRect n1 = *this; |
+ n1.Normalize(); |
+ CFX_FloatRect n2 = other_rect; |
+ n2.Normalize(); |
+ if (n2.left >= n1.left && n2.right <= n1.right && n2.bottom >= n1.bottom && |
+ n2.top <= n1.top) { |
+ return TRUE; |
+ } |
+ return FALSE; |
+} |
+FX_BOOL CFX_FloatRect::Contains(FX_FLOAT x, FX_FLOAT y) const { |
+ CFX_FloatRect n1 = *this; |
+ n1.Normalize(); |
+ return x <= n1.right && x >= n1.left && y <= n1.top && y >= n1.bottom; |
+} |
+void CFX_FloatRect::UpdateRect(FX_FLOAT x, FX_FLOAT y) { |
+ if (left > x) { |
+ left = x; |
+ } |
+ if (right < x) { |
+ right = x; |
+ } |
+ if (bottom > y) { |
+ bottom = y; |
+ } |
+ if (top < y) { |
+ top = y; |
+ } |
+} |
+CFX_FloatRect CFX_FloatRect::GetBBox(const CFX_FloatPoint* pPoints, |
+ int nPoints) { |
+ if (nPoints == 0) { |
+ return CFX_FloatRect(); |
+ } |
+ FX_FLOAT min_x = pPoints->x, max_x = pPoints->x, min_y = pPoints->y, |
+ max_y = pPoints->y; |
+ for (int i = 1; i < nPoints; i++) { |
+ if (min_x > pPoints[i].x) { |
+ min_x = pPoints[i].x; |
+ } |
+ if (max_x < pPoints[i].x) { |
+ max_x = pPoints[i].x; |
+ } |
+ if (min_y > pPoints[i].y) { |
+ min_y = pPoints[i].y; |
+ } |
+ if (max_y < pPoints[i].y) { |
+ max_y = pPoints[i].y; |
+ } |
+ } |
+ return CFX_FloatRect(min_x, min_y, max_x, max_y); |
} |
void CFX_Matrix::Set(FX_FLOAT other_a, |
FX_FLOAT other_b, |
FX_FLOAT other_c, |
FX_FLOAT other_d, |
FX_FLOAT other_e, |
- FX_FLOAT other_f) |
-{ |
- a = other_a; |
- b = other_b; |
- c = other_c; |
- d = other_d; |
- e = other_e; |
- f = other_f; |
-} |
-void CFX_Matrix::Set(const FX_FLOAT n[6]) |
-{ |
- a = n[0]; |
- b = n[1]; |
- c = n[2]; |
- d = n[3]; |
- e = n[4]; |
- f = n[5]; |
-} |
-void CFX_Matrix::SetReverse(const CFX_Matrix &m) |
-{ |
- FX_FLOAT i = m.a * m.d - m.b * m.c; |
- if (FXSYS_fabs(i) == 0) { |
- return; |
- } |
- FX_FLOAT j = -i; |
- a = m.d / i; |
- b = m.b / j; |
- c = m.c / j; |
- d = m.a / i; |
- e = (m.c * m.f - m.d * m.e) / i; |
- f = (m.a * m.f - m.b * m.e) / j; |
-} |
-static void FXCRT_Matrix_Concat(CFX_Matrix &m, const CFX_Matrix &m1, const CFX_Matrix &m2) |
-{ |
- FX_FLOAT aa = m1.a * m2.a + m1.b * m2.c; |
- FX_FLOAT bb = m1.a * m2.b + m1.b * m2.d; |
- FX_FLOAT cc = m1.c * m2.a + m1.d * m2.c; |
- FX_FLOAT dd = m1.c * m2.b + m1.d * m2.d; |
- FX_FLOAT ee = m1.e * m2.a + m1.f * m2.c + m2.e; |
- FX_FLOAT ff = m1.e * m2.b + m1.f * m2.d + m2.f; |
- m.a = aa, m.b = bb, m.c = cc, m.d = dd, m.e = ee, m.f = ff; |
-} |
-void CFX_Matrix::Concat(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, FX_BOOL bPrepended) |
-{ |
- CFX_Matrix m; |
- m.Set(a, b, c, d, e, f); |
- Concat(m, bPrepended); |
-} |
-void CFX_Matrix::Concat(const CFX_Matrix &m, FX_BOOL bPrepended) |
-{ |
- if (bPrepended) { |
- FXCRT_Matrix_Concat(*this, m, *this); |
- } else { |
- FXCRT_Matrix_Concat(*this, *this, m); |
- } |
-} |
-void CFX_Matrix::ConcatInverse(const CFX_Matrix& src, FX_BOOL bPrepended) |
-{ |
- CFX_Matrix m; |
- m.SetReverse(src); |
- Concat(m, bPrepended); |
-} |
-FX_BOOL CFX_Matrix::IsInvertible() const |
-{ |
- return FXSYS_fabs(a * d - b * c) >= 0.0001f; |
-} |
-FX_BOOL CFX_Matrix::Is90Rotated() const |
-{ |
- return FXSYS_fabs(a * 1000) < FXSYS_fabs(b) && FXSYS_fabs(d * 1000) < FXSYS_fabs(c); |
-} |
-FX_BOOL CFX_Matrix::IsScaled() const |
-{ |
- return FXSYS_fabs(b * 1000) < FXSYS_fabs(a) && FXSYS_fabs(c * 1000) < FXSYS_fabs(d); |
-} |
-void CFX_Matrix::Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended) |
-{ |
- if (bPrepended) { |
- e += x * a + y * c; |
- f += y * d + x * b; |
- } else { |
- e += x, f += y; |
- } |
-} |
-void CFX_Matrix::Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended) |
-{ |
- a *= sx, d *= sy; |
- if (bPrepended) { |
- b *= sx; |
- c *= sy; |
- } else { |
- b *= sy; |
- c *= sx; |
- e *= sx; |
- f *= sy; |
- } |
-} |
-void CFX_Matrix::Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended) |
-{ |
- FX_FLOAT cosValue = FXSYS_cos(fRadian); |
- FX_FLOAT sinValue = FXSYS_sin(fRadian); |
- CFX_Matrix m; |
- m.Set(cosValue, sinValue, -sinValue, cosValue, 0, 0); |
- if (bPrepended) { |
- FXCRT_Matrix_Concat(*this, m, *this); |
- } else { |
- FXCRT_Matrix_Concat(*this, *this, m); |
- } |
-} |
-void CFX_Matrix::RotateAt(FX_FLOAT fRadian, FX_FLOAT dx, FX_FLOAT dy, FX_BOOL bPrepended) |
-{ |
- Translate(dx, dy, bPrepended); |
- Rotate(fRadian, bPrepended); |
- Translate(-dx, -dy, bPrepended); |
-} |
-void CFX_Matrix::Shear(FX_FLOAT fAlphaRadian, FX_FLOAT fBetaRadian, FX_BOOL bPrepended) |
-{ |
- CFX_Matrix m; |
- m.Set(1, FXSYS_tan(fAlphaRadian), FXSYS_tan(fBetaRadian), 1, 0, 0); |
- if (bPrepended) { |
- FXCRT_Matrix_Concat(*this, m, *this); |
- } else { |
- FXCRT_Matrix_Concat(*this, *this, m); |
- } |
-} |
-void CFX_Matrix::MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src) |
-{ |
- FX_FLOAT fDiff = src.left - src.right; |
- a = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.left - dest.right) / fDiff; |
- fDiff = src.bottom - src.top; |
- d = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.bottom - dest.top) / fDiff; |
- e = dest.left - src.left * a; |
- f = dest.bottom - src.bottom * d; |
- b = 0; |
- c = 0; |
-} |
-FX_FLOAT CFX_Matrix::GetXUnit() const |
-{ |
- if (b == 0) { |
- return (a > 0 ? a : -a); |
- } |
- if (a == 0) { |
- return (b > 0 ? b : -b); |
- } |
- return FXSYS_sqrt(a * a + b * b); |
-} |
-FX_FLOAT CFX_Matrix::GetYUnit() const |
-{ |
- if (c == 0) { |
- return (d > 0 ? d : -d); |
- } |
- if (d == 0) { |
- return (c > 0 ? c : -c); |
- } |
- return FXSYS_sqrt(c * c + d * d); |
-} |
-void CFX_Matrix::GetUnitRect(CFX_RectF &rect) const |
-{ |
- rect.left = rect.top = 0; |
- rect.width = rect.height = 1; |
- TransformRect(rect); |
-} |
-CFX_FloatRect CFX_Matrix::GetUnitRect() const |
-{ |
- CFX_FloatRect rect(0, 0, 1, 1); |
- rect.Transform((const CFX_Matrix*)this); |
- return rect; |
-} |
-FX_FLOAT CFX_Matrix::GetUnitArea() const |
-{ |
- FX_FLOAT A = FXSYS_sqrt(a * a + b * b); |
- FX_FLOAT B = FXSYS_sqrt(c * c + d * d); |
- FX_FLOAT ac = a + c, bd = b + d; |
- FX_FLOAT C = FXSYS_sqrt(ac * ac + bd * bd); |
- FX_FLOAT P = (A + B + C ) / 2; |
- return FXSYS_sqrt(P * (P - A) * (P - B) * (P - C)) * 2; |
-} |
-FX_FLOAT CFX_Matrix::TransformXDistance(FX_FLOAT dx) const |
-{ |
- FX_FLOAT fx = a * dx, fy = b * dx; |
- return FXSYS_sqrt(fx * fx + fy * fy); |
-} |
-int32_t CFX_Matrix::TransformXDistance(int32_t dx) const |
-{ |
- FX_FLOAT fx = a * dx, fy = b * dx; |
- return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
-} |
-FX_FLOAT CFX_Matrix::TransformYDistance(FX_FLOAT dy) const |
-{ |
- FX_FLOAT fx = c * dy, fy = d * dy; |
- return FXSYS_sqrt(fx * fx + fy * fy); |
-} |
-int32_t CFX_Matrix::TransformYDistance(int32_t dy) const |
-{ |
- FX_FLOAT fx = c * dy, fy = d * dy; |
- return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
-} |
-FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const |
-{ |
- FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; |
- return FXSYS_sqrt(fx * fx + fy * fy); |
-} |
-int32_t CFX_Matrix::TransformDistance(int32_t dx, int32_t dy) const |
-{ |
- FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; |
- return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
-} |
-FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT distance) const |
-{ |
- return distance * (GetXUnit() + GetYUnit()) / 2; |
-} |
-void CFX_Matrix::TransformVector(CFX_VectorF &v) const |
-{ |
- FX_FLOAT fx = a * v.x + c * v.y; |
- FX_FLOAT fy = b * v.x + d * v.y; |
- v.x = fx, v.y = fy; |
-} |
-void CFX_Matrix::TransformVector(CFX_Vector &v) const |
-{ |
- FX_FLOAT fx = a * v.x + c * v.y; |
- FX_FLOAT fy = b * v.x + d * v.y; |
- v.x = FXSYS_round(fx); |
- v.y = FXSYS_round(fy); |
-} |
-void CFX_Matrix::TransformPoints(CFX_Point *points, int32_t iCount) const |
-{ |
- FXSYS_assert(iCount > 0); |
- FX_FLOAT fx, fy; |
- for (int32_t i = 0; i < iCount; i ++) { |
- fx = a * points->x + c * points->y + e; |
- fy = b * points->x + d * points->y + f; |
- points->x = FXSYS_round(fx); |
- points->y = FXSYS_round(fy); |
- points ++; |
- } |
-} |
-void CFX_Matrix::TransformPoints(CFX_PointF *points, int32_t iCount) const |
-{ |
- FXSYS_assert(iCount > 0); |
- FX_FLOAT fx, fy; |
- for (int32_t i = 0; i < iCount; i ++) { |
- fx = a * points->x + c * points->y + e; |
- fy = b * points->x + d * points->y + f; |
- points->x = fx, points->y = fy; |
- points ++; |
- } |
-} |
-void CFX_Matrix::TransformPoint(FX_FLOAT &x, FX_FLOAT &y) const |
-{ |
- FX_FLOAT fx = a * x + c * y + e; |
- FX_FLOAT fy = b * x + d * y + f; |
- x = fx, y = fy; |
-} |
-void CFX_Matrix::TransformPoint(int32_t &x, int32_t &y) const |
-{ |
- FX_FLOAT fx = a * x + c * y + e; |
- FX_FLOAT fy = b * x + d * y + f; |
- x = FXSYS_round(fx); |
- y = FXSYS_round(fy); |
-} |
-void CFX_Matrix::TransformRect(CFX_RectF &rect) const |
-{ |
- FX_FLOAT right = rect.right(), bottom = rect.bottom(); |
- TransformRect(rect.left, right, bottom, rect.top); |
- rect.width = right - rect.left; |
- rect.height = bottom - rect.top; |
-} |
-void CFX_Matrix::TransformRect(CFX_Rect &rect) const |
-{ |
- FX_FLOAT left = (FX_FLOAT)rect.left; |
- FX_FLOAT top = (FX_FLOAT)rect.bottom(); |
- FX_FLOAT right = (FX_FLOAT)rect.right(); |
- FX_FLOAT bottom = (FX_FLOAT)rect.top; |
- TransformRect(left, right, top, bottom); |
- rect.left = FXSYS_round(left); |
- rect.top = FXSYS_round(bottom); |
- rect.width = FXSYS_round(right - left); |
- rect.height = FXSYS_round(top - bottom); |
-} |
-void CFX_Matrix::TransformRect(FX_FLOAT& left, FX_FLOAT& right, FX_FLOAT& top, FX_FLOAT& bottom) const |
-{ |
- FX_FLOAT x[4], y[4]; |
- x[0] = left; |
- y[0] = top; |
- x[1] = left; |
- y[1] = bottom; |
- x[2] = right; |
- y[2] = top; |
- x[3] = right; |
- y[3] = bottom; |
- int i; |
- for (i = 0; i < 4; i ++) { |
- Transform(x[i], y[i], x[i], y[i]); |
- } |
- right = left = x[0]; |
- top = bottom = y[0]; |
- for (i = 1; i < 4; i ++) { |
- if (right < x[i]) { |
- right = x[i]; |
- } |
- if (left > x[i]) { |
- left = x[i]; |
- } |
- if (top < y[i]) { |
- top = y[i]; |
- } |
- if (bottom > y[i]) { |
- bottom = y[i]; |
- } |
- } |
+ FX_FLOAT other_f) { |
+ a = other_a; |
+ b = other_b; |
+ c = other_c; |
+ d = other_d; |
+ e = other_e; |
+ f = other_f; |
+} |
+void CFX_Matrix::Set(const FX_FLOAT n[6]) { |
+ a = n[0]; |
+ b = n[1]; |
+ c = n[2]; |
+ d = n[3]; |
+ e = n[4]; |
+ f = n[5]; |
+} |
+void CFX_Matrix::SetReverse(const CFX_Matrix& m) { |
+ FX_FLOAT i = m.a * m.d - m.b * m.c; |
+ if (FXSYS_fabs(i) == 0) { |
+ return; |
+ } |
+ FX_FLOAT j = -i; |
+ a = m.d / i; |
+ b = m.b / j; |
+ c = m.c / j; |
+ d = m.a / i; |
+ e = (m.c * m.f - m.d * m.e) / i; |
+ f = (m.a * m.f - m.b * m.e) / j; |
+} |
+static void FXCRT_Matrix_Concat(CFX_Matrix& m, |
+ const CFX_Matrix& m1, |
+ const CFX_Matrix& m2) { |
+ FX_FLOAT aa = m1.a * m2.a + m1.b * m2.c; |
+ FX_FLOAT bb = m1.a * m2.b + m1.b * m2.d; |
+ FX_FLOAT cc = m1.c * m2.a + m1.d * m2.c; |
+ FX_FLOAT dd = m1.c * m2.b + m1.d * m2.d; |
+ FX_FLOAT ee = m1.e * m2.a + m1.f * m2.c + m2.e; |
+ FX_FLOAT ff = m1.e * m2.b + m1.f * m2.d + m2.f; |
+ m.a = aa, m.b = bb, m.c = cc, m.d = dd, m.e = ee, m.f = ff; |
+} |
+void CFX_Matrix::Concat(FX_FLOAT a, |
+ FX_FLOAT b, |
+ FX_FLOAT c, |
+ FX_FLOAT d, |
+ FX_FLOAT e, |
+ FX_FLOAT f, |
+ FX_BOOL bPrepended) { |
+ CFX_Matrix m; |
+ m.Set(a, b, c, d, e, f); |
+ Concat(m, bPrepended); |
+} |
+void CFX_Matrix::Concat(const CFX_Matrix& m, FX_BOOL bPrepended) { |
+ if (bPrepended) { |
+ FXCRT_Matrix_Concat(*this, m, *this); |
+ } else { |
+ FXCRT_Matrix_Concat(*this, *this, m); |
+ } |
+} |
+void CFX_Matrix::ConcatInverse(const CFX_Matrix& src, FX_BOOL bPrepended) { |
+ CFX_Matrix m; |
+ m.SetReverse(src); |
+ Concat(m, bPrepended); |
+} |
+FX_BOOL CFX_Matrix::IsInvertible() const { |
+ return FXSYS_fabs(a * d - b * c) >= 0.0001f; |
+} |
+FX_BOOL CFX_Matrix::Is90Rotated() const { |
+ return FXSYS_fabs(a * 1000) < FXSYS_fabs(b) && |
+ FXSYS_fabs(d * 1000) < FXSYS_fabs(c); |
+} |
+FX_BOOL CFX_Matrix::IsScaled() const { |
+ return FXSYS_fabs(b * 1000) < FXSYS_fabs(a) && |
+ FXSYS_fabs(c * 1000) < FXSYS_fabs(d); |
+} |
+void CFX_Matrix::Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended) { |
+ if (bPrepended) { |
+ e += x * a + y * c; |
+ f += y * d + x * b; |
+ } else { |
+ e += x, f += y; |
+ } |
+} |
+void CFX_Matrix::Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended) { |
+ a *= sx, d *= sy; |
+ if (bPrepended) { |
+ b *= sx; |
+ c *= sy; |
+ } else { |
+ b *= sy; |
+ c *= sx; |
+ e *= sx; |
+ f *= sy; |
+ } |
+} |
+void CFX_Matrix::Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended) { |
+ FX_FLOAT cosValue = FXSYS_cos(fRadian); |
+ FX_FLOAT sinValue = FXSYS_sin(fRadian); |
+ CFX_Matrix m; |
+ m.Set(cosValue, sinValue, -sinValue, cosValue, 0, 0); |
+ if (bPrepended) { |
+ FXCRT_Matrix_Concat(*this, m, *this); |
+ } else { |
+ FXCRT_Matrix_Concat(*this, *this, m); |
+ } |
+} |
+void CFX_Matrix::RotateAt(FX_FLOAT fRadian, |
+ FX_FLOAT dx, |
+ FX_FLOAT dy, |
+ FX_BOOL bPrepended) { |
+ Translate(dx, dy, bPrepended); |
+ Rotate(fRadian, bPrepended); |
+ Translate(-dx, -dy, bPrepended); |
+} |
+void CFX_Matrix::Shear(FX_FLOAT fAlphaRadian, |
+ FX_FLOAT fBetaRadian, |
+ FX_BOOL bPrepended) { |
+ CFX_Matrix m; |
+ m.Set(1, FXSYS_tan(fAlphaRadian), FXSYS_tan(fBetaRadian), 1, 0, 0); |
+ if (bPrepended) { |
+ FXCRT_Matrix_Concat(*this, m, *this); |
+ } else { |
+ FXCRT_Matrix_Concat(*this, *this, m); |
+ } |
+} |
+void CFX_Matrix::MatchRect(const CFX_FloatRect& dest, |
+ const CFX_FloatRect& src) { |
+ FX_FLOAT fDiff = src.left - src.right; |
+ a = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.left - dest.right) / fDiff; |
+ fDiff = src.bottom - src.top; |
+ d = FXSYS_fabs(fDiff) < 0.001f ? 1 : (dest.bottom - dest.top) / fDiff; |
+ e = dest.left - src.left * a; |
+ f = dest.bottom - src.bottom * d; |
+ b = 0; |
+ c = 0; |
+} |
+FX_FLOAT CFX_Matrix::GetXUnit() const { |
+ if (b == 0) { |
+ return (a > 0 ? a : -a); |
+ } |
+ if (a == 0) { |
+ return (b > 0 ? b : -b); |
+ } |
+ return FXSYS_sqrt(a * a + b * b); |
+} |
+FX_FLOAT CFX_Matrix::GetYUnit() const { |
+ if (c == 0) { |
+ return (d > 0 ? d : -d); |
+ } |
+ if (d == 0) { |
+ return (c > 0 ? c : -c); |
+ } |
+ return FXSYS_sqrt(c * c + d * d); |
+} |
+void CFX_Matrix::GetUnitRect(CFX_RectF& rect) const { |
+ rect.left = rect.top = 0; |
+ rect.width = rect.height = 1; |
+ TransformRect(rect); |
+} |
+CFX_FloatRect CFX_Matrix::GetUnitRect() const { |
+ CFX_FloatRect rect(0, 0, 1, 1); |
+ rect.Transform((const CFX_Matrix*)this); |
+ return rect; |
+} |
+FX_FLOAT CFX_Matrix::GetUnitArea() const { |
+ FX_FLOAT A = FXSYS_sqrt(a * a + b * b); |
+ FX_FLOAT B = FXSYS_sqrt(c * c + d * d); |
+ FX_FLOAT ac = a + c, bd = b + d; |
+ FX_FLOAT C = FXSYS_sqrt(ac * ac + bd * bd); |
+ FX_FLOAT P = (A + B + C) / 2; |
+ return FXSYS_sqrt(P * (P - A) * (P - B) * (P - C)) * 2; |
+} |
+FX_FLOAT CFX_Matrix::TransformXDistance(FX_FLOAT dx) const { |
+ FX_FLOAT fx = a * dx, fy = b * dx; |
+ return FXSYS_sqrt(fx * fx + fy * fy); |
+} |
+int32_t CFX_Matrix::TransformXDistance(int32_t dx) const { |
+ FX_FLOAT fx = a * dx, fy = b * dx; |
+ return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
+} |
+FX_FLOAT CFX_Matrix::TransformYDistance(FX_FLOAT dy) const { |
+ FX_FLOAT fx = c * dy, fy = d * dy; |
+ return FXSYS_sqrt(fx * fx + fy * fy); |
+} |
+int32_t CFX_Matrix::TransformYDistance(int32_t dy) const { |
+ FX_FLOAT fx = c * dy, fy = d * dy; |
+ return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
+} |
+FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const { |
+ FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; |
+ return FXSYS_sqrt(fx * fx + fy * fy); |
+} |
+int32_t CFX_Matrix::TransformDistance(int32_t dx, int32_t dy) const { |
+ FX_FLOAT fx = a * dx + c * dy, fy = b * dx + d * dy; |
+ return FXSYS_round(FXSYS_sqrt(fx * fx + fy * fy)); |
+} |
+FX_FLOAT CFX_Matrix::TransformDistance(FX_FLOAT distance) const { |
+ return distance * (GetXUnit() + GetYUnit()) / 2; |
+} |
+void CFX_Matrix::TransformVector(CFX_VectorF& v) const { |
+ FX_FLOAT fx = a * v.x + c * v.y; |
+ FX_FLOAT fy = b * v.x + d * v.y; |
+ v.x = fx, v.y = fy; |
+} |
+void CFX_Matrix::TransformVector(CFX_Vector& v) const { |
+ FX_FLOAT fx = a * v.x + c * v.y; |
+ FX_FLOAT fy = b * v.x + d * v.y; |
+ v.x = FXSYS_round(fx); |
+ v.y = FXSYS_round(fy); |
+} |
+void CFX_Matrix::TransformPoints(CFX_Point* points, int32_t iCount) const { |
+ FXSYS_assert(iCount > 0); |
+ FX_FLOAT fx, fy; |
+ for (int32_t i = 0; i < iCount; i++) { |
+ fx = a * points->x + c * points->y + e; |
+ fy = b * points->x + d * points->y + f; |
+ points->x = FXSYS_round(fx); |
+ points->y = FXSYS_round(fy); |
+ points++; |
+ } |
+} |
+void CFX_Matrix::TransformPoints(CFX_PointF* points, int32_t iCount) const { |
+ FXSYS_assert(iCount > 0); |
+ FX_FLOAT fx, fy; |
+ for (int32_t i = 0; i < iCount; i++) { |
+ fx = a * points->x + c * points->y + e; |
+ fy = b * points->x + d * points->y + f; |
+ points->x = fx, points->y = fy; |
+ points++; |
+ } |
+} |
+void CFX_Matrix::TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const { |
+ FX_FLOAT fx = a * x + c * y + e; |
+ FX_FLOAT fy = b * x + d * y + f; |
+ x = fx, y = fy; |
+} |
+void CFX_Matrix::TransformPoint(int32_t& x, int32_t& y) const { |
+ FX_FLOAT fx = a * x + c * y + e; |
+ FX_FLOAT fy = b * x + d * y + f; |
+ x = FXSYS_round(fx); |
+ y = FXSYS_round(fy); |
+} |
+void CFX_Matrix::TransformRect(CFX_RectF& rect) const { |
+ FX_FLOAT right = rect.right(), bottom = rect.bottom(); |
+ TransformRect(rect.left, right, bottom, rect.top); |
+ rect.width = right - rect.left; |
+ rect.height = bottom - rect.top; |
+} |
+void CFX_Matrix::TransformRect(CFX_Rect& rect) const { |
+ FX_FLOAT left = (FX_FLOAT)rect.left; |
+ FX_FLOAT top = (FX_FLOAT)rect.bottom(); |
+ FX_FLOAT right = (FX_FLOAT)rect.right(); |
+ FX_FLOAT bottom = (FX_FLOAT)rect.top; |
+ TransformRect(left, right, top, bottom); |
+ rect.left = FXSYS_round(left); |
+ rect.top = FXSYS_round(bottom); |
+ rect.width = FXSYS_round(right - left); |
+ rect.height = FXSYS_round(top - bottom); |
+} |
+void CFX_Matrix::TransformRect(FX_FLOAT& left, |
+ FX_FLOAT& right, |
+ FX_FLOAT& top, |
+ FX_FLOAT& bottom) const { |
+ FX_FLOAT x[4], y[4]; |
+ x[0] = left; |
+ y[0] = top; |
+ x[1] = left; |
+ y[1] = bottom; |
+ x[2] = right; |
+ y[2] = top; |
+ x[3] = right; |
+ y[3] = bottom; |
+ int i; |
+ for (i = 0; i < 4; i++) { |
+ Transform(x[i], y[i], x[i], y[i]); |
+ } |
+ right = left = x[0]; |
+ top = bottom = y[0]; |
+ for (i = 1; i < 4; i++) { |
+ if (right < x[i]) { |
+ right = x[i]; |
+ } |
+ if (left > x[i]) { |
+ left = x[i]; |
+ } |
+ if (top < y[i]) { |
+ top = y[i]; |
+ } |
+ if (bottom > y[i]) { |
+ bottom = y[i]; |
+ } |
+ } |
} |