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> class CFX_PSVTemplate; 13 template<class baseType> class CFX_VTemplate; 14 template<class baseType> class CFX_PRLTemplate; 15 template<class baseType> class CFX_RTemplate; 16 template<class baseType> class CFX_ETemplate; 17 template<class baseType> class CFX_ATemplate; 18 template<class baseType> class CFX_RRTemplate; 19 class CFX_Matrix; 20 template<class baseType> 21 class CFX_PSVTemplate 22 { 23 public: 24 typedef CFX_PSVTemplate<baseType> FXT_PSV; 25 typedef CFX_PSVTemplate<baseType> FXT_POINT; 26 typedef CFX_PSVTemplate<baseType> FXT_SIZE; Set(baseType x,baseType y)27 void Set(baseType x, baseType y) 28 { 29 FXT_PSV::x = x, FXT_PSV::y = y; 30 } Set(const FXT_PSV & psv)31 void Set(const FXT_PSV &psv) 32 { 33 FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; 34 } Add(baseType x,baseType y)35 void Add(baseType x, baseType y) 36 { 37 FXT_PSV::x += x, FXT_PSV::y += y; 38 } Subtract(baseType x,baseType y)39 void Subtract(baseType x, baseType y) 40 { 41 FXT_PSV::x -= x, FXT_PSV::y -= y; 42 } Reset()43 void Reset() 44 { 45 FXT_PSV::x = FXT_PSV::y = 0; 46 } 47 FXT_PSV& operator += (const FXT_PSV &obj) 48 { 49 x += obj.x; 50 y += obj.y; 51 return *this; 52 } 53 FXT_PSV& operator -= (const FXT_PSV &obj) 54 { 55 x -= obj.x; 56 y -= obj.y; 57 return *this; 58 } 59 FXT_PSV& operator *= (baseType lamda) 60 { 61 x *= lamda; 62 y *= lamda; 63 return *this; 64 } 65 FXT_PSV& operator /= (baseType lamda) 66 { 67 x /= lamda; 68 y /= lamda; 69 return *this; 70 } 71 friend FX_BOOL operator == (const FXT_PSV &obj1, const FXT_PSV &obj2) 72 { 73 return obj1.x == obj2.x && obj1.y == obj2.y; 74 } 75 friend FX_BOOL operator != (const FXT_PSV &obj1, const FXT_PSV &obj2) 76 { 77 return obj1.x != obj2.x || obj1.y != obj2.y; 78 } 79 friend FXT_PSV operator + (const FXT_PSV &obj1, const FXT_PSV &obj2) 80 { 81 CFX_PSVTemplate obj; 82 obj.x = obj1.x + obj2.x; 83 obj.y = obj1.y + obj2.y; 84 return obj; 85 } 86 friend FXT_PSV operator - (const FXT_PSV &obj1, const FXT_PSV &obj2) 87 { 88 CFX_PSVTemplate obj; 89 obj.x = obj1.x - obj2.x; 90 obj.y = obj1.y - obj2.y; 91 return obj; 92 } 93 friend FXT_PSV operator * (const FXT_PSV &obj, baseType lamda) 94 { 95 CFX_PSVTemplate t; 96 t.x = obj.x * lamda; 97 t.y = obj.y * lamda; 98 return t; 99 } 100 friend FXT_PSV operator * (baseType lamda, const FXT_PSV &obj) 101 { 102 CFX_PSVTemplate t; 103 t.x = lamda * obj.x; 104 t.y = lamda * obj.y; 105 return t; 106 } 107 friend FXT_PSV operator / (const FXT_PSV &obj, baseType lamda) 108 { 109 CFX_PSVTemplate t; 110 t.x = obj.x / lamda; 111 t.y = obj.y / lamda; 112 return t; 113 } 114 baseType x, y; 115 }; 116 typedef CFX_PSVTemplate<FX_INT32> CFX_Point; 117 typedef CFX_PSVTemplate<FX_FLOAT> CFX_PointF; 118 typedef CFX_PSVTemplate<FX_INT32> CFX_Size; 119 typedef CFX_PSVTemplate<FX_FLOAT> CFX_SizeF; 120 typedef CFX_ArrayTemplate<CFX_Point> CFX_Points; 121 typedef CFX_ArrayTemplate<CFX_PointF> CFX_PointsF; 122 typedef CFX_PSVTemplate<FX_INT32> * FX_LPPOINT; 123 typedef CFX_PSVTemplate<FX_FLOAT> * FX_LPPOINTF; 124 typedef CFX_PSVTemplate<FX_INT32> const * FX_LPCPOINT; 125 typedef CFX_PSVTemplate<FX_FLOAT> const * FX_LPCPOINTF; 126 #define CFX_FloatPoint CFX_PointF 127 template<class baseType> 128 class CFX_VTemplate: public CFX_PSVTemplate<baseType> 129 { 130 public: 131 typedef CFX_PSVTemplate<baseType> FXT_PSV; 132 typedef CFX_PSVTemplate<baseType> FXT_POINT; 133 typedef CFX_PSVTemplate<baseType> FXT_SIZE; 134 typedef CFX_VTemplate<baseType> FXT_VECTOR; Set(baseType newx,baseType newy)135 void Set(baseType newx, baseType newy) 136 { 137 FXT_PSV::x = newx; 138 FXT_PSV::y = newy; 139 } Set(const FXT_PSV & psv)140 void Set(const FXT_PSV &psv) 141 { 142 FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; 143 } Set(const FXT_POINT & p1,const FXT_POINT & p2)144 void Set(const FXT_POINT &p1, const FXT_POINT &p2) 145 { 146 FXT_PSV::x = p2.x - p1.x, FXT_PSV::y = p2.y - p1.y; 147 } Reset()148 void Reset() 149 { 150 FXT_PSV::x = FXT_PSV::y = 0; 151 } SquareLength()152 baseType SquareLength() const 153 { 154 return FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y; 155 } Length()156 baseType Length() const 157 { 158 return FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y); 159 } Normalize()160 void Normalize() 161 { 162 FX_FLOAT fLen = FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y); 163 if (fLen < 0.0001f) { 164 return; 165 } 166 FXT_PSV::x = ((baseType)FXT_PSV::x) / fLen; 167 FXT_PSV::y = ((baseType)FXT_PSV::y) / fLen; 168 } DotProduct(baseType otherx,baseType othery)169 baseType DotProduct(baseType otherx, baseType othery) const 170 { 171 return FXT_PSV::x * otherx + FXT_PSV::y * othery; 172 } DotProduct(const FXT_VECTOR & v)173 baseType DotProduct(const FXT_VECTOR &v) const 174 { 175 return FXT_PSV::x * v.x + FXT_PSV::y * v.y; 176 } IsParallel(baseType otherx,baseType othery)177 FX_BOOL IsParallel(baseType otherx, baseType othery) const 178 { 179 baseType t = FXT_PSV::x * othery - FXT_PSV::y * otherx; 180 return FXSYS_fabs(t) < 0x0001f; 181 } IsParallel(const FXT_VECTOR & v)182 FX_BOOL IsParallel(const FXT_VECTOR &v) const 183 { 184 return IsParallel(v.x, v.y); 185 } IsPerpendicular(baseType otherx,baseType othery)186 FX_BOOL IsPerpendicular(baseType otherx, baseType othery) const 187 { 188 baseType t = DotProduct(otherx, othery); 189 return FXSYS_fabs(t) < 0x0001f; 190 } IsPerpendicular(const FXT_VECTOR & v)191 FX_BOOL IsPerpendicular(const FXT_VECTOR &v) const 192 { 193 return IsPerpendicular(v.x, v.y); 194 } Translate(baseType dx,baseType dy)195 void Translate(baseType dx, baseType dy) 196 { 197 FXT_PSV::x += dx, FXT_PSV::y += dy; 198 } Scale(baseType sx,baseType sy)199 void Scale(baseType sx, baseType sy) 200 { 201 FXT_PSV::x *= sx, FXT_PSV::y *= sy; 202 } Rotate(FX_FLOAT fRadian)203 void Rotate(FX_FLOAT fRadian) 204 { 205 FX_FLOAT xx = (FX_FLOAT)FXT_PSV::x; 206 FX_FLOAT yy = (FX_FLOAT)FXT_PSV::y; 207 FX_FLOAT cosValue = FXSYS_cos(fRadian); 208 FX_FLOAT sinValue = FXSYS_sin(fRadian); 209 FXT_PSV::x = xx * cosValue - yy * sinValue; 210 FXT_PSV::y = xx * sinValue + yy * cosValue; 211 } Cosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)212 friend FX_FLOAT Cosine(const FXT_VECTOR &v1, const FXT_VECTOR &v2) 213 { 214 FXSYS_assert(v1.SquareLength() != 0 && v2.SquareLength() != 0); 215 FX_FLOAT dotProduct = v1.DotProduct(v2); 216 return dotProduct / (FX_FLOAT)FXSYS_sqrt(v1.SquareLength() * v2.SquareLength()); 217 } ArcCosine(const FXT_VECTOR & v1,const FXT_VECTOR & v2)218 friend FX_FLOAT ArcCosine(const FXT_VECTOR &v1, const FXT_VECTOR &v2) 219 { 220 return (FX_FLOAT)FXSYS_acos(Cosine(v1, v2)); 221 } SlopeAngle(const FXT_VECTOR & v)222 friend FX_FLOAT SlopeAngle(const FXT_VECTOR &v) 223 { 224 CFX_VTemplate vx; 225 vx.Set(1, 0); 226 FX_FLOAT fSlope = ArcCosine(v, vx); 227 return v.y < 0 ? -fSlope : fSlope; 228 } 229 }; 230 typedef CFX_VTemplate<FX_INT32> CFX_Vector; 231 typedef CFX_VTemplate<FX_FLOAT> CFX_VectorF; 232 template<class baseType> 233 class CFX_RTemplate 234 { 235 public: 236 typedef CFX_PSVTemplate<baseType> FXT_POINT; 237 typedef CFX_PSVTemplate<baseType> FXT_SIZE; 238 typedef CFX_VTemplate<baseType> FXT_VECTOR; 239 typedef CFX_PRLTemplate<baseType> FXT_PARAL; 240 typedef CFX_RTemplate<baseType> FXT_RECT; Set(baseType left,baseType top,baseType width,baseType height)241 void Set(baseType left, baseType top, baseType width, baseType height) 242 { 243 FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::width = width, FXT_RECT::height = height; 244 } Set(baseType left,baseType top,const FXT_SIZE & size)245 void Set(baseType left, baseType top, const FXT_SIZE &size) 246 { 247 FXT_RECT::left = left, FXT_RECT::top = top, FXT_RECT::Size(size); 248 } Set(const FXT_POINT & p,baseType width,baseType height)249 void Set(const FXT_POINT &p, baseType width, baseType height) 250 { 251 TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height; 252 } Set(const FXT_POINT & p1,const FXT_POINT & p2)253 void Set(const FXT_POINT &p1, const FXT_POINT &p2) 254 { 255 TopLeft(p1), FXT_RECT::width = p2.x - p1.x, FXT_RECT::height = p2.y - p1.y, FXT_RECT::Normalize(); 256 } Set(const FXT_POINT & p,const FXT_VECTOR & v)257 void Set(const FXT_POINT &p, const FXT_VECTOR &v) 258 { 259 TopLeft(p), FXT_RECT::width = v.x, FXT_RECT::height = v.y, FXT_RECT::Normalize(); 260 } Reset()261 void Reset() 262 { 263 FXT_RECT::left = FXT_RECT::top = FXT_RECT::width = FXT_RECT::height = 0; 264 } 265 FXT_RECT& operator += (const FXT_POINT &p) 266 { 267 left += p.x, top += p.y; 268 return *this; 269 } 270 FXT_RECT& operator -= (const FXT_POINT &p) 271 { 272 left -= p.x, top -= p.y; 273 return *this; 274 } right()275 baseType right() const 276 { 277 return left + width; 278 } bottom()279 baseType bottom() const 280 { 281 return top + height; 282 } Normalize()283 void Normalize() 284 { 285 if (width < 0) { 286 left += width; 287 width = -width; 288 } 289 if (height < 0) { 290 top += height; 291 height = -height; 292 } 293 } Offset(baseType dx,baseType dy)294 void Offset(baseType dx, baseType dy) 295 { 296 left += dx; 297 top += dy; 298 } Inflate(baseType x,baseType y)299 void Inflate(baseType x, baseType y) 300 { 301 left -= x; 302 width += x * 2; 303 top -= y; 304 height += y * 2; 305 } Inflate(const FXT_POINT & p)306 void Inflate(const FXT_POINT &p) 307 { 308 Inflate(p.x, p.y); 309 } Inflate(baseType left,baseType top,baseType right,baseType bottom)310 void Inflate(baseType left, baseType top, baseType right, baseType bottom) 311 { 312 FXT_RECT::left -= left; 313 FXT_RECT::top -= top; 314 FXT_RECT::width += left + right; 315 FXT_RECT::height += top + bottom; 316 } Inflate(const FXT_RECT & rt)317 void Inflate(const FXT_RECT &rt) 318 { 319 Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height); 320 } Deflate(baseType x,baseType y)321 void Deflate(baseType x, baseType y) 322 { 323 left += x; 324 width -= x * 2; 325 top += y; 326 height -= y * 2; 327 } Deflate(const FXT_POINT & p)328 void Deflate(const FXT_POINT &p) 329 { 330 Deflate(p.x, p.y); 331 } Deflate(baseType left,baseType top,baseType right,baseType bottom)332 void Deflate(baseType left, baseType top, baseType right, baseType bottom) 333 { 334 FXT_RECT::left += left; 335 FXT_RECT::top += top; 336 FXT_RECT::width -= left + right; 337 FXT_RECT::height -= top + bottom; 338 } Deflate(const FXT_RECT & rt)339 void Deflate(const FXT_RECT &rt) 340 { 341 Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height); 342 } IsEmpty()343 FX_BOOL IsEmpty() const 344 { 345 return width <= 0 || height <= 0; 346 } IsEmpty(FX_FLOAT fEpsilon)347 FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const 348 { 349 return width <= fEpsilon || height <= fEpsilon; 350 } Empty()351 void Empty() 352 { 353 width = height = 0; 354 } Contains(baseType x,baseType y)355 FX_BOOL Contains(baseType x, baseType y) const 356 { 357 return x >= left && x < left + width && y >= top && y < top + height; 358 } Contains(const FXT_POINT & p)359 FX_BOOL Contains(const FXT_POINT &p) const 360 { 361 return Contains(p.x, p.y); 362 } Contains(const FXT_RECT & rt)363 FX_BOOL Contains(const FXT_RECT &rt) const 364 { 365 return rt.left >= left && rt.right() <= right() && rt.top >= top && rt.bottom() <= bottom(); 366 } Width()367 baseType Width() const 368 { 369 return width; 370 } Height()371 baseType Height() const 372 { 373 return height; 374 } Size()375 FXT_SIZE Size() const 376 { 377 FXT_SIZE size; 378 size.Set(width, height); 379 return size; 380 } Size(FXT_SIZE s)381 void Size(FXT_SIZE s) 382 { 383 width = s.x, height = s.y; 384 } TopLeft()385 FXT_POINT TopLeft() const 386 { 387 FXT_POINT p; 388 p.x = left; 389 p.y = top; 390 return p; 391 } TopRight()392 FXT_POINT TopRight() const 393 { 394 FXT_POINT p; 395 p.x = left + width; 396 p.y = top; 397 return p; 398 } BottomLeft()399 FXT_POINT BottomLeft() const 400 { 401 FXT_POINT p; 402 p.x = left; 403 p.y = top + height; 404 return p; 405 } BottomRight()406 FXT_POINT BottomRight() const 407 { 408 FXT_POINT p; 409 p.x = left + width; 410 p.y = top + height; 411 return p; 412 } TopLeft(FXT_POINT tl)413 void TopLeft(FXT_POINT tl) 414 { 415 left = tl.x; 416 top = tl.y; 417 } TopRight(FXT_POINT tr)418 void TopRight(FXT_POINT tr) 419 { 420 width = tr.x - left; 421 top = tr.y; 422 } BottomLeft(FXT_POINT bl)423 void BottomLeft(FXT_POINT bl) 424 { 425 left = bl.x; 426 height = bl.y - top; 427 } BottomRight(FXT_POINT br)428 void BottomRight(FXT_POINT br) 429 { 430 width = br.x - left; 431 height = br.y - top; 432 } Center()433 FXT_POINT Center() const 434 { 435 FXT_POINT p; 436 p.x = left + width / 2; 437 p.y = top + height / 2; 438 return p; 439 } GetParallelogram(FXT_PARAL & pg)440 void GetParallelogram(FXT_PARAL &pg) const 441 { 442 pg.x = left, pg.y = top; 443 pg.x1 = width, pg.y1 = 0; 444 pg.x2 = 0, pg.y2 = height; 445 } Union(baseType x,baseType y)446 void Union(baseType x, baseType y) 447 { 448 baseType r = right(), b = bottom(); 449 if (left > x) { 450 left = x; 451 } 452 if (r < x) { 453 r = x; 454 } 455 if (top > y) { 456 top = y; 457 } 458 if (b < y) { 459 b = y; 460 } 461 width = r - left; 462 height = b - top; 463 } Union(const FXT_POINT & p)464 void Union(const FXT_POINT &p) 465 { 466 Union(p.x, p.y); 467 } Union(const FXT_RECT & rt)468 void Union(const FXT_RECT &rt) 469 { 470 baseType r = right(), b = bottom(); 471 if (left > rt.left) { 472 left = rt.left; 473 } 474 if (r < rt.right()) { 475 r = rt.right(); 476 } 477 if (top > rt.top) { 478 top = rt.top; 479 } 480 if (b < rt.bottom()) { 481 b = rt.bottom(); 482 } 483 width = r - left; 484 height = b - top; 485 } Intersect(const FXT_RECT & rt)486 void Intersect(const FXT_RECT &rt) 487 { 488 baseType r = right(), b = bottom(); 489 if (left < rt.left) { 490 left = rt.left; 491 } 492 if (r > rt.right()) { 493 r = rt.right(); 494 } 495 if (top < rt.top) { 496 top = rt.top; 497 } 498 if (b > rt.bottom()) { 499 b = rt.bottom(); 500 } 501 width = r - left; 502 height = b - top; 503 } IntersectWith(const FXT_RECT & rt)504 FX_BOOL IntersectWith(const FXT_RECT &rt) const 505 { 506 FXT_RECT rect = rt; 507 rect.Intersect(*this); 508 return !rect.IsEmpty(); 509 } IntersectWith(const FXT_RECT & rt,FX_FLOAT fEpsilon)510 FX_BOOL IntersectWith(const FXT_RECT &rt, FX_FLOAT fEpsilon) const 511 { 512 FXT_RECT rect = rt; 513 rect.Intersect(*this); 514 return !rect.IsEmpty(fEpsilon); 515 } 516 friend FX_BOOL operator == (const FXT_RECT &rc1, const FXT_RECT &rc2) 517 { 518 return rc1.left == rc2.left && rc1.top == rc2.top && rc1.width == rc2.width && rc1.height == rc2.height; 519 } 520 friend FX_BOOL operator != (const FXT_RECT &rc1, const FXT_RECT &rc2) 521 { 522 return rc1.left != rc2.left || rc1.top != rc2.top || rc1.width != rc2.width || rc1.height != rc2.height; 523 } 524 baseType left, top; 525 baseType width, height; 526 }; 527 typedef CFX_RTemplate<FX_INT32> CFX_Rect; 528 typedef CFX_RTemplate<FX_FLOAT> CFX_RectF; 529 typedef CFX_RTemplate<FX_INT32> * FX_LPRECT; 530 typedef CFX_RTemplate<FX_FLOAT> * FX_LPRECTF; 531 typedef CFX_RTemplate<FX_INT32> const * FX_LPCRECT; 532 typedef CFX_RTemplate<FX_FLOAT> const * FX_LPCRECTF; 533 typedef CFX_ArrayTemplate<CFX_RectF> CFX_RectFArray; 534 struct FX_RECT { 535 536 int left; 537 538 int top; 539 540 int right; 541 542 int bottom; 543 FX_RECTFX_RECT544 FX_RECT(): left(0), top(0), right(0), bottom(0) { } 545 FX_RECTFX_RECT546 FX_RECT(int left1, int top1, int right1, int bottom1) 547 { 548 left = left1; 549 top = top1; 550 right = right1; 551 bottom = bottom1; 552 } 553 WidthFX_RECT554 int Width() const 555 { 556 return right - left; 557 } 558 HeightFX_RECT559 int Height() const 560 { 561 return bottom - top; 562 } 563 IsEmptyFX_RECT564 FX_BOOL IsEmpty() const 565 { 566 return right <= left || bottom <= top; 567 } 568 569 void Normalize(); 570 571 void Intersect(const FX_RECT& src); 572 IntersectFX_RECT573 void Intersect(int left1, int top1, int right1, int bottom1) 574 { 575 Intersect(FX_RECT(left1, top1, right1, bottom1)); 576 } 577 578 void Union(const FX_RECT& other_rect); 579 580 FX_BOOL operator == (const FX_RECT& src) const 581 { 582 return left == src.left && right == src.right && top == src.top && bottom == src.bottom; 583 } 584 OffsetFX_RECT585 void Offset(int dx, int dy) 586 { 587 left += dx; 588 right += dx; 589 top += dy; 590 bottom += dy; 591 } 592 ContainsFX_RECT593 FX_BOOL Contains(const FX_RECT& other_rect) const 594 { 595 return other_rect.left >= left && other_rect.right <= right && other_rect.top >= top && other_rect.bottom <= bottom; 596 } 597 ContainsFX_RECT598 FX_BOOL Contains(int x, int y) const 599 { 600 return x >= left && x < right && y >= top && y < bottom; 601 } 602 }; 603 struct FX_SMALL_RECT { 604 605 FX_SHORT Left; 606 607 FX_SHORT Top; 608 609 FX_SHORT Right; 610 611 FX_SHORT Bottom; 612 }; 613 class CFX_FloatRect 614 { 615 public: 616 CFX_FloatRect()617 CFX_FloatRect() 618 { 619 left = right = bottom = top = 0; 620 } 621 CFX_FloatRect(FX_FLOAT left1,FX_FLOAT bottom1,FX_FLOAT right1,FX_FLOAT top1)622 CFX_FloatRect(FX_FLOAT left1, FX_FLOAT bottom1, FX_FLOAT right1, FX_FLOAT top1) 623 { 624 left = left1; 625 bottom = bottom1; 626 right = right1; 627 top = top1; 628 } 629 CFX_FloatRect(const FX_FLOAT * pArray)630 CFX_FloatRect(const FX_FLOAT* pArray) 631 { 632 left = pArray[0]; 633 bottom = pArray[1]; 634 right = pArray[2]; 635 top = pArray[3]; 636 } 637 638 CFX_FloatRect(const FX_RECT& rect); 639 IsEmpty()640 FX_BOOL IsEmpty() const 641 { 642 return left >= right || bottom >= top; 643 } 644 645 void Normalize(); 646 Reset()647 void Reset() 648 { 649 left = right = bottom = top = 0; 650 } 651 652 FX_BOOL Contains(const CFX_FloatRect& other_rect) const; 653 654 FX_BOOL Contains(FX_FLOAT x, FX_FLOAT y) const; 655 656 void Transform(const CFX_Matrix* pMatrix); 657 658 void Intersect(const CFX_FloatRect& other_rect); 659 660 void Union(const CFX_FloatRect& other_rect); 661 662 FX_RECT GetInnerRect() const; 663 664 FX_RECT GetOutterRect() const; 665 666 FX_RECT GetClosestRect() const; 667 668 int Substract4(CFX_FloatRect& substract_rect, CFX_FloatRect* pRects); 669 InitRect(FX_FLOAT x,FX_FLOAT y)670 void InitRect(FX_FLOAT x, FX_FLOAT y) 671 { 672 left = right = x; 673 bottom = top = y; 674 } 675 676 void UpdateRect(FX_FLOAT x, FX_FLOAT y); 677 Width()678 FX_FLOAT Width() const 679 { 680 return right - left; 681 } 682 Height()683 FX_FLOAT Height() const 684 { 685 return top - bottom; 686 } 687 Inflate(FX_FLOAT x,FX_FLOAT y)688 void Inflate(FX_FLOAT x, FX_FLOAT y) 689 { 690 Normalize(); 691 left -= x; 692 right += x; 693 bottom -= y; 694 top += y; 695 } 696 Inflate(FX_FLOAT left,FX_FLOAT bottom,FX_FLOAT right,FX_FLOAT top)697 void Inflate(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top) 698 { 699 Normalize(); 700 this->left -= left; 701 this->bottom -= bottom; 702 this->right += right; 703 this->top += top; 704 } 705 Inflate(const CFX_FloatRect & rt)706 void Inflate(const CFX_FloatRect &rt) 707 { 708 Inflate(rt.left, rt.bottom, rt.right, rt.top); 709 } 710 Deflate(FX_FLOAT x,FX_FLOAT y)711 void Deflate(FX_FLOAT x, FX_FLOAT y) 712 { 713 Normalize(); 714 left += x; 715 right -= x; 716 bottom += y; 717 top -= y; 718 } 719 Deflate(FX_FLOAT left,FX_FLOAT bottom,FX_FLOAT right,FX_FLOAT top)720 void Deflate(FX_FLOAT left, FX_FLOAT bottom, FX_FLOAT right, FX_FLOAT top) 721 { 722 Normalize(); 723 this->left += left; 724 this->bottom += bottom; 725 this->right -= right; 726 this->top -= top; 727 } 728 Deflate(const CFX_FloatRect & rt)729 void Deflate(const CFX_FloatRect &rt) 730 { 731 Deflate(rt.left, rt.bottom, rt.right, rt.top); 732 } 733 Translate(FX_FLOAT e,FX_FLOAT f)734 void Translate(FX_FLOAT e, FX_FLOAT f) 735 { 736 left += e; 737 right += e; 738 top += f; 739 bottom += f; 740 } 741 742 static CFX_FloatRect GetBBox(const CFX_FloatPoint* pPoints, int nPoints); 743 744 FX_FLOAT left; 745 746 FX_FLOAT right; 747 748 FX_FLOAT bottom; 749 750 FX_FLOAT top; 751 }; 752 class CFX_Matrix 753 { 754 public: 755 CFX_Matrix()756 CFX_Matrix() 757 { 758 a = d = 1; 759 b = c = e = f = 0; 760 } 761 CFX_Matrix(FX_FLOAT a1,FX_FLOAT b1,FX_FLOAT c1,FX_FLOAT d1,FX_FLOAT e1,FX_FLOAT f1)762 CFX_Matrix(FX_FLOAT a1, FX_FLOAT b1, FX_FLOAT c1, FX_FLOAT d1, FX_FLOAT e1, FX_FLOAT f1) 763 { 764 a = a1; 765 b = b1; 766 c = c1; 767 d = d1; 768 e = e1; 769 f = f1; 770 } 771 772 void Set(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f); 773 void Set(const FX_FLOAT n[6]); 774 SetIdentity()775 void SetIdentity() 776 { 777 a = d = 1; 778 b = c = e = f = 0; 779 } 780 781 void SetReverse(const CFX_Matrix &m); 782 783 void Concat(FX_FLOAT a, FX_FLOAT b, FX_FLOAT c, FX_FLOAT d, FX_FLOAT e, FX_FLOAT f, FX_BOOL bPrepended = FALSE); 784 785 void Concat(const CFX_Matrix &m, FX_BOOL bPrepended = FALSE); 786 787 void ConcatInverse(const CFX_Matrix& m, FX_BOOL bPrepended = FALSE); Reset()788 void Reset() 789 { 790 SetIdentity(); 791 } 792 Copy(const CFX_Matrix & m)793 void Copy(const CFX_Matrix& m) 794 { 795 *this = m; 796 } 797 IsIdentity()798 FX_BOOL IsIdentity() const 799 { 800 return a == 1 && b == 0 && c == 0 && d == 1 && e == 0 && f == 0; 801 } 802 FX_BOOL IsInvertible() const; 803 804 FX_BOOL Is90Rotated() const; 805 806 FX_BOOL IsScaled() const; 807 808 void Translate(FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE); 809 810 void TranslateI(FX_INT32 x, FX_INT32 y, FX_BOOL bPrepended = FALSE) 811 { 812 Translate((FX_FLOAT)x, (FX_FLOAT)y, bPrepended); 813 } 814 815 void Scale(FX_FLOAT sx, FX_FLOAT sy, FX_BOOL bPrepended = FALSE); 816 817 void Rotate(FX_FLOAT fRadian, FX_BOOL bPrepended = FALSE); 818 819 void RotateAt(FX_FLOAT fRadian, FX_FLOAT x, FX_FLOAT y, FX_BOOL bPrepended = FALSE); 820 821 void Shear(FX_FLOAT fAlphaRadian, FX_FLOAT fBetaRadian, FX_BOOL bPrepended = FALSE); 822 823 void MatchRect(const CFX_FloatRect &dest, const CFX_FloatRect &src); 824 825 FX_FLOAT GetXUnit() const; 826 827 FX_FLOAT GetYUnit() const; 828 void GetUnitRect(CFX_RectF &rect) const; 829 830 CFX_FloatRect GetUnitRect() const; 831 832 FX_FLOAT GetUnitArea() const; 833 FX_FLOAT TransformXDistance(FX_FLOAT dx) const; 834 FX_INT32 TransformXDistance(FX_INT32 dx) const; 835 FX_FLOAT TransformYDistance(FX_FLOAT dy) const; 836 FX_INT32 TransformYDistance(FX_INT32 dy) const; 837 FX_FLOAT TransformDistance(FX_FLOAT dx, FX_FLOAT dy) const; 838 FX_INT32 TransformDistance(FX_INT32 dx, FX_INT32 dy) const; 839 840 FX_FLOAT TransformDistance(FX_FLOAT distance) const; 841 void TransformPoint(FX_FLOAT &x, FX_FLOAT &y) const; 842 void TransformPoint(FX_INT32 &x, FX_INT32 &y) const; 843 void TransformPoints(CFX_PointF *points, FX_INT32 iCount) const; 844 void TransformPoints(CFX_Point *points, FX_INT32 iCount) const; 845 Transform(FX_FLOAT & x,FX_FLOAT & y)846 void Transform(FX_FLOAT& x, FX_FLOAT& y) const 847 { 848 TransformPoint(x, y); 849 } 850 Transform(FX_FLOAT x,FX_FLOAT y,FX_FLOAT & x1,FX_FLOAT & y1)851 void Transform(FX_FLOAT x, FX_FLOAT y, FX_FLOAT& x1, FX_FLOAT& y1) const 852 { 853 x1 = x, y1 = y; 854 TransformPoint(x1, y1); 855 } 856 void TransformVector(CFX_VectorF &v) const; 857 void TransformVector(CFX_Vector &v) const; 858 void TransformRect(CFX_RectF &rect) const; 859 void TransformRect(CFX_Rect &rect) const; 860 861 void TransformRect(FX_FLOAT& left, FX_FLOAT& right, FX_FLOAT& top, FX_FLOAT& bottom) const; 862 TransformRect(CFX_FloatRect & rect)863 void TransformRect(CFX_FloatRect& rect) const 864 { 865 TransformRect(rect.left, rect.right, rect.top, rect.bottom); 866 } 867 GetA()868 FX_FLOAT GetA() const 869 { 870 return a; 871 } 872 GetB()873 FX_FLOAT GetB() const 874 { 875 return b; 876 } 877 GetC()878 FX_FLOAT GetC() const 879 { 880 return c; 881 } 882 GetD()883 FX_FLOAT GetD() const 884 { 885 return d; 886 } 887 GetE()888 FX_FLOAT GetE() const 889 { 890 return e; 891 } 892 GetF()893 FX_FLOAT GetF() const 894 { 895 return f; 896 } 897 public: 898 FX_FLOAT a; 899 FX_FLOAT b; 900 FX_FLOAT c; 901 FX_FLOAT d; 902 FX_FLOAT e; 903 FX_FLOAT f; 904 }; 905 #define CFX_AffineMatrix CFX_Matrix 906 907 #endif // CORE_INCLUDE_FXCRT_FX_COORDINATES_H_ 908