1. /*
  2. * @(#)CubicIterator.java 1.9 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.awt.geom;
  8. import java.util.*;
  9. /**
  10. * A utility class to iterate over the path segments of a cubic curve
  11. * segment through the PathIterator interface.
  12. *
  13. * @version 10 Feb 1997
  14. * @author Jim Graham
  15. */
  16. class CubicIterator implements PathIterator {
  17. CubicCurve2D cubic;
  18. AffineTransform affine;
  19. int index;
  20. CubicIterator(CubicCurve2D q, AffineTransform at) {
  21. this.cubic = q;
  22. this.affine = at;
  23. }
  24. /**
  25. * Return the winding rule for determining the insideness of the
  26. * path.
  27. * @see #WIND_EVEN_ODD
  28. * @see #WIND_NON_ZERO
  29. */
  30. public int getWindingRule() {
  31. return WIND_NON_ZERO;
  32. }
  33. /**
  34. * Tests if there are more points to read.
  35. * @return true if there are more points to read
  36. */
  37. public boolean isDone() {
  38. return (index > 1);
  39. }
  40. /**
  41. * Moves the iterator to the next segment of the path forwards
  42. * along the primary direction of traversal as long as there are
  43. * more points in that direction.
  44. */
  45. public void next() {
  46. index++;
  47. }
  48. /**
  49. * Returns the coordinates and type of the current path segment in
  50. * the iteration.
  51. * The return value is the path segment type:
  52. * SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE.
  53. * A float array of length 6 must be passed in and may be used to
  54. * store the coordinates of the point(s).
  55. * Each point is stored as a pair of float x,y coordinates.
  56. * SEG_MOVETO and SEG_LINETO types will return one point,
  57. * SEG_QUADTO will return two points,
  58. * SEG_CUBICTO will return 3 points
  59. * and SEG_CLOSE will not return any points.
  60. * @see #SEG_MOVETO
  61. * @see #SEG_LINETO
  62. * @see #SEG_QUADTO
  63. * @see #SEG_CUBICTO
  64. * @see #SEG_CLOSE
  65. */
  66. public int currentSegment(float[] coords) {
  67. if (isDone()) {
  68. throw new NoSuchElementException("cubic iterator iterator out of bounds");
  69. }
  70. int type;
  71. if (index == 0) {
  72. coords[0] = (float) cubic.getX1();
  73. coords[1] = (float) cubic.getY1();
  74. type = SEG_MOVETO;
  75. } else {
  76. coords[0] = (float) cubic.getCtrlX1();
  77. coords[1] = (float) cubic.getCtrlY1();
  78. coords[2] = (float) cubic.getCtrlX2();
  79. coords[3] = (float) cubic.getCtrlY2();
  80. coords[4] = (float) cubic.getX2();
  81. coords[5] = (float) cubic.getY2();
  82. type = SEG_CUBICTO;
  83. }
  84. if (affine != null) {
  85. affine.transform(coords, 0, coords, 0, index == 0 ? 1 : 3);
  86. }
  87. return type;
  88. }
  89. /**
  90. * Returns the coordinates and type of the current path segment in
  91. * the iteration.
  92. * The return value is the path segment type:
  93. * SEG_MOVETO, SEG_LINETO, SEG_QUADTO, SEG_CUBICTO, or SEG_CLOSE.
  94. * A double array of length 6 must be passed in and may be used to
  95. * store the coordinates of the point(s).
  96. * Each point is stored as a pair of double x,y coordinates.
  97. * SEG_MOVETO and SEG_LINETO types will return one point,
  98. * SEG_QUADTO will return two points,
  99. * SEG_CUBICTO will return 3 points
  100. * and SEG_CLOSE will not return any points.
  101. * @see #SEG_MOVETO
  102. * @see #SEG_LINETO
  103. * @see #SEG_QUADTO
  104. * @see #SEG_CUBICTO
  105. * @see #SEG_CLOSE
  106. */
  107. public int currentSegment(double[] coords) {
  108. if (isDone()) {
  109. throw new NoSuchElementException("cubic iterator iterator out of bounds");
  110. }
  111. int type;
  112. if (index == 0) {
  113. coords[0] = cubic.getX1();
  114. coords[1] = cubic.getY1();
  115. type = SEG_MOVETO;
  116. } else {
  117. coords[0] = cubic.getCtrlX1();
  118. coords[1] = cubic.getCtrlY1();
  119. coords[2] = cubic.getCtrlX2();
  120. coords[3] = cubic.getCtrlY2();
  121. coords[4] = cubic.getX2();
  122. coords[5] = cubic.getY2();
  123. type = SEG_CUBICTO;
  124. }
  125. if (affine != null) {
  126. affine.transform(coords, 0, coords, 0, index == 0 ? 1 : 3);
  127. }
  128. return type;
  129. }
  130. }