Draw_line.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  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. double ax[4], ay[4];
  54. double k = png.linewidth / 2;
  55. int dx, dy;
  56. if (png.linewidth <= 1) {
  57. draw_line(x1, y1, x2, y2);
  58. png.modified = 1;
  59. return;
  60. }
  61. if (dy > dx) {
  62. ax[0] = x1 - k; ay[0] = y1;
  63. ax[1] = x1 + k; ay[1] = y1;
  64. ax[2] = x2 + k; ay[2] = y2;
  65. ax[3] = x2 - k; ay[3] = y2;
  66. }
  67. else {
  68. ax[0] = x1; ay[0] = y1 - k;
  69. ax[1] = x1; ay[1] = y1 + k;
  70. ax[2] = x2; ay[2] = y2 + k;
  71. ax[3] = x2; ay[3] = y2 - k;
  72. }
  73. png_polygon(ax, ay, 4);
  74. }