From a8a28e0702a1874d29d3c9f2b155bce1557eb4fd Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Wed, 23 Mar 2016 15:41:39 -0400 Subject: Move core/include/fxcrt to core/fxcrt/include. This CL moves the fxcrt code into the core/fxcrt directory. The only exception was fx_bidi.h which was moved into core/fxcrt as it is not used outside of core/. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1825953002 . --- core/fxcrt/include/fx_coordinates.h | 672 ++++++++++++++++++++++++++++++++++++ 1 file changed, 672 insertions(+) create mode 100644 core/fxcrt/include/fx_coordinates.h (limited to 'core/fxcrt/include/fx_coordinates.h') diff --git a/core/fxcrt/include/fx_coordinates.h b/core/fxcrt/include/fx_coordinates.h new file mode 100644 index 0000000000..a7f0b8d5dc --- /dev/null +++ b/core/fxcrt/include/fx_coordinates.h @@ -0,0 +1,672 @@ +// 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 + +#ifndef CORE_FXCRT_INCLUDE_FX_COORDINATES_H_ +#define CORE_FXCRT_INCLUDE_FX_COORDINATES_H_ + +#include "core/fxcrt/include/fx_basic.h" + +class CFX_Matrix; + +template +class CFX_PSTemplate { + public: + CFX_PSTemplate() : x(0), y(0) {} + CFX_PSTemplate(BaseType new_x, BaseType new_y) : x(new_x), y(new_y) {} + CFX_PSTemplate(const CFX_PSTemplate& other) : x(other.x), y(other.y) {} + void clear() { + x = 0; + y = 0; + } + CFX_PSTemplate operator=(const CFX_PSTemplate& other) { + if (this != &other) { + x = other.x; + y = other.y; + } + return *this; + } + bool operator==(const CFX_PSTemplate& other) const { + return x == other.x && y == other.y; + } + bool operator!=(const CFX_PSTemplate& other) const { + return !(*this == other); + } + CFX_PSTemplate& operator+=(const CFX_PSTemplate& obj) { + x += obj.x; + y += obj.y; + return *this; + } + CFX_PSTemplate& operator-=(const CFX_PSTemplate& obj) { + x -= obj.x; + y -= obj.y; + return *this; + } + CFX_PSTemplate& operator*=(BaseType factor) { + x *= factor; + y *= factor; + return *this; + } + CFX_PSTemplate& operator/=(BaseType divisor) { + x /= divisor; + y /= divisor; + return *this; + } + CFX_PSTemplate operator+(const CFX_PSTemplate& other) { + return CFX_PSTemplate(x + other.x, y + other.y); + } + CFX_PSTemplate operator-(const CFX_PSTemplate& other) { + return CFX_PSTemplate(x - other.x, y - other.y); + } + CFX_PSTemplate operator*(BaseType factor) { + return CFX_PSTemplate(x * factor, y * factor); + } + CFX_PSTemplate operator/(BaseType divisor) { + return CFX_PSTemplate(x / divisor, y / divisor); + } + + BaseType x; + BaseType y; +}; +typedef CFX_PSTemplate CFX_Point; +typedef CFX_PSTemplate CFX_PointF; +typedef CFX_PSTemplate CFX_Size; +typedef CFX_PSTemplate CFX_SizeF; +typedef CFX_ArrayTemplate CFX_Points; +typedef CFX_ArrayTemplate CFX_PointsF; + +template +class CFX_VTemplate : public CFX_PSTemplate { + public: + using CFX_PSTemplate::x; + using CFX_PSTemplate::y; + + CFX_VTemplate() : CFX_PSTemplate() {} + CFX_VTemplate(BaseType new_x, BaseType new_y) + : CFX_PSTemplate(new_x, new_y) {} + + CFX_VTemplate(const CFX_VTemplate& other) : CFX_PSTemplate(other) {} + + CFX_VTemplate(const CFX_PSTemplate& point1, + const CFX_PSTemplate& point2) + : CFX_PSTemplate(point2.x - point1.x, point2.y - point1.y) {} + + FX_FLOAT Length() const { return FXSYS_sqrt(x * x + y * y); } + void Normalize() { + FX_FLOAT fLen = Length(); + if (fLen < 0.0001f) + return; + + x /= fLen; + y /= fLen; + } + void Translate(BaseType dx, BaseType dy) { + x += dx; + y += dy; + } + void Scale(BaseType sx, BaseType sy) { + x *= sx; + y *= sy; + } + void Rotate(FX_FLOAT fRadian) { + FX_FLOAT cosValue = FXSYS_cos(fRadian); + FX_FLOAT sinValue = FXSYS_sin(fRadian); + x = x * cosValue - y * sinValue; + y = x * sinValue + y * cosValue; + } +}; +typedef CFX_VTemplate CFX_Vector; +typedef CFX_VTemplate CFX_VectorF; + +// Rectangles. +// TODO(tsepez): Consolidate all these different rectangle classes. + +// LTRB rectangles (y-axis runs downwards). +struct FX_SMALL_RECT { + FX_SMALL_RECT() : FX_SMALL_RECT(kInvalid, kInvalid, kInvalid, kInvalid) {} + + FX_SMALL_RECT(int16_t l, int16_t t, int16_t r, int16_t b) + : left(l), top(t), right(r), bottom(b) {} + + static const int16_t kInvalid = -1; + + int16_t left; + int16_t top; + int16_t right; + int16_t bottom; +}; + +struct FX_RECT { + FX_RECT() : left(0), top(0), right(0), bottom(0) {} + + FX_RECT(int l, int t, int r, int b) : left(l), top(t), right(r), bottom(b) {} + + explicit FX_RECT(const FX_SMALL_RECT& other) + : FX_RECT(other.left, other.top, other.right, other.bottom) {} + + int Width() const { return right - left; } + int Height() const { return bottom - top; } + bool IsEmpty() const { return right <= left || bottom <= top; } + + void Normalize(); + + void Intersect(const FX_RECT& src); + void Intersect(int l, int t, int r, int b) { Intersect(FX_RECT(l, t, r, b)); } + + void Union(const FX_RECT& other_rect); + void Union(int l, int t, int r, int b) { Union(FX_RECT(l, t, r, b)); } + + void Offset(int dx, int dy) { + left += dx; + right += dx; + top += dy; + bottom += dy; + } + + bool operator==(const FX_RECT& src) const { + return left == src.left && right == src.right && top == src.top && + bottom == src.bottom; + } + + FX_BOOL Contains(const FX_RECT& other_rect) const { + return other_rect.left >= left && other_rect.right <= right && + other_rect.top >= top && other_rect.bottom <= bottom; + } + + FX_BOOL Contains(int x, int y) const { + return x >= left && x < right && y >= top && y < bottom; + } + + FX_SMALL_RECT ToSmallRect() const { + return FX_SMALL_RECT( + static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)); + } + + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + +// LBRT rectangles (y-axis runs upwards). +class CFX_FloatPoint { + public: + CFX_FloatPoint(FX_FLOAT xx, FX_FLOAT yy) : x(xx), y(yy) {} + + FX_FLOAT x; + FX_FLOAT y; +}; + +class CFX_FloatRect { + public: + CFX_FloatRect() : CFX_FloatRect(0.0f, 0.0f, 0.0f, 0.0f) {} + CFX_FloatRect(FX_FLOAT l, FX_FLOAT b, FX_FLOAT r, FX_FLOAT t) + : left(l), bottom(b), right(r), top(t) {} + + explicit CFX_FloatRect(const FX_FLOAT* pArray) + : CFX_FloatRect(pArray[0], pArray[1], pArray[2], pArray[3]) {} + + explicit CFX_FloatRect(const FX_RECT& rect); + + void Normalize(); + + void Reset() { + left = 0.0f; + right = 0.0f; + bottom = 0.0f; + top = 0.0f; + } + + bool IsEmpty() const { return left >= right || bottom >= top; } + bool Contains(const CFX_FloatRect& other_rect) const; + bool Contains(FX_FLOAT x, FX_FLOAT y) const; + + void Transform(const CFX_Matrix* pMatrix); + void Intersect(const CFX_FloatRect& other_rect); + void Union(const CFX_FloatRect& other_rect); + + FX_RECT GetInnerRect() const; + FX_RECT GetOutterRect() const; + FX_RECT GetClosestRect() const; + + int Substract4(CFX_FloatRect& substract_rect, CFX_FloatRect* pRects); + + void InitRect(FX_FLOAT x, FX_FLOAT y) { + left = x; + right = x; + bottom = y; + top = y; + } + void UpdateRect(FX_FLOAT x, FX_FLOAT y); + + FX_FLOAT Width() const { return right - left; } + FX_FLOAT Height() const { return top - bottom; } + + void Inflate(FX_FLOAT x, FX_FLOAT y) { + Normalize(); + left -= x; + right += x; + bottom -= y; + top += y; + } + + void Inflate(FX_FLOAT other_left, + FX_FLOAT other_bottom, + FX_FLOAT other_right, + FX_FLOAT other_top) { + Normalize(); + left -= other_left; + bottom -= other_bottom; + right += other_right; + top += other_top; + } + + void Inflate(const CFX_FloatRect& rt) { + Inflate(rt.left, rt.bottom, rt.right, rt.top); + } + + void Deflate(FX_FLOAT x, FX_FLOAT y) { + Normalize(); + left += x; + right -= x; + bottom += y; + top -= y; + } + + void Deflate(FX_FLOAT other_left, + FX_FLOAT other_bottom, + FX_FLOAT other_right, + FX_FLOAT other_top) { + Normalize(); + left += other_left; + bottom += other_bottom; + right -= other_right; + top -= other_top; + } + + void Deflate(const CFX_FloatRect& rt) { + Deflate(rt.left, rt.bottom, rt.right, rt.top); + } + + void Translate(FX_FLOAT e, FX_FLOAT f) { + left += e; + right += e; + top += f; + bottom += f; + } + + static CFX_FloatRect GetBBox(const CFX_PointF* pPoints, int nPoints); + + FX_RECT ToFxRect() const { + return FX_RECT(static_cast(left), static_cast(top), + static_cast(right), static_cast(bottom)); + } + + FX_FLOAT left; + FX_FLOAT bottom; + FX_FLOAT right; + FX_FLOAT top; +}; +using CFX_RectArray = CFX_ArrayTemplate; + +// LTWH rectangles (y-axis runs downwards). +template +class CFX_RTemplate { + public: + typedef CFX_PSTemplate FXT_POINT; + typedef CFX_PSTemplate FXT_SIZE; + typedef CFX_VTemplate FXT_VECTOR; + typedef CFX_RTemplate FXT_RECT; + void Set(baseType left, baseType top, baseType width, baseType height) { + FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::width = width, + FXT_RECT::height = height; + } + void Set(baseType left, baseType top, const FXT_SIZE& size) { + FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::Size(size); + } + void Set(const FXT_POINT& p, baseType width, baseType height) { + TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height; + } + void Set(const FXT_POINT& p1, const FXT_POINT& p2) { + TopLeft(p1), FXT_RECT::width = p2.x - p1.x, FXT_RECT::height = p2.y - p1.y, + FXT_RECT::Normalize(); + } + void Set(const FXT_POINT& p, const FXT_VECTOR& v) { + TopLeft(p), FXT_RECT::width = v.x, FXT_RECT::height = v.y, + FXT_RECT::Normalize(); + } + void Reset() { + FXT_RECT::left = FXT_RECT::top = FXT_RECT::width = FXT_RECT::height = 0; + } + FXT_RECT& operator+=(const FXT_POINT& p) { + left += p.x, top += p.y; + return *this; + } + FXT_RECT& operator-=(const FXT_POINT& p) { + left -= p.x, top -= p.y; + return *this; + } + baseType right() const { return left + width; } + baseType bottom() const { return top + height; } + void Normalize() { + if (width < 0) { + left += width; + width = -width; + } + if (height < 0) { + top += height; + height = -height; + } + } + void Offset(baseType dx, baseType dy) { + left += dx; + top += dy; + } + void Inflate(baseType x, baseType y) { + left -= x; + width += x * 2; + top -= y; + height += y * 2; + } + void Inflate(const FXT_POINT& p) { Inflate(p.x, p.y); } + void Inflate(baseType left, baseType top, baseType right, baseType bottom) { + FXT_RECT::left -= left; + FXT_RECT::top -= top; + FXT_RECT::width += left + right; + FXT_RECT::height += top + bottom; + } + void Inflate(const FXT_RECT& rt) { + Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height); + } + void Deflate(baseType x, baseType y) { + left += x; + width -= x * 2; + top += y; + height -= y * 2; + } + void Deflate(const FXT_POINT& p) { Deflate(p.x, p.y); } + void Deflate(baseType left, baseType top, baseType right, baseType bottom) { + FXT_RECT::left += left; + FXT_RECT::top += top; + FXT_RECT::width -= left + right; + FXT_RECT::height -= top + bottom; + } + void Deflate(const FXT_RECT& rt) { + Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height); + } + FX_BOOL IsEmpty() const { return width <= 0 || height <= 0; } + FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const { + return width <= fEpsilon || height <= fEpsilon; + } + void Empty() { width = height = 0; } + FX_BOOL Contains(baseType x, baseType y) const { + return x >= left && x < left + width && y >= top && y < top + height; + } + FX_BOOL Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); } + FX_BOOL Contains(const FXT_RECT& rt) const { + return rt.left >= left && rt.right() <= right() && rt.top >= top && + rt.bottom() <= bottom(); + } + baseType Width() const { return width; } + baseType Height() const { return height; } + FXT_SIZE Size() const { + FXT_SIZE size; + size.Set(width, height); + return size; + } + void Size(FXT_SIZE s) { width = s.x, height = s.y; } + FXT_POINT TopLeft() const { + FXT_POINT p; + p.x = left; + p.y = top; + return p; + } + FXT_POINT TopRight() const { + FXT_POINT p; + p.x = left + width; + p.y = top; + return p; + } + FXT_POINT BottomLeft() const { + FXT_POINT p; + p.x = left; + p.y = top + height; + return p; + } + FXT_POINT BottomRight() const { + FXT_POINT p; + p.x = left + width; + p.y = top + height; + return p; + } + void TopLeft(FXT_POINT tl) { + left = tl.x; + top = tl.y; + } + void TopRight(FXT_POINT tr) { + width = tr.x - left; + top = tr.y; + } + void BottomLeft(FXT_POINT bl) { + left = bl.x; + height = bl.y - top; + } + void BottomRight(FXT_POINT br) { + width = br.x - left; + height = br.y - top; + } + FXT_POINT Center() const { + FXT_POINT p; + p.x = left + width / 2; + p.y = top + height / 2; + return p; + } + void Union(baseType x, baseType y) { + baseType r = right(), b = bottom(); + if (left > x) { + left = x; + } + if (r < x) { + r = x; + } + if (top > y) { + top = y; + } + if (b < y) { + b = y; + } + width = r - left; + height = b - top; + } + void Union(const FXT_POINT& p) { Union(p.x, p.y); } + void Union(const FXT_RECT& rt) { + baseType r = right(), b = bottom(); + if (left > rt.left) { + left = rt.left; + } + if (r < rt.right()) { + r = rt.right(); + } + if (top > rt.top) { + top = rt.top; + } + if (b < rt.bottom()) { + b = rt.bottom(); + } + width = r - left; + height = b - top; + } + void Intersect(const FXT_RECT& rt) { + baseType r = right(), b = bottom(); + if (left < rt.left) { + left = rt.left; + } + if (r > rt.right()) { + r = rt.right(); + } + if (top < rt.top) { + top = rt.top; + } + if (b > rt.bottom()) { + b = rt.bottom(); + } + width = r - left; + height = b - top; + } + FX_BOOL IntersectWith(const FXT_RECT& rt) const { + FXT_RECT rect = rt; + rect.Intersect(*this); + return !rect.IsEmpty(); + } + FX_BOOL IntersectWith(const FXT_RECT& rt, FX_FLOAT fEpsilon) const { + FXT_RECT rect = rt; + rect.Intersect(*this); + return !rect.IsEmpty(fEpsilon); + } + friend bool operator==(const FXT_RECT& rc1, const FXT_RECT& rc2) { + return rc1.left == rc2.left && rc1.top == rc2.top && + rc1.width == rc2.width && rc1.height == rc2.height; + } + friend bool operator!=(const FXT_RECT& rc1, const FXT_RECT& rc2) { + return !(rc1 == rc2); + } + baseType left, top; + baseType width, height; +}; +typedef CFX_RTemplate CFX_Rect; +typedef CFX_RTemplate CFX_RectF; +typedef CFX_ArrayTemplate CFX_RectFArray; + +class CFX_Matrix { + public: + CFX_Matrix() { SetIdentity(); } + + CFX_Matrix(FX_FLOAT a1, + FX_FLOAT b1, + FX_FLOAT c1, + FX_FLOAT d1, + FX_FLOAT e1, + FX_FLOAT f1) { + a = a1; + b = b1; + c = c1; + d = d1; + e = e1; + f = f1; + } + + void Set(FX_FLOAT a, + FX_FLOAT b, + FX_FLOAT c, + FX_FLOAT d, + FX_FLOAT e, + FX_FLOAT f); + void Set(const FX_FLOAT n[6]); + + void SetIdentity() { + a = d = 1; + b = c = e = f = 0; + } + + void SetReverse(const CFX_Matrix& m); + + void Concat(FX_FLOAT a, + FX_FLOAT b, + FX_FLOAT c, + FX_FLOAT d, + FX_FLOAT e, + FX_FLOAT f, + FX_BOOL bPrepended = FALSE); + void Concat(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE); + void ConcatInverse(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE); + + void Copy(const CFX_Matrix& m) { *this = m; } + + FX_BOOL IsIdentity() const { + return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0; + } + FX_BOOL IsInvertible() const; + + FX_BOOL Is90Rotated() const; + + FX_BOOL IsScaled() const; + + void Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE); + + void TranslateI(int32_t x, int32_t y, FX_BOOL bPrepended = FALSE) { + Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended); + } + + void Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended = FALSE); + + void Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended = FALSE); + + void RotateAt(FX_FLOAT fRadian, + FX_FLOAT x, + FX_FLOAT y, + FX_BOOL bPrepended = FALSE); + + void Shear(FX_FLOAT fAlphaRadian, + FX_FLOAT fBetaRadian, + FX_BOOL bPrepended = FALSE); + + void MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src); + + FX_FLOAT GetXUnit() const; + + FX_FLOAT GetYUnit() const; + void GetUnitRect(CFX_RectF& rect) const; + + CFX_FloatRect GetUnitRect() const; + + FX_FLOAT GetUnitArea() const; + FX_FLOAT TransformXDistance(FX_FLOAT dx) const; + int32_t TransformXDistance(int32_t dx) const; + FX_FLOAT TransformYDistance(FX_FLOAT dy) const; + int32_t TransformYDistance(int32_t dy) const; + FX_FLOAT TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const; + int32_t TransformDistance(int32_t dx, int32_t dy) const; + FX_FLOAT TransformDistance(FX_FLOAT distance) const; + + void TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const; + void TransformPoint(int32_t& x, int32_t& y) const; + + void Transform(FX_FLOAT& x, FX_FLOAT& y) const { TransformPoint(x, y); } + void Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const { + x1 = x, y1 = y; + TransformPoint(x1, y1); + } + + void TransformVector(CFX_VectorF& v) const; + void TransformVector(CFX_Vector& v) const; + void TransformRect(CFX_RectF& rect) const; + void TransformRect(CFX_Rect& rect) const; + + void TransformRect(FX_FLOAT& left, + FX_FLOAT& right, + FX_FLOAT& top, + FX_FLOAT& bottom) const; + void TransformRect(CFX_FloatRect& rect) const { + TransformRect(rect.left, rect.right, rect.top, rect.bottom); + } + + FX_FLOAT GetA() const { return a; } + FX_FLOAT GetB() const { return b; } + FX_FLOAT GetC() const { return c; } + FX_FLOAT GetD() const { return d; } + FX_FLOAT GetE() const { return e; } + FX_FLOAT GetF() const { return f; } + + public: + FX_FLOAT a; + FX_FLOAT b; + FX_FLOAT c; + FX_FLOAT d; + FX_FLOAT e; + FX_FLOAT f; +}; + +#endif // CORE_FXCRT_INCLUDE_FX_COORDINATES_H_ -- cgit v1.2.3