mi_scanfill.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. /* This file is part of the GNU libxmi package.
  2. Copyright (C) 1985, 1986, 1987, 1988, 1989, X Consortium. For an
  3. associated permission notice, see the accompanying file README-X.
  4. GNU enhancements Copyright (C) 1998, 1999, 2000, 2005, Free Software
  5. Foundation, Inc.
  6. The GNU libxmi package is free software. You may redistribute it
  7. and/or modify it under the terms of the GNU General Public License as
  8. published by the Free Software foundation; either version 2, or (at your
  9. option) any later version.
  10. The GNU libxmi package is distributed in the hope that it will be
  11. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. General Public License for more details.
  14. You should have received a copy of the GNU General Public License along
  15. with the GNU plotutils package; see the file COPYING. If not, write to
  16. the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
  17. Boston, MA 02110-1301, USA. */
  18. #ifndef SCANFILLINCLUDED
  19. #define SCANFILLINCLUDED
  20. /*
  21. * miscanfill.h
  22. *
  23. * Written by Brian Kelleher; Jan 1985
  24. *
  25. * This file contains a few macros to help track
  26. * the edge of a filled object. The object is assumed
  27. * to be filled in scanline order, and thus the
  28. * algorithm used is an extension of Bresenham's line
  29. * drawing algorithm which assumes that y is always the
  30. * major axis.
  31. * Since these pieces of code are the same for any filled shape,
  32. * it is more convenient to gather the library in one
  33. * place, but since these pieces of code are also in
  34. * the inner loops of output primitives, procedure call
  35. * overhead is out of the question.
  36. * See the author for a derivation if needed.
  37. */
  38. /*
  39. * In scan converting polygons, we want to choose those pixels
  40. * which are inside the polygon. Thus, we add .5 to the starting
  41. * x coordinate for both left and right edges. Now we choose the
  42. * first pixel which is inside the polygon for the left edge and the
  43. * first pixel which is outside the polygon for the right edge.
  44. * Draw the left pixel, but not the right.
  45. *
  46. * How to add .5 to the starting x coordinate:
  47. * If the edge is moving to the right, then subtract dy from the
  48. * error term from the general form of the algorithm.
  49. * If the edge is moving to the left, then add dy to the error term.
  50. *
  51. * The reason for the difference between edges moving to the left
  52. * and edges moving to the right is simple: If an edge is moving
  53. * to the right, then we want the algorithm to flip immediately.
  54. * If it is moving to the left, then we don't want it to flip until
  55. * we traverse an entire pixel.
  56. */
  57. #define BRESINITPGON(dy, x1, x2, xStart, d, m, m1, incr1, incr2) { \
  58. int dx; /* local storage */ \
  59. \
  60. /* \
  61. * if the edge is horizontal, then it is ignored \
  62. * and assumed not to be processed. Otherwise, do this stuff. \
  63. */ \
  64. if ((dy) != 0) { \
  65. xStart = (x1); \
  66. dx = (x2) - xStart; \
  67. if (dx < 0) { \
  68. m = dx / (dy); \
  69. m1 = m - 1; \
  70. incr1 = -2 * dx + 2 * (dy) * m1; \
  71. incr2 = -2 * dx + 2 * (dy) * m; \
  72. d = 2 * m * (dy) - 2 * dx - 2 * (dy); \
  73. } else { \
  74. m = dx / (dy); \
  75. m1 = m + 1; \
  76. incr1 = 2 * dx - 2 * (dy) * m1; \
  77. incr2 = 2 * dx - 2 * (dy) * m; \
  78. d = -2 * m * (dy) + 2 * dx; \
  79. } \
  80. } \
  81. }
  82. #define BRESINCRPGON(d, minval, m, m1, incr1, incr2) { \
  83. if (m1 > 0) { \
  84. if (d > 0) { \
  85. minval += m1; \
  86. d += incr1; \
  87. } \
  88. else { \
  89. minval += m; \
  90. d += incr2; \
  91. } \
  92. } else {\
  93. if (d >= 0) { \
  94. minval += m1; \
  95. d += incr1; \
  96. } \
  97. else { \
  98. minval += m; \
  99. d += incr2; \
  100. } \
  101. } \
  102. }
  103. /*
  104. * This structure contains all of the information needed
  105. * to run the bresenham algorithm.
  106. * The variables may be hardcoded into the declarations
  107. * instead of using this structure to make use of
  108. * register declarations.
  109. */
  110. typedef struct
  111. {
  112. int minor_axis; /* minor axis */
  113. int d; /* decision variable */
  114. int m, m1; /* slope and slope+1 */
  115. int incr1, incr2; /* error increments */
  116. } BRESINFO;
  117. #define BRESINITPGONSTRUCT(dmaj, min1, min2, bres) \
  118. BRESINITPGON(dmaj, min1, min2, bres.minor_axis, bres.d, \
  119. bres.m, bres.m1, bres.incr1, bres.incr2)
  120. #define BRESINCRPGONSTRUCT(bres) \
  121. BRESINCRPGON(bres.d, bres.minor_axis, bres.m, bres.m1, bres.incr1, bres.incr2)
  122. #endif