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