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. fz_path *
  4. fz_new_path(void)
  5. {
  6.         fz_path *path;
  7.  
  8.         path = fz_malloc(sizeof(fz_path));
  9.         path->len = 0;
  10.         path->cap = 0;
  11.         path->items = NULL;
  12.  
  13.         return path;
  14. }
  15.  
  16. fz_path *
  17. fz_clone_path(fz_path *old)
  18. {
  19.         fz_path *path;
  20.  
  21.         path = fz_malloc(sizeof(fz_path));
  22.         path->len = old->len;
  23.         path->cap = old->len;
  24.         path->items = fz_calloc(path->cap, sizeof(fz_path_item));
  25.         memcpy(path->items, old->items, sizeof(fz_path_item) * path->len);
  26.  
  27.         return path;
  28. }
  29.  
  30. void
  31. fz_free_path(fz_path *path)
  32. {
  33.         fz_free(path->items);
  34.         fz_free(path);
  35. }
  36.  
  37. static void
  38. grow_path(fz_path *path, int n)
  39. {
  40.         if (path->len + n < path->cap)
  41.                 return;
  42.         while (path->len + n > path->cap)
  43.                 path->cap = path->cap + 36;
  44.         path->items = fz_realloc(path->items, path->cap, sizeof(fz_path_item));
  45. }
  46.  
  47. void
  48. fz_moveto(fz_path *path, float x, float y)
  49. {
  50.         grow_path(path, 3);
  51.         path->items[path->len++].k = FZ_MOVETO;
  52.         path->items[path->len++].v = x;
  53.         path->items[path->len++].v = y;
  54. }
  55.  
  56. void
  57. fz_lineto(fz_path *path, float x, float y)
  58. {
  59.         if (path->len == 0)
  60.         {
  61.                 fz_warn("lineto with no current point");
  62.                 return;
  63.         }
  64.         grow_path(path, 3);
  65.         path->items[path->len++].k = FZ_LINETO;
  66.         path->items[path->len++].v = x;
  67.         path->items[path->len++].v = y;
  68. }
  69.  
  70. void
  71. fz_curveto(fz_path *path,
  72.         float x1, float y1,
  73.         float x2, float y2,
  74.         float x3, float y3)
  75. {
  76.         if (path->len == 0)
  77.         {
  78.                 fz_warn("curveto with no current point");
  79.                 return;
  80.         }
  81.         grow_path(path, 7);
  82.         path->items[path->len++].k = FZ_CURVETO;
  83.         path->items[path->len++].v = x1;
  84.         path->items[path->len++].v = y1;
  85.         path->items[path->len++].v = x2;
  86.         path->items[path->len++].v = y2;
  87.         path->items[path->len++].v = x3;
  88.         path->items[path->len++].v = y3;
  89. }
  90.  
  91. void
  92. fz_curvetov(fz_path *path, float x2, float y2, float x3, float y3)
  93. {
  94.         float x1, y1;
  95.         if (path->len == 0)
  96.         {
  97.                 fz_warn("curvetov with no current point");
  98.                 return;
  99.         }
  100.         x1 = path->items[path->len-2].v;
  101.         y1 = path->items[path->len-1].v;
  102.         fz_curveto(path, x1, y1, x2, y2, x3, y3);
  103. }
  104.  
  105. void
  106. fz_curvetoy(fz_path *path, float x1, float y1, float x3, float y3)
  107. {
  108.         fz_curveto(path, x1, y1, x3, y3, x3, y3);
  109. }
  110.  
  111. void
  112. fz_closepath(fz_path *path)
  113. {
  114.         if (path->len == 0)
  115.         {
  116.                 fz_warn("closepath with no current point");
  117.                 return;
  118.         }
  119.         grow_path(path, 1);
  120.         path->items[path->len++].k = FZ_CLOSE_PATH;
  121. }
  122.  
  123. static inline fz_rect bound_expand(fz_rect r, fz_point p)
  124. {
  125.         if (p.x < r.x0) r.x0 = p.x;
  126.         if (p.y < r.y0) r.y0 = p.y;
  127.         if (p.x > r.x1) r.x1 = p.x;
  128.         if (p.y > r.y1) r.y1 = p.y;
  129.         return r;
  130. }
  131.  
  132. fz_rect
  133. fz_bound_path(fz_path *path, fz_stroke_state *stroke, fz_matrix ctm)
  134. {
  135.         fz_point p;
  136.         fz_rect r = fz_empty_rect;
  137.         int i = 0;
  138.  
  139.         if (path->len)
  140.         {
  141.                 p.x = path->items[1].v;
  142.                 p.y = path->items[2].v;
  143.                 p = fz_transform_point(ctm, p);
  144.                 r.x0 = r.x1 = p.x;
  145.                 r.y0 = r.y1 = p.y;
  146.         }
  147.  
  148.         while (i < path->len)
  149.         {
  150.                 switch (path->items[i++].k)
  151.                 {
  152.                 case FZ_CURVETO:
  153.                         p.x = path->items[i++].v;
  154.                         p.y = path->items[i++].v;
  155.                         r = bound_expand(r, fz_transform_point(ctm, p));
  156.                         p.x = path->items[i++].v;
  157.                         p.y = path->items[i++].v;
  158.                         r = bound_expand(r, fz_transform_point(ctm, p));
  159.                         p.x = path->items[i++].v;
  160.                         p.y = path->items[i++].v;
  161.                         r = bound_expand(r, fz_transform_point(ctm, p));
  162.                         break;
  163.                 case FZ_MOVETO:
  164.                 case FZ_LINETO:
  165.                         p.x = path->items[i++].v;
  166.                         p.y = path->items[i++].v;
  167.                         r = bound_expand(r, fz_transform_point(ctm, p));
  168.                         break;
  169.                 case FZ_CLOSE_PATH:
  170.                         break;
  171.                 }
  172.         }
  173.  
  174.         if (stroke)
  175.         {
  176.                 float miterlength = stroke->miterlimit;
  177.                 float linewidth = stroke->linewidth;
  178.                 float expand = MAX(miterlength, linewidth) * 0.5f;
  179.                 r.x0 -= expand;
  180.                 r.y0 -= expand;
  181.                 r.x1 += expand;
  182.                 r.y1 += expand;
  183.         }
  184.  
  185.         return r;
  186. }
  187.  
  188. void
  189. fz_transform_path(fz_path *path, fz_matrix ctm)
  190. {
  191.         fz_point p;
  192.         int k, i = 0;
  193.  
  194.         while (i < path->len)
  195.         {
  196.                 switch (path->items[i++].k)
  197.                 {
  198.                 case FZ_CURVETO:
  199.                         for (k = 0; k < 3; k++)
  200.                         {
  201.                                 p.x = path->items[i].v;
  202.                                 p.y = path->items[i+1].v;
  203.                                 p = fz_transform_point(ctm, p);
  204.                                 path->items[i].v = p.x;
  205.                                 path->items[i+1].v = p.y;
  206.                                 i += 2;
  207.                         }
  208.                         break;
  209.                 case FZ_MOVETO:
  210.                 case FZ_LINETO:
  211.                         p.x = path->items[i].v;
  212.                         p.y = path->items[i+1].v;
  213.                         p = fz_transform_point(ctm, p);
  214.                         path->items[i].v = p.x;
  215.                         path->items[i+1].v = p.y;
  216.                         i += 2;
  217.                         break;
  218.                 case FZ_CLOSE_PATH:
  219.                         break;
  220.                 }
  221.         }
  222. }
  223.  
  224. void
  225. fz_debug_path(fz_path *path, int indent)
  226. {
  227.         float x, y;
  228.         int i = 0;
  229.         int n;
  230.         while (i < path->len)
  231.         {
  232.                 for (n = 0; n < indent; n++)
  233.                         putchar(' ');
  234.                 switch (path->items[i++].k)
  235.                 {
  236.                 case FZ_MOVETO:
  237.                         x = path->items[i++].v;
  238.                         y = path->items[i++].v;
  239.                         printf("%g %g m\n", x, y);
  240.                         break;
  241.                 case FZ_LINETO:
  242.                         x = path->items[i++].v;
  243.                         y = path->items[i++].v;
  244.                         printf("%g %g l\n", x, y);
  245.                         break;
  246.                 case FZ_CURVETO:
  247.                         x = path->items[i++].v;
  248.                         y = path->items[i++].v;
  249.                         printf("%g %g ", x, y);
  250.                         x = path->items[i++].v;
  251.                         y = path->items[i++].v;
  252.                         printf("%g %g ", x, y);
  253.                         x = path->items[i++].v;
  254.                         y = path->items[i++].v;
  255.                         printf("%g %g c\n", x, y);
  256.                         break;
  257.                 case FZ_CLOSE_PATH:
  258.                         printf("h\n");
  259.                         break;
  260.                 }
  261.         }
  262. }
  263.