Draw_line.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * draw a line between two given points in the current color.
  3. *
  4. * Called by:
  5. * Cont_abs() in ../lib/Cont_abs.c
  6. */
  7. #include <stdlib.h>
  8. #include <math.h>
  9. #include "pngdriver.h"
  10. static void store_xy(double x, double y)
  11. {
  12. int xi = (int) floor(x);
  13. int yi = (int) floor(y);
  14. if (x < png.clip_left || x >= png.clip_rite || y < png.clip_top || y >= png.clip_bot)
  15. return;
  16. png.grid[yi * png.width + xi] = png.current_color;
  17. }
  18. static void swap(double *a, double *b)
  19. {
  20. double t = *a; *a = *b; *b = t;
  21. }
  22. static void draw_line(double x1, double y1, double x2, double y2)
  23. {
  24. double x, y;
  25. double dx, dy;
  26. if (fabs(y1 - y2) > fabs(x1 - x2)) {
  27. if (y1 > y2) {
  28. swap(&y1, &y2);
  29. swap(&x1, &x2);
  30. }
  31. dy = y2 - y1;
  32. dx = x2 - x1;
  33. for (y = floor(y1) + 0.5; y < y2; y++) {
  34. x = x1 + (y - y1) * dx / dy;
  35. store_xy(x, y);
  36. }
  37. }
  38. else {
  39. if (x1 > x2) {
  40. swap(&x1, &x2);
  41. swap(&y1, &y2);
  42. }
  43. dx = x2 - x1;
  44. dy = y2 - y1;
  45. for (x = floor(x1) + 0.5; x < x2; x++) {
  46. y = y1 + (x - x1) * dy / dx;
  47. store_xy(x, y);
  48. }
  49. }
  50. }
  51. void png_draw_line(double x1, double y1, double x2, double y2)
  52. {
  53. struct path path;
  54. struct vertex vertices[5];
  55. double k = png.linewidth / 2;
  56. int dx, dy;
  57. if (png.linewidth <= 1) {
  58. draw_line(x1, y1, x2, y2);
  59. png.modified = 1;
  60. return;
  61. }
  62. path.vertices = vertices;
  63. path.count = 0;
  64. path.alloc = 5;
  65. path.start = -1;
  66. if (dy > dx) {
  67. path_move(&path, x1 - k, y1);
  68. path_cont(&path, x1 + k, y1);
  69. path_cont(&path, x2 + k, y2);
  70. path_cont(&path, x2 - k, y2);
  71. path_close(&path);
  72. }
  73. else {
  74. path_move(&path, x1, y1 - k);
  75. path_cont(&path, x1, y1 + k);
  76. path_cont(&path, x2, y2 + k);
  77. path_cont(&path, x2, y2 - k);
  78. path_close(&path);
  79. }
  80. png_polygon(&path);
  81. }