Geometry.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #include "Geometry.h"
  2. MuPDF::Box MuPDF::Box::Transform(Matrix matrix) {
  3. return fz_transform_rect(*this, matrix);
  4. }
  5. MuPDF::BBox MuPDF::Box::Round() {
  6. return (BBox)*this;
  7. }
  8. MuPDF::Box::operator Box(BBox box) {
  9. return { (float)box.X0, (float)box.Y0, (float)box.X1, (float)box.Y1 };
  10. }
  11. MuPDF::Box MuPDF::Box::operator&(Box a, Box b) {
  12. if (b.IsInfinite) return a;
  13. if (a.IsInfinite) return b;
  14. return { a.X0 < b.X0 ? b.X0 : a.X0,
  15. a.Y0 < b.Y0 ? b.Y0 : a.Y0,
  16. a.X1 > b.X1 ? b.X1 : a.X1,
  17. a.Y1 > b.Y1 ? b.Y1 : a.Y1
  18. };
  19. }
  20. MuPDF::Box MuPDF::Box::operator|(Box a, Box b) {
  21. /* Check for empty box before infinite box */
  22. if (!b.IsValid) return a;
  23. if (!a.IsValid) return b;
  24. if (a.IsInfinite) return a;
  25. if (b.IsInfinite) return b;
  26. return { a.X0 > b.X0 ? b.X0 : a.X0,
  27. a.Y0 > b.Y0 ? b.Y0 : a.Y0,
  28. a.X1 < b.X1 ? b.X1 : a.X1,
  29. a.Y1 < b.Y1 ? b.Y1 : a.Y1 };
  30. }
  31. MuPDF::BBox MuPDF::BBox::operator|(BBox a, BBox b) {
  32. /* Check for empty box before infinite box */
  33. if (!b.IsValid) return a;
  34. if (!a.IsValid) return b;
  35. if (a.IsInfinite) return a;
  36. if (b.IsInfinite) return b;
  37. return { a.X0 > b.X0 ? b.X0 : a.X0,
  38. a.Y0 > b.Y0 ? b.Y0 : a.Y0,
  39. a.X1 < b.X1 ? b.X1 : a.X1,
  40. a.Y1 < b.Y1 ? b.Y1 : a.Y1 };
  41. }
  42. MuPDF::BBox::operator BBox(Box box) {
  43. const static float t = 0.001f;
  44. return { (int)floor(box.X0 + t), (int)floor(box.Y0 + t), (int)ceil(box.X1 - t), (int)ceil(box.Y1 - t) };
  45. }
  46. MuPDF::BBox MuPDF::BBox::operator&(BBox a, BBox b) {
  47. if (b.IsInfinite) return a;
  48. if (a.IsInfinite) return b;
  49. return { a.X0 < b.X0 ? b.X0 : a.X0,
  50. a.Y0 < b.Y0 ? b.Y0 : a.Y0,
  51. a.X1 > b.X1 ? b.X1 : a.X1,
  52. a.Y1 > b.Y1 ? b.Y1 : a.Y1
  53. };
  54. }
  55. MuPDF::Matrix MuPDF::Matrix::Concat(Matrix value) {
  56. return Matrix(
  57. A * value.A + B * value.C,
  58. A * value.B + B * value.D,
  59. C * value.A + D * value.C,
  60. C * value.B + D * value.D,
  61. E * value.A + F * value.C + value.E,
  62. E * value.B + F * value.D + value.F);
  63. }
  64. MuPDF::Matrix MuPDF::Matrix::RotateTo(float theta) {
  65. while (theta < 0)
  66. theta += 360;
  67. while (theta >= 360)
  68. theta -= 360;
  69. if (fabs(0 - theta) < FLT_EPSILON) {
  70. return *this;
  71. }
  72. if (fabs(90.0f - theta) < FLT_EPSILON) {
  73. return Matrix(C, D, -A, -B, E, F);
  74. }
  75. if (fabs(180.0f - theta) < FLT_EPSILON) {
  76. return Matrix(-A, -B, -C, -D, E, F);
  77. }
  78. if (fabs(270.0f - theta) < FLT_EPSILON) {
  79. return Matrix(-C, -D, A, B, E, F);
  80. }
  81. float s = sin(theta * FZ_PI / 180);
  82. float c = cos(theta * FZ_PI / 180);
  83. return Matrix(c * A + s * C, c * B + s * D, -s * A + c * C, -s * B + c * D, E, F);
  84. }
  85. MuPDF::Matrix MuPDF::Matrix::ShearTo(float h, float v) {
  86. return Matrix(
  87. v * C + A,
  88. v * D + B,
  89. h * A + C,
  90. h * B + D,
  91. E, F);
  92. }
  93. MuPDF::Matrix MuPDF::Matrix::Rotate(float theta) {
  94. float s;
  95. float c;
  96. while (theta < 0)
  97. theta += 360;
  98. while (theta >= 360)
  99. theta -= 360;
  100. if (fabs(0 - theta) < FLT_EPSILON) {
  101. s = 0;
  102. c = 1;
  103. }
  104. else if (fabs(90.0f - theta) < FLT_EPSILON) {
  105. s = 1;
  106. c = 0;
  107. }
  108. else if (fabs(180.0f - theta) < FLT_EPSILON) {
  109. s = 0;
  110. c = -1;
  111. }
  112. else if (fabs(270.0f - theta) < FLT_EPSILON) {
  113. s = -1;
  114. c = 0;
  115. }
  116. else {
  117. s = sin(theta * FZ_PI / 180);
  118. c = cos(theta * FZ_PI / 180);
  119. }
  120. return MuPDF::Matrix(c, s, -s, c, 0, 0);
  121. }
  122. MuPDF::Quad MuPDF::Quad::Union(Quad other) {
  123. float x1 = fz_min(fz_min(UpperLeft.X, other.UpperLeft.X), fz_min(LowerLeft.X, other.LowerLeft.X));
  124. float x2 = fz_max(fz_max(UpperLeft.X, other.UpperLeft.X), fz_max(LowerLeft.X, other.LowerLeft.X));
  125. float y1 = fz_min(fz_min(UpperLeft.Y, other.UpperLeft.Y), fz_min(LowerLeft.Y, other.LowerLeft.Y));
  126. float y2 = fz_max(fz_max(UpperLeft.Y, other.UpperLeft.Y), fz_max(LowerLeft.Y, other.LowerLeft.Y));
  127. return Quad(Point(x1, y1), Point(x2, y2), Point(x1, y2), Point(x2, y2));
  128. }
  129. MuPDF::Box MuPDF::Quad::ToBox() {
  130. float x0, y0, x1, y1;
  131. x0 = fz_min(fz_min(LowerLeft.X, LowerRight.X), fz_min(UpperLeft.X, UpperRight.X));
  132. y0 = fz_min(fz_min(LowerLeft.Y, LowerRight.Y), fz_min(UpperLeft.Y, UpperRight.Y));
  133. x1 = fz_max(fz_max(LowerLeft.X, LowerRight.X), fz_max(UpperLeft.X, UpperRight.X));
  134. y1 = fz_max(fz_max(LowerLeft.Y, LowerRight.Y), fz_max(UpperLeft.Y, UpperRight.Y));
  135. return Box(x0, y0, x1, y1);
  136. }
  137. bool MuPDF::Quad::IsPointInsideTriangle(Point p, Point a, Point b, Point c) {
  138. float s, t, area;
  139. s = a.Y * c.X - a.X * c.Y + (c.Y - a.Y) * p.X + (a.X - c.X) * p.Y;
  140. t = a.X * b.Y - a.Y * b.X + (a.Y - b.Y) * p.X + (b.X - a.X) * p.Y;
  141. if ((s < 0) != (t < 0))
  142. return 0;
  143. area = -b.Y * c.X + a.Y * (c.X - b.X) + a.X * (b.Y - c.Y) + b.X * c.Y;
  144. return area < 0 ?
  145. (s <= 0 && s + t >= area) :
  146. (s >= 0 && s + t <= area);
  147. }