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_ 9template<class baseType> class CFX_PSVTemplate; 10template<class baseType> class CFX_VTemplate; 11template<class baseType> class CFX_PRLTemplate; 12template<class baseType> class CFX_RTemplate; 13template<class baseType> class CFX_ETemplate; 14template<class baseType> class CFX_ATemplate; 15template<class baseType> class CFX_RRTemplate; 16class CFX_Matrix; 17template<class baseType> 18class CFX_PSVTemplate : public CFX_Object 19{ 20public: 21 typedef CFX_PSVTemplate<baseType> FXT_PSV; 22 typedef CFX_PSVTemplate<baseType> FXT_POINT; 23 typedef CFX_PSVTemplate<baseType> FXT_SIZE; 24 void Set(baseType x, baseType y) 25 { 26 FXT_PSV::x = x, FXT_PSV::y = y; 27 } 28 void Set(const FXT_PSV &psv) 29 { 30 FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; 31 } 32 void Add(baseType x, baseType y) 33 { 34 FXT_PSV::x += x, FXT_PSV::y += y; 35 } 36 void Subtract(baseType x, baseType y) 37 { 38 FXT_PSV::x -= x, FXT_PSV::y -= y; 39 } 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}; 113typedef CFX_PSVTemplate<FX_INT32> CFX_Point; 114typedef CFX_PSVTemplate<FX_FLOAT> CFX_PointF; 115typedef CFX_PSVTemplate<FX_INT32> CFX_Size; 116typedef CFX_PSVTemplate<FX_FLOAT> CFX_SizeF; 117typedef CFX_ArrayTemplate<CFX_Point> CFX_Points; 118typedef CFX_ArrayTemplate<CFX_PointF> CFX_PointsF; 119typedef CFX_PSVTemplate<FX_INT32> * FX_LPPOINT; 120typedef CFX_PSVTemplate<FX_FLOAT> * FX_LPPOINTF; 121typedef CFX_PSVTemplate<FX_INT32> const * FX_LPCPOINT; 122typedef CFX_PSVTemplate<FX_FLOAT> const * FX_LPCPOINTF; 123#define CFX_FloatPoint CFX_PointF 124template<class baseType> 125class CFX_VTemplate: public CFX_PSVTemplate<baseType> 126{ 127public: 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; 132 void Set(baseType x, baseType y) 133 { 134 FXT_PSV::x = x, FXT_PSV::y = y; 135 } 136 void Set(const FXT_PSV &psv) 137 { 138 FXT_PSV::x = psv.x, FXT_PSV::y = psv.y; 139 } 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 } 144 void Reset() 145 { 146 FXT_PSV::x = FXT_PSV::y = 0; 147 } 148 baseType SquareLength() const 149 { 150 return FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y; 151 } 152 baseType Length() const 153 { 154 return FXSYS_sqrt(FXT_PSV::x * FXT_PSV::x + FXT_PSV::y * FXT_PSV::y); 155 } 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 } 163 baseType DotProduct(baseType x, baseType y) const 164 { 165 return FXT_PSV::x * x + FXT_PSV::y * y; 166 } 167 baseType DotProduct(const FXT_VECTOR &v) const 168 { 169 return FXT_PSV::x * v.x + FXT_PSV::y * v.y; 170 } 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 } 176 FX_BOOL IsParallel(const FXT_VECTOR &v) const 177 { 178 return IsParallel(v.x, v.y); 179 } 180 FX_BOOL IsPerpendicular(baseType x, baseType y) const 181 { 182 baseType t = DotProduct(x, y); 183 return FXSYS_fabs(t) < 0x0001f; 184 } 185 FX_BOOL IsPerpendicular(const FXT_VECTOR &v) const 186 { 187 return IsPerpendicular(v.x, v.y); 188 } 189 void Translate(baseType dx, baseType dy) 190 { 191 FXT_PSV::x += dx, FXT_PSV::y += dy; 192 } 193 void Scale(baseType sx, baseType sy) 194 { 195 FXT_PSV::x *= sx, FXT_PSV::y *= sy; 196 } 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 } 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 } 212 friend FX_FLOAT ArcCosine(const FXT_VECTOR &v1, const FXT_VECTOR &v2) 213 { 214 return (FX_FLOAT)FXSYS_acos(Cosine(v1, v2)); 215 } 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}; 224typedef CFX_VTemplate<FX_INT32> CFX_Vector; 225typedef CFX_VTemplate<FX_FLOAT> CFX_VectorF; 226template<class baseType> 227class CFX_RTemplate: public CFX_Object 228{ 229public: 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; 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 } 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 } 243 void Set(const FXT_POINT &p, baseType width, baseType height) 244 { 245 TopLeft(p), FXT_RECT::width = width, FXT_RECT::height = height; 246 } 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 } 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 } 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 } 269 baseType right() const 270 { 271 return left + width; 272 } 273 baseType bottom() const 274 { 275 return top + height; 276 } 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 } 288 void Offset(baseType dx, baseType dy) 289 { 290 left += dx; 291 top += dy; 292 } 293 void Inflate(baseType x, baseType y) 294 { 295 left -= x; 296 width += x * 2; 297 top -= y; 298 height += y * 2; 299 } 300 void Inflate(const FXT_POINT &p) 301 { 302 Inflate(p.x, p.y); 303 } 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 } 311 void Inflate(const FXT_RECT &rt) 312 { 313 Inflate(rt.left, rt.top, rt.left + rt.width, rt.top + rt.height); 314 } 315 void Deflate(baseType x, baseType y) 316 { 317 left += x; 318 width -= x * 2; 319 top += y; 320 height -= y * 2; 321 } 322 void Deflate(const FXT_POINT &p) 323 { 324 Deflate(p.x, p.y); 325 } 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 } 333 void Deflate(const FXT_RECT &rt) 334 { 335 Deflate(rt.left, rt.top, rt.top + rt.width, rt.top + rt.height); 336 } 337 FX_BOOL IsEmpty() const 338 { 339 return width <= 0 || height <= 0; 340 } 341 FX_BOOL IsEmpty(FX_FLOAT fEpsilon) const 342 { 343 return width <= fEpsilon || height <= fEpsilon; 344 } 345 void Empty() 346 { 347 width = height = 0; 348 } 349 FX_BOOL Contains(baseType x, baseType y) const 350 { 351 return x >= left && x < left + width && y >= top && y < top + height; 352 } 353 FX_BOOL Contains(const FXT_POINT &p) const 354 { 355 return Contains(p.x, p.y); 356 } 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 } 361 baseType Width() const 362 { 363 return width; 364 } 365 baseType Height() const 366 { 367 return height; 368 } 369 FXT_SIZE Size() const 370 { 371 FXT_SIZE size; 372 size.Set(width, height); 373 return size; 374 } 375 void Size(FXT_SIZE s) 376 { 377 width = s.x, height = s.y; 378 } 379 FXT_POINT TopLeft() const 380 { 381 FXT_POINT p; 382 p.x = left; 383 p.y = top; 384 return p; 385 } 386 FXT_POINT TopRight() const 387 { 388 FXT_POINT p; 389 p.x = left + width; 390 p.y = top; 391 return p; 392 } 393 FXT_POINT BottomLeft() const 394 { 395 FXT_POINT p; 396 p.x = left; 397 p.y = top + height; 398 return p; 399 } 400 FXT_POINT BottomRight() const 401 { 402 FXT_POINT p; 403 p.x = left + width; 404 p.y = top + height; 405 return p; 406 } 407 void TopLeft(FXT_POINT tl) 408 { 409 left = tl.x; 410 top = tl.y; 411 } 412 void TopRight(FXT_POINT tr) 413 { 414 width = tr.x - left; 415 top = tr.y; 416 } 417 void BottomLeft(FXT_POINT bl) 418 { 419 left = bl.x; 420 height = bl.y - top; 421 } 422 void BottomRight(FXT_POINT br) 423 { 424 width = br.x - left; 425 height = br.y - top; 426 } 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 } 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 } 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 } 458 void Union(const FXT_POINT &p) 459 { 460 Union(p.x, p.y); 461 } 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 } 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 } 498 FX_BOOL IntersectWith(const FXT_RECT &rt) const 499 { 500 FXT_RECT rect = rt; 501 rect.Intersect(*this); 502 return !rect.IsEmpty(); 503 } 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}; 521typedef CFX_RTemplate<FX_INT32> CFX_Rect; 522typedef CFX_RTemplate<FX_FLOAT> CFX_RectF; 523typedef CFX_RTemplate<FX_INT32> * FX_LPRECT; 524typedef CFX_RTemplate<FX_FLOAT> * FX_LPRECTF; 525typedef CFX_RTemplate<FX_INT32> const * FX_LPCRECT; 526typedef CFX_RTemplate<FX_FLOAT> const * FX_LPCRECTF; 527typedef CFX_ArrayTemplate<CFX_RectF> CFX_RectFArray; 528struct FX_RECT { 529 530 int left; 531 532 int top; 533 534 int right; 535 536 int bottom; 537 538 FX_RECT() {} 539 540 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 548 int Width() const 549 { 550 return right - left; 551 } 552 553 int Height() const 554 { 555 return bottom - top; 556 } 557 558 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 567 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 579 void Offset(int dx, int dy) 580 { 581 left += dx; 582 right += dx; 583 top += dy; 584 bottom += dy; 585 } 586 587 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 592 FX_BOOL Contains(int x, int y) const 593 { 594 return x >= left && x < right && y >= top && y < bottom; 595 } 596}; 597struct FX_SMALL_RECT { 598 599 FX_SHORT Left; 600 601 FX_SHORT Top; 602 603 FX_SHORT Right; 604 605 FX_SHORT Bottom; 606}; 607class CFX_FloatRect : public CFX_Object 608{ 609public: 610 611 CFX_FloatRect() 612 { 613 left = right = bottom = top = 0; 614 } 615 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 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 634 FX_BOOL IsEmpty() const 635 { 636 return left >= right || bottom >= top; 637 } 638 639 void Normalize(); 640 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 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 672 FX_FLOAT Width() const 673 { 674 return right - left; 675 } 676 677 FX_FLOAT Height() const 678 { 679 return top - bottom; 680 } 681 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 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 700 void Inflate(const CFX_FloatRect &rt) 701 { 702 Inflate(rt.left, rt.bottom, rt.right, rt.top); 703 } 704 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 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 723 void Deflate(const CFX_FloatRect &rt) 724 { 725 Deflate(rt.left, rt.bottom, rt.right, rt.top); 726 } 727 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}; 746class CFX_Matrix : public CFX_Object 747{ 748public: 749 750 CFX_Matrix() 751 { 752 a = d = 1; 753 b = c = e = f = 0; 754 } 755 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 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); 782 void Reset() 783 { 784 SetIdentity(); 785 } 786 787 void Copy(const CFX_Matrix& m) 788 { 789 *this = m; 790 } 791 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 840 void Transform(FX_FLOAT& x, FX_FLOAT& y) const 841 { 842 TransformPoint(x, y); 843 } 844 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 857 void TransformRect(CFX_FloatRect& rect) const 858 { 859 TransformRect(rect.left, rect.right, rect.top, rect.bottom); 860 } 861 862 FX_FLOAT GetA() const 863 { 864 return a; 865 } 866 867 FX_FLOAT GetB() const 868 { 869 return b; 870 } 871 872 FX_FLOAT GetC() const 873 { 874 return c; 875 } 876 877 FX_FLOAT GetD() const 878 { 879 return d; 880 } 881 882 FX_FLOAT GetE() const 883 { 884 return e; 885 } 886 887 FX_FLOAT GetF() const 888 { 889 return f; 890 } 891public: 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