1 // Copyright 2014 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com 6 7 #ifndef CORE_INCLUDE_FXCRT_FX_COORDINATES_H_ 8 #define CORE_INCLUDE_FXCRT_FX_COORDINATES_H_ 9 10 #include "fx_basic.h" 11 12 template <class baseType> 13 class CFX_PSVTemplate; 14 template <class baseType> 15 class CFX_VTemplate; 16 template <class baseType> 17 class CFX_PRLTemplate; 18 template <class baseType> 19 class CFX_RTemplate; 20 template <class baseType> 21 class CFX_ETemplate; 22 template <class baseType> 23 class CFX_ATemplate; 24 template <class baseType> 25 class CFX_RRTemplate; 26 class CFX_Matrix; 27 template <class baseType> 28 class CFX_PSVTemplate { 29 public: 30 typedef CFX_PSVTemplate<baseType> FXT_PSV; 31 typedef CFX_PSVTemplate<baseType> FXT_POINT; 32 typedef CFX_PSVTemplate<baseType> FXT_SIZE; Set(baseType x,baseType y)33 void Set(baseType x, baseType y) { FXT_PSV::x = x, FXT_PSV::y = y; } Set(const FXT_PSV & psv)34 void Set(const FXT_PSV& psv) { FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; } Add(baseType x,baseType y)35 void Add(baseType x, baseType y) { FXT_PSV::x += x, FXT_PSV::y += y; } Subtract(baseType x,baseType y)36 void Subtract(baseType x, baseType y) { FXT_PSV::x -= x, FXT_PSV::y -= y; } Reset()37 void Reset() { FXT_PSV::x = FXT_PSV::y = 0; } 38 FXT_PSV& operator+=(const FXT_PSV& obj) { 39 x += obj.x; 40 y += obj.y; 41 return *this; 42 } 43 FXT_PSV& operator-=(const FXT_PSV& obj) { 44 x -= obj.x; 45 y -= obj.y; 46 return *this; 47 } 48 FXT_PSV& operator*=(baseType lamda) { 49 x *= lamda; 50 y *= lamda; 51 return *this; 52 } 53 FXT_PSV& operator/=(baseType lamda) { 54 x /= lamda; 55 y /= lamda; 56 return *this; 57 } 58 friend FX_BOOL operator==(const FXT_PSV& obj1, const FXT_PSV& obj2) { 59 return obj1.x == obj2.x && obj1.y == obj2.y; 60 } 61 friend FX_BOOL operator!=(const FXT_PSV& obj1, const FXT_PSV& obj2) { 62 return obj1.x != obj2.x || obj1.y != obj2.y; 63 } 64 friend FXT_PSV operator+(const FXT_PSV& obj1, const FXT_PSV& obj2) { 65 CFX_PSVTemplate obj; 66 obj.x = obj1.x + obj2.x; 67 obj.y = obj1.y + obj2.y; 68 return obj; 69 } 70 friend FXT_PSV operator-(const FXT_PSV& obj1, const FXT_PSV& obj2) { 71 CFX_PSVTemplate obj; 72 obj.x = obj1.x - obj2.x; 73 obj.y = obj1.y - obj2.y; 74 return obj; 75 } 76 friend FXT_PSV operator*(const FXT_PSV& obj, baseType lamda) { 77 CFX_PSVTemplate t; 78 t.x = obj.x * lamda; 79 t.y = obj.y * lamda; 80 return t; 81 } 82 friend FXT_PSV operator*(baseType lamda, const FXT_PSV& obj) { 83 CFX_PSVTemplate t; 84 t.x = lamda * obj.x; 85 t.y = lamda * obj.y; 86 return t; 87 } 88 friend FXT_PSV operator/(const FXT_PSV& obj, baseType lamda) { 89 CFX_PSVTemplate t; 90 t.x = obj.x / lamda; 91 t.y = obj.y / lamda; 92 return t; 93 } 94 baseType x, y; 95 }; 96 typedef CFX_PSVTemplate<int32_t> CFX_Point; 97 typedef CFX_PSVTemplate<FX_FLOAT> CFX_PointF; 98 typedef CFX_PSVTemplate<int32_t> CFX_Size; 99 typedef CFX_PSVTemplate<FX_FLOAT> CFX_SizeF; 100 typedef CFX_ArrayTemplate<CFX_Point> CFX_Points; 101 typedef CFX_ArrayTemplate<CFX_PointF> CFX_PointsF; 102 typedef CFX_PSVTemplate<int32_t>* FX_LPPOINT; 103 typedef CFX_PSVTemplate<FX_FLOAT>* FX_LPPOINTF; 104 typedef CFX_PSVTemplate<int32_t> const* FX_LPCPOINT; 105 typedef CFX_PSVTemplate<FX_FLOAT> const* FX_LPCPOINTF; 106 #define CFX_FloatPoint CFX_PointF 107 template <class baseType> 108 class CFX_VTemplate : public CFX_PSVTemplate<baseType> { 109 public: 110 typedef CFX_PSVTemplate<baseType> FXT_PSV; 111 typedef CFX_PSVTemplate<baseType> FXT_POINT; 112 typedef CFX_PSVTemplate<baseType> FXT_SIZE; 113 typedef CFX_VTemplate<baseType> FXT_VECTOR; Set(baseType newx,baseType newy)114 void Set(baseType newx, baseType newy) { 115 FXT_PSV::x = newx; 116 FXT_PSV::y = newy; 117 } Set(const FXT_PSV & psv)118 void Set(const FXT_PSV& psv) { FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; } Set(const FXT_POINT & p1,const FXT_POINT & p2)119 void Set(const FXT_POINT& p1, const FXT_POINT& p2) { 120 FXT_PSV::x = p2.x - p1.x, FXT_PSV::y = p2.y - p1.y; 121 } Reset()122 void Reset() { FXT_PSV::x = FXT_PSV::y = 0; } SquareLength()123 baseType SquareLength() const { 124 return FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y; 125 } Length()126 baseType Length() const { 127 return FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y); 128 } Normalize()129 void Normalize() { 130 FX_FLOAT fLen = 131 FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y); 132 if (fLen < 0.0001f) { 133 return; 134 } 135 FXT_PSV::x = ((baseType)FXT_PSV::x) / fLen; 136 FXT_PSV::y = ((baseType)FXT_PSV::y) / fLen; 137 } DotProduct(baseType otherx,baseType othery)138 baseType DotProduct(baseType otherx, baseType othery) const { 139 return FXT_PSV::x * otherx + FXT_PSV::y * othery; 140 } DotProduct(const FXT_VECTOR & v)141 baseType DotProduct(const FXT_VECTOR& v) const { 142 return FXT_PSV::x * v.x + FXT_PSV::y * v.y; 143 } IsParallel(baseType otherx,baseType othery)144 FX_BOOL IsParallel(baseType otherx, baseType othery) const { 145 baseType t = FXT_PSV::x * othery - FXT_PSV::y * otherx; 146 return FXSYS_fabs(t) < 0x0001f; 147 } IsParallel(const FXT_VECTOR & v)148 FX_BOOL IsParallel(const FXT_VECTOR& v) const { return IsParallel(v.x, v.y); } IsPerpendicular(baseType otherx,baseType othery)149 FX_BOOL IsPerpendicular(baseType otherx, baseType othery) const { 150 baseType t = DotProduct(otherx, othery); 151 return FXSYS_fabs(t) < 0x0001f; 152 } IsPerpendicular(const FXT_VECTOR & v)153 FX_BOOL IsPerpendicular(const FXT_VECTOR& v) const { 154 return IsPerpendicular(v.x, v.y); 155 } Translate(baseType dx,baseType dy)156 void Translate(baseType dx, baseType dy) { 157 FXT_PSV::x += dx, FXT_PSV::y += dy; 158 } Scale(baseType sx,baseType sy)159 void Scale(baseType sx, baseType sy) { FXT_PSV::x *= sx, FXT_PSV::y *= sy; } Rotate(FX_FLOAT fRadian)160 void Rotate(FX_FLOAT fRadian) { 161 FX_FLOAT xx = (FX_FLOAT)FXT_PSV::x; 162 FX_FLOAT yy = (FX_FLOAT)FXT_PSV::y; 163 FX_FLOAT cosValue = FXSYS_cos(fRadian); 164 FX_FLOAT sinValue = FXSYS_sin(fRadian); 165 FXT_PSV::x = xx * cosValue - yy * sinValue; 166 FXT_PSV::y = xx * sinValue + yy * cosValue; 167 } Cosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)168 friend FX_FLOAT Cosine(const FXT_VECTOR& v1, const FXT_VECTOR& v2) { 169 FXSYS_assert(v1.SquareLength() != 0 && v2.SquareLength() != 0); 170 FX_FLOAT dotProduct = v1.DotProduct(v2); 171 return dotProduct / 172 (FX_FLOAT)FXSYS_sqrt(v1.SquareLength() * v2.SquareLength()); 173 } ArcCosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)174 friend FX_FLOAT ArcCosine(const FXT_VECTOR& v1, const FXT_VECTOR& v2) { 175 return (FX_FLOAT)FXSYS_acos(Cosine(v1, v2)); 176 } SlopeAngle(const FXT_VECTOR & v)177 friend FX_FLOAT SlopeAngle(const FXT_VECTOR& v) { 178 CFX_VTemplate vx; 179 vx.Set(1, 0); 180 FX_FLOAT fSlope = ArcCosine(v, vx); 181 return v.y < 0 ? -fSlope : fSlope; 182 } 183 }; 184 typedef CFX_VTemplate<int32_t> CFX_Vector; 185 typedef CFX_VTemplate<FX_FLOAT> CFX_VectorF; 186 template <class baseType> 187 class CFX_RTemplate { 188 public: 189 typedef CFX_PSVTemplate<baseType> FXT_POINT; 190 typedef CFX_PSVTemplate<baseType> FXT_SIZE; 191 typedef CFX_VTemplate<baseType> FXT_VECTOR; 192 typedef CFX_PRLTemplate<baseType> FXT_PARAL; 193 typedef CFX_RTemplate<baseType> FXT_RECT; Set(baseType left,baseType top,baseType width,baseType height)194 void Set(baseType left, baseType top, baseType width, baseType height) { 195 FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::width = width, 196 FXT_RECT::height = height; 197 } Set(baseType left,baseType top,const FXT_SIZE & size)198 void Set(baseType left, baseType top, const FXT_SIZE& size) { 199 FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::Size(size); 200 } Set(const FXT_POINT & p,baseType width,baseType height)201 void Set(const FXT_POINT& p, baseType width, baseType height) { 202 TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height; 203 } Set(const FXT_POINT & p1,const FXT_POINT & p2)204 void Set(const FXT_POINT& p1, const FXT_POINT& p2) { 205 TopLeft(p1), FXT_RECT::width = p2.x - p1.x, FXT_RECT::height = p2.y - p1.y, 206 FXT_RECT::Normalize(); 207 } Set(const FXT_POINT & p,const FXT_VECTOR & v)208 void Set(const FXT_POINT& p, const FXT_VECTOR& v) { 209 TopLeft(p), FXT_RECT::width = v.x, FXT_RECT::height = v.y, 210 FXT_RECT::Normalize(); 211 } Reset()212 void Reset() { 213 FXT_RECT::left = FXT_RECT::top = FXT_RECT::width = FXT_RECT::height = 0; 214 } 215 FXT_RECT& operator+=(const FXT_POINT& p) { 216 left += p.x, top += p.y; 217 return *this; 218 } 219 FXT_RECT& operator-=(const FXT_POINT& p) { 220 left -= p.x, top -= p.y; 221 return *this; 222 } right()223 baseType right() const { return left + width; } bottom()224 baseType bottom() const { return top + height; } Normalize()225 void Normalize() { 226 if (width < 0) { 227 left += width; 228 width = -width; 229 } 230 if (height < 0) { 231 top += height; 232 height = -height; 233 } 234 } Offset(baseType dx,baseType dy)235 void Offset(baseType dx, baseType dy) { 236 left += dx; 237 top += dy; 238 } Inflate(baseType x,baseType y)239 void Inflate(baseType x, baseType y) { 240 left -= x; 241 width += x * 2; 242 top -= y; 243 height += y * 2; 244 } Inflate(const FXT_POINT & p)245 void Inflate(const FXT_POINT& p) { Inflate(p.x, p.y); } Inflate(baseType left,baseType top,baseType right,baseType bottom)246 void Inflate(baseType left, baseType top, baseType right, baseType bottom) { 247 FXT_RECT::left -= left; 248 FXT_RECT::top -= top; 249 FXT_RECT::width += left + right; 250 FXT_RECT::height += top + bottom; 251 } Inflate(const FXT_RECT & rt)252 void Inflate(const FXT_RECT& rt) { 253 Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height); 254 } Deflate(baseType x,baseType y)255 void Deflate(baseType x, baseType y) { 256 left += x; 257 width -= x * 2; 258 top += y; 259 height -= y * 2; 260 } Deflate(const FXT_POINT & p)261 void Deflate(const FXT_POINT& p) { Deflate(p.x, p.y); } Deflate(baseType left,baseType top,baseType right,baseType bottom)262 void Deflate(baseType left, baseType top, baseType right, baseType bottom) { 263 FXT_RECT::left += left; 264 FXT_RECT::top += top; 265 FXT_RECT::width -= left + right; 266 FXT_RECT::height -= top + bottom; 267 } Deflate(const FXT_RECT & rt)268 void Deflate(const FXT_RECT& rt) { 269 Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height); 270 } IsEmpty()271 FX_BOOL IsEmpty() const { return width <= 0 || height <= 0; } IsEmpty(FX_FLOAT fEpsilon)272 FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const { 273 return width <= fEpsilon || height <= fEpsilon; 274 } Empty()275 void Empty() { width = height = 0; } Contains(baseType x,baseType y)276 FX_BOOL Contains(baseType x, baseType y) const { 277 return x >= left && x < left + width && y >= top && y < top + height; 278 } Contains(const FXT_POINT & p)279 FX_BOOL Contains(const FXT_POINT& p) const { return Contains(p.x, p.y); } Contains(const FXT_RECT & rt)280 FX_BOOL Contains(const FXT_RECT& rt) const { 281 return rt.left >= left && rt.right() <= right() && rt.top >= top && 282 rt.bottom() <= bottom(); 283 } Width()284 baseType Width() const { return width; } Height()285 baseType Height() const { return height; } Size()286 FXT_SIZE Size() const { 287 FXT_SIZE size; 288 size.Set(width, height); 289 return size; 290 } Size(FXT_SIZE s)291 void Size(FXT_SIZE s) { width = s.x, height = s.y; } TopLeft()292 FXT_POINT TopLeft() const { 293 FXT_POINT p; 294 p.x = left; 295 p.y = top; 296 return p; 297 } TopRight()298 FXT_POINT TopRight() const { 299 FXT_POINT p; 300 p.x = left + width; 301 p.y = top; 302 return p; 303 } BottomLeft()304 FXT_POINT BottomLeft() const { 305 FXT_POINT p; 306 p.x = left; 307 p.y = top + height; 308 return p; 309 } BottomRight()310 FXT_POINT BottomRight() const { 311 FXT_POINT p; 312 p.x = left + width; 313 p.y = top + height; 314 return p; 315 } TopLeft(FXT_POINT tl)316 void TopLeft(FXT_POINT tl) { 317 left = tl.x; 318 top = tl.y; 319 } TopRight(FXT_POINT tr)320 void TopRight(FXT_POINT tr) { 321 width = tr.x - left; 322 top = tr.y; 323 } BottomLeft(FXT_POINT bl)324 void BottomLeft(FXT_POINT bl) { 325 left = bl.x; 326 height = bl.y - top; 327 } BottomRight(FXT_POINT br)328 void BottomRight(FXT_POINT br) { 329 width = br.x - left; 330 height = br.y - top; 331 } Center()332 FXT_POINT Center() const { 333 FXT_POINT p; 334 p.x = left + width / 2; 335 p.y = top + height / 2; 336 return p; 337 } GetParallelogram(FXT_PARAL & pg)338 void GetParallelogram(FXT_PARAL& pg) const { 339 pg.x = left, pg.y = top; 340 pg.x1 = width, pg.y1 = 0; 341 pg.x2 = 0, pg.y2 = height; 342 } Union(baseType x,baseType y)343 void Union(baseType x, baseType y) { 344 baseType r = right(), b = bottom(); 345 if (left > x) { 346 left = x; 347 } 348 if (r < x) { 349 r = x; 350 } 351 if (top > y) { 352 top = y; 353 } 354 if (b < y) { 355 b = y; 356 } 357 width = r - left; 358 height = b - top; 359 } Union(const FXT_POINT & p)360 void Union(const FXT_POINT& p) { Union(p.x, p.y); } Union(const FXT_RECT & rt)361 void Union(const FXT_RECT& rt) { 362 baseType r = right(), b = bottom(); 363 if (left > rt.left) { 364 left = rt.left; 365 } 366 if (r < rt.right()) { 367 r = rt.right(); 368 } 369 if (top > rt.top) { 370 top = rt.top; 371 } 372 if (b < rt.bottom()) { 373 b = rt.bottom(); 374 } 375 width = r - left; 376 height = b - top; 377 } Intersect(const FXT_RECT & rt)378 void Intersect(const FXT_RECT& rt) { 379 baseType r = right(), b = bottom(); 380 if (left < rt.left) { 381 left = rt.left; 382 } 383 if (r > rt.right()) { 384 r = rt.right(); 385 } 386 if (top < rt.top) { 387 top = rt.top; 388 } 389 if (b > rt.bottom()) { 390 b = rt.bottom(); 391 } 392 width = r - left; 393 height = b - top; 394 } IntersectWith(const FXT_RECT & rt)395 FX_BOOL IntersectWith(const FXT_RECT& rt) const { 396 FXT_RECT rect = rt; 397 rect.Intersect(*this); 398 return !rect.IsEmpty(); 399 } IntersectWith(const FXT_RECT & rt,FX_FLOAT fEpsilon)400 FX_BOOL IntersectWith(const FXT_RECT& rt, FX_FLOAT fEpsilon) const { 401 FXT_RECT rect = rt; 402 rect.Intersect(*this); 403 return !rect.IsEmpty(fEpsilon); 404 } 405 friend FX_BOOL operator==(const FXT_RECT& rc1, const FXT_RECT& rc2) { 406 return rc1.left == rc2.left && rc1.top == rc2.top && 407 rc1.width == rc2.width && rc1.height == rc2.height; 408 } 409 friend FX_BOOL operator!=(const FXT_RECT& rc1, const FXT_RECT& rc2) { 410 return rc1.left != rc2.left || rc1.top != rc2.top || 411 rc1.width != rc2.width || rc1.height != rc2.height; 412 } 413 baseType left, top; 414 baseType width, height; 415 }; 416 typedef CFX_RTemplate<int32_t> CFX_Rect; 417 typedef CFX_RTemplate<FX_FLOAT> CFX_RectF; 418 typedef CFX_RTemplate<int32_t>* FX_LPRECT; 419 typedef CFX_RTemplate<FX_FLOAT>* FX_LPRECTF; 420 typedef CFX_RTemplate<int32_t> const* FX_LPCRECT; 421 typedef CFX_RTemplate<FX_FLOAT> const* FX_LPCRECTF; 422 typedef CFX_ArrayTemplate<CFX_RectF> CFX_RectFArray; 423 struct FX_RECT { 424 int left; 425 426 int top; 427 428 int right; 429 430 int bottom; 431 FX_RECTFX_RECT432 FX_RECT() : left(0), top(0), right(0), bottom(0) {} 433 FX_RECTFX_RECT434 FX_RECT(int left1, int top1, int right1, int bottom1) { 435 left = left1; 436 top = top1; 437 right = right1; 438 bottom = bottom1; 439 } 440 WidthFX_RECT441 int Width() const { return right - left; } 442 HeightFX_RECT443 int Height() const { return bottom - top; } 444 IsEmptyFX_RECT445 FX_BOOL IsEmpty() const { return right <= left || bottom <= top; } 446 447 void Normalize(); 448 449 void Intersect(const FX_RECT& src); 450 IntersectFX_RECT451 void Intersect(int left1, int top1, int right1, int bottom1) { 452 Intersect(FX_RECT(left1, top1, right1, bottom1)); 453 } 454 455 void Union(const FX_RECT& other_rect); 456 457 FX_BOOL operator==(const FX_RECT& src) const { 458 return left == src.left && right == src.right && top == src.top && 459 bottom == src.bottom; 460 } 461 OffsetFX_RECT462 void Offset(int dx, int dy) { 463 left += dx; 464 right += dx; 465 top += dy; 466 bottom += dy; 467 } 468 ContainsFX_RECT469 FX_BOOL Contains(const FX_RECT& other_rect) const { 470 return other_rect.left >= left && other_rect.right <= right && 471 other_rect.top >= top && other_rect.bottom <= bottom; 472 } 473 ContainsFX_RECT474 FX_BOOL Contains(int x, int y) const { 475 return x >= left && x < right && y >= top && y < bottom; 476 } 477 }; 478 struct FX_SMALL_RECT { 479 int16_t Left; 480 481 int16_t Top; 482 483 int16_t Right; 484 485 int16_t Bottom; 486 }; 487 class CFX_FloatRect { 488 public: CFX_FloatRect()489 CFX_FloatRect() { left = right = bottom = top = 0; } 490 CFX_FloatRect(FX_FLOAT left1,FX_FLOAT bottom1,FX_FLOAT right1,FX_FLOAT top1)491 CFX_FloatRect(FX_FLOAT left1, 492 FX_FLOAT bottom1, 493 FX_FLOAT right1, 494 FX_FLOAT top1) { 495 left = left1; 496 bottom = bottom1; 497 right = right1; 498 top = top1; 499 } 500 CFX_FloatRect(const FX_FLOAT * pArray)501 CFX_FloatRect(const FX_FLOAT* pArray) { 502 left = pArray[0]; 503 bottom = pArray[1]; 504 right = pArray[2]; 505 top = pArray[3]; 506 } 507 508 CFX_FloatRect(const FX_RECT& rect); 509 IsEmpty()510 FX_BOOL IsEmpty() const { return left >= right || bottom >= top; } 511 512 void Normalize(); 513 Reset()514 void Reset() { left = right = bottom = top = 0; } 515 516 FX_BOOL Contains(const CFX_FloatRect& other_rect) const; 517 518 FX_BOOL Contains(FX_FLOAT x, FX_FLOAT y) const; 519 520 void Transform(const CFX_Matrix* pMatrix); 521 522 void Intersect(const CFX_FloatRect& other_rect); 523 524 void Union(const CFX_FloatRect& other_rect); 525 526 FX_RECT GetInnerRect() const; 527 528 FX_RECT GetOutterRect() const; 529 530 FX_RECT GetClosestRect() const; 531 532 int Substract4(CFX_FloatRect& substract_rect, CFX_FloatRect* pRects); 533 InitRect(FX_FLOAT x,FX_FLOAT y)534 void InitRect(FX_FLOAT x, FX_FLOAT y) { 535 left = right = x; 536 bottom = top = y; 537 } 538 539 void UpdateRect(FX_FLOAT x, FX_FLOAT y); 540 Width()541 FX_FLOAT Width() const { return right - left; } 542 Height()543 FX_FLOAT Height() const { return top - bottom; } 544 Inflate(FX_FLOAT x,FX_FLOAT y)545 void Inflate(FX_FLOAT x, FX_FLOAT y) { 546 Normalize(); 547 left -= x; 548 right += x; 549 bottom -= y; 550 top += y; 551 } 552 Inflate(FX_FLOAT other_left,FX_FLOAT other_bottom,FX_FLOAT other_right,FX_FLOAT other_top)553 void Inflate(FX_FLOAT other_left, 554 FX_FLOAT other_bottom, 555 FX_FLOAT other_right, 556 FX_FLOAT other_top) { 557 Normalize(); 558 left -= other_left; 559 bottom -= other_bottom; 560 right += other_right; 561 top += other_top; 562 } 563 Inflate(const CFX_FloatRect & rt)564 void Inflate(const CFX_FloatRect& rt) { 565 Inflate(rt.left, rt.bottom, rt.right, rt.top); 566 } 567 Deflate(FX_FLOAT x,FX_FLOAT y)568 void Deflate(FX_FLOAT x, FX_FLOAT y) { 569 Normalize(); 570 left += x; 571 right -= x; 572 bottom += y; 573 top -= y; 574 } 575 Deflate(FX_FLOAT other_left,FX_FLOAT other_bottom,FX_FLOAT other_right,FX_FLOAT other_top)576 void Deflate(FX_FLOAT other_left, 577 FX_FLOAT other_bottom, 578 FX_FLOAT other_right, 579 FX_FLOAT other_top) { 580 Normalize(); 581 left += other_left; 582 bottom += other_bottom; 583 right -= other_right; 584 top -= other_top; 585 } 586 Deflate(const CFX_FloatRect & rt)587 void Deflate(const CFX_FloatRect& rt) { 588 Deflate(rt.left, rt.bottom, rt.right, rt.top); 589 } 590 Translate(FX_FLOAT e,FX_FLOAT f)591 void Translate(FX_FLOAT e, FX_FLOAT f) { 592 left += e; 593 right += e; 594 top += f; 595 bottom += f; 596 } 597 598 static CFX_FloatRect GetBBox(const CFX_FloatPoint* pPoints, int nPoints); 599 600 FX_FLOAT left; 601 602 FX_FLOAT right; 603 604 FX_FLOAT bottom; 605 606 FX_FLOAT top; 607 }; 608 class CFX_Matrix { 609 public: CFX_Matrix()610 CFX_Matrix() { SetIdentity(); } 611 CFX_Matrix(FX_FLOAT a1,FX_FLOAT b1,FX_FLOAT c1,FX_FLOAT d1,FX_FLOAT e1,FX_FLOAT f1)612 CFX_Matrix(FX_FLOAT a1, 613 FX_FLOAT b1, 614 FX_FLOAT c1, 615 FX_FLOAT d1, 616 FX_FLOAT e1, 617 FX_FLOAT f1) { 618 a = a1; 619 b = b1; 620 c = c1; 621 d = d1; 622 e = e1; 623 f = f1; 624 } 625 626 void Set(FX_FLOAT a, 627 FX_FLOAT b, 628 FX_FLOAT c, 629 FX_FLOAT d, 630 FX_FLOAT e, 631 FX_FLOAT f); 632 void Set(const FX_FLOAT n[6]); 633 SetIdentity()634 void SetIdentity() { 635 a = d = 1; 636 b = c = e = f = 0; 637 } 638 639 void SetReverse(const CFX_Matrix& m); 640 641 void Concat(FX_FLOAT a, 642 FX_FLOAT b, 643 FX_FLOAT c, 644 FX_FLOAT d, 645 FX_FLOAT e, 646 FX_FLOAT f, 647 FX_BOOL bPrepended = FALSE); 648 void Concat(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE); 649 void ConcatInverse(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE); 650 Copy(const CFX_Matrix & m)651 void Copy(const CFX_Matrix& m) { *this = m; } 652 IsIdentity()653 FX_BOOL IsIdentity() const { 654 return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0; 655 } 656 FX_BOOL IsInvertible() const; 657 658 FX_BOOL Is90Rotated() const; 659 660 FX_BOOL IsScaled() const; 661 662 void Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE); 663 664 void TranslateI(int32_t x, int32_t y, FX_BOOL bPrepended = FALSE) { 665 Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended); 666 } 667 668 void Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended = FALSE); 669 670 void Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended = FALSE); 671 672 void RotateAt(FX_FLOAT fRadian, 673 FX_FLOAT x, 674 FX_FLOAT y, 675 FX_BOOL bPrepended = FALSE); 676 677 void Shear(FX_FLOAT fAlphaRadian, 678 FX_FLOAT fBetaRadian, 679 FX_BOOL bPrepended = FALSE); 680 681 void MatchRect(const CFX_FloatRect& dest, const CFX_FloatRect& src); 682 683 FX_FLOAT GetXUnit() const; 684 685 FX_FLOAT GetYUnit() const; 686 void GetUnitRect(CFX_RectF& rect) const; 687 688 CFX_FloatRect GetUnitRect() const; 689 690 FX_FLOAT GetUnitArea() const; 691 FX_FLOAT TransformXDistance(FX_FLOAT dx) const; 692 int32_t TransformXDistance(int32_t dx) const; 693 FX_FLOAT TransformYDistance(FX_FLOAT dy) const; 694 int32_t TransformYDistance(int32_t dy) const; 695 FX_FLOAT TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const; 696 int32_t TransformDistance(int32_t dx, int32_t dy) const; 697 698 FX_FLOAT TransformDistance(FX_FLOAT distance) const; 699 void TransformPoint(FX_FLOAT& x, FX_FLOAT& y) const; 700 void TransformPoint(int32_t& x, int32_t& y) const; 701 void TransformPoints(CFX_PointF* points, int32_t iCount) const; 702 void TransformPoints(CFX_Point* points, int32_t iCount) const; 703 Transform(FX_FLOAT & x,FX_FLOAT & y)704 void Transform(FX_FLOAT& x, FX_FLOAT& y) const { TransformPoint(x, y); } 705 Transform(FX_FLOAT x,FX_FLOAT y,FX_FLOAT & x1,FX_FLOAT & y1)706 void Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const { 707 x1 = x, y1 = y; 708 TransformPoint(x1, y1); 709 } 710 void TransformVector(CFX_VectorF& v) const; 711 void TransformVector(CFX_Vector& v) const; 712 void TransformRect(CFX_RectF& rect) const; 713 void TransformRect(CFX_Rect& rect) const; 714 715 void TransformRect(FX_FLOAT& left, 716 FX_FLOAT& right, 717 FX_FLOAT& top, 718 FX_FLOAT& bottom) const; 719 TransformRect(CFX_FloatRect & rect)720 void TransformRect(CFX_FloatRect& rect) const { 721 TransformRect(rect.left, rect.right, rect.top, rect.bottom); 722 } 723 GetA()724 FX_FLOAT GetA() const { return a; } 725 GetB()726 FX_FLOAT GetB() const { return b; } 727 GetC()728 FX_FLOAT GetC() const { return c; } 729 GetD()730 FX_FLOAT GetD() const { return d; } 731 GetE()732 FX_FLOAT GetE() const { return e; } 733 GetF()734 FX_FLOAT GetF() const { return f; } 735 736 public: 737 FX_FLOAT a; 738 FX_FLOAT b; 739 FX_FLOAT c; 740 FX_FLOAT d; 741 FX_FLOAT e; 742 FX_FLOAT f; 743 }; 744 745 #endif // CORE_INCLUDE_FXCRT_FX_COORDINATES_H_ 746