// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#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)
{
    int iRet = 0;
    if (d >= 0.0f) {
        iRet = (int)(d + 0.5f);
        if (iRet >= 0) {
            return iRet;
        }
        return -iRet;
    }
    return (int)(d - 0.5f);
}
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 a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f)
{
    this->a = a;
    this->b = b;
    this->c = c;
    this->d = d;
    this->e = e;
    this->f = f;
}
void CFX_Matrix::Set(const FX_FLOAT n[6])
{
    FXSYS_memcpy32((void*)this, &n, sizeof(CFX_Matrix));
}
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);
}
FX_INT32 CFX_Matrix::TransformXDistance(FX_INT32 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);
}
FX_INT32 CFX_Matrix::TransformYDistance(FX_INT32 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);
}
FX_INT32 CFX_Matrix::TransformDistance(FX_INT32 dx, FX_INT32 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, FX_INT32 iCount) const
{
    FXSYS_assert(iCount > 0);
    FX_FLOAT fx, fy;
    for (FX_INT32 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, FX_INT32 iCount) const
{
    FXSYS_assert(iCount > 0);
    FX_FLOAT fx, fy;
    for (FX_INT32 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(FX_INT32 &x, FX_INT32 &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];
        }
    }
}
