Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2.  
  3. #define MAX4(a,b,c,d) MAX(MAX(a,b), MAX(c,d))
  4. #define MIN4(a,b,c,d) MIN(MIN(a,b), MIN(c,d))
  5.  
  6. /* Matrices, points and affine transformations */
  7.  
  8. const fz_matrix fz_identity = { 1, 0, 0, 1, 0, 0 };
  9.  
  10. fz_matrix
  11. fz_concat(fz_matrix one, fz_matrix two)
  12. {
  13.         fz_matrix dst;
  14.         dst.a = one.a * two.a + one.b * two.c;
  15.         dst.b = one.a * two.b + one.b * two.d;
  16.         dst.c = one.c * two.a + one.d * two.c;
  17.         dst.d = one.c * two.b + one.d * two.d;
  18.         dst.e = one.e * two.a + one.f * two.c + two.e;
  19.         dst.f = one.e * two.b + one.f * two.d + two.f;
  20.         return dst;
  21. }
  22.  
  23. fz_matrix
  24. fz_scale(float sx, float sy)
  25. {
  26.         fz_matrix m;
  27.         m.a = sx; m.b = 0;
  28.         m.c = 0; m.d = sy;
  29.         m.e = 0; m.f = 0;
  30.         return m;
  31. }
  32.  
  33. fz_matrix
  34. fz_shear(float h, float v)
  35. {
  36.         fz_matrix m;
  37.         m.a = 1; m.b = v;
  38.         m.c = h; m.d = 1;
  39.         m.e = 0; m.f = 0;
  40.         return m;
  41. }
  42.  
  43. fz_matrix
  44. fz_rotate(float theta)
  45. {
  46.         fz_matrix m;
  47.         float s;
  48.         float c;
  49.  
  50.         while (theta < 0)
  51.                 theta += 360;
  52.         while (theta >= 360)
  53.                 theta -= 360;
  54.  
  55.         if (fabsf(0 - theta) < FLT_EPSILON)
  56.         {
  57.                 s = 0;
  58.                 c = 1;
  59.         }
  60.         else if (fabsf(90.0f - theta) < FLT_EPSILON)
  61.         {
  62.                 s = 1;
  63.                 c = 0;
  64.         }
  65.         else if (fabsf(180.0f - theta) < FLT_EPSILON)
  66.         {
  67.                 s = 0;
  68.                 c = -1;
  69.         }
  70.         else if (fabsf(270.0f - theta) < FLT_EPSILON)
  71.         {
  72.                 s = -1;
  73.                 c = 0;
  74.         }
  75.         else
  76.         {
  77.                 s = sinf(theta * (float)M_PI / 180);
  78.                 c = cosf(theta * (float)M_PI / 180);
  79.         }
  80.  
  81.         m.a = c; m.b = s;
  82.         m.c = -s; m.d = c;
  83.         m.e = 0; m.f = 0;
  84.         return m;
  85. }
  86.  
  87. fz_matrix
  88. fz_translate(float tx, float ty)
  89. {
  90.         fz_matrix m;
  91.         m.a = 1; m.b = 0;
  92.         m.c = 0; m.d = 1;
  93.         m.e = tx; m.f = ty;
  94.         return m;
  95. }
  96.  
  97. fz_matrix
  98. fz_invert_matrix(fz_matrix src)
  99. {
  100.         fz_matrix dst;
  101.         float rdet = 1 / (src.a * src.d - src.b * src.c);
  102.         dst.a = src.d * rdet;
  103.         dst.b = -src.b * rdet;
  104.         dst.c = -src.c * rdet;
  105.         dst.d = src.a * rdet;
  106.         dst.e = -src.e * dst.a - src.f * dst.c;
  107.         dst.f = -src.e * dst.b - src.f * dst.d;
  108.         return dst;
  109. }
  110.  
  111. int
  112. fz_is_rectilinear(fz_matrix m)
  113. {
  114.         return (fabsf(m.b) < FLT_EPSILON && fabsf(m.c) < FLT_EPSILON) ||
  115.                 (fabsf(m.a) < FLT_EPSILON && fabsf(m.d) < FLT_EPSILON);
  116. }
  117.  
  118. float
  119. fz_matrix_expansion(fz_matrix m)
  120. {
  121.         return sqrtf(fabsf(m.a * m.d - m.b * m.c));
  122. }
  123.  
  124. fz_point
  125. fz_transform_point(fz_matrix m, fz_point p)
  126. {
  127.         fz_point t;
  128.         t.x = p.x * m.a + p.y * m.c + m.e;
  129.         t.y = p.x * m.b + p.y * m.d + m.f;
  130.         return t;
  131. }
  132.  
  133. fz_point
  134. fz_transform_vector(fz_matrix m, fz_point p)
  135. {
  136.         fz_point t;
  137.         t.x = p.x * m.a + p.y * m.c;
  138.         t.y = p.x * m.b + p.y * m.d;
  139.         return t;
  140. }
  141.  
  142. /* Rectangles and bounding boxes */
  143.  
  144. const fz_rect fz_infinite_rect = { 1, 1, -1, -1 };
  145. const fz_rect fz_empty_rect = { 0, 0, 0, 0 };
  146. const fz_rect fz_unit_rect = { 0, 0, 1, 1 };
  147.  
  148. const fz_bbox fz_infinite_bbox = { 1, 1, -1, -1 };
  149. const fz_bbox fz_empty_bbox = { 0, 0, 0, 0 };
  150. const fz_bbox fz_unit_bbox = { 0, 0, 1, 1 };
  151.  
  152. fz_bbox
  153. fz_round_rect(fz_rect f)
  154. {
  155.         fz_bbox i;
  156.         i.x0 = floorf(f.x0 + 0.001f); /* adjust by 0.001 to compensate for precision errors */
  157.         i.y0 = floorf(f.y0 + 0.001f);
  158.         i.x1 = ceilf(f.x1 - 0.001f);
  159.         i.y1 = ceilf(f.y1 - 0.001f);
  160.         return i;
  161. }
  162.  
  163. fz_rect
  164. fz_intersect_rect(fz_rect a, fz_rect b)
  165. {
  166.         fz_rect r;
  167.         if (fz_is_infinite_rect(a)) return b;
  168.         if (fz_is_infinite_rect(b)) return a;
  169.         if (fz_is_empty_rect(a)) return fz_empty_rect;
  170.         if (fz_is_empty_rect(b)) return fz_empty_rect;
  171.         r.x0 = MAX(a.x0, b.x0);
  172.         r.y0 = MAX(a.y0, b.y0);
  173.         r.x1 = MIN(a.x1, b.x1);
  174.         r.y1 = MIN(a.y1, b.y1);
  175.         return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_rect : r;
  176. }
  177.  
  178. fz_rect
  179. fz_union_rect(fz_rect a, fz_rect b)
  180. {
  181.         fz_rect r;
  182.         if (fz_is_infinite_rect(a)) return a;
  183.         if (fz_is_infinite_rect(b)) return b;
  184.         if (fz_is_empty_rect(a)) return b;
  185.         if (fz_is_empty_rect(b)) return a;
  186.         r.x0 = MIN(a.x0, b.x0);
  187.         r.y0 = MIN(a.y0, b.y0);
  188.         r.x1 = MAX(a.x1, b.x1);
  189.         r.y1 = MAX(a.y1, b.y1);
  190.         return r;
  191. }
  192.  
  193. fz_bbox
  194. fz_intersect_bbox(fz_bbox a, fz_bbox b)
  195. {
  196.         fz_bbox r;
  197.         if (fz_is_infinite_rect(a)) return b;
  198.         if (fz_is_infinite_rect(b)) return a;
  199.         if (fz_is_empty_rect(a)) return fz_empty_bbox;
  200.         if (fz_is_empty_rect(b)) return fz_empty_bbox;
  201.         r.x0 = MAX(a.x0, b.x0);
  202.         r.y0 = MAX(a.y0, b.y0);
  203.         r.x1 = MIN(a.x1, b.x1);
  204.         r.y1 = MIN(a.y1, b.y1);
  205.         return (r.x1 < r.x0 || r.y1 < r.y0) ? fz_empty_bbox : r;
  206. }
  207.  
  208. fz_bbox
  209. fz_union_bbox(fz_bbox a, fz_bbox b)
  210. {
  211.         fz_bbox r;
  212.         if (fz_is_infinite_rect(a)) return a;
  213.         if (fz_is_infinite_rect(b)) return b;
  214.         if (fz_is_empty_rect(a)) return b;
  215.         if (fz_is_empty_rect(b)) return a;
  216.         r.x0 = MIN(a.x0, b.x0);
  217.         r.y0 = MIN(a.y0, b.y0);
  218.         r.x1 = MAX(a.x1, b.x1);
  219.         r.y1 = MAX(a.y1, b.y1);
  220.         return r;
  221. }
  222.  
  223. fz_rect
  224. fz_transform_rect(fz_matrix m, fz_rect r)
  225. {
  226.         fz_point s, t, u, v;
  227.  
  228.         if (fz_is_infinite_rect(r))
  229.                 return r;
  230.  
  231.         s.x = r.x0; s.y = r.y0;
  232.         t.x = r.x0; t.y = r.y1;
  233.         u.x = r.x1; u.y = r.y1;
  234.         v.x = r.x1; v.y = r.y0;
  235.         s = fz_transform_point(m, s);
  236.         t = fz_transform_point(m, t);
  237.         u = fz_transform_point(m, u);
  238.         v = fz_transform_point(m, v);
  239.         r.x0 = MIN4(s.x, t.x, u.x, v.x);
  240.         r.y0 = MIN4(s.y, t.y, u.y, v.y);
  241.         r.x1 = MAX4(s.x, t.x, u.x, v.x);
  242.         r.y1 = MAX4(s.y, t.y, u.y, v.y);
  243.         return r;
  244. }
  245.  
  246. fz_bbox
  247. fz_transform_bbox(fz_matrix m, fz_bbox b)
  248. {
  249.         fz_point s, t, u, v;
  250.  
  251.         if (fz_is_infinite_bbox(b))
  252.                 return b;
  253.  
  254.         s.x = b.x0; s.y = b.y0;
  255.         t.x = b.x0; t.y = b.y1;
  256.         u.x = b.x1; u.y = b.y1;
  257.         v.x = b.x1; v.y = b.y0;
  258.         s = fz_transform_point(m, s);
  259.         t = fz_transform_point(m, t);
  260.         u = fz_transform_point(m, u);
  261.         v = fz_transform_point(m, v);
  262.         b.x0 = MIN4(s.x, t.x, u.x, v.x);
  263.         b.y0 = MIN4(s.y, t.y, u.y, v.y);
  264.         b.x1 = MAX4(s.x, t.x, u.x, v.x);
  265.         b.y1 = MAX4(s.y, t.y, u.y, v.y);
  266.         return b;
  267.  
  268. }
  269.