From 5e50e48893a9520e2f9a92916e447f242bae6e24 Mon Sep 17 00:00:00 2001 From: yixy-only Date: Thu, 27 Jun 2024 18:42:26 +0800 Subject: [PATCH] =?UTF-8?q?adjust:=20type.h=20=E9=87=8D=E5=91=BD=E5=90=8D?= =?UTF-8?q?=E4=B8=BA=20types.h=EF=BC=8C=E5=B9=B6=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=B8=B8=E8=A7=81=E6=93=8D=E4=BD=9C=E7=9A=84?= =?UTF-8?q?=20Rect=20=E7=BB=93=E6=9E=84=E4=BD=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/color.h | 2 +- src/ege_common.h | 2 +- src/type.h | 86 --------- src/types.cpp | 161 ++++++++++++++++ src/types.h | 484 +++++++++++++++++++++++++++++++++++++++++++++++ src/window.h | 2 +- 6 files changed, 648 insertions(+), 89 deletions(-) delete mode 100644 src/type.h create mode 100644 src/types.cpp create mode 100644 src/types.h diff --git a/src/color.h b/src/color.h index b37c80b0..49e6fd9f 100644 --- a/src/color.h +++ b/src/color.h @@ -3,7 +3,7 @@ #include #include "ege_def.h" #include "ege_math.h" -#include "type.h" +#include "types.h" // 交换颜色中 R 通道和 B 通道: 0xAARRGGBB -> 0xAABBGGRR #define RGBTOBGR(color) ((color_t)((((color) & 0xFF) << 16) | (((color) & 0xFF0000) >> 16) | ((color) & 0xFF00FF00))) diff --git a/src/ege_common.h b/src/ege_common.h index c28f713b..bcb5fc18 100644 --- a/src/ege_common.h +++ b/src/ege_common.h @@ -14,7 +14,7 @@ #include "ege_graph.h" #include "ege_dllimport.h" -#include "type.h" +#include "types.h" #include "utils.h" #include "color.h" #include "encodeconv.h" diff --git a/src/type.h b/src/type.h deleted file mode 100644 index 1f0c88b3..00000000 --- a/src/type.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -// MSVC 从 10.0(VS2010)开始有 stdint.h -// GCC 从 4.5 开始有 stdint.h -#if _MSC_VER >= 1600 || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) -#include -#elif !defined(_MSC_VER) || _MSC_VER > 1300 -#include "stdint.h" -#endif - -#include - -#if !defined(EGE_W64) -#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -#define EGE_W64 __w64 -#else -#define EGE_W64 -#endif -#endif - -#ifndef __int3264 -#if defined(_WIN64) -typedef __int64 LONG_PTR, *PLONG_PTR; -typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; - -#define __int3264 __int64 - -#else -typedef EGE_W64 long LONG_PTR, *PLONG_PTR; -typedef EGE_W64 unsigned long ULONG_PTR, *PULONG_PTR; - -#define __int3264 __int32 - -#endif -#endif - -typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; - -typedef unsigned int uint32; - -#if !defined(_MSC_VER) || _MSC_VER > 1200 -typedef intptr_t POINTER_SIZE; -#else -typedef long POINTER_SIZE; -#endif - -namespace ege -{ - -typedef unsigned char byte; - -struct Point -{ - int x; - int y; - -public: - Point() : x(0), y(0) {} - Point(int x, int y) : x(x), y(y) {} -}; - - -struct Size -{ - int width; - int height; - -public: - Size() : width(0), height(0) {} - Size(int width, int height) : width(width), height(height) {} -}; - -struct Rect -{ - int x; - int y; - int width; - int height; - -public: - Rect() : x(0), y(0), width(0), height(0) {} - Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {} - Rect(Point point, Size size) : x(point.x), y(point.y), width(size.width), height(size.height) {} -}; - -} diff --git a/src/types.cpp b/src/types.cpp new file mode 100644 index 00000000..d32dd704 --- /dev/null +++ b/src/types.cpp @@ -0,0 +1,161 @@ +#include "ege_head.h" +#include "ege_common.h" +#include "types.h" + +namespace ege +{ + +//------------------------------------------------------------------------------ +// Rect +//------------------------------------------------------------------------------ + +Rect normalize(const Rect& rect) +{ + return Rect(rect).normalize(); +} + +Rect intersect(const Rect& a, const Rect& b) +{ + return Rect(a).intersect(b); +} + +Rect& Rect::intersect(const Rect& rect) +{ + if (isNull() || rect.isNull()) + return setEmpty(); + + Rect a(*this), b(rect); + a.normalize(); + b.normalize(); + + if ( (a.right() <= b.left()) || (b.right() <= a.left()) + || (a.bottom() <= b.top()) || (b.bottom() <= a.top() )) { + return setEmpty(); + } + + int left = MAX(a.left(), b.left()); + int top = MAX(a.top(), b.top()); + int right = MIN(a.right(), b.right()); + int bottom = MIN(a.bottom(), b.bottom()); + + setBounds(left, top, right, bottom); + + return *this; +} + +Rect& Rect::unite(const Rect& rect) +{ + if (rect.isNull()) + return *this;; + + if (isNull()) + return *this = rect; + + Rect a(*this), b(rect); + a.normalize(); + b.normalize(); + + int left = MIN(a.left(), b.left()); + int top = MIN(a.top(), b.top()); + int right = MAX(a.right(), b.right()); + int bottom = MAX(a.bottom(), b.bottom()); + + setBounds(left, top, right, bottom); + return *this; +} + +Rect& Rect::unite(int x, int y, int width, int height) +{ + unite(Rect(x, y, width, height)); + return *this; +} + +Rect& Rect::unite(const Point& point) +{ + if (isNull()) { + set(point, Size(1, 1)); + } else { + if (point.x < left()) { + setLeft(point.x); + } else if (point.x >= right()) { + setRight(point.x + 1); + } + + if (point.y < top()) { + setTop(point.y); + } else if (point.y >= bottom()) { + setBottom(point.y + 1); + } + } + + return *this; +} + +Rect& Rect::unite(const Point points[], int count) +{ + unite(bounds(points, count)); + return *this; +} + +Rect unite(const Rect& a, const Rect& b) +{ + return Rect(a).unite(b); +} + +Rect bounds(const Point points[], int count) +{ + if (count <= 0) + return Rect(); + + int xMin = points[0].x, xMax = xMin; + int yMin = points[0].y, yMax = yMin; + + for (int i = 1; i < count; i++) { + if (points[i].x < xMin) { + xMin = points[i].x; + } else if (points[i].x > xMax) { + xMax = points[i].x; + } + + if (points[i].y < yMin) { + yMin = points[i].y; + } else if (points[i].y > yMax) { + yMax = points[i].y; + } + } + + Point leftTop(xMin, yMin); + Point bottomRight(xMax + 1, yMax + 1); + + return Rect(leftTop, bottomRight, false); +} + +Rect bounds(const Point& a, const Point& b) +{ + int xMin, xMax; + if (a.x <= b.x) { + xMin = a.x; + xMax = b.x; + } else { + xMin = b.x; + xMax = a.x; + } + + int yMin, yMax; + if (a.y <= b.y) { + yMin = a.y; + yMax = b.y; + } else { + yMin = b.y; + yMax = a.y; + } + + Point leftTop(xMin, yMin); + Point bottomRight(xMax + 1, yMax + 1); + + return Rect(leftTop, bottomRight, false); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/types.h b/src/types.h new file mode 100644 index 00000000..6e5f8a39 --- /dev/null +++ b/src/types.h @@ -0,0 +1,484 @@ +#pragma once + +// MSVC 从 10.0(VS2010)开始有 stdint.h +// GCC 从 4.5 开始有 stdint.h +#if _MSC_VER >= 1600 || __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) +#include +#elif !defined(_MSC_VER) || _MSC_VER > 1300 +#include "stdint.h" +#endif + +#include + +#if !defined(EGE_W64) +#if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 +#define EGE_W64 __w64 +#else +#define EGE_W64 +#endif +#endif + +#ifndef __int3264 +#if defined(_WIN64) +typedef __int64 LONG_PTR, *PLONG_PTR; +typedef unsigned __int64 ULONG_PTR, *PULONG_PTR; + +#define __int3264 __int64 + +#else +typedef EGE_W64 long LONG_PTR, *PLONG_PTR; +typedef EGE_W64 unsigned long ULONG_PTR, *PULONG_PTR; + +#define __int3264 __int32 + +#endif +#endif + +typedef ULONG_PTR DWORD_PTR, *PDWORD_PTR; + +typedef unsigned int uint32; + +#if !defined(_MSC_VER) || _MSC_VER > 1200 +typedef intptr_t POINTER_SIZE; +#else +typedef long POINTER_SIZE; +#endif + +namespace ege +{ + +#ifndef EGE_BYTE_TYPEDEF +#define EGE_BYTE_TYPEDEF +typedef unsigned char byte; +#endif + +//------------------------------------------------------------------------------ +// Point +//------------------------------------------------------------------------------ + +#ifndef EGE_Point_TYPEDEF +#define EGE_Point_TYPEDEF +struct Point +{ + int x; + int y; + +public: + Point() : x(0), y(0) {} + Point(int x, int y) : x(x), y(y) {} +}; +#endif + + +//------------------------------------------------------------------------------ +// Size +//------------------------------------------------------------------------------ + +#ifndef EGE_Size_TYPEDEF +#define EGE_Size_TYPEDEF +struct Size +{ + int width; + int height; + +public: + Size() : width(0), height(0) {} + Size(int width, int height) : width(width), height(height) {} + + Size& set(int width, int height); + + bool isNull() const { return (width == 0) && (height == 0); } + bool isEmpty() const { return (width <= 0) || (height <= 0); } + bool isValid() const { return (width > 0) && (height > 0); } + bool isNormalized() const { return (width >= 0) && (height >= 0); } + + Size& tranpose(); + Size& normalize(); +}; + +bool operator== (const Size& a, const Size& b); +bool operator!= (const Size& a, const Size& b); + +Size normalize(const Size& size); + +//------------------------------------------------------------------------------ + +inline Size& Size::set(int width, int height) +{ + this->width = width; + this->height = height; + return *this; +} + +inline bool operator== (const Size& a, const Size& b) +{ + return (a.width == b.width) && (a.height == b.height); +} + +inline bool operator!= (const Size& a, const Size& b) +{ + return !(a == b); +} + +inline Size& Size::tranpose() +{ + int temp = width; + width = height; + height = temp; + return *this; +} + +inline Size& Size::normalize() +{ + if (width < 0) { + width = -width; + } + + if (height < 0) { + height = -height; + } + + return *this; +} + +inline Size normalize(const Size& size) +{ + return Size(size).tranpose(); +} + +#endif + +//------------------------------------------------------------------------------ +// Rect +//------------------------------------------------------------------------------ +#ifndef EGE_Rect_TYPEDEF +#define EGE_Rect_TYPEDEF +struct Rect +{ + int x; + int y; + int width; + int height; + +public: + Rect(); + Rect(int x, int y, int width, int height); + Rect(const Point& topLeft, const Size& size); + Rect(const Point& topLeft, const Point& bottomRight, bool normalize = true); + + int left() const; + int top() const; + int right() const; + int bottom() const; + + Point topLeft() const; + Point bottomRight() const; + Point center() const; + Size size() const; + + Rect& setTopLeft(const Point& topLeft); + Rect& setTopLeft(int x, int y); + Rect& setBottomRight(const Point& bottomRight); + Rect& setBottomRight(int x, int y); + Rect& setLeftRight(int left, int right); + Rect& setTopBottom(int top, int bottom); + Rect& setSize(const Size& size); + Rect& setSize(int width, int height); + Rect& setLeft(int left); + Rect& setTop(int top); + Rect& setRight(int right); + Rect& setBottom(int bottom); + Rect& set(int x, int y, int width, int height); + Rect& set(const Point& topLeft, const Size& size); + Rect& setBounds(const Point& topLeft, const Point& bottomRight, bool normalize = true); + Rect& setBounds(int left, int top, int right, int bottom, bool normalize = true); + Rect& setEmpty(); + + Rect& normalize(); + Rect& transpose(); + Rect& offset (int dx, int dy); + Rect& offsetTo(int x, int y); + Rect& inset (int dx, int dy); + Rect& outset (int dx, int dy); + + Rect& intersect(const Rect& rect); + Rect& unite(const Rect& rect); + Rect& unite(int x, int y, int width, int height); + Rect& unite(const Point& point); + Rect& unite(const Point points[], int count); + + bool isNull() const; + bool isEmpty() const; + bool isValid() const; + bool isNormalized() const; + + bool contains (int x, int y) const; + bool contains (const Point& point) const; + bool contains (const Rect& rect) const; + bool isOverlap(const Rect& rect) const; +}; // Rect + +Rect normalize(const Rect& rect); + +Rect intersect(const Rect& a, const Rect& b); + +Rect unite(const Rect& a, const Rect& b); + +Rect bounds(const Point point[], int count); + +Rect bounds(const Point& a, const Point& b); + +//------------------------------------------------------------------------------ + +inline Rect::Rect(): x(0), y(0), width(0), height(0) {} + +inline Rect::Rect(int x, int y, int width, int height) : x(x), y(y), width(width), height(height) {} + +inline Rect::Rect(const Point& topLeft, const Size& size) + : x(topLeft.x), y(topLeft.y), width(size.width), height(size.height) +{ } + +inline Rect::Rect(const Point& topLeft, const Point& bottomRight, bool normalize) + : x(topLeft.x), y(topLeft.y), width(bottomRight.x - topLeft.x), height(bottomRight.y - topLeft.y) +{ + if (normalize) + this->normalize(); +} + +inline int Rect::left() const { return x; } +inline int Rect::top() const { return y; } +inline int Rect::right() const { return x + width; } +inline int Rect::bottom() const { return y + height; } + +inline Point Rect::topLeft() const { return Point(x, y); } +inline Point Rect::bottomRight() const { return Point(x + width, y + height); } +inline Size Rect::size() const { return Size(width, height); } +inline Point Rect::center() const { return Point(x + width / 2, y + height / 2);} + +inline Rect& Rect::setLeft(int left) +{ + int diff = left - this->left(); + width -= diff; + x = left; + + return *this; +} + +inline Rect& Rect::setTop(int top) +{ + int diff = top - this->top(); + height -= diff; + y = top; + return *this; +} + +inline Rect& Rect::setRight(int right) +{ + width = right - left(); + return *this; +} + +inline Rect& Rect::setBottom(int bottom) +{ + height = bottom - top(); + return *this; +} + +inline Rect& Rect::setSize(const Size& size) +{ + setSize(size.width, size.height); + return *this; +} + +inline Rect& Rect::setSize(int width, int height) +{ + this->width = width; + this->height = height; + return *this; +} + +inline Rect& Rect::setTopLeft(const Point& topLeft) +{ + setTopLeft(topLeft.x, topLeft.y); + return *this; +} + +inline Rect& Rect::setTopLeft(int x, int y) +{ + setBounds(Point(x, y), bottomRight(), false); + return *this; +} + +inline Rect& Rect::setBottomRight(const Point& bottomRight) +{ + return setBottomRight(bottomRight.x, bottomRight.y); +} + +inline Rect& Rect::setBottomRight(int x, int y) +{ + setRight(x); + setBottom(y); + return *this; +} + +inline Rect& Rect::setLeftRight(int left, int right) +{ + x = left; + width = right - left; + return *this; +} + +inline Rect& Rect::setTopBottom(int top, int bottom) +{ + y = top; + height = bottom - top; + return *this; +} + +inline Rect& Rect::set(int x, int y, int width, int height) +{ + this->x = x; + this->y = y; + this->width = width; + this->height = height; + + return *this; +} + +inline Rect& Rect::set(const Point& topLeft, const Size& size) +{ + setTopLeft(topLeft); + setSize(size); + return *this; +} + +inline Rect& Rect::setBounds(const Point& topLeft, const Point& bottomRight, bool normalize) +{ + x = topLeft.x; + y = topLeft.y; + width = bottomRight.x - topLeft.x; + height = bottomRight.y - topLeft.y; + + if (normalize) + this->normalize(); + + return *this; +} + +inline Rect& Rect::setBounds(int left, int top, int right, int bottom, bool normalize) +{ + x = left; + y = top; + setRight(right); + setBottom(bottom); + + if (normalize) + this->normalize(); + + return *this; +} + +inline Rect& Rect::setEmpty() +{ + x = y = width = height = 0; + return *this; +} + +inline Rect& Rect::normalize() +{ + if (width < 0) { + x += width + 1; + width = -width; + } + + if (height < 0) { + y += height + 1; + height = -height; + } + + return *this; +} + +inline Rect& Rect::transpose() +{ + int temp = width; + width = height; + height = temp; + return *this; +} + +inline Rect& Rect::offset(int dx, int dy) +{ + x += dx; + y += dy; + return *this; +} + +inline Rect& Rect::offsetTo(int x, int y) +{ + this->x = x; + this->y = y; + return *this; +} + +inline Rect& Rect::inset(int dx, int dy) +{ + x += dx; + y += dy; + width += 2 * dx; + height += 2 * dy; + return *this; +} + +inline Rect& Rect::outset(int dx, int dy) +{ + inset(-dx, -dy); + return *this; +} + +inline bool Rect::isNull() const { return (width == 0) && (height == 0); } +inline bool Rect::isEmpty() const { return (width <= 0) || (height <= 0); } +inline bool Rect::isValid() const { return (width > 0) && (height > 0); } +inline bool Rect::isNormalized() const { return (width >= 0) && (height >= 0); } + +inline bool Rect::contains(int x, int y) const +{ + return ((x >= left()) && (x < right()) && (y >= top() && y < bottom())); +} + +inline bool Rect::contains(const Point& point) const +{ + return contains(point.x, point.y); +} + +inline bool Rect::contains(const Rect& rect) const +{ + return ( left() <= rect.left()) && ( top() <= rect.top()) + && (right() >= rect.right()) && (bottom() >= rect.bottom()); +} + +inline bool Rect::isOverlap(const Rect& rect) const +{ + if (isEmpty() || rect.isEmpty()) + return false; + + if ((left() >= rect.right()) || (top() >= rect.bottom()) || (right() <= rect.left() || bottom() <= rect.top())) + return false; + + return true; +} + +inline bool operator== (const Rect& a, const Rect& b) +{ + return (a.x == b.x) && (a.y == b.y) && (a.width == b.width) && (a.height == b.height); +} + +inline bool operator!= (const Rect& a, const Rect& b) +{ + return !(a == b); +} +#endif +//------------------------------------------------------------------------------ + + +} diff --git a/src/window.h b/src/window.h index 9d4d095a..34f58f02 100644 --- a/src/window.h +++ b/src/window.h @@ -2,7 +2,7 @@ #include #include -#include "type.h" +#include "types.h" #include #include